5.4.59-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 171/270 Smack: fix another vsscanf out of bounds
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit a6bd4f6d9b07452b0b19842044a6c3ea384b0b88 ]
This is similar to commit 84e99e58e8d1 ("Smack: slab-out-of-bounds in vsscanf") where we added a bounds check on "rule".
--- security/smack/smackfs.c | 4 ++++ 1 file changed, 4 insertions(+)
security/smack/smackfs.c +4 -0
@@ -905,6 +905,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,for (i =0 ; i < catlen; i++) { rule +=SMK_DIGITLEN ; +if (rule > data + count) { + rc = -EOVERFLOW ; + goto out; + } ret =sscanf (rule,"%u" , &cat);if (ret !=1 || cat >SMACK_CIPSO_MAXCATNUM ) goto out;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 172/270 Smack: prevent underflow in smk_set_cipso()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 42a2df3e829f3c5562090391b33714b2e2e5ad4a ]
We have an upper bound on "maplevel" but forgot to check for negative values.
--- security/smack/smackfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/smack/smackfs.c +1 -1
@@ -884,7 +884,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, } ret =sscanf (rule,"%d" , &maplevel); -if (ret !=1 || maplevel >SMACK_CIPSO_MAXLEVEL ) +if (ret !=1 || maplevel <0 || maplevel >SMACK_CIPSO_MAXLEVEL ) goto out; rule +=SMK_DIGITLEN ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 173/270 power: supply: check if calc_soc succeeded in pm860x_init_battery
In reply to Greg Kroah-HartmanFrom: Tom Rix <[email protected]>
[ Upstream commit ccf193dee1f0fff55b556928591f7818bac1b3b1 ]
clang static analysis flags this error
88pm860x_battery.c:522:19: warning: Assigned value is
garbage or undefined [core.uninitialized.Assign]
info->start_soc = soc;
^ ~~~soc is set by calling calc_soc.
But calc_soc can return without setting soc.
So check the return status and bail similarly to other checks in pm860x_init_battery and initialize soc to silence the warning.
--- drivers/power/supply/88pm860x_battery.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/power/supply/88pm860x_battery.c +4 -2
@@ -433,7 +433,7 @@ static void pm860x_init_battery(struct pm860x_battery_info *info)int ret;int data;int bat_remove; -int soc; +int soc =0 ;/* measure enable on GPADC1 */ data =MEAS1_GP1 ;
@@ -496,7 +496,9 @@ static void pm860x_init_battery(struct pm860x_battery_info *info) }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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 174/270 Bluetooth: hci_h5: Set HCI_UART_RESET_ON_INIT to correct flags
In reply to Greg Kroah-HartmanFrom: Nicolas Boichat <[email protected]>
[ Upstream commit a7ad4b6119d740b1ec5788f1b98be0fd1c1b5a5a ]
HCI_UART_RESET_ON_INIT belongs in hdev_flags, not flags.
--- drivers/bluetooth/hci_h5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/bluetooth/hci_h5.c +1 -1
@@ -790,7 +790,7 @@ static int h5_serdev_probe(struct serdev_device *serdev)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;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 175/270 Bluetooth: hci_serdev: Only unregister device if it was registered
In reply to Greg Kroah-HartmanFrom: Nicolas Boichat <[email protected]>
[ Upstream commit 202798db9570104728dce8bb57dfeed47ce764bc ]
We should not call hci_unregister_dev if the device was not successfully registered.
--- drivers/bluetooth/hci_serdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bluetooth/hci_serdev.c +2 -1
@@ -357,7 +357,8 @@ void hci_uart_unregister_device(struct hci_uart *hu)struct hci_dev *hdev = hu->hdev;clear_bit (HCI_UART_PROTO_READY , &hu->flags); -hci_unregister_dev (hdev); +if (test_bit (HCI_UART_REGISTERED , &hu->flags)) +hci_unregister_dev (hdev);hci_free_dev (hdev);cancel_work_sync (&hu->write_work);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 176/270 net: dsa: rtl8366: Fix VLAN semantics
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit 15ab7906cc9290afb006df1bb1074907fbcc7061 ]
The RTL8366 would not handle adding new members (ports) to a VLAN: the code assumed that ->port_vlan_add() was only called once for a single port. When intializing the switch with .configure_vlan_while_not_filtering set to true, the function is called numerous times for adding all ports to VLAN1, which was something the code could not handle.
Alter rtl8366_set_vlan() to just |= new members and untagged flags to 4k and MC VLAN table entries alike. This makes it possible to just add new ports to a VLAN.
Put in some helpful debug code that can be used to find any further bugs here.
--- drivers/net/dsa/rtl8366.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/net/dsa/rtl8366.c +17 -4
@@ -43,18 +43,26 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,int ret;int i; +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.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); +/* Try to find an existing MC entry for this VID */ for (i =0 ; i < smi->num_vlan_mc; i++) {struct rtl8366_vlan_mc vlanmc;
@@ -65,11 +73,16 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,if (vid == vlanmc.vid) {/* update the MC entry */ - vlanmc.member = member; - vlanmc.untag = untag; + vlanmc.member |= member; + vlanmc.untag |= untag; vlanmc.fid = fid; ret = smi->ops->set_vlan_mc (smi, i, &vlanmc); + +dev_dbg (smi->dev, +"resulting VLAN%d MC members: 0x%02x, untagged: 0x%02x\n" , + vid, vlanmc.member, vlanmc.untag); +break ; } }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 177/270 net: dsa: rtl8366: Fix VLAN set-up
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit 788abc6d9d278ed6fa1fa94db2098481a04152b7 ]
Alter the rtl8366_vlan_add() to call rtl8366_set_vlan() inside the loop that goes over all VIDs since we now properly support calling that function more than once. Augment the loop to postincrement as this is more intuitive.
The loop moved past the last VID but called rtl8366_set_vlan() with the port number instead of the VID, assuming a 1-to-1 correspondence between ports and VIDs. This was also a bug.
--- drivers/net/dsa/rtl8366.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/dsa/rtl8366.c +7 -7
@@ -397,7 +397,7 @@ void rtl8366_vlan_add(struct dsa_switch *ds, int port,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) { +for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {int pvid_val =0 ;dev_info (smi->dev,"add VLAN %04x\n" , vid);
@@ -420,13 +420,13 @@ void rtl8366_vlan_add(struct dsa_switch *ds, int port,if (ret <0 )return ; } - } - ret =rtl8366_set_vlan (smi, port, member, untag,0 ); -if (ret) -dev_err (smi->dev, -"failed to set up VLAN %04x" , - vid); + ret =rtl8366_set_vlan (smi, vid, member, untag,0 ); +if (ret) +dev_err (smi->dev, +"failed to set up VLAN %04x" , + vid); + } }EXPORT_SYMBOL_GPL (rtl8366_vlan_add);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 178/270 xfs: fix inode allocation block res calculation precedence
In reply to Greg Kroah-HartmanFrom: Brian Foster <[email protected]>
[ Upstream commit b2a8864728683443f34a9fd33a2b78b860934cc1 ]
The block reservation calculation for inode allocation is supposed to consist of the blocks required for the inode chunk plus (maxlevels-1) of the inode btree multiplied by the number of inode btrees in the fs (2 when finobt is enabled, 1 otherwise).
Instead, the macro returns (ialloc_blocks + 2) due to a precedence error in the calculation logic. This leads to block reservation overruns via generic/531 on small block filesystems with finobt enabled. Add braces to fix the calculation and reserve the appropriate number of blocks.
--- fs/xfs/libxfs/xfs_trans_space.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/libxfs/xfs_trans_space.h +1 -1
@@ -57,7 +57,7 @@ XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)#define XFS_IALLOC_SPACE_RES (mp) \ (M_IGEO(mp)->ialloc_blks + \ - (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \ + ((xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1) * \ (M_IGEO(mp)->inobt_maxlevels - 1)))/*
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 179/270 selftests/powerpc: Squash spurious errors due to device removal
In reply to Greg Kroah-HartmanFrom: Oliver O'Halloran <[email protected]>
[ Upstream commit 5f8cf6475828b600ff6d000e580c961ac839cc61 ]
For drivers that don't have the error handling callbacks we implement recovery by removing the device and re-probing it. This causes the sysfs directory for the PCI device to be removed which causes the following spurious error to be printed when checking the PE state:
Breaking 0005:03:00.0...
./eeh-basic.sh: line 13: can't open /sys/bus/pci/devices/0005:03:00.0/eeh_pe_state: no such file 0005:03:00.0, waited 0/60
0005:03:00.0, waited 1/60
0005:03:00.0, waited 2/60
0005:03:00.0, waited 3/60
0005:03:00.0, waited 4/60
0005:03:00.0, waited 5/60
0005:03:00.0, waited 6/60
0005:03:00.0, waited 7/60
0005:03:00.0, Recovered after 8 seconds
We currently try to avoid this by checking if the PE state file exists before reading from it. This is however inherently racy so re-work the state checking so that we only read from the file once, and we squash any errors that occur while reading.
--- tools/testing/selftests/powerpc/eeh/eeh-functions.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
tools/testing/selftests/powerpc/eeh/eeh-functions.sh +8 -3
@@ -5,12 +5,17 @@ pe_ok() { local dev="$1" local path="/sys/bus/pci/devices/$dev/eeh_pe_state" - if ! [ -e "$path" ] ; then + # if a driver doesn't support the error handling callbacks then the + # device is recovered by removing and re-probing it. This causes the + # sysfs directory to disappear so read the PE state once and squash + # any potential error messages + local eeh_state="$(cat $path 2>/dev/null)" + if [ -z "$eeh_state" ]; then return 1; fi - local fw_state="$(cut -d' ' -f1 < $path)" - local sw_state="$(cut -d' ' -f2 < $path)" + local fw_state="$(echo $eeh_state | cut -d' ' -f1)" + local sw_state="$(echo $eeh_state | cut -d' ' -f2)" # If EEH_PE_ISOLATED or EEH_PE_RECOVERING are set then the PE is in an # error state or being recovered. Either way, not ok.
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 180/270 powerpc/32s: Fix CONFIG_BOOK3S_601 uses
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit df4d4ef22446b3a789a4efd74d34f2ec1e24deb2 ]
We have two uses of CONFIG_BOOK3S_601, which doesn't exist. Fix them to use CONFIG_PPC_BOOK3S_601 which is the correct symbol.
--- arch/powerpc/include/asm/ptrace.h | 2 +- arch/powerpc/include/asm/timex.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/ptrace.h +1 -1
@@ -203,7 +203,7 @@ do { \#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)
arch/powerpc/include/asm/timex.h +1 -1
@@ -17,7 +17,7 @@ typedef unsigned long cycles_t;static inline cycles_t get_cycles (void ) { -if (IS_ENABLED (CONFIG_BOOK3S_601 )) +if (IS_ENABLED (CONFIG_PPC_BOOK3S_601 ))return 0 ;return mftb ();
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 181/270 powerpc/boot: Fix CONFIG_PPC_MPC52XX references
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit e5eff89657e72a9050d95fde146b54c7dc165981 ]
Commit 866bfc75f40e ("powerpc: conditionally compile platform-specific serial drivers") made some code depend on CONFIG_PPC_MPC52XX, which doesn't exist.
Fix it to use CONFIG_PPC_MPC52xx.
--- arch/powerpc/boot/Makefile | 2 +- arch/powerpc/boot/serial.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/boot/Makefile +1 -1
@@ -119,7 +119,7 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \ 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
arch/powerpc/boot/serial.c +1 -1
@@ -128,7 +128,7 @@ int serial_console_init(void) 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
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 182/270 selftests/powerpc: Fix CPU affinity for child process
In reply to Greg Kroah-HartmanFrom: Harish <[email protected]>
[ Upstream commit 854eb5022be04f81e318765f089f41a57c8e5d83 ]
On systems with large number of cpus, test fails trying to set affinity by calling sched_setaffinity() with smaller size for affinity mask. This patch fixes it by making sure that the size of allocated affinity mask is dependent on the number of CPUs as reported by get_nprocs().
--- .../powerpc/benchmarks/context_switch.c | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
tools/testing/selftests/powerpc/benchmarks/context_switch.c +16 -5
@@ -19,6 +19,7 @@#include <limits.h> #include <sys/time.h> #include <sys/syscall.h> +#include <sys/sysinfo.h> #include <sys/types.h> #include <sys/shm.h> #include <linux/futex.h>
@@ -104,8 +105,9 @@ static void start_thread_on(void *(*fn)(void *), void *arg, unsigned long cpu)static void start_process_on (void *(*fn)(void *),void *arg,unsigned long cpu) { -int pid; -cpu_set_t cpuset; +int pid, ncpus; +cpu_set_t *cpuset; +size_t size; pid =fork ();if (pid ==-1 ) {
@@ -116,14 +118,23 @@ static void start_process_on(void *(*fn)(void *), void *arg, unsigned long cpu)if (pid)return ; -CPU_ZERO (&cpuset); -CPU_SET (cpu, &cpuset); + ncpus =get_nprocs (); + size =CPU_ALLOC_SIZE (ncpus); + cpuset =CPU_ALLOC (ncpus); +if (!cpuset) { +perror ("malloc" ); +exit (1 ); + } +CPU_ZERO_S (size, cpuset); +CPU_SET_S (cpu, size, cpuset); -if (sched_setaffinity (0 ,sizeof (cpuset), &cpuset)) { +if (sched_setaffinity (0 , size, cpuset)) {perror ("sched_setaffinity" ); +CPU_FREE (cpuset);exit (1 ); } +CPU_FREE (cpuset);fn (arg);exit (0 );
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 183/270 RDMA/netlink: Remove CAP_NET_RAW check when dump a raw QP
In reply to Greg Kroah-HartmanFrom: Mark Zhang <[email protected]>
[ Upstream commit 1d70ad0f85435a7262de802b104e49e6598c50ff ]
When dumping QPs bound to a counter, raw QPs should be allowed to dump without the CAP_NET_RAW privilege. This is consistent with what "rdma res show qp" does.
--- drivers/infiniband/core/nldev.c | 3 --- 1 file changed, 3 deletions(-)
drivers/infiniband/core/nldev.c +0 -3
@@ -702,9 +702,6 @@ static int fill_stat_counter_qps(struct sk_buff *msg,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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 184/270 PCI: Release IVRS table in AMD ACS quirk
In reply to Greg Kroah-HartmanFrom: Hanjun Guo <[email protected]>
[ Upstream commit 090688fa4e448284aaa16136372397d7d10814db ]
The acpi_get_table() should be coupled with acpi_put_table() if the mapped table is not used at runtime to release the table mapping.
In pci_quirk_amd_sb_acs(), IVRS table is just used for checking AMD IOMMU is supported, not used at runtime, so put the table after using it.
--- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/quirks.c +2 -0
@@ -4446,6 +4446,8 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags)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 );
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 185/270 cpufreq: ap806: fix cpufreq driver needs ap cpu clk
In reply to Greg Kroah-HartmanFrom: Sven Auhagen <[email protected]>
[ Upstream commit 8c37ad2f523396e15cf002b29f8f796447c71932 ]
The Armada 8K cpufreq driver needs the Armada AP CPU CLK to work. This dependency is currently not satisfied and the ARMADA_AP_CPU_CLK can not be selected independently.
Add it to the cpufreq Armada8k driver.
--- drivers/cpufreq/Kconfig.arm | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/Kconfig.arm +1 -0
@@ -41,6 +41,7 @@ config ARM_ARMADA_37XX_CPUFREQ 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.
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 186/270 selftests/powerpc: Fix online CPU selection
In reply to Greg Kroah-HartmanFrom: Sandipan Das <[email protected]>
[ Upstream commit dfa03fff86027e58c8dba5c03ae68150d4e513ad ]
The size of the CPU affinity mask must be large enough for systems with a very large number of CPUs. Otherwise, tests which try to determine the first online CPU by calling sched_getaffinity() will fail. This makes sure that the size of the allocated affinity mask is dependent on the number of CPUs as reported by get_nprocs_conf().
--- tools/testing/selftests/powerpc/utils.c | 37 +++++++++++++++++-------- 1 file changed, 25 insertions(+), 12 deletions(-)
tools/testing/selftests/powerpc/utils.c +25 -12
@@ -16,6 +16,7 @@#include <string.h> #include <sys/ioctl.h> #include <sys/stat.h> +#include <sys/sysinfo.h> #include <sys/types.h> #include <sys/utsname.h> #include <unistd.h>
@@ -88,28 +89,40 @@ void *get_auxv_entry(int type)int pick_online_cpu (void ) { -cpu_set_t mask; -int cpu; +int ncpus, cpu =-1 ; +cpu_set_t *mask; +size_t size; + + ncpus =get_nprocs_conf (); + size =CPU_ALLOC_SIZE (ncpus); + mask =CPU_ALLOC (ncpus); +if (!mask) { +perror ("malloc" ); +return -1 ; + } -CPU_ZERO (&mask); +CPU_ZERO_S (size, mask); -if (sched_getaffinity (0 ,sizeof (mask), &mask)) { +if (sched_getaffinity (0 , size, mask)) {perror ("sched_getaffinity" ); -return -1 ; + goto done; }/* We prefer a primary thread, but skip 0 */ -for (cpu =8 ; cpu <CPU_SETSIZE ; cpu +=8 ) -if (CPU_ISSET (cpu, &mask)) -return cpu; +for (cpu =8 ; cpu < ncpus; cpu +=8 ) +if (CPU_ISSET_S (cpu, size, mask)) + goto done;/* Search for anything, but in reverse */ -for (cpu =CPU_SETSIZE -1 ; cpu >=0 ; cpu--) -if (CPU_ISSET (cpu, &mask)) -return cpu; +for (cpu = ncpus -1 ; cpu >=0 ; cpu--) +if (CPU_ISSET_S (cpu, size, mask)) + goto done;printf ("No cpus in affinity mask?!\n" ); -return -1 ; + +done: +CPU_FREE (mask); +return cpu; }bool is_ppc64le (void )
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 187/270 ASoC: meson: axg-tdm-interface: fix link fmt setup
In reply to Greg Kroah-HartmanFrom: Jerome Brunet <[email protected]>
[ Upstream commit 6878ba91ce84f7a07887a0615af70f969508839f ]
The .set_fmt() callback of the axg tdm interface incorrectly test the content of SND_SOC_DAIFMT_MASTER_MASK as if it was a bitfield, which it is not.
Implement the test correctly.
--- sound/soc/meson/axg-tdm-interface.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
sound/soc/meson/axg-tdm-interface.c +17 -9
@@ -119,18 +119,25 @@ static int axg_tdm_iface_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {struct axg_tdm_iface *iface =snd_soc_dai_get_drvdata (dai); -/* These modes are not supported */ -if (fmt & (SND_SOC_DAIFMT_CBS_CFM |SND_SOC_DAIFMT_CBM_CFS )) { +switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) { +case SND_SOC_DAIFMT_CBS_CFS : +if (!iface->mclk) { +dev_err (dai->dev,"cpu clock master: mclk missing\n" ); +return -ENODEV ; + } +break ; + +case SND_SOC_DAIFMT_CBM_CFM : +break ; + +case SND_SOC_DAIFMT_CBS_CFM : +case SND_SOC_DAIFMT_CBM_CFS :dev_err (dai->dev,"only CBS_CFS and CBM_CFM are supported\n" ); +/* Fall-through */ +default :return -EINVAL ; } -/* If the TDM interface is the clock master, it requires mclk */ -if (!iface->mclk && (fmt &SND_SOC_DAIFMT_CBS_CFS )) { -dev_err (dai->dev,"cpu clock master: mclk missing\n" ); -return -ENODEV ; - } - iface->fmt = fmt;return 0 ; }
@@ -319,7 +326,8 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream,if (ret)return ret; -if (iface->fmt &SND_SOC_DAIFMT_CBS_CFS ) { +if ((iface->fmt &SND_SOC_DAIFMT_MASTER_MASK ) == +SND_SOC_DAIFMT_CBS_CFS ) { ret =axg_tdm_iface_set_sclk (dai, params);if (ret)return ret;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 188/270 ASoC: meson: axg-tdmin: fix g12a skew
In reply to Greg Kroah-HartmanFrom: Jerome Brunet <[email protected]>
[ Upstream commit 80a254394fcfe55450b0351da298ca7231889219 ]
After carefully checking the result provided by the TDMIN on the g12a and sm1 SoC families, the TDMIN skew offset appears to be 3 instead of 2 on the axg.
--- sound/soc/meson/axg-tdmin.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
sound/soc/meson/axg-tdmin.c +16 -0
@@ -233,10 +233,26 @@ static const struct axg_tdm_formatter_driver axg_tdmin_drv = { }, }; +static const struct axg_tdm_formatter_driver g12a_tdmin_drv = { + .component_drv = &axg_tdmin_component_drv, + .regmap_cfg = &axg_tdmin_regmap_cfg, + .ops = &axg_tdmin_ops, + .quirks = &(const struct axg_tdm_formatter_hw ) { + .invert_sclk = false, + .skew_offset =3 , + }, +}; +static const struct of_device_id axg_tdmin_of_match[] = { { .compatible ="amlogic,axg-tdmin" , .data = &axg_tdmin_drv, + }, { + .compatible ="amlogic,g12a-tdmin" , + .data = &g12a_tdmin_drv, + }, { + .compatible ="amlogic,sm1-tdmin" , + .data = &g12a_tdmin_drv, }, {} };MODULE_DEVICE_TABLE (of, axg_tdmin_of_match);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 189/270 ASoC: meson: axg-tdm-formatters: fix sclk inversion
In reply to Greg Kroah-HartmanFrom: Jerome Brunet <[email protected]>
[ Upstream commit 0d3f01dcdc234001f979a0af0b6b31cb9f25b6c1 ]
After carefully checking, it appears that both tdmout and tdmin require the rising edge of the sclk they get to be synchronized with the frame sync event (which should be a rising edge of lrclk).
TDMIN was improperly set before this patch. Remove the sclk_invert quirk which is no longer needed and fix the sclk phase.
--- sound/soc/meson/axg-tdm-formatter.c | 11 ++++++----- sound/soc/meson/axg-tdm-formatter.h | 1 - sound/soc/meson/axg-tdmin.c | 2 -- sound/soc/meson/axg-tdmout.c | 3 --- 4 files changed, 6 insertions(+), 11 deletions(-)
sound/soc/meson/axg-tdm-formatter.c +6 -5
@@ -70,7 +70,7 @@ EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);static int axg_tdm_formatter_enable (struct axg_tdm_formatter *formatter) {struct axg_tdm_stream *ts = formatter->stream; -bool invert = formatter->drv->quirks->invert_sclk; +bool invert;int ret;/* Do nothing if the formatter is already enabled */
@@ -96,11 +96,12 @@ static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)return ret;/* -* If sclk is inverted, invert it back and provide the inversion -* required by the formatter +* If sclk is inverted, it means the bit should latched on the +* rising edge which is what our HW expects. If not, we need to +* invert it before the formatter. */ - invert ^=axg_tdm_sclk_invert (ts->iface->fmt); - ret =clk_set_phase (formatter->sclk, invert ?180 :0 ); + invert =axg_tdm_sclk_invert (ts->iface->fmt); + ret =clk_set_phase (formatter->sclk, invert ?0 :180 );if (ret)return ret;
sound/soc/meson/axg-tdm-formatter.h +0 -1
@@ -16,7 +16,6 @@ struct snd_kcontrol;struct axg_tdm_formatter_hw {unsigned int skew_offset; -bool invert_sclk; };struct axg_tdm_formatter_ops {
sound/soc/meson/axg-tdmin.c +0 -2
@@ -228,7 +228,6 @@ static const struct axg_tdm_formatter_driver axg_tdmin_drv = { .regmap_cfg = &axg_tdmin_regmap_cfg, .ops = &axg_tdmin_ops, .quirks = &(const struct axg_tdm_formatter_hw ) { - .invert_sclk = false, .skew_offset =2 , }, };
@@ -238,7 +237,6 @@ static const struct axg_tdm_formatter_driver g12a_tdmin_drv = { .regmap_cfg = &axg_tdmin_regmap_cfg, .ops = &axg_tdmin_ops, .quirks = &(const struct axg_tdm_formatter_hw ) { - .invert_sclk = false, .skew_offset =3 , }, };
sound/soc/meson/axg-tdmout.c +0 -3
@@ -238,7 +238,6 @@ static const struct axg_tdm_formatter_driver axg_tdmout_drv = { .regmap_cfg = &axg_tdmout_regmap_cfg, .ops = &axg_tdmout_ops, .quirks = &(const struct axg_tdm_formatter_hw ) { - .invert_sclk = true, .skew_offset =1 , }, };
@@ -248,7 +247,6 @@ static const struct axg_tdm_formatter_driver g12a_tdmout_drv = { .regmap_cfg = &axg_tdmout_regmap_cfg, .ops = &axg_tdmout_ops, .quirks = &(const struct axg_tdm_formatter_hw ) { - .invert_sclk = true, .skew_offset =2 , }, };
@@ -309,7 +307,6 @@ static const struct axg_tdm_formatter_driver sm1_tdmout_drv = { .regmap_cfg = &axg_tdmout_regmap_cfg, .ops = &axg_tdmout_ops, .quirks = &(const struct axg_tdm_formatter_hw ) { - .invert_sclk = true, .skew_offset =2 , }, };
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 190/270 ASoC: fsl_sai: Fix value of FSL_SAI_CR1_RFW_MASK
In reply to Greg Kroah-HartmanFrom: Shengjiu Wang <[email protected]>
[ Upstream commit 5aef1ff2397d021f93d874b57dff032fdfac73de ]
The fifo_depth is 64 on i.MX8QM/i.MX8QXP, 128 on i.MX8MQ, 16 on i.MX7ULP.
Original FSL_SAI_CR1_RFW_MASK value 0x1F is not suitable for these platform, the FIFO watermark mask should be updated according to the fifo_depth.
--- sound/soc/fsl/fsl_sai.c | 5 +++-- sound/soc/fsl/fsl_sai.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
sound/soc/fsl/fsl_sai.c +3 -2
@@ -680,10 +680,11 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)regmap_write (sai->regmap,FSL_SAI_RCSR (ofs),0 );regmap_update_bits (sai->regmap,FSL_SAI_TCR1 (ofs), -FSL_SAI_CR1_RFW_MASK , +FSL_SAI_CR1_RFW_MASK (sai->soc_data->fifo_depth), sai->soc_data->fifo_depth -FSL_SAI_MAXBURST_TX );regmap_update_bits (sai->regmap,FSL_SAI_RCR1 (ofs), -FSL_SAI_CR1_RFW_MASK ,FSL_SAI_MAXBURST_RX -1 ); +FSL_SAI_CR1_RFW_MASK (sai->soc_data->fifo_depth), +FSL_SAI_MAXBURST_RX -1 );snd_soc_dai_init_dma_data (cpu_dai, &sai->dma_params_tx, &sai->dma_params_rx);
sound/soc/fsl/fsl_sai.h +1 -1
@@ -94,7 +94,7 @@#define FSL_SAI_CSR_FRDE BIT(0)/* SAI Transmit and Receive Configuration 1 Register */ -#define FSL_SAI_CR1_RFW_MASK 0x1f +#define FSL_SAI_CR1_RFW_MASK (x) ((x) - 1)/* SAI Transmit and Receive Configuration 2 Register */ #define FSL_SAI_CR2_SYNC BIT(30)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 191/270 s390/qeth: dont process empty bridge port events
In reply to Greg Kroah-HartmanFrom: Julian Wiedmann <[email protected]>
[ Upstream commit 02472e28b9a45471c6d8729ff2c7422baa9be46a ]
Discard events that don't contain any entries. This shouldn't happen, but subsequent code relies on being able to use entry 0. So better be safe than accessing garbage.
--- drivers/s390/net/qeth_l2_main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/s390/net/qeth_l2_main.c +4 -0
@@ -1199,6 +1199,10 @@ static void qeth_bridge_state_change(struct qeth_card *card,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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 192/270 ice: Graceful error handling in HW table calloc failure
In reply to Greg Kroah-HartmanFrom: Surabhi Boob <[email protected]>
[ Upstream commit bcc46cb8a077c6189b44f1555b8659837f748eb2 ]
In the ice_init_hw_tbls, if the devm_kcalloc for es->written fails, catch that error and bail out gracefully, instead of continuing with a NULL pointer.
--- drivers/net/ethernet/intel/ice/ice_flex_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_flex_pipe.c +3 -1
@@ -1535,10 +1535,12 @@ enum ice_status ice_init_hw_tbls(struct ice_hw *hw) 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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 193/270 rtw88: fix LDPC field for RA info
In reply to Greg Kroah-HartmanFrom: Tsang-Shian Lin <[email protected]>
[ Upstream commit ae44fa993e8e6c1a1d22e5ca03d9eadd53b2745b ]
Convert the type of LDPC field to boolen because LDPC field of RA info H2C command to firmware
is only one bit.
--- drivers/net/wireless/realtek/rtw88/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/fw.c +1 -1
@@ -340,7 +340,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)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);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 194/270 rtw88: fix short GI capability based on current bandwidth
In reply to Greg Kroah-HartmanFrom: Tsang-Shian Lin <[email protected]>
[ Upstream commit 4dd86b901d1373ef8446ecb50a7ca009f3475211 ]
Fix the transmission is not sent with short GI under some conditions even if the receiver supports short GI. If VHT capability IE exists in the beacon, the original code uses the short GI for 80M field as driver's short GI setting for transmission, even the current bandwidth is not 80MHz.
Short GI supported fields for 20M/40M are informed in HT capability information element, and short GI supported field for 80M is informed in VHT capability information element.
These three fields may be set to different values. Driver needs to record each short GI support field for each bandwidth, and send correct info depends on current bandwidth to the WiFi firmware.
--- drivers/net/wireless/realtek/rtw88/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/net/wireless/realtek/rtw88/main.c +6 -5
@@ -553,8 +553,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) 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[1 ] <<20 ) | (sta->ht_cap.mcs.rx_mask[0 ] <<12 );
@@ -562,9 +560,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) 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 )
@@ -606,12 +601,18 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)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 ; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 195/270 rtw88: coex: only skip coex triggered by BT info
In reply to Greg Kroah-HartmanFrom: Yan-Hsuan Chuang <[email protected]>
[ Upstream commit 3f194bd4ca1cd9b8eef34d37d562279dbeb80319 ]
The coex mechanism used to skip upon the freeze flag is raised. That will cause the coex mechanism being skipped unexpectedly. Coex only wanted to keep the TDMA table from being changed by BT side.
So, check the freeze and reason, if the coex reason is coming from BT info, skip it, to make sure the coex triggered by Wifi itself can work.
This is required for the AP mode, while the control flow is different with STA mode. When starting an AP mode, the AP mode needs to start working immedaitely after leaving IPS, and the freeze flag could be raised. If the coex info is skipped, then the AP mode will not set the antenna owner, leads to TX stuck.
--- drivers/net/wireless/realtek/rtw88/coex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/coex.c +2 -1
@@ -1923,7 +1923,8 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)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 ]++;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 196/270 wl1251: fix always return 0 error
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit 20e6421344b5bc2f97b8e2db47b6994368417904 ]
wl1251_event_ps_report() should not always return 0 because wl1251_ps_set_mode() may fail. Change it to return 'ret'.
--- drivers/net/wireless/ti/wl1251/event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ti/wl1251/event.c +1 -1
@@ -70,7 +70,7 @@ static int wl1251_event_ps_report(struct wl1251 *wl,break ; } -return 0 ; +return ret; }static void wl1251_event_mbox_dump (struct event_mailbox *mbox)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 197/270 tools, build: Propagate build failures from tools/build/Makefile.build
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit a278f3d8191228212c553a5d4303fa603214b717 ]
The '&&' command seems to have a bad effect when $(cmd_$(1)) exits with non-zero effect: the command failure is masked (despite set -e) and all but the first command of $(dep-cmd) is executed (successfully, as they are mostly printfs), thus overall returning 0 in the end.
This means in practice that despite compilation errors, tools's build Makefile will return success. We see this very reliably with libbpf's Makefile, which doesn't get compilation error propagated properly. This in turns causes issues with selftests build, as well as bpftool and other projects that rely on building libbpf.
The fix is simple: don't use &&. Given set -e, we don't need to chain commands with &&. The shell will exit on first failure, giving desired behavior and propagating error properly.
--- tools/build/Build.include | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/build/Build.include +2 -1
@@ -74,7 +74,8 @@ dep-cmd = $(if $(wildcard $(fixdep)), # dependencies in the cmd file if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ @set -e; \ - $(echo-cmd) $(cmd_$(1)) && $(dep-cmd)) + $(echo-cmd) $(cmd_$(1)); \ + $(dep-cmd)) # if_changed - execute command if any prerequisite is newer than # target, or command line has changed
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 198/270 tools, bpftool: Fix wrong return value in do_dump()
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
[ Upstream commit 041549b7b2c7811ec40e705c439211f00ade2dda ]
In case of btf_id does not exist, a negative error code -ENOENT should be returned.
--- tools/bpf/bpftool/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/bpf/bpftool/btf.c +1 -1
@@ -510,7 +510,7 @@ static int do_dump(int argc, char **argv) goto done; }if (!btf) { - err =ENOENT ; + err = -ENOENT ;p_err ("can't find btf with ID (%u)" , btf_id); goto done; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 199/270 net/mlx5: DR, Change push vlan action sequence
In reply to Greg Kroah-HartmanFrom: Alex Vesker <[email protected]>
[ Upstream commit b206490940216542c68563699b279eed3c55107c ]
The DR TX state machine supports the following order:
modify header, push vlan and encapsulation. Instead fs_dr would pass:
push vlan, modify header and encapsulation.
The above caused the rule creation to fail on invalid action sequence provided error.
--- .../mellanox/mlx5/core/steering/fs_dr.c | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c +21 -21
@@ -247,29 +247,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,/* 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 +302,26 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, 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;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 200/270 net/mlx5: Delete extra dump stack that gives nothing
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
[ Upstream commit 6c4e9bcfb48933d533ff975e152757991556294a ]
The WARN_*() macros are intended to catch impossible situations from the SW point of view. They gave a little in case HW<->SW interface is out-of-sync.
Such out-of-sync scenario can be due to SW errors that are not part of this flow or because some HW errors, where dump stack won't help either.
This specific WARN_ON() is useless because mlx5_core code is prepared to handle such situations and will unfold everything correctly while providing enough information to the users to understand why FS is not working.
WARNING: CPU: 0 PID: 3222 at drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:825 connect_fts_in_prio.isra.20+0x1dd/0x260 linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:825 Kernel panic - not syncing: panic_on_warn set ... CPU: 0 PID: 3222 Comm: syz-executor861 Not tainted 5.5.0-rc6+ #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Call Trace: __dump_stack linux/lib/dump_stack.c:77 [inline] dump_stack+0x94/0xce linux/lib/dump_stack.c:118 panic+0x234/0x56f linux/kernel/panic.c:221 __warn+0x1cc/0x1e1 linux/kernel/panic.c:582 report_bug+0x200/0x310 linux/lib/bug.c:195 fixup_bug.part.11+0x32/0x80 linux/arch/x86/kernel/traps.c:174 fixup_bug linux/arch/x86/kernel/traps.c:273 [inline] do_error_trap+0xd3/0x100 linux/arch/x86/kernel/traps.c:267 do_invalid_op+0x31/0x40 linux/arch/x86/kernel/traps.c:286 invalid_op+0x1e/0x30 linux/arch/x86/entry/entry_64.S:1027 RIP: 0010:connect_fts_in_prio.isra.20+0x1dd/0x260 linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:825 Code: 00 00 48 c7 c2 60 8c 31 84 48 c7 c6 00 81 31 84 48 8b 38 e8 3c a8
cb ff 41 83 fd 01 8b 04 24 0f 8e 29 ff ff ff e8 83 7b bc fe <0f> 0b 8b 04 24 e9 1a ff ff ff 89 04 24 e8 c1 20 e0 fe 8b 04 24 eb
RSP: 0018:ffffc90004bb7858 EFLAGS: 00010293
RAX: ffff88805de98e80 RBX: 0000000000000c96 RCX: ffffffff827a853d
RDX: 0000000000000000 RSI: 0000000000000000 RDI: fffff52000976efa
RBP: 0000000000000007 R08: ffffed100da060e3 R09: ffffed100da060e3
R10: 0000000000000001 R11: ffffed100da060e2 R12: dffffc0000000000
R13: 0000000000000002 R14: ffff8880683a1a10 R15: ffffed100d07bc1c
connect_prev_fts linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:844 [inline] connect_flow_table linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:975 [inline] __mlx5_create_flow_table+0x8f8/0x1710 linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:1064 mlx5_create_flow_table linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:1094 [inline] mlx5_create_auto_grouped_flow_table+0xe1/0x210 linux/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c:1136 _get_prio linux/drivers/infiniband/hw/mlx5/main.c:3286 [inline] get_flow_table+0x2ea/0x760 linux/drivers/infiniband/hw/mlx5/main.c:3376 mlx5_ib_create_flow+0x331/0x11c0 linux/drivers/infiniband/hw/mlx5/main.c:3896 ib_uverbs_ex_create_flow+0x13e8/0x1b40 linux/drivers/infiniband/core/uverbs_cmd.c:3311 ib_uverbs_write+0xaa5/0xdf0 linux/drivers/infiniband/core/uverbs_main.c:769 __vfs_write+0x7c/0x100 linux/fs/read_write.c:494 vfs_write+0x168/0x4a0 linux/fs/read_write.c:558 ksys_write+0xc8/0x200 linux/fs/read_write.c:611 do_syscall_64+0x9c/0x390 linux/arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x45a059 Code: 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89
f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fcc17564c98 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007fcc17564ca0 RCX: 000000000045a059
RDX: 0000000000000030 RSI: 00000000200003c0 RDI: 0000000000000005
RBP: 0000000000000007 R08: 0000000000000002 R09: 0000000000003131
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000006e636c
R13: 0000000000000000 R14: 00000000006e6360 R15: 00007ffdcbdaf6a0 Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
Rebooting in 1 seconds..
--- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +3 -6
@@ -809,18 +809,15 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev, {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; } }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 201/270 net: ethernet: aquantia: Fix wrong return value
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
[ Upstream commit 0470a48880f8bc42ce26962b79c7b802c5a695ec ]
In function hw_atl_a0_hw_multicast_list_set(), when an invalid request is encountered, a negative error code should be returned.
--- drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +1 -1
@@ -776,7 +776,7 @@ static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self,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;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 202/270 liquidio: Fix wrong return value in cn23xx_get_pf_num()
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
[ Upstream commit aa027850a292ea65524b8fab83eb91a124ad362c ]
On an error exit path, a negative error code should be returned instead of a positive return value.
--- drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +1 -1
@@ -1167,7 +1167,7 @@ static int cn23xx_get_pf_num(struct octeon_device *oct) 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.
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 203/270 net: spider_net: Fix the size used in a dma_free_coherent() call
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 36f28f7687a9ce665479cce5d64ce7afaa9e77ae ]
Update the size used in 'dma_free_coherent()' in order to match the one used in the corresponding 'dma_alloc_coherent()', in 'spider_net_init_chain()'.
--- drivers/net/ethernet/toshiba/spider_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/toshiba/spider_net.c +2 -2
@@ -283,8 +283,8 @@ spider_net_free_chain(struct spider_net_card *card, 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); }/**
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 204/270 fsl/fman: use 32-bit unsigned integer
In reply to Greg Kroah-HartmanFrom: Florinel Iordache <[email protected]>
[ Upstream commit 99f47abd9f7bf6e365820d355dc98f6955a562df ]
Potentially overflowing expression (ts_freq << 16 and intgr << 16) declared as type u32 (32-bit unsigned) is evaluated using 32-bit arithmetic and then used in a context that expects an expression of type u64 (64-bit unsigned) which ultimately is used as 16-bit unsigned by typecasting to u16. Fixed by using an unsigned 32-bit integer since the value is truncated anyway in the end.
--- drivers/net/ethernet/freescale/fman/fman.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/freescale/fman/fman.c +1 -2
@@ -1396,8 +1396,7 @@ static void enable_time_stamp(struct fman *fman) {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
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 205/270 fsl/fman: fix dereference null return value
In reply to Greg Kroah-HartmanFrom: Florinel Iordache <[email protected]>
[ Upstream commit 0572054617f32670abab4b4e89a876954d54b704 ]
Check before using returned value to avoid dereferencing null pointer.
--- drivers/net/ethernet/freescale/fman/fman_port.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/ethernet/freescale/fman/fman_port.c +8 -1
@@ -1756,6 +1756,7 @@ static int fman_port_probe(struct platform_device *of_dev)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,8 +1781,14 @@ static int fman_port_probe(struct platform_device *of_dev) 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 (!fm_pdev) { + err = -EINVAL ; + goto return_err; + } + + fman =dev_get_drvdata (&fm_pdev->dev);if (!fman) { err = -EINVAL ; goto return_err;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 206/270 fsl/fman: fix unreachable code
In reply to Greg Kroah-HartmanFrom: Florinel Iordache <[email protected]>
[ Upstream commit cc79fd8f557767de90ff199d3b6fb911df43160a ]
The parameter 'priority' is incorrectly forced to zero which ultimately induces logically dead code in the subsequent lines.
--- drivers/net/ethernet/freescale/fman/fman_memac.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/freescale/fman/fman_memac.c +0 -1
@@ -856,7 +856,6 @@ int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority, tmp =ioread32be (®s->command_config); tmp &= ~CMD_CFG_PFC_MODE ; - priority =0 ;iowrite32be (tmp, ®s->command_config);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 207/270 fsl/fman: check dereferencing null pointer
In reply to Greg Kroah-HartmanFrom: Florinel Iordache <[email protected]>
[ Upstream commit cc5d229a122106733a85c279d89d7703f21e4d4f ]
Add a safe check to avoid dereferencing null pointer
--- drivers/net/ethernet/freescale/fman/fman_dtsec.c | 4 ++-- drivers/net/ethernet/freescale/fman/fman_memac.c | 2 +- drivers/net/ethernet/freescale/fman/fman_tgec.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/freescale/fman/fman_dtsec.c +2 -2
@@ -1205,7 +1205,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)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 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)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 ;
drivers/net/ethernet/freescale/fman/fman_memac.c +1 -1
@@ -985,7 +985,7 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)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 ;
drivers/net/ethernet/freescale/fman/fman_tgec.c +1 -1
@@ -630,7 +630,7 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 208/270 fsl/fman: fix eth hash table allocation
In reply to Greg Kroah-HartmanFrom: Florinel Iordache <[email protected]>
[ Upstream commit 3207f715c34317d08e798e11a10ce816feb53c0f ]
Fix memory allocation for ethernet address hash table. The code was wrongly allocating an array for eth hash table which is incorrect because this is the main structure for eth hash table (struct eth_hash_t) that contains inside a number of elements.
--- drivers/net/ethernet/freescale/fman/fman_mac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/freescale/fman/fman_mac.h +1 -1
@@ -252,7 +252,7 @@ static inline struct eth_hash_t *alloc_hash_table(u16 size)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 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 209/270 net: thunderx: initialize VFs mailbox mutex before first usage
In reply to Greg Kroah-HartmanFrom: Dean Nelson <[email protected]>
[ Upstream commit c1055b76ad00aed0e8b79417080f212d736246b6 ]
A VF's mailbox mutex is not getting initialized by nicvf_probe() until after it is first used. And such usage is resulting in...
[ 28.270927] ------------[ cut here ]------------ [ 28.270934] DEBUG_LOCKS_WARN_ON(lock->magic != lock) [ 28.270980] WARNING: CPU: 9 PID: 675 at kernel/locking/mutex.c:938 __mutex_lock+0xdac/0x12f0 [ 28.270985] Modules linked in: ast(+) nicvf(+) i2c_algo_bit drm_vram_helper drm_ttm_helper ttm nicpf(+) drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm ixgbe(+) sg thunder_bgx mdio i2c_thunderx mdio_thunder thunder_xcv mdio_cavium dm_mirror dm_region_hash dm_log dm_mod [ 28.271064] CPU: 9 PID: 675 Comm: systemd-udevd Not tainted 4.18.0+ #1 [ 28.271070] Hardware name: GIGABYTE R120-T34-00/MT30-GS2-00, BIOS F02 08/06/2019 [ 28.271078] pstate: 60000005 (nZCv daif -PAN -UAO) [ 28.271086] pc : __mutex_lock+0xdac/0x12f0 [ 28.271092] lr : __mutex_lock+0xdac/0x12f0 [ 28.271097] sp : ffff800d42146fb0 [ 28.271103] x29: ffff800d42146fb0 x28: 0000000000000000 [ 28.271113] x27: ffff800d24361180 x26: dfff200000000000 [ 28.271122] x25: 0000000000000000 x24: 0000000000000002 [ 28.271132] x23: ffff20001597cc80 x22: ffff2000139e9848 [ 28.271141] x21: 0000000000000000 x20: 1ffff001a8428e0c [ 28.271151] x19: ffff200015d5d000 x18: 1ffff001ae0f2184 [ 28.271160] x17: 0000000000000000 x16: 0000000000000000 [ 28.271170] x15: ffff800d70790c38 x14: ffff20001597c000 [ 28.271179] x13: ffff20001597cc80 x12: ffff040002b2f779 [ 28.271189] x11: 1fffe40002b2f778 x10: ffff040002b2f778 [ 28.271199] x9 : 0000000000000000 x8 : 00000000f1f1f1f1 [ 28.271208] x7 : 00000000f2f2f2f2 x6 : 0000000000000000 [ 28.271217] x5 : 1ffff001ae0f2186 x4 : 1fffe400027eb03c [ 28.271227] x3 : dfff200000000000 x2 : ffff1001a8428dbe [ 28.271237] x1 : c87fdfac7ea11d00 x0 : 0000000000000000 [ 28.271246] Call trace: [ 28.271254] __mutex_lock+0xdac/0x12f0 [ 28.271261] mutex_lock_nested+0x3c/0x50 [ 28.271297] nicvf_send_msg_to_pf+0x40/0x3a0 [nicvf] [ 28.271316] nicvf_register_misc_interrupt+0x20c/0x328 [nicvf] [ 28.271334] nicvf_probe+0x508/0xda0 [nicvf] [ 28.271344] local_pci_probe+0xc4/0x180 [ 28.271352] pci_device_probe+0x3ec/0x528 [ 28.271363] driver_probe_device+0x21c/0xb98 [ 28.271371] device_driver_attach+0xe8/0x120 [ 28.271379] __driver_attach+0xe0/0x2a0 [ 28.271386] bus_for_each_dev+0x118/0x190 [ 28.271394] driver_attach+0x48/0x60 [ 28.271401] bus_add_driver+0x328/0x558 [ 28.271409] driver_register+0x148/0x398 [ 28.271416] __pci_register_driver+0x14c/0x1b0 [ 28.271437] nicvf_init_module+0x54/0x10000 [nicvf] [ 28.271447] do_one_initcall+0x18c/0xc18 [ 28.271457] do_init_module+0x18c/0x618 [ 28.271464] load_module+0x2bc0/0x4088 [ 28.271472] __se_sys_finit_module+0x110/0x188 [ 28.271479] __arm64_sys_finit_module+0x70/0xa0 [ 28.271490] el0_svc_handler+0x15c/0x380 [ 28.271496] el0_svc+0x8/0xc [ 28.271502] irq event stamp: 52649 [ 28.271513] hardirqs last enabled at (52649): [<ffff200011b4d790>] _raw_spin_unlock_irqrestore+0xc0/0xd8 [ 28.271522] hardirqs last disabled at (52648): [<ffff200011b4d3c4>] _raw_spin_lock_irqsave+0x3c/0xf0 [ 28.271530] softirqs last enabled at (52330): [<ffff200010082af4>] __do_softirq+0xacc/0x117c [ 28.271540] softirqs last disabled at (52313): [<ffff20001019b354>] irq_exit+0x3cc/0x500 [ 28.271545] ---[ end trace a9b90324c8a0d4ee ]---
This problem is resolved by moving the call to mutex_init() up earlier in nicvf_probe().
--- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/cavium/thunder/nicvf_main.c +3 -1
@@ -2185,6 +2185,9 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 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,7 +2264,6 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)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) {
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 210/270 dlm: Fix kobject memleak
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit 0ffddafc3a3970ef7013696e7f36b3d378bc4c16 ]
Currently the error return path from kobject_init_and_add() is not followed by a call to kobject_put() - which means we are leaking the kobject.
Set do_unreg = 1 before kobject_init_and_add() to ensure that kobject_put() can be called in its error patch.
--- fs/dlm/lockspace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/dlm/lockspace.c +3 -3
@@ -632,6 +632,9 @@ static int new_lockspace(const char *name, const char *cluster,wait_event (ls->ls_recover_lock_wait,test_bit (LSFL_RECOVER_LOCK , &ls->ls_flags)); +/* let kobject handle freeing of ls if there's an error */ + do_unreg =1 ; + ls->ls_kobj.kset = dlm_kset; error =kobject_init_and_add (&ls->ls_kobj, &dlm_ktype,NULL ,"%s" , ls->ls_name);
@@ -639,9 +642,6 @@ static int new_lockspace(const char *name, const char *cluster, goto out_recoverd;kobject_uevent (&ls->ls_kobj,KOBJ_ADD ); -/* let kobject handle freeing of ls if there's an error */ - do_unreg =1 ; -/* This uevent triggers dlm_controld in userspace to add us to the group of nodes that are members of this lockspace (managed by the cluster infrastructure.) Once it's done that, it tells us who the
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 211/270 ocfs2: fix unbalanced locking
In reply to Greg Kroah-HartmanFrom: Pavel Machek <[email protected]>
[ Upstream commit 57c720d4144a9c2b88105c3e8f7b0e97e4b5cc93 ]
Based on what fails, function can return with nfs_sync_rwlock either locked or unlocked. That can not be right.
Always return with lock unlocked on error.
--- fs/ocfs2/dlmglue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/ocfs2/dlmglue.c +7 -1
@@ -2871,9 +2871,15 @@ int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex) status =ocfs2_cluster_lock (osb, lockres, ex ?LKM_EXMODE :LKM_PRMODE ,0 ,0 ); -if (status <0 ) +if (status <0 ) {mlog (ML_ERROR ,"lock on nfs sync lock failed %d\n" , status); +if (ex) +up_write (&osb->nfs_sync_rwlock); +else +up_read (&osb->nfs_sync_rwlock); + } +return status; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 212/270 pinctrl-single: fix pcs_parse_pinconf() return value
In reply to Greg Kroah-HartmanFrom: Drew Fustini <[email protected]>
[ Upstream commit f46fe79ff1b65692a65266a5bec6dbe2bf7fc70f ]
This patch causes pcs_parse_pinconf() to return -ENOTSUPP when no pinctrl_map is added. The current behavior is to return 0 when !PCS_HAS_PINCONF or !nconfs. Thus pcs_parse_one_pinctrl_entry() incorrectly assumes that a map was added and sets num_maps = 2.
Analysis:
=========
The function pcs_parse_one_pinctrl_entry() calls pcs_parse_pinconf() if PCS_HAS_PINCONF is enabled. The function pcs_parse_pinconf() returns 0 to indicate there was no error and num_maps is then set to 2:
980 static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
981 struct device_node *np,
982 struct pinctrl_map **map,
983 unsigned *num_maps,
984 const char **pgnames)
985 {
<snip>
1053 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
1054 (*map)->data.mux.group = np->name;
1055 (*map)->data.mux.function = np->name;1056
1057 if (PCS_HAS_PINCONF && function) {
1058 res = pcs_parse_pinconf(pcs, np, function, map);
1059 if (res)
1060 goto free_pingroups;
1061 *num_maps = 2;
1062 } else {
1063 *num_maps = 1;
1064 }
However, pcs_parse_pinconf() will also return 0 if !PCS_HAS_PINCONF or !nconfs. I believe these conditions should indicate that no map was added by returning -ENOTSUPP. Otherwise pcs_parse_one_pinctrl_entry() will set num_maps = 2 even though no maps were successfully added, as it does not reach "m++" on line 940:
895 static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
896 struct pcs_function *func,
897 struct pinctrl_map **map)
898
899 {
900 struct pinctrl_map *m = *map;
<snip>
917 /* If pinconf isn't supported, don't parse properties in below. */
918 if (!PCS_HAS_PINCONF)
919 return 0;
920
921 /* cacluate how much properties are supported in current node */
922 for (i = 0; i < ARRAY_SIZE(prop2); i++) {
923 if (of_find_property(np, prop2[i].name, NULL))
924 nconfs++;
925 }
926 for (i = 0; i < ARRAY_SIZE(prop4); i++) {
927 if (of_find_property(np, prop4[i].name, NULL))
928 nconfs++;
929 }
930 if (!nconfs)
919 return 0;
932
933 func->conf = devm_kcalloc(pcs->dev,
934 nconfs, sizeof(struct pcs_conf_vals),
935 GFP_KERNEL);
936 if (!func->conf)
937 return -ENOMEM;
938 func->nconfs = nconfs; 939 conf = &(func->conf[0]); 940 m++;
This situtation will cause a boot failure [0] on the BeagleBone Black (AM3358) when am33xx_pinmux node in arch/arm/boot/dts/am33xx-l4.dtsi has compatible = "pinconf-single" instead of "pinctrl-single".
The patch fixes this issue by returning -ENOSUPP when !PCS_HAS_PINCONF or !nconfs, so that pcs_parse_one_pinctrl_entry() will know that no map was added.
Logic is also added to pcs_parse_one_pinctrl_entry() to distinguish between -ENOSUPP and other errors. In the case of -ENOSUPP, num_maps is set to 1 as it is valid for pinconf to be enabled and a given pin group to not any pinconf properties.
[0] https://lore.kernel.org/linux-omap/20200529175544.GA3766151@x1/
--- drivers/pinctrl/pinctrl-single.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/pinctrl/pinctrl-single.c +7 -4
@@ -916,7 +916,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,/* 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 +928,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, nconfs++; }if (!nconfs) -return 0 ; +return -ENOTSUPP ; func->conf = devm_kcalloc(pcs->dev, nconfs, sizeof(struct pcs_conf_vals),
@@ -1056,9 +1056,12 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,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 ; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 213/270 svcrdma: Fix page leak in svc_rdma_recv_read_chunk()
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit e814eecbe3bbeaa8b004d25a4b8974d232b765a9 ]
Commit 07d0ff3b0cd2 ("svcrdma: Clean up Read chunk path") moved the page saver logic so that it gets executed event when an error occurs. In that case, the I/O is never posted, and those pages are then leaked. Errors in this path, however, are quite rare.
--- net/sunrpc/xprtrdma/svc_rdma_rw.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
net/sunrpc/xprtrdma/svc_rdma_rw.c +21 -7
@@ -677,7 +677,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,struct svc_rdma_read_info *info, __be32 *p) { - unsigned int i; int ret; ret = -EINVAL ;
@@ -700,12 +699,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, info->ri_chunklen += rs_length; } -/* Pages under I/O have been copied to head->rc_pages. -* Prevent their premature release by svc_xprt_release() . -*/ -for (i =0 ; i < info->ri_readctxt->rc_page_count; i++) - rqstp->rq_pages[i] =NULL ; -return ret; }
@@ -800,6 +793,26 @@ static int svc_rdma_build_pz_read_chunk(struct svc_rqst *rqstp,return ret; } +/* Pages under I/O have been copied to head->rc_pages. Ensure they +* are not released by svc_xprt_release() until the I/O is complete. +* +* This has to be done after all Read WRs are constructed to properly +* handle a page that is part of I/O on behalf of two different RDMA +* segments. +* +* Do this only if I/O has been posted. Otherwise, we do indeed want +* svc_xprt_release() to clean things up properly. +*/ +static void svc_rdma_save_io_pages (struct svc_rqst *rqstp, +const unsigned int start, +const unsigned int num_pages) +{ +unsigned int i; + +for (i = start; i < num_pages + start; i++) + rqstp->rq_pages[i] =NULL ; +} +/** * svc_rdma_recv_read_chunk - Pull a Read chunk from the client * @rdma: controlling RDMA transport
@@ -853,6 +866,7 @@ int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, struct svc_rqst *rqstp, ret =svc_rdma_post_chunk_ctxt (&info->ri_cc);if (ret <0 ) goto out_err; +svc_rdma_save_io_pages (rqstp,0 , head->rc_page_count);return 0 ; out_err:
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 214/270 SUNRPC: Fix ("SUNRPC: Add "@len" parameter to gss_unwrap()")
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 986a4b63d3bc5f2c0eb4083b05aff2bf883b7b2f ]
Braino when converting "buf->len -=" to "buf->len = len -".
The result is under-estimation of the ralign and rslack values. On krb5p mounts, this has caused READDIR to fail with EIO, and KASAN splats when decoding READLINK replies.
As a result of fixing this oversight, the gss_unwrap method now returns a buf->len that can be shorter than priv_len for small RPC messages. The additional adjustment done in unwrap_priv_data() can underflow buf->len. This causes the nfsd_request_too_large check to fail during some NFSv3 operations.
--- net/sunrpc/auth_gss/gss_krb5_wrap.c | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
net/sunrpc/auth_gss/gss_krb5_wrap.c +1 -1
@@ -584,7 +584,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, buf->head[0].iov_len);memmove (ptr, ptr +GSS_KRB5_TOK_HDR_LEN + headskip, movelen); buf->head[0 ].iov_len -=GSS_KRB5_TOK_HDR_LEN + headskip; - buf->len = len -GSS_KRB5_TOK_HDR_LEN + headskip; + buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip);/* Trim off the trailing "extra count" and checksum blob */ xdr_buf_trim (buf, ec +GSS_KRB5_TOK_HDR_LEN + tailskip);
net/sunrpc/auth_gss/svcauth_gss.c +0 -1
@@ -949,7 +949,6 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs maj_stat =gss_unwrap (ctx,0 , priv_len, buf); pad = priv_len - buf->len; - buf->len -= pad;/* The upper layers assume the buffer is aligned on 4-byte boundaries. * In the krb5p case, at least, the data ends up offset, so we need to * move it around. */
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 215/270 x86/fsgsbase/64: Fix NULL deref in 86_fsgsbase_read_task
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 8ab49526b53d3172d1d8dd03a75c7d1f5bd21239 ]
syzbot found its way in 86_fsgsbase_read_task() and triggered this oops:
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
CPU: 0 PID: 6866 Comm: syz-executor262 Not tainted 5.8.0-syzkaller #0
RIP: 0010:x86_fsgsbase_read_task+0x16d/0x310 arch/x86/kernel/process_64.c:393
Call Trace:
putreg32+0x3ab/0x530 arch/x86/kernel/ptrace.c:876
genregs32_set arch/x86/kernel/ptrace.c:1026 [inline]
genregs32_set+0xa4/0x100 arch/x86/kernel/ptrace.c:1006
copy_regset_from_user include/linux/regset.h:326 [inline]
ia32_arch_ptrace arch/x86/kernel/ptrace.c:1061 [inline]
compat_arch_ptrace+0x36c/0xd90 arch/x86/kernel/ptrace.c:1198
__do_compat_sys_ptrace kernel/ptrace.c:1420 [inline]
__se_compat_sys_ptrace kernel/ptrace.c:1389 [inline]
__ia32_compat_sys_ptrace+0x220/0x2f0 kernel/ptrace.c:1389
do_syscall_32_irqs_on arch/x86/entry/common.c:84 [inline]
__do_fast_syscall_32+0x57/0x80 arch/x86/entry/common.c:126
do_fast_syscall_32+0x2f/0x70 arch/x86/entry/common.c:149
entry_SYSENTER_compat_after_hwframe+0x4d/0x5cThis can happen if ptrace() or sigreturn() pokes an LDT selector into FS or GS for a task with no LDT and something tries to read the base before a return to usermode notices the bad selector and fixes it.
The fix is to make sure ldt pointer is not NULL.
--- arch/x86/kernel/process_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/process_64.c +1 -1
@@ -316,7 +316,7 @@ static unsigned long x86_fsgsbase_read_task(struct task_struct *task,*/ 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);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 216/270 crypto: aesni - add compatibility with IAS
In reply to Greg Kroah-HartmanFrom: Jian Cai <[email protected]>
[ Upstream commit 44069737ac9625a0f02f0f7f5ab96aae4cd819bc ]
Clang's integrated assembler complains "invalid reassignment of non-absolute variable 'var_ddq_add'" while assembling arch/x86/crypto/aes_ctrby8_avx-x86_64.S. It was because var_ddq_add was reassigned with non-absolute values several times, which IAS did not support. We can avoid the reassignment by replacing the uses of var_ddq_add with its definitions accordingly to have compatilibility with IAS.
--- arch/x86/crypto/aes_ctrby8_avx-x86_64.S | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
arch/x86/crypto/aes_ctrby8_avx-x86_64.S +3 -11
@@ -127,10 +127,6 @@ ddq_add_8: /* 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 @@ ddq_add_8: .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 @@ ddq_add_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 @@ ddq_add_8: 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
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 217/270 af_packet: TPACKET_V3: fix fill status rwlock imbalance
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit 88fd1cb80daa20af063bce81e1fad14e945a8dc4 ]
After @blk_fill_in_prog_lock is acquired there is an early out vnet situation that can occur. In that case, the rwlock needs to be released.
Also, since @blk_fill_in_prog_lock is only acquired when @tp_version is exactly TPACKET_V3, only release it on that exact condition as well.
And finally, add sparse annotation so that it is clearer that prb_fill_curr_block() and prb_clear_blk_fill_status() are acquiring and releasing @blk_fill_in_prog_lock, respectively. sparse is still unable to understand the balance, but the warnings are now on a higher level that make more sense.
--- net/packet/af_packet.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/packet/af_packet.c +7 -2
@@ -941,6 +941,7 @@ static int prb_queue_frozen(struct tpack }static void prb_clear_blk_fill_status (struct packet_ring_buffer *rb) + __releases(&pkc->blk_fill_in_prog_lock) {struct tpacket_kbdq_core *pkc =GET_PBDQC_FROM_RB (rb);atomic_dec (&pkc->blk_fill_in_prog);
@@ -988,6 +989,7 @@ static void prb_fill_curr_block(char *custruct tpacket_kbdq_core *pkc, struct tpacket_block_desc *pbd, unsigned int len) + __acquires(&pkc->blk_fill_in_prog_lock) { struct tpacket3_hdr *ppd;
@@ -2285,8 +2287,11 @@ static int tpacket_rcv(struct sk_buff *sif (do_vnet &&virtio_net_hdr_from_skb (skb, h.raw + macoff -sizeof (struct virtio_net_hdr ), -vio_le (), true,0 )) +vio_le (), true,0 )) { +if (po->tp_version ==TPACKET_V3 ) +prb_clear_blk_fill_status (&po->rx_ring); goto drop_n_account; + }if (po->tp_version <=TPACKET_V2 ) {packet_increment_rx_head (po, &po->rx_ring);
@@ -2392,7 +2397,7 @@ static int tpacket_rcv(struct sk_buff *s__clear_bit (slot_id, po->rx_ring.rx_owner_map);spin_unlock (&sk->sk_receive_queue.lock); sk->sk_data_ready (sk); - }else { + }else if (po->tp_version ==TPACKET_V3 ) {prb_clear_blk_fill_status (&po->rx_ring); }
Greg Kroah-Hartman
maintainerPATCH 218/270 drivers/net/wan/lapbether: Added needed_headroom and a skb->len check
In reply to Greg Kroah-HartmanFrom: Xie He <[email protected]>
[ Upstream commit c7ca03c216acb14466a713fedf1b9f2c24994ef2 ]
1. Added a skb->len check
This driver expects upper layers to include a pseudo header of 1 byte when passing down a skb for transmission. This driver will read this 1-byte header. This patch added a skb->len check before reading the header to make sure the header exists.
2. Changed to use needed_headroom instead of hard_header_len to request necessary headroom to be allocated
In net/packet/af_packet.c, the function packet_snd first reserves a headroom of length (dev->hard_header_len + dev->needed_headroom). Then if the socket is a SOCK_DGRAM socket, it calls dev_hard_header, which calls dev->header_ops->create, to create the link layer header. If the socket is a SOCK_RAW socket, it "un-reserves" a headroom of length (dev->hard_header_len), and assumes the user to provide the appropriate link layer header.
So according to the logic of af_packet.c, dev->hard_header_len should be the length of the header that would be created by dev->header_ops->create.
However, this driver doesn't provide dev->header_ops, so logically dev->hard_header_len should be 0.
So we should use dev->needed_headroom instead of dev->hard_header_len to request necessary headroom to be allocated.
This change fixes kernel panic when this driver is used with AF_PACKET SOCK_RAW sockets.
Call stack when panic:
[ 168.399197] skbuff: skb_under_panic: text:ffffffff819d95fb len:20 put:14 head:ffff8882704c0a00 data:ffff8882704c09fd tail:0x11 end:0xc0 dev:veth0 ... [ 168.399255] Call Trace: [ 168.399259] skb_push.cold+0x14/0x24 [ 168.399262] eth_header+0x2b/0xc0 [ 168.399267] lapbeth_data_transmit+0x9a/0xb0 [lapbether] [ 168.399275] lapb_data_transmit+0x22/0x2c [lapb] [ 168.399277] lapb_transmit_buffer+0x71/0xb0 [lapb] [ 168.399279] lapb_kick+0xe3/0x1c0 [lapb] [ 168.399281] lapb_data_request+0x76/0xc0 [lapb] [ 168.399283] lapbeth_xmit+0x56/0x90 [lapbether] [ 168.399286] dev_hard_start_xmit+0x91/0x1f0 [ 168.399289] ? irq_init_percpu_irqstack+0xc0/0x100 [ 168.399291] __dev_queue_xmit+0x721/0x8e0 [ 168.399295] ? packet_parse_headers.isra.0+0xd2/0x110 [ 168.399297] dev_queue_xmit+0x10/0x20 [ 168.399298] packet_sendmsg+0xbf0/0x19b0
......
--- drivers/net/wan/lapbether.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/net/wan/lapbether.c +9 -1
@@ -157,6 +157,12 @@ static netdev_tx_t lapbeth_xmit(struct sif (!netif_running (dev)) 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 (skb->len <1 ) + goto drop; +switch (skb->data[0 ]) {case X25_IFACE_DATA :break ;
@@ -305,6 +311,7 @@ static void lapbeth_setup(struct net_dev dev->netdev_ops = &lapbeth_netdev_ops; dev->needs_free_netdev = true; dev->type =ARPHRD_X25 ; + dev->hard_header_len =0 ; dev->mtu =1000 ; dev->addr_len =0 ; }
@@ -331,7 +338,8 @@ static int lapbeth_new_device(struct net* then this driver prepends a length field of 2 bytes, * then the underlying Ethernet device prepends its own header. */ - ndev->hard_header_len =-1 +3 +2 + dev->hard_header_len; + ndev->needed_headroom =-1 +3 +2 + dev->hard_header_len + + dev->needed_headroom; lapbeth =netdev_priv (ndev); lapbeth->axdev = ndev;
Greg Kroah-Hartman
maintainerPATCH 219/270 net: Fix potential memory leak in proto_register()
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit 0f5907af39137f8183ed536aaa00f322d7365130 ]
If we failed to assign proto idx, we free the twsk_slab_name but forget to free the twsk_slab. Add a helper function tw_prot_cleanup() to free these together and also use this helper function in proto_unregister().
--- net/core/sock.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
net/core/sock.c +15 -10
@@ -3337,6 +3337,16 @@ static void sock_inuse_add(struct net *n }#endif +static void tw_prot_cleanup (struct timewait_sock_ops *twsk_prot) +{ +if (!twsk_prot) +return ; +kfree (twsk_prot->twsk_slab_name); + twsk_prot->twsk_slab_name =NULL ; +kmem_cache_destroy (twsk_prot->twsk_slab); + twsk_prot->twsk_slab =NULL ; +} +static void req_prot_cleanup (struct request_sock_ops *rsk_prot) {if (!rsk_prot)
@@ -3407,7 +3417,7 @@ int proto_register(struct proto *prot, i prot->slab_flags, NULL);if (prot->twsk_prot->twsk_slab ==NULL ) - goto out_free_timewait_sock_slab_name; + goto out_free_timewait_sock_slab; } }
@@ -3415,15 +3425,15 @@ int proto_register(struct proto *prot, i ret =assign_proto_idx (prot);if (ret) {mutex_unlock (&proto_list_mutex); - goto out_free_timewait_sock_slab_name; + goto out_free_timewait_sock_slab; }list_add (&prot->node, &proto_list);mutex_unlock (&proto_list_mutex);return ret; -out_free_timewait_sock_slab_name: +out_free_timewait_sock_slab:if (alloc_slab && prot->twsk_prot) -kfree (prot->twsk_prot->twsk_slab_name); +tw_prot_cleanup (prot->twsk_prot); out_free_request_sock_slab:if (alloc_slab) {req_prot_cleanup (prot->rsk_prot);
@@ -3447,12 +3457,7 @@ void proto_unregister(struct proto *prot prot->slab =NULL ;req_prot_cleanup (prot->rsk_prot); - -if (prot->twsk_prot !=NULL && prot->twsk_prot->twsk_slab !=NULL ) { -kmem_cache_destroy (prot->twsk_prot->twsk_slab); -kfree (prot->twsk_prot->twsk_slab_name); - prot->twsk_prot->twsk_slab =NULL ; - } +tw_prot_cleanup (prot->twsk_prot); }EXPORT_SYMBOL (proto_unregister);
Greg Kroah-Hartman
maintainerPATCH 220/270 net/nfc/rawsock.c: add CAP_NET_RAW check.
In reply to Greg Kroah-HartmanFrom: Qingyu Li <[email protected]>
[ Upstream commit 26896f01467a28651f7a536143fe5ac8449d4041 ]
When creating a raw AF_NFC socket, CAP_NET_RAW needs to be checked first.
--- net/nfc/rawsock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/nfc/rawsock.c +5 -2
@@ -332,10 +332,13 @@ static int rawsock_create(struct net *neif ((sock->type !=SOCK_SEQPACKET ) && (sock->type !=SOCK_RAW ))return -ESOCKTNOSUPPORT ; -if (sock->type ==SOCK_RAW ) +if (sock->type ==SOCK_RAW ) { +if (!capable (CAP_NET_RAW )) +return -EPERM ; sock->ops = &rawsock_raw_ops; -else + }else { sock->ops = &rawsock_ops; + } sk =sk_alloc (net,PF_NFC ,GFP_ATOMIC , nfc_proto->proto, kern);if (!sk)
Greg Kroah-Hartman
maintainerPATCH 221/270 net: phy: fix memory leak in device-create error path
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit d02cbc46136105cf86f84ac355e16f04696f538d ]
A recent commit introduced a late error path in phy_device_create() which fails to release the device name allocated by dev_set_name().
--- drivers/net/phy/phy_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/phy/phy_device.c +4 -4
@@ -615,7 +615,9 @@ struct phy_device *phy_device_create(strif (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 ;
@@ -649,10 +651,8 @@ struct phy_device *phy_device_create(str 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); }
Greg Kroah-Hartman
maintainerPATCH 222/270 net: Set fput_needed iff FDPUT_FPUT is set
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit ce787a5a074a86f76f5d3fd804fa78e01bfb9e89 ]
We should fput() file iff FDPUT_FPUT is set. So we should set fput_needed accordingly.
--- net/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/socket.c +1 -1
@@ -485,7 +485,7 @@ static struct socket *sockfd_lookup_lighif (f.file) { sock =sock_from_file (f.file, err);if (likely (sock)) { - *fput_needed = f.flags; + *fput_needed = f.flags &FDPUT_FPUT ;return sock; }fdput (f);
Greg Kroah-Hartman
maintainerPATCH 223/270 net/tls: Fix kmap usage
In reply to Greg Kroah-HartmanFrom: Ira Weiny <[email protected]>
[ Upstream commit b06c19d9f827f6743122795570bfc0c72db482b0 ]
When MSG_OOB is specified to tls_device_sendpage() the mapped page is never unmapped.
Hold off mapping the page until after the flags are checked and the page is actually needed.
--- net/tls/tls_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/tls/tls_device.c +2 -1
@@ -549,7 +549,7 @@ int tls_device_sendpage(struct sock *sk, {struct tls_context *tls_ctx =tls_get_ctx (sk);struct iov_iter msg_iter; -char *kaddr =kmap (page); +char *kaddr;struct kvec iov;int rc;
@@ -564,6 +564,7 @@ int tls_device_sendpage(struct sock *sk, goto out; } + kaddr =kmap (page); iov.iov_base = kaddr + offset; iov.iov_len = size;iov_iter_kvec (&msg_iter,WRITE , &iov,1 , size);
Greg Kroah-Hartman
maintainerPATCH 224/270 tcp: correct read of TFO keys on big endian systems
In reply to Greg Kroah-HartmanFrom: Jason Baron <[email protected]>
[ Upstream commit f19008e676366c44e9241af57f331b6c6edf9552 ]
When TFO keys are read back on big endian systems either via the global sysctl interface or via getsockopt() using TCP_FASTOPEN_KEY, the values don't match what was written.
For example, on s390x:
# echo "1-2-3-4" > /proc/sys/net/ipv4/tcp_fastopen_key # cat /proc/sys/net/ipv4/tcp_fastopen_key 02000000-01000000-04000000-03000000
Instead of:
# cat /proc/sys/net/ipv4/tcp_fastopen_key 00000001-00000002-00000003-00000004
Fix this by converting to the correct endianness on read. This was reported by Colin Ian King when running the 'tcp_fastopen_backup_key' net selftest on s390x, which depends on the read value matching what was written. I've confirmed that the test now passes on big and little endian systems.
--- include/net/tcp.h | 2 ++ net/ipv4/sysctl_net_ipv4.c | 16 ++++------------ net/ipv4/tcp.c | 16 ++++------------ net/ipv4/tcp_fastopen.c | 23 +++++++++++++++++++++++ 4 files changed, 33 insertions(+), 24 deletions(-)
include/net/tcp.h +2 -0
@@ -1650,6 +1650,8 @@ void tcp_fastopen_destroy_cipher(structvoid tcp_fastopen_ctx_destroy (struct net *net);int tcp_fastopen_reset_cipher (struct net *net,struct sock *sk,void *primary_key,void *backup_key); +int tcp_fastopen_get_cipher (struct net *net,struct inet_connection_sock *icsk, +u64 *key);void tcp_fastopen_add_skb (struct sock *sk,struct sk_buff *skb); struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, struct request_sock *req,
net/ipv4/sysctl_net_ipv4.c +4 -12
@@ -307,24 +307,16 @@ static int proc_tcp_fastopen_key(structstruct ctl_table tbl = { .maxlen = ((TCP_FASTOPEN_KEY_LENGTH *2 *TCP_FASTOPEN_KEY_MAX ) + (TCP_FASTOPEN_KEY_MAX *5 )) }; -struct tcp_fastopen_context *ctx; -u32 user_key[TCP_FASTOPEN_KEY_MAX *4 ]; -__le32 key[TCP_FASTOPEN_KEY_MAX *4 ]; +u32 user_key[TCP_FASTOPEN_KEY_BUF_LENGTH /sizeof (u32)]; +__le32 key[TCP_FASTOPEN_KEY_BUF_LENGTH /sizeof (__le32)];char *backup_data; -int ret, i =0 , off =0 , n_keys =0 ; +int ret, i =0 , off =0 , n_keys; tbl.data =kmalloc (tbl.maxlen,GFP_KERNEL );if (!tbl.data)return -ENOMEM ; -rcu_read_lock (); - ctx =rcu_dereference (net->ipv4.tcp_fastopen_ctx); -if (ctx) { - n_keys =tcp_fastopen_context_len (ctx); -memcpy (&key[0 ], &ctx->key[0 ],TCP_FASTOPEN_KEY_LENGTH * n_keys); - } -rcu_read_unlock (); - + n_keys =tcp_fastopen_get_cipher (net,NULL , (u64 *)key);if (!n_keys) {memset (&key[0 ],0 ,TCP_FASTOPEN_KEY_LENGTH ); n_keys =1 ;
net/ipv4/tcp.c +4 -12
@@ -3527,22 +3527,14 @@ static int do_tcp_getsockopt(struct sockreturn 0 ;case TCP_FASTOPEN_KEY : { -__u8 key[TCP_FASTOPEN_KEY_BUF_LENGTH ]; -struct tcp_fastopen_context *ctx; -unsigned int key_len =0 ; +u64 key[TCP_FASTOPEN_KEY_BUF_LENGTH /sizeof (u64)]; +unsigned int key_len;if (get_user (len, optlen))return -EFAULT ; -rcu_read_lock (); - ctx =rcu_dereference (icsk->icsk_accept_queue.fastopenq.ctx); -if (ctx) { - key_len =tcp_fastopen_context_len (ctx) * -TCP_FASTOPEN_KEY_LENGTH ; -memcpy (&key[0 ], &ctx->key[0 ], key_len); - } -rcu_read_unlock (); - + key_len =tcp_fastopen_get_cipher (net, icsk, key) * +TCP_FASTOPEN_KEY_LENGTH ; len = min_t(unsigned int, len, key_len);if (put_user (len, optlen))return -EFAULT ;
net/ipv4/tcp_fastopen.c +23 -0
@@ -108,6 +108,29 @@ out:return err; } +int tcp_fastopen_get_cipher (struct net *net,struct inet_connection_sock *icsk, +u64 *key) +{ +struct tcp_fastopen_context *ctx; +int n_keys =0 , i; + +rcu_read_lock (); +if (icsk) + ctx =rcu_dereference (icsk->icsk_accept_queue.fastopenq.ctx); +else + ctx =rcu_dereference (net->ipv4.tcp_fastopen_ctx); +if (ctx) { + n_keys =tcp_fastopen_context_len (ctx); +for (i =0 ; i < n_keys; i++) { +put_unaligned_le64 (ctx->key[i].key[0 ], key + (i *2 )); +put_unaligned_le64 (ctx->key[i].key[1 ], key + (i *2 ) +1 ); + } + } +rcu_read_unlock (); + +return n_keys; +} + static bool __tcp_fastopen_cookie_gen_cipher(struct request_sock *req, struct sk_buff *syn, const siphash_key_t *key,
Greg Kroah-Hartman
maintainerPATCH 225/270 vmxnet3: use correct tcp hdr length when packet is encapsulated
In reply to Greg Kroah-HartmanFrom: Ronak Doshi <[email protected]>
[ Upstream commit 8a7f280f29a80f6e0798f5d6e07c5dd8726620fe ]
Commit dacce2be3312 ("vmxnet3: add geneve and vxlan tunnel offload support") added support for encapsulation offload. However, while calculating tcp hdr length, it does not take into account if the packet is encapsulated or not.
This patch fixes this issue by using correct reference for inner tcp header.
--- drivers/net/vmxnet3/vmxnet3_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/vmxnet3/vmxnet3_drv.c +2 -1
@@ -861,7 +861,8 @@ vmxnet3_parse_hdr(struct sk_buff *skb, sswitch (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 );
Greg Kroah-Hartman
maintainerPATCH 226/270 net: refactor bind_bucket fastreuse into helper
In reply to Greg Kroah-HartmanFrom: Tim Froidcoeur <[email protected]>
[ Upstream commit 62ffc589abb176821662efc4525ee4ac0b9c3894 ]
Refactor the fastreuse update code in inet_csk_get_port into a small helper function that can be called from other places.
--- include/net/inet_connection_sock.h | 4 + net/ipv4/inet_connection_sock.c | 97 ++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 44 deletions(-)
include/net/inet_connection_sock.h +4 -0
@@ -309,6 +309,10 @@ int inet_csk_compat_getsockopt(struct soint inet_csk_compat_setsockopt (struct sock *sk,int level,int optname,char __user *optval,unsigned int optlen); +/* update the fast reuse flag when adding a socket */ +void inet_csk_update_fastreuse (struct inet_bind_bucket *tb, +struct sock *sk); +struct dst_entry *inet_csk_update_pmtu (struct sock *sk,u32 mtu);#define TCP_PINGPONG_THRESH 3
net/ipv4/inet_connection_sock.c +53 -44
115 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 227/270 net: initialize fastreuse on inet_inherit_port
In reply to Greg Kroah-HartmanFrom: Tim Froidcoeur <[email protected]>
[ Upstream commit d76f3351cea2d927fdf70dd7c06898235035e84e ]
In the case of TPROXY, bind_conflict optimizations for SO_REUSEADDR or SO_REUSEPORT are broken, possibly resulting in O(n) instead of O(1) bind behaviour or in the incorrect reuse of a bind.
the kernel keeps track for each bind_bucket if all sockets in the bind_bucket support SO_REUSEADDR or SO_REUSEPORT in two fastreuse flags. These flags allow skipping the costly bind_conflict check when possible (meaning when all sockets have the proper SO_REUSE option).
For every socket added to a bind_bucket, these flags need to be updated. As soon as a socket that does not support reuse is added, the flag is set to false and will never go back to true, unless the bind_bucket is deleted.
Note that there is no mechanism to re-evaluate these flags when a socket is removed (this might make sense when removing a socket that would not allow reuse; this leaves room for a future patch).
For this optimization to work, it is mandatory that these flags are properly initialized and updated.
When a child socket is created from a listen socket in __inet_inherit_port, the TPROXY case could create a new bind bucket without properly initializing these flags, thus preventing the optimization to work. Alternatively, a socket not allowing reuse could be added to an existing bind bucket without updating the flags, causing bind_conflict to never be called as it should.
Call inet_csk_update_fastreuse when __inet_inherit_port decides to create a new bind_bucket or use a different bind_bucket than the one of the listen socket.
--- net/ipv4/inet_hashtables.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/inet_hashtables.c +1 -0
@@ -163,6 +163,7 @@ int __inet_inherit_port(const struct socreturn -ENOMEM ; } } +inet_csk_update_fastreuse (tb, child); }inet_bind_hash (child, tb, port);spin_unlock (&head->lock);
Greg Kroah-Hartman
maintainerPATCH 228/270 USB: serial: cp210x: re-enable auto-RTS on open
In reply to Greg Kroah-HartmanFrom: Brant Merryman <[email protected]>
commit c7614ff9b73a1e6fb2b1b51396da132ed22fecdb upstream.
CP210x hardware disables auto-RTS but leaves auto-CTS when in hardware flow control mode and UART on cp210x hardware is disabled. When re-opening the port, if auto-CTS is enabled on the cp210x, then auto-RTS must be re-enabled in the driver.
--- drivers/usb/serial/cp210x.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/usb/serial/cp210x.c +17 -0
@@ -915,6 +915,7 @@ static void cp210x_get_termios_port(struu32 baud;u16 bits;u32 ctl_hs; +u32 flow_repl;cp210x_read_u32_reg (port,CP210X_GET_BAUDRATE , &baud);
@@ -1015,6 +1016,22 @@ static void cp210x_get_termios_port(stru ctl_hs =le32_to_cpu (flow_ctl.ulControlHandshake);if (ctl_hs &CP210X_SERIAL_CTS_HANDSHAKE ) {dev_dbg (dev,"%s - flow control = CRTSCTS\n" , __func__); +/* +* When the port is closed, the CP210x hardware disables +* auto-RTS and RTS is deasserted but it leaves auto-CTS when +* in hardware flow control mode. When re-opening the port, if +* auto-CTS is enabled on the cp210x, then auto-RTS must be +* re-enabled in the driver. +*/ + flow_repl =le32_to_cpu (flow_ctl.ulFlowReplace); + flow_repl &= ~CP210X_SERIAL_RTS_MASK ; + flow_repl |=CP210X_SERIAL_RTS_SHIFT (CP210X_SERIAL_RTS_FLOW_CTL ); + flow_ctl.ulFlowReplace =cpu_to_le32 (flow_repl); +cp210x_write_reg_block (port, +CP210X_SET_FLOW , + &flow_ctl, +sizeof (flow_ctl)); + cflag |=CRTSCTS ; }else {dev_dbg (dev,"%s - flow control = NONE\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 229/270 USB: serial: cp210x: enable usb generic throttle/unthrottle
In reply to Greg Kroah-HartmanFrom: Brant Merryman <[email protected]>
commit 4387b3dbb079d482d3c2b43a703ceed4dd27ed28 upstream.
Assign the .throttle and .unthrottle functions to be generic function in the driver structure to prevent data loss that can otherwise occur if the host does not enable USB throttling.
--- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/cp210x.c +2 -0
@@ -272,6 +272,8 @@ static struct usb_serial_driver cp210x_d .break_ctl = cp210x_break_ctl, .set_termios = cp210x_set_termios, .tx_empty = cp210x_tx_empty, + .throttle = usb_serial_generic_throttle, + .unthrottle = usb_serial_generic_unthrottle, .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_attach,
Greg Kroah-Hartman
maintainerPATCH 230/270 ALSA: hda - fix the micmute led status for Lenovo ThinkCentre AIO
In reply to Greg Kroah-HartmanFrom: Hui Wang <[email protected]>
commit 386a6539992b82fe9ac4f9dc3f548956fd894d8c upstream.
After installing the Ubuntu Linux, the micmute led status is not correct. Users expect that the led is on if the capture is disabled, but with the current kernel, the led is off with the capture disabled.
We tried the old linux kernel like linux-4.15, there is no this issue. It looks like we introduced this issue when switching to the led_cdev.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -4391,6 +4391,7 @@ static void alc233_fixup_lenovo_line2_mi {struct alc_spec *spec = codec->spec; + spec->micmute_led_polarity =1 ;alc_fixup_hp_gpio_led (codec, action,0 ,0x04 );if (action ==HDA_FIXUP_ACT_PRE_PROBE ) { spec->init_amp =ALC_INIT_DEFAULT ;
Greg Kroah-Hartman
maintainerPATCH 231/270 ALSA: usb-audio: Creative USB X-Fi Pro SB1095 volume knob support
In reply to Greg Kroah-HartmanFrom: Mirko Dietrich <[email protected]>
commit fec9008828cde0076aae595ac031bfcf49d335a4 upstream.
Adds an entry for Creative USB X-Fi to the rc_config array in mixer_quirks.c to allow use of volume knob on the device. Adds support for newer X-Fi Pro card, known as "Model No. SB1095" with USB ID "041e:3263"
--- sound/usb/mixer_quirks.c | 1 + 1 file changed, 1 insertion(+)
sound/usb/mixer_quirks.c +1 -0
@@ -184,6 +184,7 @@ static const struct rc_config { { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */ { USB_ID(0x041e, 0x3237), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */ + { USB_ID(0x041e, 0x3263), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */ { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ };
Greg Kroah-Hartman
maintainerPATCH 232/270 ALSA: usb-audio: fix overeager device match for MacroSilicon MS2109
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
commit 14a720dc1f5332f3bdf30a23a3bc549e81be974c upstream.
Matching by device matches all interfaces, which breaks the video/HID portions of the device depending on module load order.
--- sound/usb/quirks-table.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
sound/usb/quirks-table.h +7 -1
@@ -3623,7 +3623,13 @@ ALC1220_VB_DESKTOP(0x26ce, 0x0a01), /* A* with. */ { - USB_DEVICE(0x534d, 0x2109), + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | +USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x534d, + .idProduct = 0x2109, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { .vendor_name ="MacroSilicon" , .product_name ="MS2109" ,
Greg Kroah-Hartman
maintainerPATCH 233/270 ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
commit 1b7ecc241a67ad6b584e071bd791a54e0cd5f097 upstream.
Further investigation of the L-R swap problem on the MS2109 reveals that the problem isn't that the channels are swapped, but rather that they are swapped and also out of phase by one sample. In other words, the issue is actually that the very first frame that comes from the hardware is a half-frame containing only the right channel, and after that everything becomes offset.
So introduce a new quirk field to drop the very first 2 bytes that come in after the format is configured and a capture stream starts. This puts the channels in phase and in the correct order.
--- sound/usb/card.h | 1 + sound/usb/pcm.c | 6 ++++++ sound/usb/quirks.c | 3 +++ sound/usb/stream.c | 1 + 4 files changed, 11 insertions(+)
sound/usb/card.h +1 -0
@@ -133,6 +133,7 @@ struct snd_usb_substream { unsigned int tx_length_quirk:1; /* add length specifier to transfers */unsigned int fmt_type;/* USB audio format type (1-3) */ unsigned int pkt_offset_adj;/* Bytes to drop from beginning of packets (for non-compliant devices) */ +unsigned int stream_offset_adj;/* Bytes to drop from beginning of stream (for non-compliant devices) */ unsigned int running: 1; /* running status */
sound/usb/pcm.c +6 -0
@@ -1417,6 +1417,12 @@ static void retire_capture_urb(struct sn// continue; } bytes = urb->iso_frame_desc[i].actual_length; +if (subs->stream_offset_adj >0 ) { +unsigned int adj =min (subs->stream_offset_adj, bytes); + cp += adj; + bytes -= adj; + subs->stream_offset_adj -= adj; + } frames = bytes / stride;if (!subs->txfr_quirk) bytes = frames * stride;
sound/usb/quirks.c +3 -0
@@ -1432,6 +1432,9 @@ void snd_usb_set_format_quirk(struct sndcase USB_ID (0x041e ,0x3f19 ):/* E-Mu 0204 USB */ set_format_emu_quirk (subs, fmt);break ; +case USB_ID (0x534d ,0x2109 ):/* MacroSilicon MS2109 */ + subs->stream_offset_adj =2 ; +break ; } }
sound/usb/stream.c +1 -0
@@ -94,6 +94,7 @@ static void snd_usb_init_substream(struc subs->tx_length_quirk = as->chip->tx_length_quirk; subs->speed =snd_usb_get_speed (subs->dev); subs->pkt_offset_adj =0 ; + subs->stream_offset_adj =0 ;snd_usb_set_pcm_ops (as->pcm, stream);
Greg Kroah-Hartman
maintainerPATCH 234/270 9p: Fix memory leak in v9fs_mount
In reply to Greg Kroah-HartmanFrom: Zheng Bin <[email protected]>
commit cb0aae0e31c632c407a2cab4307be85a001d4d98 upstream.
v9fs_mount
v9fs_session_init
v9fs_cache_session_get_cookie
v9fs_random_cachetag -->alloc cachetag
v9ses->fscache = fscache_acquire_cookie -->maybe NULL
sb = sget -->fail, goto clunk
clunk_fid:
v9fs_session_close
if (v9ses->fscache) -->NULL
kfree(v9ses->cachetag)Thus memleak happens.
--- fs/9p/v9fs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/9p/v9fs.c +2 -3
@@ -500,10 +500,9 @@ void v9fs_session_close(struct v9fs_sess }#ifdef CONFIG_9P_FSCACHE -if (v9ses->fscache) { +if (v9ses->fscache)v9fs_cache_session_put_cookie (v9ses); -kfree (v9ses->cachetag); - } +kfree (v9ses->cachetag);#endif kfree (v9ses->uname);kfree (v9ses->aname);
Greg Kroah-Hartman
maintainerPATCH 235/270 media: media-request: Fix crash if memory allocation fails
In reply to Greg Kroah-HartmanFrom: Tuomas Tynkkynen <[email protected]>
commit e30cc79cc80fd919b697a15c5000d9f57487de8e upstream.
Syzbot reports a NULL-ptr deref in the kref_put() call:
BUG: KASAN: null-ptr-deref in media_request_put drivers/media/mc/mc-request.c:81 [inline] kref_put include/linux/kref.h:64 [inline] media_request_put drivers/media/mc/mc-request.c:81 [inline] media_request_close+0x4d/0x170 drivers/media/mc/mc-request.c:89 __fput+0x2ed/0x750 fs/file_table.c:281 task_work_run+0x147/0x1d0 kernel/task_work.c:123 tracehook_notify_resume include/linux/tracehook.h:188 [inline] exit_to_usermode_loop arch/x86/entry/common.c:165 [inline] prepare_exit_to_usermode+0x48e/0x600 arch/x86/entry/common.c:196
What led to this crash was an injected memory allocation failure in media_request_alloc():
FAULT_INJECTION: forcing a failure.
name failslab, interval 1, probability 0, space 0, times 0
should_failslab+0x5/0x20 kmem_cache_alloc_trace+0x57/0x300 ? anon_inode_getfile+0xe5/0x170 media_request_alloc+0x339/0x440 media_device_request_alloc+0x94/0xc0 media_device_ioctl+0x1fb/0x330 ? do_vfs_ioctl+0x6ea/0x1a00 ? media_ioctl+0x101/0x120 ? __media_device_usb_init+0x430/0x430 ? media_poll+0x110/0x110 __se_sys_ioctl+0xf9/0x160 do_syscall_64+0xf3/0x1b0
When that allocation fails, filp->private_data is left uninitialized which media_request_close() does not expect and crashes.
To avoid this, reorder media_request_alloc() such that allocating the struct file happens as the last step thus media_request_close() will no longer get called for a partially created media request.
--- drivers/media/mc/mc-request.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
drivers/media/mc/mc-request.c +17 -14
@@ -296,9 +296,18 @@ int media_request_alloc(struct media_devif (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 @@ int media_request_alloc(struct media_dev 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 @@ int media_request_alloc(struct media_devreturn 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; }
Greg Kroah-Hartman
maintainerPATCH 236/270 drm/ttm/nouveau: dont call tt destroy callback on alloc failure.
In reply to Greg Kroah-HartmanFrom: Dave Airlie <[email protected]>
commit 5de5b6ecf97a021f29403aa272cb4e03318ef586 upstream.
This is confusing, and from my reading of all the drivers only nouveau got this right.
Just make the API act under driver control of it's own allocation failing, and don't call destroy, if the page table fails to create there is nothing to cleanup here.
(I'm willing to believe I've missed something here, so please review deeply).
--- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 9 +++------ drivers/gpu/drm/ttm/ttm_tt.c | 3 --- 2 files changed, 3 insertions(+), 9 deletions(-)
drivers/gpu/drm/nouveau/nouveau_sgdma.c +3 -6
@@ -96,12 +96,9 @@ nouveau_sgdma_create_ttm(struct ttm_buffelse 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; }
drivers/gpu/drm/ttm/ttm_tt.c +0 -3
@@ -241,7 +241,6 @@ int ttm_tt_init(struct ttm_tt *ttm, struttm_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 @@ int ttm_dma_tt_init(struct ttm_dma_tt *tINIT_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 @@ int ttm_sg_tt_init(struct ttm_dma_tt *ttelse ret =ttm_dma_tt_alloc_page_directory (ttm_dma);if (ret) { -ttm_tt_destroy (ttm);pr_err ("Failed allocating page table\n" );return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 237/270 io_uring: set ctx sq/cq entry count earlier
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit bd74048108c179cea0ff52979506164c80f29da7 upstream.
If we hit an earlier error path in io_uring_create(), then we will have accounted memory, but not set ctx->{sq,cq}_entries yet. Then when the ring is torn down in error, we use those values to unaccount the memory.
Ensure we set the ctx entries before we're able to hit a potential error path.
--- fs/io_uring.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/io_uring.c +4 -2
@@ -3857,6 +3857,10 @@ static int io_allocate_scq_urings(structstruct io_rings *rings;size_t size, sq_array_offset; +/* make sure these are sane, as we already accounted them */ + ctx->sq_entries = p->sq_entries; + ctx->cq_entries = p->cq_entries; + size =rings_size (p->sq_entries, p->cq_entries, &sq_array_offset);if (size ==SIZE_MAX )return -EOVERFLOW ;
@@ -3873,8 +3877,6 @@ static int io_allocate_scq_urings(struct rings->cq_ring_entries = p->cq_entries; ctx->sq_mask = rings->sq_ring_mask; ctx->cq_mask = rings->cq_ring_mask; - ctx->sq_entries = rings->sq_ring_entries; - ctx->cq_entries = rings->cq_ring_entries; size =array_size (sizeof (struct io_uring_sqe ), p->sq_entries);if (size ==SIZE_MAX ) {
Greg Kroah-Hartman
maintainerPATCH 238/270 NFS: Dont move layouts to plh_return_segs list while in use
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit ff041727e9e029845857cac41aae118ead5e261b upstream.
If the layout segment is still in use for a read or a write, we should not move it to the layout plh_return_segs list. If we do, we can end up returning the layout while I/O is still in progress.
--- fs/nfs/pnfs.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
fs/nfs/pnfs.c +1 -11
@@ -2362,16 +2362,6 @@ out_forget:return ERR_PTR (-EAGAIN ); } -static int -mark_lseg_invalid_or_return (struct pnfs_layout_segment *lseg, -struct list_head *tmp_list) -{ -if (!mark_lseg_invalid (lseg, tmp_list)) -return 0 ; -pnfs_cache_lseg_for_layoutreturn (lseg->pls_layout, lseg); -return 1 ; -} -/** * pnfs_mark_matching_lsegs_return - Free or return matching layout segments * @lo: pointer to layout header
@@ -2408,7 +2398,7 @@ pnfs_mark_matching_lsegs_return(struct p lseg, lseg->pls_range.iomode, lseg->pls_range.offset, lseg->pls_range.length); -if (mark_lseg_invalid_or_return (lseg, tmp_list)) +if (mark_lseg_invalid (lseg, tmp_list))continue ; remaining++;set_bit (NFS_LSEG_LAYOUTRETURN , &lseg->pls_flags);
Greg Kroah-Hartman
maintainerPATCH 239/270 NFS: Dont return layout segments that are in use
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit d474f96104bd4377573526ebae2ee212205a6839 upstream.
If the NFS_LAYOUT_RETURN_REQUESTED flag is set, we want to return the layout as soon as possible, meaning that the affected layout segments should be marked as invalid, and should no longer be in use for I/O.
--- fs/nfs/pnfs.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-)
fs/nfs/pnfs.c +15 -19
@@ -1198,31 +1198,27 @@ out:return status; } +static bool +pnfs_layout_segments_returnable (struct pnfs_layout_hdr *lo, +enum pnfs_iomode iomode, +u32 seq) +{ +struct pnfs_layout_range recall_range = { + .length =NFS4_MAX_UINT64 , + .iomode = iomode, + }; +return pnfs_mark_matching_lsegs_return (lo, &lo->plh_return_segs, + &recall_range, seq) != -EBUSY ; +} +/* Return true if layoutreturn is needed */ static bool pnfs_layout_need_return (struct pnfs_layout_hdr *lo) { -struct pnfs_layout_segment *s; -enum pnfs_iomode iomode; -u32 seq; -if (!test_bit (NFS_LAYOUT_RETURN_REQUESTED , &lo->plh_flags))return false; - - seq = lo->plh_return_seq; - iomode = lo->plh_return_iomode; - -/* Defer layoutreturn until all recalled lsegs are done */ -list_for_each_entry (s, &lo->plh_segs, pls_list) { -if (seq &&pnfs_seqid_is_newer (s->pls_seq, seq)) -continue ; -if (iomode !=IOMODE_ANY && s->pls_range.iomode != iomode) -continue ; -if (test_bit (NFS_LSEG_LAYOUTRETURN , &s->pls_flags)) -return false; - } - -return true; +return pnfs_layout_segments_returnable (lo, lo->plh_return_iomode, + lo->plh_return_seq); }static void pnfs_layoutreturn_before_put_layout_hdr (struct pnfs_layout_hdr *lo)
Greg Kroah-Hartman
maintainerPATCH 240/270 cpufreq: Fix locking issues with governors
In reply to Greg Kroah-HartmanFrom: Viresh Kumar <[email protected]>
commit 8cc46ae565c393f77417cb9530b1265eb50f5d2e upstream.
The locking around governors handling isn't adequate currently.
The list of governors should never be traversed without the locking in place. Also governor modules must not be removed while the code in them is still in use.
--- drivers/cpufreq/cpufreq.c | 58 +++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 23 deletions(-)
drivers/cpufreq/cpufreq.c +35 -23
@@ -616,6 +616,24 @@ static struct cpufreq_governor *find_govreturn NULL ; } +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) + goto unlock; + +if (!try_module_get (t->owner)) + t =NULL ; + +unlock: +mutex_unlock (&cpufreq_governor_mutex); + +return t; +} +static unsigned int cpufreq_parse_policy (char *str_governor) {if (!strncasecmp (str_governor,"performance" ,CPUFREQ_NAME_LEN ))
@@ -635,28 +653,14 @@ static struct cpufreq_governor *cpufreq_ {struct cpufreq_governor *t; -mutex_lock (&cpufreq_governor_mutex); - - t =find_governor (str_governor); -if (!t) { -int ret; + t =get_governor (str_governor); +if (t) +return t; -mutex_unlock (&cpufreq_governor_mutex); +if (request_module ("cpufreq_%s" , str_governor)) +return NULL ; - ret =request_module ("cpufreq_%s" , str_governor); -if (ret) -return NULL ; - -mutex_lock (&cpufreq_governor_mutex); - - t =find_governor (str_governor); - } -if (t && !try_module_get (t->owner)) - t =NULL ; - -mutex_unlock (&cpufreq_governor_mutex); - -return t; +return get_governor (str_governor); }/**
@@ -810,12 +814,14 @@ static ssize_t show_scaling_available_go 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;
@@ -1053,15 +1059,17 @@ static int cpufreq_init_policy(struct cpstruct cpufreq_governor *def_gov =cpufreq_default_governor ();struct cpufreq_governor *gov =NULL ;unsigned int pol =CPUFREQ_POLICY_UNKNOWN ; +int ret;if (has_target ()) {/* Update policy governor to the one used before hotplug. */ - gov =find_governor (policy->last_governor); + 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) { gov = def_gov; +__module_get (gov->owner); }else {return -ENODATA ; }
@@ -1084,7 +1092,11 @@ static int cpufreq_init_policy(struct cpreturn -ENODATA ; } -return cpufreq_set_policy (policy, gov, pol); + 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)
Greg Kroah-Hartman
maintainerPATCH 241/270 cpufreq: dt: fix oops on armada37xx
In reply to Greg Kroah-HartmanFrom: Ivan Kokshaysky <[email protected]>
commit 10470dec3decaf5ed3c596f85debd7c42777ae12 upstream.
Commit 0c868627e617e43a295d8 (cpufreq: dt: Allow platform specific intermediate callbacks) added two function pointers to the struct cpufreq_dt_platform_data. However, armada37xx_cpufreq_driver_init() has this struct (pdata) located on the stack and uses only "suspend" and "resume" fields. So these newly added "get_intermediate" and "target_intermediate" pointers are uninitialized and contain arbitrary non-null values, causing all kinds of trouble.
For instance, here is an oops on espressobin after an attempt to change the cpefreq governor:
[ 29.174554] Unable to handle kernel execute from non-executable memory at virtual address ffff00003f87bdc0 ... [ 29.269373] pc : 0xffff00003f87bdc0 [ 29.272957] lr : __cpufreq_driver_target+0x138/0x580
...
Fixed by zeroing out pdata before use.
--- drivers/cpufreq/armada-37xx-cpufreq.c | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/armada-37xx-cpufreq.c +1 -0
@@ -456,6 +456,7 @@ static int __init armada37xx_cpufreq_dri/* 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;
Greg Kroah-Hartman
maintainerPATCH 242/270 include/asm-generic/vmlinux.lds.h: align ro_after_init
In reply to Greg Kroah-HartmanFrom: Romain Naour <[email protected]>
commit 7f897acbe5d57995438c831670b7c400e9c0dc00 upstream.
Since the patch [1], building the kernel using a toolchain built with binutils 2.33.1 prevents booting a sh4 system under Qemu. Apply the patch provided by Alan Modra [2] that fix alignment of rodata.
[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ebd2263ba9a9124d93bbc0ece63d7e0fae89b40e
[2] https://www.sourceware.org/ml/binutils/2019-12/msg00112.html
--- include/asm-generic/vmlinux.lds.h | 1 + 1 file changed, 1 insertion(+)
include/asm-generic/vmlinux.lds.h +1 -0
@@ -340,6 +340,7 @@*/ #ifndef RO_AFTER_INIT_DATA #define RO_AFTER_INIT_DATA \ + . = ALIGN(8); \ __start_ro_after_init = .; \ *(.data..ro_after_init) \ JUMP_TABLE_DATA \
Greg Kroah-Hartman
maintainerPATCH 243/270 spi: spidev: Align buffers for DMA
In reply to Greg Kroah-HartmanFrom: Christian Eggers <[email protected]>
commit aa9e862d7d5bcecd4dca9f39e8b684b93dd84ee7 upstream.
Simply copying all xfers from userspace into one bounce buffer causes alignment problems if the SPI controller uses DMA.
Ensure that all transfer data blocks within the rx and tx bounce buffers are aligned for DMA (according to ARCH_KMALLOC_MINALIGN).
Alignment may increase the usage of the bounce buffers. In some cases, the buffers may need to be increased using the "bufsiz" module parameter.
--- drivers/spi/spidev.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/spi/spidev.c +13 -8
@@ -223,6 +223,11 @@ static int spidev_message(struct spidev_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 @@ static int spidev_message(struct spidev_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 @@ static int spidev_message(struct spidev_ (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 @@ static int spidev_message(struct spidev_ 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;
Greg Kroah-Hartman
maintainerPATCH 244/270 mtd: rawnand: qcom: avoid write to unavailable register
In reply to Greg Kroah-HartmanFrom: Sivaprakash Murugesan <[email protected]>
commit 443440cc4a901af462239d286cd10721aa1c7dfc upstream.
SFLASHC_BURST_CFG is only available on older ipq NAND platforms, this register has been removed when the NAND controller got implemented in the qpic controller.
Avoid writing this register on devices which are based on qpic NAND controller.
--- drivers/mtd/nand/raw/qcom_nandc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/qcom_nandc.c +6 -1
@@ -459,11 +459,13 @@ struct qcom_nand_host {* 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; };
@@ -2751,7 +2753,8 @@ static int qcom_nandc_setup(struct qcom_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 );
@@ -3007,12 +3010,14 @@ static const struct qcom_nandc_props ipqstatic 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 , };
Greg Kroah-Hartman
maintainerPATCH 245/270 erofs: fix extended inode could cross boundary
In reply to Greg Kroah-HartmanFrom: Gao Xiang <[email protected]>
commit 0dcd3c94e02438f4a571690e26f4ee997524102a upstream.
Each ondisk inode should be aligned with inode slot boundary (32-byte alignment) because of nid calculation formula, so all compact inodes (32 byte) cannot across page boundary. However, extended inode is now 64-byte form, which can across page boundary in principle if the location is specified on purpose, although it's hard to be generated by mkfs due to the allocation policy and rarely used by Android use case now mainly for > 4GiB files.
For now, only two fields i_ctime_nsec and `i_nlink' couldn't be read from disk properly and cause out-of-bound memory read with random value.
Let's fix now.
--- fs/erofs/inode.c | 121 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 42 deletions(-)
fs/erofs/inode.c +79 -42
@@ -8,31 +8,80 @@#include <trace/events/erofs.h> -/* no locking */ -static int erofs_read_inode (struct inode *inode,void *data) +/* +* if inode is successfully read, return its inode page (or sometimes +* the inode payload page if it's an extended inode) in order to fill +* inline data if possible. +*/ +static struct page *erofs_read_inode (struct inode *inode, +unsigned int *ofs) { +struct super_block *sb = inode->i_sb; +struct erofs_sb_info *sbi =EROFS_SB (sb);struct erofs_inode *vi =EROFS_I (inode); -struct erofs_inode_compact *dic = data; -struct erofs_inode_extended *die; +const erofs_off_t inode_loc =iloc (sbi, vi->nid); -const unsigned int ifmt =le16_to_cpu (dic->i_format); -struct erofs_sb_info *sbi =EROFS_SB (inode->i_sb); -erofs_blk_t nblks =0 ; +erofs_blk_t blkaddr, nblks =0 ; +struct page *page; +struct erofs_inode_compact *dic; +struct erofs_inode_extended *die, *copied =NULL ; +unsigned int ifmt; +int err; - vi->datalayout =erofs_inode_datalayout (ifmt); + blkaddr =erofs_blknr (inode_loc); + *ofs =erofs_blkoff (inode_loc); +erofs_dbg ("%s, reading inode nid %llu at %u of blkaddr %u" , + __func__, vi->nid, *ofs, blkaddr); + + page =erofs_get_meta_page (sb, blkaddr); +if (IS_ERR (page)) { +erofs_err (sb,"failed to get inode (nid: %llu) page, err %ld" , + vi->nid,PTR_ERR (page)); +return page; + } + + dic =page_address (page) + *ofs; + ifmt =le16_to_cpu (dic->i_format); + + vi->datalayout =erofs_inode_datalayout (ifmt);if (vi->datalayout >=EROFS_INODE_DATALAYOUT_MAX ) {erofs_err (inode->i_sb,"unsupported datalayout %u of nid %llu" , vi->datalayout, vi->nid); -DBG_BUGON (1 ); -return -EOPNOTSUPP ; + err = -EOPNOTSUPP ; + goto err_out; }switch (erofs_inode_version (ifmt)) {case EROFS_INODE_LAYOUT_EXTENDED : - die = data; - vi->inode_isize =sizeof (struct erofs_inode_extended ); +/* check if the inode acrosses page boundary */ +if (*ofs + vi->inode_isize <=PAGE_SIZE ) { + *ofs += vi->inode_isize; + die = (struct erofs_inode_extended *)dic; + }else { +const unsigned int gotten =PAGE_SIZE - *ofs; + + copied =kmalloc (vi->inode_isize,GFP_NOFS ); +if (!copied) { + err = -ENOMEM ; + goto err_out; + } +memcpy (copied, dic, gotten); +unlock_page (page); +put_page (page); + + page =erofs_get_meta_page (sb, blkaddr +1 ); +if (IS_ERR (page)) { +erofs_err (sb,"failed to get inode payload page (nid: %llu), err %ld" , + vi->nid,PTR_ERR (page)); +kfree (copied); +return page; + } + *ofs = vi->inode_isize - gotten; +memcpy ((u8 *)copied + gotten,page_address (page), *ofs); + die = copied; + } vi->xattr_isize =erofs_xattr_ibody_size (die->i_xattr_icount); inode->i_mode =le16_to_cpu (die->i_mode);
@@ -69,9 +118,12 @@ static int erofs_read_inode(struct inode/* total blocks for compressed files */ if (erofs_inode_is_data_compressed (vi->datalayout)) nblks =le32_to_cpu (die->i_u.compressed_blocks); + +kfree (copied);break ;case EROFS_INODE_LAYOUT_COMPACT : vi->inode_isize =sizeof (struct erofs_inode_compact ); + *ofs += vi->inode_isize; vi->xattr_isize =erofs_xattr_ibody_size (dic->i_xattr_icount); inode->i_mode =le16_to_cpu (dic->i_mode);
@@ -111,8 +163,8 @@ static int erofs_read_inode(struct inodeerofs_err (inode->i_sb,"unsupported on-disk inode version %u of nid %llu" ,erofs_inode_version (ifmt), vi->nid); -DBG_BUGON (1 ); -return -EOPNOTSUPP ; + err = -EOPNOTSUPP ; + goto err_out; }if (!nblks)
@@ -120,13 +172,18 @@ static int erofs_read_inode(struct inode inode->i_blocks =roundup (inode->i_size,EROFS_BLKSIZ ) >>9 ; else inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK; -return 0 ; +return page; bogusimode:erofs_err (inode->i_sb,"bogus i_mode (%o) @ nid %llu" , inode->i_mode, vi->nid); + err = -EFSCORRUPTED ; +err_out:DBG_BUGON (1 ); -return -EFSCORRUPTED ; +kfree (copied); +unlock_page (page); +put_page (page); +return ERR_PTR (err); } static int erofs_fill_symlink(struct inode *inode, void *data,
@@ -146,7 +203,7 @@ static int erofs_fill_symlink(struct inoif (!lnk)return -ENOMEM ; - m_pofs += vi->inode_isize + vi->xattr_isize; + m_pofs += vi->xattr_isize;/* inline symlink data shouldn't cross page boundary as well */ if (m_pofs + inode->i_size >PAGE_SIZE ) {kfree (lnk);
@@ -167,37 +224,17 @@ static int erofs_fill_symlink(struct inostatic int erofs_fill_inode (struct inode *inode,int isdir) { -struct super_block *sb = inode->i_sb;struct erofs_inode *vi =EROFS_I (inode);struct page *page; -void *data; -int err; -erofs_blk_t blkaddr;unsigned int ofs; -erofs_off_t inode_loc; +int err =0 ;trace_erofs_fill_inode (inode, isdir); - inode_loc =iloc (EROFS_SB (sb), vi->nid); - blkaddr =erofs_blknr (inode_loc); - ofs =erofs_blkoff (inode_loc); - -erofs_dbg ("%s, reading inode nid %llu at %u of blkaddr %u" , - __func__, vi->nid, ofs, blkaddr); - page =erofs_get_meta_page (sb, blkaddr); - -if (IS_ERR (page)) { -erofs_err (sb,"failed to get inode (nid: %llu) page, err %ld" , - vi->nid,PTR_ERR (page)); +/* read inode base data from disk */ + page =erofs_read_inode (inode, &ofs); +if (IS_ERR (page))return PTR_ERR (page); - } - -DBG_BUGON (!PageUptodate (page)); - data =page_address (page); - - err =erofs_read_inode (inode, data + ofs); -if (err) - goto out_unlock;/* setup the new inode */ switch (inode->i_mode &S_IFMT ) {
@@ -210,7 +247,7 @@ static int erofs_fill_inode(struct inode inode->i_fop = &erofs_dir_fops;break ;case S_IFLNK : - err =erofs_fill_symlink (inode, data, ofs); + err =erofs_fill_symlink (inode,page_address (page), ofs);if (err) goto out_unlock;inode_nohighmem (inode);
Greg Kroah-Hartman
maintainerPATCH 246/270 Revert "parisc: Drop LDCW barrier in CAS code when running UP"
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 462fb756c7de1ffe5bc6099149136031c2d9c02a upstream.
This reverts commit e6eb5fe9123f05dcbf339ae5c0b6d32fcc0685d5. We need to optimize it differently. A follow up patch will correct it.
--- arch/parisc/kernel/syscall.S | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
arch/parisc/kernel/syscall.S +4 -8
@@ -641,8 +641,7 @@ cas_action: 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) + LDCW 0(%sr2,%r20), %r1 /* Barrier */ #endif stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG
@@ -659,8 +658,7 @@ cas_action: /* 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) + LDCW 0(%sr2,%r20), %r1 /* Barrier */ #endif stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG
@@ -864,8 +862,7 @@ cas2_action: cas2_end: /* Free lock */ #ifdef CONFIG_SMP -98: LDCW 0(%sr2,%r20), %r1 /* Barrier */ -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) + LDCW 0(%sr2,%r20), %r1 /* Barrier */ #endif stw %r20, 0(%sr2,%r20) /* Enable interrupts */
@@ -878,8 +875,7 @@ cas2_end: /* 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) + LDCW 0(%sr2,%r20), %r1 /* Barrier */ #endif stw %r20, 0(%sr2,%r20) ssm PSW_SM_I, %r0
Greg Kroah-Hartman
maintainerPATCH 247/270 Revert "parisc: Use ldcw instruction for SMP spinlock release barrier"
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 6e9f06ee6c9566f3606d93182ac8f803a148504b upstream.
This reverts commit 9e5c602186a692a7e848c0da17aed40f49d30519. No need to use the ldcw instruction as SMP spinlock release barrier. Revert it to gain back speed again.
--- arch/parisc/include/asm/spinlock.h | 4 --- arch/parisc/kernel/entry.S | 43 +++++++++++++++++-------------------- arch/parisc/kernel/syscall.S | 16 +++---------- 3 files changed, 24 insertions(+), 39 deletions(-)
arch/parisc/include/asm/spinlock.h +0 -4
@@ -37,11 +37,7 @@ static inline void arch_spin_unlock(archvolatile unsigned int *a; a =__ldcw_align (x); -#ifdef CONFIG_SMP - (void )__ldcw (a); -#else mb (); -#endif *a =1 ; }
arch/parisc/kernel/entry.S +20 -23
156 lines not on this page · raw message
arch/parisc/kernel/syscall.S +4 -12
@@ -640,9 +640,7 @@ cas_action: sub,<> %r28, %r25, %r0 2: stw %r24, 0(%r26) /* Free lock */ -#ifdef CONFIG_SMP - LDCW 0(%sr2,%r20), %r1 /* Barrier */ -#endif + sync stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG /* Clear thread register indicator */
@@ -657,9 +655,7 @@ cas_action: 3: /* Error occurred on load or store */ /* Free lock */ -#ifdef CONFIG_SMP - LDCW 0(%sr2,%r20), %r1 /* Barrier */ -#endif + sync stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG stw %r0, 4(%sr2,%r20)
@@ -861,9 +857,7 @@ cas2_action: cas2_end: /* Free lock */ -#ifdef CONFIG_SMP - LDCW 0(%sr2,%r20), %r1 /* Barrier */ -#endif + sync stw %r20, 0(%sr2,%r20) /* Enable interrupts */ ssm PSW_SM_I, %r0
@@ -874,9 +868,7 @@ cas2_end: 22: /* Error occurred on load or store */ /* Free lock */ -#ifdef CONFIG_SMP - LDCW 0(%sr2,%r20), %r1 /* Barrier */ -#endif + sync stw %r20, 0(%sr2,%r20) ssm PSW_SM_I, %r0 ldo 1(%r0),%r28
Greg Kroah-Hartman
maintainerPATCH 248/270 Revert "parisc: Revert "Release spinlocks using ordered store""
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 157e9afcc4fa25068b0e8743bc254a9b56010e13 upstream.
This reverts commit 86d4d068df573a8c2105554624796c086d6bec3d.
--- arch/parisc/include/asm/spinlock.h | 4 ++-- arch/parisc/kernel/syscall.S | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-)
arch/parisc/include/asm/spinlock.h +2 -2
@@ -37,8 +37,8 @@ static inline void arch_spin_unlock(archvolatile unsigned int *a; a =__ldcw_align (x); -mb (); - *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)
arch/parisc/kernel/syscall.S +4 -8
@@ -640,8 +640,7 @@ cas_action: sub,<> %r28, %r25, %r0 2: stw %r24, 0(%r26) /* Free lock */ - sync - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG /* Clear thread register indicator */ stw %r0, 4(%sr2,%r20)
@@ -655,8 +654,7 @@ cas_action: 3: /* Error occurred on load or store */ /* Free lock */ - sync - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG stw %r0, 4(%sr2,%r20) #endif
@@ -857,8 +855,7 @@ cas2_action: cas2_end: /* Free lock */ - sync - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) /* Enable interrupts */ ssm PSW_SM_I, %r0 /* Return to userspace, set no error */
@@ -868,8 +865,7 @@ cas2_end: 22: /* Error occurred on load or store */ /* Free lock */ - sync - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) ssm PSW_SM_I, %r0 ldo 1(%r0),%r28 b lws_exit
Greg Kroah-Hartman
maintainerPATCH 249/270 parisc: Do not use an ordered store in pa_tlb_lock()
In reply to Greg Kroah-HartmanFrom: John David Anglin <[email protected]>
commit e72b23dec1da5e62a0090c5da1d926778284e230 upstream.
No need to use an ordered store in pa_tlb_lock() and update the comment regarng usage of the sid register to unlocak a spinlock in tlb_unlock0().
--- arch/parisc/kernel/entry.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/parisc/kernel/entry.S +7 -2
@@ -455,7 +455,7 @@ LDREG 0(\ptp),\pte bb,<,n \pte,_PAGE_PRESENT_BIT,3f b \fault - stw,ma \spc,0(\tmp) + stw \spc,0(\tmp) 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) #endif 2: LDREG 0(\ptp),\pte
@@ -463,7 +463,12 @@ 3: .endm - /* Release pa_tlb_lock lock without reloading lock address. */ + /* 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
Greg Kroah-Hartman
maintainerPATCH 250/270 parisc: Implement __smp_store_release and __smp_load_acquire barriers
In reply to Greg Kroah-HartmanFrom: John David Anglin <[email protected]>
commit e96ebd589debd9a6a793608c4ec7019c38785dea upstream.
This patch implements the __smp_store_release and __smp_load_acquire barriers using ordered stores and loads. This avoids the sync instruction present in the generic implementation.
--- arch/parisc/include/asm/barrier.h | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
arch/parisc/include/asm/barrier.h +61 -0
@@ -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 <asm-generic/barrier.h> #endif /* !__ASSEMBLY__ */
Greg Kroah-Hartman
maintainerPATCH 251/270 parisc: mask out enable and reserved bits from sba imask
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
commit 5b24993c21cbf2de11aff077a48c5cb0505a0450 upstream.
When using kexec the SBA IOMMU IBASE might still have the RE bit set. This triggers a WARN_ON when trying to write back the IBASE register later, and it also makes some mask calculations fail.
--- drivers/parisc/sba_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/parisc/sba_iommu.c +1 -1
@@ -1270,7 +1270,7 @@ sba_ioc_init_pluto(struct parisc_device** (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 )) {
Greg Kroah-Hartman
maintainerPATCH 252/270 ARM: 8992/1: Fix unwind_frame for clang-built kernels
In reply to Greg Kroah-HartmanFrom: Nathan Huckleberry <[email protected]>
commit b4d5ec9b39f8b31d98f65bc5577b5d15d93795d7 upstream.
Since clang does not push pc and sp in function prologues, the current implementation of unwind_frame does not work. By using the previous frame's lr/fp instead of saved pc/sp we get valid unwinds on clang-built kernels.
The bounds check on next frame pointer must be changed as well since there are 8 less bytes between frames.
This fixes /proc/<pid>/stack.
--- arch/arm/kernel/stacktrace.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
arch/arm/kernel/stacktrace.c +24 -0
@@ -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,6 +47,16 @@ int notrace unwind_frame(struct stackfra 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 = *(unsigned long *)(fp); + frame->pc = frame->lr; + frame->lr = *(unsigned long *)(fp +4 ); +#else /* check current frame pointer is within bounds */ if (fp < low +12 || fp > high -4 )return -EINVAL ;
@@ -42,6 +65,7 @@ int notrace unwind_frame(struct stackfra frame->fp = *(unsigned long *)(fp -12 ); frame->sp = *(unsigned long *)(fp -8 ); frame->pc = *(unsigned long *)(fp -4 ); +#endif return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 253/270 irqdomain/treewide: Free firmware node after domain removal
In reply to Greg Kroah-HartmanFrom: Jon Derrick <[email protected]>
commit ec0160891e387f4771f953b888b1fe951398e5d9 upstream.
Commit 711419e504eb ("irqdomain: Add the missing assignment of domain->fwnode for named fwnode") unintentionally caused a dangling pointer page fault issue on firmware nodes that were freed after IRQ domain allocation. Commit e3beca48a45b fixed that dangling pointer issue by only freeing the firmware node after an IRQ domain allocation failure. That fix no longer frees the firmware node immediately, but leaves the firmware node allocated after the domain is removed.
The firmware node must be kept around through irq_domain_remove, but should be freed it afterwards.
Add the missing free operations after domain removal where where appropriate.
--- arch/mips/pci/pci-xtalk-bridge.c | 3 +++ arch/x86/kernel/apic/io_apic.c | 5 +++++ drivers/iommu/intel_irq_remapping.c | 8 ++++++++ drivers/pci/controller/vmd.c | 3 +++ 4 files changed, 19 insertions(+)
arch/mips/pci/pci-xtalk-bridge.c +3 -0
@@ -539,6 +539,7 @@ err_free_resource:pci_free_resource_list (&host->windows); err_remove_domain:irq_domain_remove (domain); +irq_domain_free_fwnode (fn);return err; }
@@ -546,8 +547,10 @@ static int bridge_remove(struct platform {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);
arch/x86/kernel/apic/io_apic.c +5 -0
@@ -2348,8 +2348,13 @@ static int mp_irqdomain_create(int ioapistatic 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 ; } }
drivers/iommu/intel_irq_remapping.c +8 -0
@@ -628,13 +628,21 @@ out_free_table: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,
drivers/pci/controller/vmd.c +3 -0
@@ -694,6 +694,7 @@ static int vmd_enable_domain(struct vmd_if (!vmd->bus) {pci_free_resource_list (&resources);irq_domain_remove (vmd->irq_domain); +irq_domain_free_fwnode (fn);return -ENODEV ; }
@@ -808,6 +809,7 @@ static void vmd_cleanup_srcu(struct vmd_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);
@@ -816,6 +818,7 @@ static void vmd_remove(struct pci_dev *dvmd_teardown_dma_ops (vmd);vmd_detach_resources (vmd);irq_domain_remove (vmd->irq_domain); +irq_domain_free_fwnode (fn); }#ifdef CONFIG_PM_SLEEP
Greg Kroah-Hartman
maintainerPATCH 254/270 ALSA: usb-audio: add quirk for Pioneer DDJ-RB
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
commit 6e8596172ee1cd46ec0bfd5adcf4ff86371478b6 upstream.
This is just another Pioneer device with fixed endpoints. Input is dummy but used as feedback (it always returns silence).
--- sound/usb/quirks-table.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
sound/usb/quirks-table.h +56 -0
@@ -3570,6 +3570,62 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge } } }, +{ +/* +* PIONEER DJ DDJ-RB +* PCM is 4 channels out, 2 dummy channels in @ 44.1 fixed +* The feedback for the output is the dummy input. +*/ + USB_DEVICE_VENDOR_SPEC(0x2b73, 0x000e), + .driver_info = (unsigned long ) &(const struct snd_usb_audio_quirk ) { + .ifnum =QUIRK_ANY_INTERFACE , + .type =QUIRK_COMPOSITE , + .data = (const struct snd_usb_audio_quirk []) { + { + .ifnum =0 , + .type =QUIRK_AUDIO_FIXED_ENDPOINT , + .data = &(const struct audioformat ) { + .formats =SNDRV_PCM_FMTBIT_S24_3LE , + .channels =4 , + .iface =0 , + .altsetting =1 , + .altset_idx =1 , + .endpoint =0x01 , + .ep_attr =USB_ENDPOINT_XFER_ISOC | +USB_ENDPOINT_SYNC_ASYNC , + .rates =SNDRV_PCM_RATE_44100 , + .rate_min =44100 , + .rate_max =44100 , + .nr_rates =1 , + .rate_table = (unsigned int []) {44100 } + } + }, + { + .ifnum =0 , + .type =QUIRK_AUDIO_FIXED_ENDPOINT , + .data = &(const struct audioformat ) { + .formats =SNDRV_PCM_FMTBIT_S24_3LE , + .channels =2 , + .iface =0 , + .altsetting =1 , + .altset_idx =1 , + .endpoint =0x82 , + .ep_attr =USB_ENDPOINT_XFER_ISOC | +USB_ENDPOINT_SYNC_ASYNC | +USB_ENDPOINT_USAGE_IMPLICIT_FB , + .rates =SNDRV_PCM_RATE_44100 , + .rate_min =44100 , + .rate_max =44100 , + .nr_rates =1 , + .rate_table = (unsigned int []) {44100 } + } + }, + { + .ifnum =-1 + } + } + } +}, #define ALC1220_VB_DESKTOP(vend, prod) { \ USB_DEVICE(vend, prod), \
Greg Kroah-Hartman
maintainerPATCH 255/270 tpm: Unify the mismatching TPM space buffer sizes
In reply to Greg Kroah-HartmanFrom: Jarkko Sakkinen <[email protected]>
commit 6c4e79d99e6f42b79040f1a33cd4018f5425030b upstream.
The size of the buffers for storing context's and sessions can vary from arch to arch as PAGE_SIZE can be anything between 4 kB and 256 kB (the maximum for PPC64). Define a fixed buffer size set to 16 kB. This should be enough for most use with three handles (that is how many we allow at the moment). Parametrize the buffer size while doing this, so that it is easier to revisit this later on if required.
--- drivers/char/tpm/tpm-chip.c | 9 ++------- drivers/char/tpm/tpm.h | 5 ++++- drivers/char/tpm/tpm2-space.c | 26 ++++++++++++++++---------- drivers/char/tpm/tpmrm-dev.c | 2 +- include/linux/tpm.h | 1 + 5 files changed, 24 insertions(+), 19 deletions(-)
drivers/char/tpm/tpm-chip.c +2 -7
@@ -386,13 +386,8 @@ struct tpm_chip *tpm_chip_alloc(struct d 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; }
drivers/char/tpm/tpm.h +4 -1
@@ -177,6 +177,9 @@ struct tpm_header {#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,7 +459,7 @@ void tpm2_shutdown(struct tpm_chip *chipunsigned 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,
drivers/char/tpm/tpm2-space.c +16 -10
@@ -38,18 +38,21 @@ static void tpm2_flush_sessions(struct t } } -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 ; }
@@ -311,8 +314,10 @@ int tpm2_prepare_space(struct tpm_chip * 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) {
@@ -492,7 +497,7 @@ static int tpm2_save_space(struct tpm_chcontinue ; 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 +514,8 @@ static int tpm2_save_space(struct tpm_chcontinue ; 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,8 +561,10 @@ int tpm2_commit_space(struct tpm_chip *c 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:
drivers/char/tpm/tpmrm-dev.c +1 -1
@@ -21,7 +21,7 @@ static int tpmrm_open(struct inode *inodif (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 ;
include/linux/tpm.h +1 -0
@@ -93,6 +93,7 @@ struct tpm_space {u8 *context_buf;u32 session_tbl[3 ];u8 *session_buf; +u32 buf_size; };struct tpm_bios_log {
Greg Kroah-Hartman
maintainerPATCH 256/270 pstore: Fix linking when crypto API disabled
In reply to Greg Kroah-HartmanFrom: Matteo Croce <[email protected]>
commit fd49e03280e596e54edb93a91bc96170f8e97e4a upstream.
When building a kernel with CONFIG_PSTORE=y and CONFIG_CRYPTO not set, a build error happens:
ld: fs/pstore/platform.o: in function `pstore_dump':
platform.c:(.text+0x3f9): undefined reference to `crypto_comp_compress'
ld: fs/pstore/platform.o: in function `pstore_get_backend_records':
platform.c:(.text+0x784): undefined reference to `crypto_comp_decompress'
This because some pstore code uses crypto_comp_(de)compress regardless of the CONFIG_CRYPTO status. Fix it by wrapping the (de)compress usage by IS_ENABLED(CONFIG_PSTORE_COMPRESS)
--- fs/pstore/platform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/pstore/platform.c +4 -1
@@ -275,6 +275,9 @@ static int pstore_compress(const void *i {int ret; +if (!IS_ENABLED (CONFIG_PSTORE_COMPRESSION )) +return -EINVAL ; + ret =crypto_comp_compress (tfm, in, inlen, out, &outlen);if (ret) {pr_err ("crypto_comp_compress failed, ret = %d!\n" , ret);
@@ -661,7 +664,7 @@ static void decompress_record(struct pstint unzipped_len;char *unzipped, *workspace; -if (!record->compressed) +if (!IS_ENABLED (CONFIG_PSTORE_COMPRESSION ) || !record->compressed)return ;/* Only PSTORE_TYPE_DMESG support compression. */
Greg Kroah-Hartman
maintainerPATCH 257/270 crypto: hisilicon - dont sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit 5ead051780404b5cb22147170acadd1994dc3236 upstream.
There is this call chain:sec_alg_skcipher_encrypt -> sec_alg_skcipher_crypto -> sec_alg_alloc_and_calc_split_sizes -> kcalloc
where we call sleeping allocator function even if CRYPTO_TFM_REQ_MAY_SLEEP was not specified.
--- drivers/crypto/hisilicon/sec/sec_algs.c | 34 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
drivers/crypto/hisilicon/sec/sec_algs.c +18 -16
@@ -175,7 +175,8 @@ static int sec_alloc_and_fill_hw_sgl(strdma_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 @@ static int sec_alloc_and_fill_hw_sgl(str 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;
@@ -545,14 +546,14 @@ void sec_alg_callback(struct sec_bd_info }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 @@ static int sec_map_and_split_sg(struct s 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 @@ static int sec_map_and_split_sg(struct sif (!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 @@ static int sec_map_and_split_sg(struct s/* 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 @@ static struct sec_request_el 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 @@ static struct sec_request_el 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 @@ static struct sec_request_el 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 @@ static int sec_alg_skcipher_crypto(strucint *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 @@ static int sec_alg_skcipher_crypto(struc 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 @@ static int sec_alg_skcipher_crypto(struc 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 @@ static int sec_alg_skcipher_crypto(struc 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;
Greg Kroah-Hartman
maintainerPATCH 258/270 crypto: qat - fix double free in qat_uclo_create_batch_init_list
In reply to Greg Kroah-HartmanFrom: Tom Rix <[email protected]>
commit c06c76602e03bde24ee69a2022a829127e504202 upstream.
clang static analysis flags this error
qat_uclo.c:297:3: warning: Attempt to free released memory
[unix.Malloc]
kfree(*init_tab_base);
^~~~~~~~~~~~~~~~~~~~~When input *init_tab_base is null, the function allocates memory for the head of the list. When there is problem allocating other list elements the list is unwound and freed. Then a check is made if the list head was allocated and is also freed.
Keeping track of the what may need to be freed is the variable 'tail_old'. The unwinding/freeing block is
while (tail_old) {
mem_init = tail_old->next;
kfree(tail_old);
tail_old = mem_init;
}The problem is that the first element of tail_old is also what was allocated for the list head
init_header = kzalloc(sizeof(*init_header), GFP_KERNEL); ... *init_tab_base = init_header; flag = 1; } tail_old = init_header;
So *init_tab_base/init_header are freed twice.
There is another problem.
When the input *init_tab_base is non null the tail_old is calculated by traveling down the list to first non null entry.
tail_old = init_header; while (tail_old->next) tail_old = tail_old->next;
When the unwinding free happens, the last entry of the input list will be freed.
So the freeing needs a general changed.
If locally allocated the first element of tail_old is freed, else it is skipped. As a bit of cleanup, reset *init_tab_base if it came in as null.
--- drivers/crypto/qat/qat_common/qat_uclo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/crypto/qat/qat_common/qat_uclo.c +7 -2
@@ -332,13 +332,18 @@ static int qat_uclo_create_batch_init_li }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 ; }
Greg Kroah-Hartman
maintainerPATCH 259/270 crypto: ccp - Fix use of merged scatterlists
In reply to Greg Kroah-HartmanFrom: John Allen <[email protected]>
commit 8a302808c60d441d9884cb00ea7f2b534f2e3ca5 upstream.
Running the crypto manager self tests with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS may result in several types of errors when using the ccp-crypto driver:
alg: skcipher: cbc-des3-ccp encryption failed on test vector 0; expected_error=0, actual_error=-5 ...
alg: skcipher: ctr-aes-ccp decryption overran dst buffer on test vector 0 ...
alg: ahash: sha224-ccp test failed (wrong result) on test vector ...
These errors are the result of improper processing of scatterlists mapped for DMA.
Given a scatterlist in which entries are merged as part of mapping the scatterlist for DMA, the DMA length of a merged entry will reflect the combined length of the entries that were merged. The subsequent scatterlist entry will contain DMA information for the scatterlist entry after the last merged entry, but the non-DMA information will be that of the first merged entry.
The ccp driver does not take this scatterlist merging into account. To address this, add a second scatterlist pointer to track the current position in the DMA mapped representation of the scatterlist. Both the DMA representation and the original representation of the scatterlist must be tracked as while most of the driver can use just the DMA representation, scatterlist_map_and_copy() must use the original representation and expects the scatterlist pointer to be accurate to the original representation.
In order to properly walk the original scatterlist, the scatterlist must be walked until the combined lengths of the entries seen is equal to the DMA length of the current entry being processed in the DMA mapped representation.
--- drivers/crypto/ccp/ccp-dev.h | 1 + drivers/crypto/ccp/ccp-ops.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-)
drivers/crypto/ccp/ccp-dev.h +1 -0
@@ -469,6 +469,7 @@ struct ccp_sg_workarea {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;
drivers/crypto/ccp/ccp-ops.c +26 -11
@@ -63,7 +63,7 @@ static u32 ccp_gen_jobid(struct ccp_devistatic 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 @@ static int ccp_init_sg_workarea(struct creturn 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 int ccp_init_sg_workarea(struct cstatic 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 ; } }
@@ -299,7 +314,7 @@ static unsigned int ccp_queue_buf(struct/* 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 +346,11 @@ static void ccp_prepare_data(struct ccp_* 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 +380,7 @@ static void ccp_prepare_data(struct ccp_/* 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 +401,7 @@ static void ccp_prepare_data(struct ccp_/* 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; }
@@ -2028,7 +2043,7 @@ ccp_run_passthru_cmd(struct ccp_cmd_queu 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; }
@@ -2054,8 +2069,8 @@ ccp_run_passthru_cmd(struct ccp_cmd_queu 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 ; }
Greg Kroah-Hartman
maintainerPATCH 260/270 crypto: cpt - dont sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit 9e27c99104707f083dccd3b4d79762859b5a0614 upstream.
There is this call chain:cvm_encrypt -> cvm_enc_dec -> cptvf_do_request -> process_request -> kzalloc where we call sleeping allocator function even if CRYPTO_TFM_REQ_MAY_SLEEP was not specified.
--- drivers/crypto/cavium/cpt/cptvf_algs.c | 1 + drivers/crypto/cavium/cpt/cptvf_reqmanager.c | 12 ++++++------ drivers/crypto/cavium/cpt/request_manager.h | 2 ++ 3 files changed, 9 insertions(+), 6 deletions(-)
drivers/crypto/cavium/cpt/cptvf_algs.c +1 -0
@@ -200,6 +200,7 @@ static inline int cvm_enc_dec(struct ablint 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);
drivers/crypto/cavium/cpt/cptvf_reqmanager.c +6 -6
@@ -133,7 +133,7 @@ static inline int setup_sgio_list(struct/* 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 @@ static inline int setup_sgio_list(struct/* 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 @@ static inline int setup_sgio_list(struct/* 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 @@ static inline int setup_sgio_list(struct }/* 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 @@ int process_request(struct cpt_vf *cptvfstruct 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 @@ int process_request(struct cpt_vf *cptvf* 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 ;
drivers/crypto/cavium/cpt/request_manager.h +2 -0
@@ -62,6 +62,8 @@ struct cpt_request_info {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 ];
Greg Kroah-Hartman
maintainerPATCH 261/270 bitfield.h: dont compile-time validate _val in FIELD_FIT
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
commit 444da3f52407d74c9aa12187ac6b01f76ee47d62 upstream.
When ur_load_imm_any() is inlined into jeq_imm(), it's possible for the compiler to deduce a case where _val can only have the value of -1 at compile time. Specifically,
/* struct bpf_insn: _s32 imm */
u64 imm = insn->imm; /* sign extend */
if (imm >> 32) { /* non-zero only if insn->imm is negative */
/* inlined from ur_load_imm_any */
u32 __imm = imm >> 32; /* therefore, always 0xffffffff */ if (__builtin_constant_p(__imm) && __imm > 255)
compiletime_assert_XXX()
This can result in tripping a BUILD_BUG_ON() in __BF_FIELD_CHECK() that checks that a given value is representable in one byte (interpreted as unsigned).
FIELD_FIT() should return true or false at runtime for whether a value can fit for not. Don't break the build over a value that's too large for the mask. We'd prefer to keep the inlining and compiler optimizations though we know this case will always return false.
--- include/linux/bitfield.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/bitfield.h +1 -1
@@ -64,7 +64,7 @@*/ #define FIELD_FIT (_mask, _val) \ ({ \ - __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ + __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ })
Greg Kroah-Hartman
maintainerPATCH 262/270 fs/minix: check return value of sb_getblk()
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit da27e0a0e5f655f0d58d4e153c3182bb2b290f64 upstream.
Patch series "fs/minix: fix syzbot bugs and set s_maxbytes".
This series fixes all syzbot bugs in the minix filesystem:
KASAN: null-ptr-deref Write in get_block KASAN: use-after-free Write in get_block KASAN: use-after-free Read in get_block WARNING in inc_nlink KMSAN: uninit-value in get_block WARNING in drop_nlink
It also fixes the minix filesystem to set s_maxbytes correctly, so that userspace sees the correct behavior when exceeding the max file size.
This patch (of 6):
sb_getblk() can fail, so check its return value.
This fixes a NULL pointer dereference.
Originally from Qiujun Huang.
--- fs/minix/itree_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/minix/itree_common.c +7 -1
@@ -75,6 +75,7 @@ static int alloc_branch(struct inode *inint n =0 ;int i;int parent =minix_new_block (inode); +int err = -ENOSPC ; branch[0 ].key =cpu_to_block (parent);if (parent)for (n =1 ; n < num; n++) {
@@ -85,6 +86,11 @@ static int alloc_branch(struct inode *inbreak ; branch[n].key =cpu_to_block (nr); bh =sb_getblk (inode->i_sb, parent); +if (!bh) { +minix_free_block (inode, nr); + err = -ENOMEM ; +break ; + }lock_buffer (bh);memset (bh->b_data,0 , bh->b_size); branch[n].bh = bh;
@@ -103,7 +109,7 @@ static int alloc_branch(struct inode *inbforget (branch[i].bh);for (i =0 ; i < n; i++)minix_free_block (inode,block_to_cpu (branch[i].key)); -return -ENOSPC ; +return err; } static inline int splice_branch(struct inode *inode,
Greg Kroah-Hartman
maintainerPATCH 263/270 fs/minix: dont allow getting deleted inodes
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit facb03dddec04e4aac1bb2139accdceb04deb1f3 upstream.
If an inode has no links, we need to mark it bad rather than allowing it to be accessed. This avoids WARNINGs in inc_nlink() and drop_nlink() when doing directory operations on a fuzzed filesystem.
--- fs/minix/inode.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/minix/inode.c +14 -0
@@ -468,6 +468,13 @@ static struct inode *V1_minix_iget(struciget_failed (inode);return ERR_PTR (-EIO ); } +if (raw_inode->i_nlinks ==0 ) { +printk ("MINIX-fs: deleted inode referenced: %lu\n" , + inode->i_ino); +brelse (bh); +iget_failed (inode); +return ERR_PTR (-ESTALE ); + } inode->i_mode = raw_inode->i_mode;i_uid_write (inode, raw_inode->i_uid);i_gid_write (inode, raw_inode->i_gid);
@@ -501,6 +508,13 @@ static struct inode *V2_minix_iget(struciget_failed (inode);return ERR_PTR (-EIO ); } +if (raw_inode->i_nlinks ==0 ) { +printk ("MINIX-fs: deleted inode referenced: %lu\n" , + inode->i_ino); +brelse (bh); +iget_failed (inode); +return ERR_PTR (-ESTALE ); + } inode->i_mode = raw_inode->i_mode;i_uid_write (inode, raw_inode->i_uid);i_gid_write (inode, raw_inode->i_gid);
Greg Kroah-Hartman
maintainerPATCH 264/270 fs/minix: reject too-large maximum file size
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 270ef41094e9fa95273f288d7d785313ceab2ff3 upstream.
If the minix filesystem tries to map a very large logical block number to its on-disk location, block_to_path() can return offsets that are too large, causing out-of-bounds memory accesses when accessing indirect index blocks. This should be prevented by the check against the maximum file size, but this doesn't work because the maximum file size is read directly from the on-disk superblock and isn't validated itself.
Fix this by validating the maximum file size at mount time.
--- fs/minix/inode.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
fs/minix/inode.c +20 -2
@@ -150,6 +150,23 @@ static int minix_remount (struct super_breturn 0 ; } +static bool minix_check_superblock (struct minix_sb_info *sbi) +{ +if (sbi->s_imap_blocks ==0 || sbi->s_zmap_blocks ==0 ) +return false; + +/* +* s_max_size must not exceed the block mapping limitation. This check +* is only needed for V1 filesystems, since V2/V3 support an extra level +* of indirect blocks which places the limit well above U32_MAX. +*/ +if (sbi->s_version ==MINIX_V1 && + sbi->s_max_size > (7 +512 +512 *512 ) *BLOCK_SIZE ) +return false; + +return true; +} +static int minix_fill_super (struct super_block *s,void *data,int silent) {struct buffer_head *bh;
@@ -228,11 +245,12 @@ static int minix_fill_super(struct super }else goto out_no_fs; +if (!minix_check_superblock (sbi)) + goto out_illegal_sb; +/* * Allocate the buffer map to keep the superblock small. */ -if (sbi->s_imap_blocks ==0 || sbi->s_zmap_blocks ==0 ) - goto out_illegal_sb; i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) *sizeof (bh); map =kzalloc (i,GFP_KERNEL );if (!map)
Greg Kroah-Hartman
maintainerPATCH 265/270 xen/balloon: fix accounting in alloc_xenballooned_pages error path
In reply to Greg Kroah-HartmanFrom: Roger Pau Monne <[email protected]>
commit 1951fa33ec259abdf3497bfee7b63e7ddbb1a394 upstream.
target_unpopulated is incremented with nr_pages at the start of the function, but the call to free_xenballooned_pages will only subtract pgno number of pages, and thus the rest need to be subtracted before returning or else accounting will be skewed.
--- drivers/xen/balloon.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/xen/balloon.c +6 -0
@@ -632,6 +632,12 @@ int alloc_xenballooned_pages(int nr_page out_undo:mutex_unlock (&balloon_mutex);free_xenballooned_pages (pgno, pages); +/* +* NB: free_xenballooned_pages will only subtract pgno pages, but since +* target_unpopulated is incremented with nr_pages at the start we need +* to remove the remaining ones also, or accounting will be screwed. +*/ + balloon_stats.target_unpopulated -= nr_pages - pgno;return ret; }EXPORT_SYMBOL (alloc_xenballooned_pages);
Greg Kroah-Hartman
maintainerPATCH 266/270 xen/balloon: make the balloon wait interruptible
In reply to Greg Kroah-HartmanFrom: Roger Pau Monne <[email protected]>
commit 88a479ff6ef8af7f07e11593d58befc644244ff7 upstream.
So it can be killed, or else processes can get hung indefinitely waiting for balloon pages.
--- drivers/xen/balloon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/xen/balloon.c +4 -2
@@ -570,11 +570,13 @@ static int add_ballooned_pages(int nr_paif (xen_hotplug_unpopulated) { st =reserve_additional_memory ();if (st !=BP_ECANCELED ) { +int rc; +mutex_unlock (&balloon_mutex); -wait_event (balloon_wq, + rc =wait_event_interruptible (balloon_wq, !list_empty (&ballooned_pages));mutex_lock (&balloon_mutex); -return 0 ; +return rc ? -ENOMEM :0 ; } }
Greg Kroah-Hartman
maintainerPATCH 267/270 xen/gntdev: Fix dmabuf import with non-zero sgt offset
In reply to Greg Kroah-HartmanFrom: Oleksandr Andrushchenko <[email protected]>
commit 5fa4e6f1c2d8c9a4e47e1931b42893172d388f2b upstream.
It is possible that the scatter-gather table during dmabuf import has non-zero offset of the data, but user-space doesn't expect that. Fix this by failing the import, so user-space doesn't access wrong data.
--- drivers/xen/gntdev-dmabuf.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/xen/gntdev-dmabuf.c +8 -0
@@ -641,6 +641,14 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_ goto fail_detach; } +/* Check that we have zero offset. */ +if (sgt->sgl->offset) { + ret =ERR_PTR (-EINVAL ); +pr_debug ("DMA buffer has %d bytes offset, user-space expects 0\n" , + sgt->sgl->offset); + goto fail_unmap; + } +/* Check number of pages that imported buffer has. */ if (attach->dmabuf->size != gntdev_dmabuf->nr_pages <<PAGE_SHIFT ) { ret =ERR_PTR (-EINVAL );
Greg Kroah-Hartman
maintainerPATCH 268/270 s390/dasd: fix inability to use DASD with DIAG driver
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 9f4aa52387c68049403b59939df5c0dd8e3872cc upstream.
During initialization of the DASD DIAG driver a request is issued that has a bio structure that resides on the stack. With virtually mapped kernel stacks this bio address might be in virtual storage which is unsuitable for usage with the diag250 call.
In this case the device can not be set online using the DIAG discipline and fails with -EOPNOTSUP.
In the system journal the following error message is presented:
dasd: X.X.XXXX Setting the DASD online with discipline DIAG failed with rc=-95
Fix by allocating the bio structure instead of having it on the stack.
--- drivers/s390/block/dasd_diag.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
drivers/s390/block/dasd_diag.c +17 -8
@@ -319,7 +319,7 @@ dasd_diag_check_device(struct dasd_devicstruct 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 @@ dasd_diag_check_device(struct dasd_devic 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 @@ dasd_diag_check_device(struct dasd_devicpr_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 @@ dasd_diag_check_device(struct dasd_devic (rc == 4) ? ", read-only device" : ""); rc =0 ; } +out_bio: +kfree (bio); out_label:free_page ((long ) label); out:
Greg Kroah-Hartman
maintainerPATCH 269/270 s390/gmap: improve THP splitting
In reply to Greg Kroah-HartmanFrom: Gerald Schaefer <[email protected]>
commit ba925fa35057a062ac98c3e8138b013ce4ce351c upstream.
During s390_enable_sie(), we need to take care of splitting all qemu user process THP mappings. This is currently done with follow_page(FOLL_SPLIT), by simply iterating over all vma ranges, with PAGE_SIZE increment.
This logic is sub-optimal and can result in a lot of unnecessary overhead, especially when using qemu and ASAN with large shadow map. Ilya reported significant system slow-down with one CPU busy for a long time and overall unresponsiveness.
Fix this by using walk_page_vma() and directly calling split_huge_pmd() only for present pmds, which greatly reduces overhead.
--- arch/s390/mm/gmap.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
arch/s390/mm/gmap.c +20 -7
@@ -2485,23 +2485,36 @@ void gmap_sync_dirty_log_pmd(struct gmap }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
Greg Kroah-Hartman
maintainerPATCH 270/270 io_uring: Fix NULL pointer dereference in loop_rw_iter()
In reply to Greg Kroah-HartmanFrom: Guoyu Huang <[email protected]>
commit 2dd2111d0d383df104b144e0d1f6b5a00cb7cd88 upstream.
loop_rw_iter() does not check whether the file has a read or write function. This can lead to NULL pointer dereference when the user passes in a file descriptor that does not have read or write function.
The crash log looks like this:
[ 99.834071] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 99.835364] #PF: supervisor instruction fetch in kernel mode [ 99.836522] #PF: error_code(0x0010) - not-present page [ 99.837771] PGD 8000000079d62067 P4D 8000000079d62067 PUD 79d8c067 PMD 0 [ 99.839649] Oops: 0010 [#2] SMP PTI [ 99.840591] CPU: 1 PID: 333 Comm: io_wqe_worker-0 Tainted: G D 5.8.0 #2 [ 99.842622] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/01/2014 [ 99.845140] RIP: 0010:0x0 [ 99.845840] Code: Bad RIP value. [ 99.846672] RSP: 0018:ffffa1c7c01ebc08 EFLAGS: 00010202 [ 99.848018] RAX: 0000000000000000 RBX: ffff92363bd67300 RCX: ffff92363d461208 [ 99.849854] RDX: 0000000000000010 RSI: 00007ffdbf696bb0 RDI: ffff92363bd67300 [ 99.851743] RBP: ffffa1c7c01ebc40 R08: 0000000000000000 R09: 0000000000000000 [ 99.853394] R10: ffffffff9ec692a0 R11: 0000000000000000 R12: 0000000000000010 [ 99.855148] R13: 0000000000000000 R14: ffff92363d461208 R15: ffffa1c7c01ebc68 [ 99.856914] FS: 0000000000000000(0000) GS:ffff92363dd00000(0000) knlGS:0000000000000000 [ 99.858651] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 99.860032] CR2: ffffffffffffffd6 CR3: 000000007ac66000 CR4: 00000000000006e0 [ 99.861979] Call Trace: [ 99.862617] loop_rw_iter.part.0+0xad/0x110 [ 99.863838] io_write+0x2ae/0x380 [ 99.864644] ? kvm_sched_clock_read+0x11/0x20 [ 99.865595] ? sched_clock+0x9/0x10 [ 99.866453] ? sched_clock_cpu+0x11/0xb0 [ 99.867326] ? newidle_balance+0x1d4/0x3c0 [ 99.868283] io_issue_sqe+0xd8f/0x1340 [ 99.869216] ? __switch_to+0x7f/0x450 [ 99.870280] ? __switch_to_asm+0x42/0x70 [ 99.871254] ? __switch_to_asm+0x36/0x70 [ 99.872133] ? lock_timer_base+0x72/0xa0 [ 99.873155] ? switch_mm_irqs_off+0x1bf/0x420 [ 99.874152] io_wq_submit_work+0x64/0x180 [ 99.875192] ? kthread_use_mm+0x71/0x100 [ 99.876132] io_worker_handle_work+0x267/0x440 [ 99.877233] io_wqe_worker+0x297/0x350 [ 99.878145] kthread+0x112/0x150 [ 99.878849] ? __io_worker_unuse+0x100/0x100 [ 99.879935] ? kthread_park+0x90/0x90 [ 99.880874] ret_from_fork+0x22/0x30 [ 99.881679] Modules linked in: [ 99.882493] CR2: 0000000000000000 [ 99.883324] ---[ end trace 4453745f4673190b ]--- [ 99.884289] RIP: 0010:0x0 [ 99.884837] Code: Bad RIP value. [ 99.885492] RSP: 0018:ffffa1c7c01ebc08 EFLAGS: 00010202 [ 99.886851] RAX: 0000000000000000 RBX: ffff92363acd7f00 RCX: ffff92363d461608 [ 99.888561] RDX: 0000000000000010 RSI: 00007ffe040d9e10 RDI: ffff92363acd7f00 [ 99.890203] RBP: ffffa1c7c01ebc40 R08: 0000000000000000 R09: 0000000000000000 [ 99.891907] R10: ffffffff9ec692a0 R11: 0000000000000000 R12: 0000000000000010 [ 99.894106] R13: 0000000000000000 R14: ffff92363d461608 R15: ffffa1c7c01ebc68 [ 99.896079] FS: 0000000000000000(0000) GS:ffff92363dd00000(0000) knlGS:0000000000000000 [ 99.898017] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 99.899197] CR2: ffffffffffffffd6 CR3: 000000007ac66000 CR4: 00000000000006e0
--- fs/io_uring.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/io_uring.c +6 -2
@@ -1433,8 +1433,10 @@ static int io_read(struct io_kiocb *req,if (file->f_op->read_iter) ret2 =call_read_iter (file, kiocb, &iter); -else +else if (req->file->f_op->read) ret2 =loop_rw_iter (READ , file, kiocb, &iter); +else + ret2 = -EINVAL ;/* * In case of a short read, punt to async. This can happen
@@ -1524,8 +1526,10 @@ static int io_write(struct io_kiocb *reqif (file->f_op->write_iter) ret2 =call_write_iter (file, kiocb, &iter); -else +else if (req->file->f_op->write) ret2 =loop_rw_iter (WRITE , file, kiocb, &iter); +else + ret2 = -EINVAL ;if (!force_nonblock) current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ;
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.59 release. There are 270 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2020 14:36:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.4:
11 builds: 11 pass, 0 fail
26 boots: 26 pass, 0 fail
56 tests: 56 pass, 0 failLinux version: 5.4.59-rc1-g6982f544144f
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.59 release. There are 270 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2020 14:36:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 5.4.59-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-5.4.y
git commit: 6982f544144f32263ec02a0eb61a60148824b853
git describe: v5.4.58-271-g6982f544144f
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/build/v5.4.58-271-g6982f544144f
No regressions (compared to build v5.4.58)
No fixes (compared to build v5.4.58)
Ran 31881 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- juno-r2-compat
- juno-r2-kasan
- nxp-ls2088
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15
- x86
- x86-kasan
Test Suites
-----------
* build
* igt-gpu-tools
* install-android-platform-tools-r2600
* kselftest
* kselftest/drivers
* kselftest/filesystems
* kselftest/net
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-dio-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-securebits-tests
* ltp-tracing-tests
* perf
* v4l2-compliance
* ltp-containers-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-sched-tests
* ltp-syscalls-tests
* network-basic-tests
* ltp-controllers-tests
* ltp-cve-tests
* ltp-open-posix-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-native/drivers
* kselftest-vsyscall-mode-native/filesystems
* kselftest-vsyscall-mode-native/net
* kselftest-vsyscall-mode-none
* kselftest-vsyscall-mode-none/drivers
* kselftest-vsyscall-mode-none/filesystems
* kselftest-vsyscall-mode-none/net
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.59 release. There are 270 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2020 14:36:49 +0000. Anything received after that time might be too late.
Build results:
total: 157 pass: 157 fail: 0 Qemu test results: total: 430 pass: 430 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.59 release. There are 270 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2020 14:36:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah