5.8.2-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 309/464 Bluetooth: Fix suspend notifier race
In reply to Greg Kroah-HartmanFrom: Abhishek Pandit-Subedi <[email protected]>
[ Upstream commit 4e8c36c3b0d73d46aa27cfd4308aaa445a1067df ]
Unregister from suspend notifications and cancel suspend preparations before running hci_dev_do_close. Otherwise, the suspend notifier may race with unregister and cause cmd_timeout even after hdev has been freed.
Below is the trace from when this panic was seen:
[ 832.578518] Bluetooth: hci_core.c:hci_cmd_timeout() hci0: command 0x0c05 tx timeout [ 832.586200] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 832.586203] #PF: supervisor read access in kernel mode [ 832.586205] #PF: error_code(0x0000) - not-present page [ 832.586206] PGD 0 P4D 0 [ 832.586210] PM: suspend exit [ 832.608870] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 832.613232] CPU: 3 PID: 10755 Comm: kworker/3:7 Not tainted 5.4.44-04894-g1e9dbb96a161 #1 [ 832.630036] Workqueue: events hci_cmd_timeout [bluetooth] [ 832.630046] RIP: 0010:__queue_work+0xf0/0x374 [ 832.630051] RSP: 0018:ffff9b5285f1fdf8 EFLAGS: 00010046 [ 832.674033] RAX: ffff8a97681bac00 RBX: 0000000000000000 RCX: ffff8a976a000600 [ 832.681162] RDX: 0000000000000000 RSI: 0000000000000009 RDI: ffff8a976a000748 [ 832.688289] RBP: ffff9b5285f1fe38 R08: 0000000000000000 R09: ffff8a97681bac00 [ 832.695418] R10: 0000000000000002 R11: ffff8a976a0006d8 R12: ffff8a9745107600 [ 832.698045] usb 1-6: new full-speed USB device number 119 using xhci_hcd [ 832.702547] R13: ffff8a9673658850 R14: 0000000000000040 R15: 000000000000001e [ 832.702549] FS: 0000000000000000(0000) GS:ffff8a976af80000(0000) knlGS:0000000000000000 [ 832.702550] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 832.702550] CR2: 0000000000000000 CR3: 000000010415a000 CR4: 00000000003406e0 [ 832.702551] Call Trace: [ 832.702558] queue_work_on+0x3f/0x68 [ 832.702562] process_one_work+0x1db/0x396 [ 832.747397] worker_thread+0x216/0x375 [ 832.751147] kthread+0x138/0x140 [ 832.754377] ? pr_cont_work+0x58/0x58 [ 832.758037] ? kthread_blkcg+0x2e/0x2e [ 832.761787] ret_from_fork+0x22/0x40 [ 832.846191] ---[ end trace fa93f466da517212 ]---
--- net/bluetooth/hci_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/bluetooth/hci_core.c +3 -2
@@ -3608,9 +3608,10 @@ void hci_unregister_dev(struct hci_dev *hdev)cancel_work_sync (&hdev->power_on); -hci_dev_do_close (hdev); -unregister_pm_notifier (&hdev->suspend_notifier); +cancel_work_sync (&hdev->suspend_prepare); + +hci_dev_do_close (hdev); if (!test_bit(HCI_INIT, &hdev->flags) && !hci_dev_test_flag(hdev, HCI_SETUP) &&
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 310/464 Bluetooth: hci_qca: Stop collecting memdump again for command timeout during SSR
In reply to Greg Kroah-HartmanFrom: Venkata Lakshmi Narayana Gubba <[email protected]>
[ Upstream commit 58789a1990c1a849a461ac912e72a698a771951a ]
Setting memdump state to idle prior to setting of callback function pointer for command timeout to NULL,causing the issue.Now moved the initialisation of memdump state to qca_setup().
--- drivers/bluetooth/hci_qca.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/bluetooth/hci_qca.c +5 -4
@@ -1676,6 +1676,8 @@ static int qca_setup(struct hci_uart *hu)bt_dev_info (hdev,"setting up %s" ,qca_is_wcn399x (soc_type) ?"wcn399x" :"ROME/QCA6390" ); + qca->memdump_state =QCA_MEMDUMP_IDLE ; + retry: ret =qca_power_on (hdev);if (ret)
@@ -1825,9 +1827,6 @@ static void qca_power_shutdown(struct hci_uart *hu)qca_flush (hu);spin_unlock_irqrestore (&qca->hci_ibs_lock, flags); - hu->hdev->hw_error =NULL ; - hu->hdev->cmd_timeout =NULL ; -/* Non-serdev device usually is powered by external power * and don't need additional action in driver for power down */
@@ -1849,6 +1848,9 @@ static int qca_power_off(struct hci_dev *hdev)struct qca_data *qca = hu->priv;enum qca_btsoc_type soc_type =qca_soc_type (hu); + hu->hdev->hw_error =NULL ; + hu->hdev->cmd_timeout =NULL ; +/* Stop sending shutdown command if soc crashes. */ if (soc_type !=QCA_ROME && qca->memdump_state ==QCA_MEMDUMP_IDLE ) {
@@ -1856,7 +1858,6 @@ static int qca_power_off(struct hci_dev *hdev)usleep_range (8000 ,10000 ); } - qca->memdump_state =QCA_MEMDUMP_IDLE ;qca_power_shutdown (hu);return 0 ; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 311/464 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 312/464 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 313/464 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 314/464 xfs: clear XFS_DQ_FREEING if we cant lock the dquot buffer to flush
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit c97738a960a86081a147e7d436138e6481757445 ]
In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we can't lock the dquot buf to flush the dquot. This prevents the AIL from blocking on the dquot, but it also forgets to clear the FREEING flag on its way out. A subsequent purge attempt will see the FREEING flag is set and bail out, which leads to dqpurge_all failing to purge all the dquots.
(copy-pasting from Dave Chinner's identical patch)
This was found by inspection after having xfs/305 hang 1 in ~50 iterations in a quotaoff operation:
[ 8872.301115] xfs_quota D13888 92262 91813 0x00004002 [ 8872.302538] Call Trace: [ 8872.303193] __schedule+0x2d2/0x780 [ 8872.304108] ? do_raw_spin_unlock+0x57/0xd0 [ 8872.305198] schedule+0x6e/0xe0 [ 8872.306021] schedule_timeout+0x14d/0x300 [ 8872.307060] ? __next_timer_interrupt+0xe0/0xe0 [ 8872.308231] ? xfs_qm_dqusage_adjust+0x200/0x200 [ 8872.309422] schedule_timeout_uninterruptible+0x2a/0x30 [ 8872.310759] xfs_qm_dquot_walk.isra.0+0x15a/0x1b0 [ 8872.311971] xfs_qm_dqpurge_all+0x7f/0x90 [ 8872.313022] xfs_qm_scall_quotaoff+0x18d/0x2b0 [ 8872.314163] xfs_quota_disable+0x3a/0x60 [ 8872.315179] kernel_quotactl+0x7e2/0x8d0 [ 8872.316196] ? __do_sys_newstat+0x51/0x80 [ 8872.317238] __x64_sys_quotactl+0x1e/0x30 [ 8872.318266] do_syscall_64+0x46/0x90 [ 8872.319193] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 8872.320490] RIP: 0033:0x7f46b5490f2a [ 8872.321414] Code: Bad RIP value.
Returning -EAGAIN from xfs_qm_dqpurge() without clearing the XFS_DQ_FREEING flag means the xfs_qm_dqpurge_all() code can never free the dquot, and we loop forever waiting for the XFS_DQ_FREEING flag to go away on the dquot that leaked it via -EAGAIN.
--- fs/xfs/xfs_qm.c | 1 + 1 file changed, 1 insertion(+)
fs/xfs/xfs_qm.c +1 -0
@@ -148,6 +148,7 @@ xfs_qm_dqpurge( error =xfs_bwrite (bp);xfs_buf_relse (bp); }else if (error == -EAGAIN ) { + dqp->dq_flags &= ~XFS_DQ_FREEING ; goto out_unlock; }xfs_dqflock (dqp);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 315/464 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 316/464 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
@@ -238,7 +238,7 @@ static inline void set_trap_norestart(struct pt_regs *regs) }#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 317/464 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
@@ -117,7 +117,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 318/464 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 319/464 nvmem: sprd: Fix return value of sprd_efuse_probe()
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
[ Upstream commit bcd14bb7a68520bf88e45e91d354e43535624f82 ]
When call function devm_platform_ioremap_resource(), we should use IS_ERR() to check the return value and return PTR_ERR() if failed.
--- drivers/nvmem/sprd-efuse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvmem/sprd-efuse.c +2 -2
@@ -378,8 +378,8 @@ static int sprd_efuse_probe(struct platform_device *pdev)return -ENOMEM ; efuse->base =devm_platform_ioremap_resource (pdev,0 ); -if (!efuse->base) -return -ENOMEM ; +if (IS_ERR (efuse->base)) +return PTR_ERR (efuse->base); ret =of_hwspin_lock_get_id (np,0 );if (ret <0 ) {
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 320/464 RDMA/rtrs-clt: add an additional random 8 seconds before reconnecting
In reply to Greg Kroah-HartmanFrom: Danil Kipnis <[email protected]>
[ Upstream commit 09e0dbbeed82e35ce2cd21e086a6fac934163e2a ]
In order to avoid all the clients to start reconnecting at the same time schedule the reconnect dwork with a random jitter of +[0,8] seconds.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +12 -2
@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/rculist.h> +#include <linux/random.h> #include "rtrs-clt.h" #include "rtrs-log.h"
@@ -23,6 +24,12 @@* leads to "false positives" failed reconnect attempts */ #define RTRS_RECONNECT_BACKOFF 1000 +/* +* Wait for additional random time between 0 and 8 seconds +* before starting to reconnect to avoid clients reconnecting +* all at once in case of a major network outage +*/ +#define RTRS_RECONNECT_SEED 8MODULE_DESCRIPTION ("RDMA Transport Client" );MODULE_LICENSE ("GPL" );
@@ -306,7 +313,8 @@ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)*/ delay_ms = clt->reconnect_delay_sec *1000 ;queue_delayed_work (rtrs_wq, &sess->reconnect_dwork, -msecs_to_jiffies (delay_ms)); +msecs_to_jiffies (delay_ms + +prandom_u32 () %RTRS_RECONNECT_SEED )); }else {/* * Error can happen just on establishing new connection,
@@ -2503,7 +2511,9 @@ static void rtrs_clt_reconnect_work(struct work_struct *work) sess->stats->reconnects.fail_cnt++; delay_ms = clt->reconnect_delay_sec *1000 ;queue_delayed_work (rtrs_wq, &sess->reconnect_dwork, -msecs_to_jiffies (delay_ms)); +msecs_to_jiffies (delay_ms + +prandom_u32 () % +RTRS_RECONNECT_SEED )); } }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 321/464 RDMA/rtrs: remove WQ_MEM_RECLAIM for rtrs_wq
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 03ed5a8cda659e3c71d106b0dd4ce6520e4dcd6e ]
lockdep triggers a warning from time to time when running a regression test:
rnbd_client L685: </dev/nullb0@bla> Device disconnected. rnbd_client L1756: Unloading module
workqueue: WQ_MEM_RECLAIM rtrs_client_wq:rtrs_clt_reconnect_work [rtrs_client] is flushing !WQ_MEM_RECLAIM ib_addr:process_one_req [ib_core]
WARNING: CPU: 2 PID: 18824 at kernel/workqueue.c:2517 check_flush_dependency+0xad/0x130
The root cause is workqueue core expect flushing should not be done for a !WQ_MEM_RECLAIM wq from a WQ_MEM_RECLAIM workqueue.
In above case ib_addr workqueue without WQ_MEM_RECLAIM, but rtrs_wq WQ_MEM_RECLAIM.
To avoid the warning, remove the WQ_MEM_RECLAIM flag.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +1 -1
@@ -2982,7 +2982,7 @@ static int __init rtrs_client_init(void)pr_err ("Failed to create rtrs-client dev class\n" );return PTR_ERR (rtrs_clt_dev_class); } - rtrs_wq =alloc_workqueue ("rtrs_client_wq" ,WQ_MEM_RECLAIM ,0 ); + rtrs_wq =alloc_workqueue ("rtrs_client_wq" ,0 ,0 );if (!rtrs_wq) {class_destroy (rtrs_clt_dev_class);return -ENOMEM ;
drivers/infiniband/ulp/rtrs/rtrs-srv.c +1 -1
@@ -2150,7 +2150,7 @@ static int __init rtrs_server_init(void) err =PTR_ERR (rtrs_dev_class); goto out_chunk_pool; } - rtrs_wq =alloc_workqueue ("rtrs_server_wq" ,WQ_MEM_RECLAIM ,0 ); + rtrs_wq =alloc_workqueue ("rtrs_server_wq" ,0 ,0 );if (!rtrs_wq) { err = -ENOMEM ; goto out_dev_class;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 322/464 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
@@ -738,9 +738,6 @@ static int fill_stat_counter_qps(struct sk_buff *msg,xa_lock (&rt->xa);xa_for_each (&rt->xa, id, res) { 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 323/464 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
@@ -4422,6 +4422,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 324/464 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 325/464 powerpc/pseries/hotplug-cpu: Remove double free in error path
In reply to Greg Kroah-HartmanFrom: Nathan Lynch <[email protected]>
[ Upstream commit a0ff72f9f5a780341e7ff5e9ba50a0dad5fa1980 ]
In the unlikely event that the device tree lacks a /cpus node, find_dlpar_cpus_to_add() oddly frees the cpu_drcs buffer it has been passed before returning an error. Its only caller also frees the buffer on error.
Remove the less conventional kfree() of a caller-supplied buffer from find_dlpar_cpus_to_add().
--- arch/powerpc/platforms/pseries/hotplug-cpu.c | 1 - 1 file changed, 1 deletion(-)
arch/powerpc/platforms/pseries/hotplug-cpu.c +0 -1
@@ -739,7 +739,6 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add) parent =of_find_node_by_path ("/cpus" );if (!parent) {pr_warn ("Could not find CPU root node in device tree\n" ); -kfree (cpu_drcs);return -1 ; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 326/464 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 327/464 RDMA/hns: Fix error during modify qp RTS2RTS
In reply to Greg Kroah-HartmanFrom: Lang Cheng <[email protected]>
[ Upstream commit 4327bd2c41412657ee2c8c0d8d3d1945268b4238 ]
One qp state migrations legal configuration was deleted mistakenly.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +3 -1
@@ -4301,7 +4301,9 @@ static bool check_qp_state(enum ib_qp_state cur_state, [IB_QPS_RTR ] = { [IB_QPS_RESET ] = true, [IB_QPS_RTS ] = true, [IB_QPS_ERR] = true }, - [IB_QPS_RTS] = { [IB_QPS_RESET] = true, [IB_QPS_ERR] = true }, + [IB_QPS_RTS ] = { [IB_QPS_RESET ] = true, + [IB_QPS_RTS ] = true, + [IB_QPS_ERR] = true }, [IB_QPS_SQD] = {}, [IB_QPS_SQE] = {}, [IB_QPS_ERR ] = { [IB_QPS_RESET ] = true, [IB_QPS_ERR ] = true }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 328/464 RDMA/hns: Fix the unneeded process when getting a general type of CQE error
In reply to Greg Kroah-HartmanFrom: Xi Wang <[email protected]>
[ Upstream commit 395f2e8fd340c5bfad026f5968b56ec34cf20dd1 ]
If the hns ROCEE reports a general error CQE (types not specified by the IB General Specifications), it's no need to change the QP state to error, and the driver should just skip it.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 9 +++++++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 + 2 files changed, 10 insertions(+)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +9 -0
@@ -3053,6 +3053,7 @@ static void get_cqe_status(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, IB_WC_RETRY_EXC_ERR }, { HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR, IB_WC_RNR_RETRY_EXC_ERR }, { HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR, IB_WC_REM_ABORT_ERR }, + { HNS_ROCE_CQE_V2_GENERAL_ERR, IB_WC_GENERAL_ERR} }; u32 cqe_status = roce_get_field(cqe->byte_4, V2_CQE_BYTE_4_STATUS_M,
@@ -3074,6 +3075,14 @@ static void get_cqe_status(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp,print_hex_dump (KERN_ERR ,"" ,DUMP_PREFIX_NONE ,16 ,4 , cqe,sizeof (*cqe), false); +/* +* For hns ROCEE, GENERAL_ERR is an error type that is not defined in +* the standard protocol, the driver must ignore it and needn't to set +* the QP to an error state. +*/ +if (cqe_status ==HNS_ROCE_CQE_V2_GENERAL_ERR ) +return ; +/* * Hip08 hardware cannot flush the WQEs in SQ/RQ if the QP state gets * into errored mode. Hence, as a workaround to this hardware
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +1 -0
@@ -230,6 +230,7 @@ enum {HNS_ROCE_CQE_V2_TRANSPORT_RETRY_EXC_ERR =0x15 ,HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR =0x16 ,HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR =0x22 , +HNS_ROCE_CQE_V2_GENERAL_ERR =0x23 , HNS_ROCE_V2_CQE_STATUS_MASK = 0xff, };
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 329/464 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 330/464 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 331/464 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 332/464 ASoC: soc-core: Fix regression causing sysfs entries to disappear
In reply to Greg Kroah-HartmanFrom: Charles Keepax <[email protected]>
[ Upstream commit 5c74c9d34aec1ac756de6979dd5580096aba8643 ]
The allocation order of things in soc_new_pcm_runtime was changed to move the device_register before the allocation of the rtd structure. This was to allow the rtd allocation to be managed by devm. However currently the sysfs entries are added by device_register and their visibility depends on variables within the rtd structure, this causes the pmdown_time and dapm_widgets sysfs entries to be missing for all rtds.
Correct this issue by manually calling device_add_groups after the appropriate information is available.
--- sound/soc/soc-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
sound/soc/soc-core.c +4 -1
@@ -446,7 +446,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( dev->parent = card->dev; dev->release = soc_release_rtd_dev; - dev->groups = soc_dev_attr_groups;dev_set_name (dev,"%s" , dai_link->name);
@@ -503,6 +502,10 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(/* see for_each_card_rtds */ list_add_tail (&rtd->list, &card->rtd_list); + ret =device_add_groups (dev, soc_dev_attr_groups); +if (ret <0 ) + goto free_rtd; +return rtd; free_rtd:
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 333/464 net: ll_temac: Use devm_platform_ioremap_resource_byname()
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit bd69058f50d5ffa659423bcfa6fe6280ce9c760a ]
platform_get_resource() may fail and return NULL, so we had better check its return value to avoid a NULL pointer dereference a bit later in the code. Fix it to use devm_platform_ioremap_resource_byname() instead of calling platform_get_resource_byname() and devm_ioremap().
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +2 -4
@@ -1407,10 +1407,8 @@ static int temac_probe(struct platform_device *pdev) }/* map device registers */ - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - lp->regs =devm_ioremap (&pdev->dev, res->start, -resource_size (res)); -if (!lp->regs) { + lp->regs =devm_platform_ioremap_resource_byname (pdev,0 ); +if (IS_ERR (lp->regs)) {dev_err (&pdev->dev,"could not map TEMAC registers\n" );return -ENOMEM ; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 334/464 drm/msm/dpu: dont use INTF_INPUT_CTRL feature on sdm845
In reply to Greg Kroah-HartmanFrom: Jonathan Marek <[email protected]>
[ Upstream commit cace3ac4bc08c5261aa4360a7d7aacc45a362fc2 ]
The INTF_INPUT_CTRL feature is not available on sdm845, so don't set it.
This also adds separate feature bits for INTF (based on downstream) instead of using CTL feature bit for it, and removes the unnecessary NULL check in the added bind_pingpong_blk function.
--- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 20 +++++++++++-------- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 13 ++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 9 ++------- 3 files changed, 27 insertions(+), 15 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +12 -8
@@ -43,6 +43,10 @@#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC) +#define INTF_SDM845_MASK (0) + +#define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) +#define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)#define DEFAULT_DPU_LINE_WIDTH 2048#define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
@@ -400,26 +404,26 @@ static struct dpu_pingpong_cfg sc7180_pp[] = {/************************************************************* * INTF sub blocks config *************************************************************/ -#define INTF_BLK (_name, _id, _base, _type, _ctrl_id) \ +#define INTF_BLK (_name, _id, _base, _type, _ctrl_id, _features) \ {\ .name = _name, .id = _id, \ .base = _base, .len = 0x280, \ - .features = BIT(DPU_CTL_ACTIVE_CFG), \ + .features = _features, \ .type = _type, \ .controller_id = _ctrl_id, \ .prog_fetch_lines_worst_case = 24 \ }static const struct dpu_intf_cfg sdm845_intf[] = { -INTF_BLK ("intf_0" ,INTF_0 ,0x6A000 ,INTF_DP ,0 ), -INTF_BLK ("intf_1" ,INTF_1 ,0x6A800 ,INTF_DSI ,0 ), -INTF_BLK ("intf_2" ,INTF_2 ,0x6B000 ,INTF_DSI ,1 ), -INTF_BLK ("intf_3" ,INTF_3 ,0x6B800 ,INTF_DP ,1 ), +INTF_BLK ("intf_0" ,INTF_0 ,0x6A000 ,INTF_DP ,0 ,INTF_SDM845_MASK ), +INTF_BLK ("intf_1" ,INTF_1 ,0x6A800 ,INTF_DSI ,0 ,INTF_SDM845_MASK ), +INTF_BLK ("intf_2" ,INTF_2 ,0x6B000 ,INTF_DSI ,1 ,INTF_SDM845_MASK ), +INTF_BLK ("intf_3" ,INTF_3 ,0x6B800 ,INTF_DP ,1 ,INTF_SDM845_MASK ), };static const struct dpu_intf_cfg sc7180_intf[] = { -INTF_BLK ("intf_0" ,INTF_0 ,0x6A000 ,INTF_DP ,0 ), -INTF_BLK ("intf_1" ,INTF_1 ,0x6A800 ,INTF_DSI ,0 ), +INTF_BLK ("intf_0" ,INTF_0 ,0x6A000 ,INTF_DP ,0 ,INTF_SC7180_MASK ), +INTF_BLK ("intf_1" ,INTF_1 ,0x6A800 ,INTF_DSI ,0 ,INTF_SC7180_MASK ), };/*************************************************************
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +13 -0
@@ -185,6 +185,19 @@ enum { DPU_CTL_MAX }; +/** +* INTF sub-blocks +* @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which +* pixel data arrives to this INTF +* @DPU_INTF_TE INTF block has TE configuration support +* @DPU_INTF_MAX +*/ +enum { +DPU_INTF_INPUT_CTRL =0x1 , +DPU_INTF_TE , +DPU_INTF_MAX +}; +/** * VBIF sub-blocks and features * @DPU_VBIF_QOS_OTLIM VBIF supports OT Limit
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +2 -7
@@ -225,14 +225,9 @@ static void dpu_hw_intf_bind_pingpong_blk(bool enable, const enum dpu_pingpong pp) { - struct dpu_hw_blk_reg_map *c; + struct dpu_hw_blk_reg_map *c = &intf->hw;u32 mux_cfg; -if (!intf) -return ; - - c = &intf->hw; - mux_cfg =DPU_REG_READ (c,INTF_MUX ); mux_cfg &= ~0xf ;
@@ -280,7 +275,7 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->get_status = dpu_hw_intf_get_status; ops->enable_timing = dpu_hw_intf_enable_timing_engine; ops->get_line_count = dpu_hw_intf_get_line_count; -if (cap &BIT (DPU_CTL_ACTIVE_CFG )) +if (cap &BIT (DPU_INTF_INPUT_CTRL )) ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 335/464 libbpf: Fix register in PT_REGS MIPS macros
In reply to Greg Kroah-HartmanFrom: Jerry Crunchtime <[email protected]>
[ Upstream commit 1acf8f90ea7ee59006d0474275922145ac291331 ]
The o32, n32 and n64 calling conventions require the return value to be stored in $v0 which maps to $2 register, i.e., the register 2.
--- tools/lib/bpf/bpf_tracing.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/lib/bpf/bpf_tracing.h +2 -2
@@ -215,7 +215,7 @@ struct pt_regs;#define PT_REGS_PARM5 (x) ((x)->regs[8])#define PT_REGS_RET (x) ((x)->regs[31])#define PT_REGS_FP (x) ((x)->regs[30])/* Works only with CONFIG_FRAME_POINTER */ -#define PT_REGS_RC (x) ((x)->regs[1]) +#define PT_REGS_RC (x) ((x)->regs[2])#define PT_REGS_SP (x) ((x)->regs[29])#define PT_REGS_IP (x) ((x)->cp0_epc)
@@ -226,7 +226,7 @@ struct pt_regs;#define PT_REGS_PARM5_CORE (x) BPF_CORE_READ((x), regs[8])#define PT_REGS_RET_CORE (x) BPF_CORE_READ((x), regs[31])#define PT_REGS_FP_CORE (x) BPF_CORE_READ((x), regs[30]) -#define PT_REGS_RC_CORE (x) BPF_CORE_READ((x), regs[1]) +#define PT_REGS_RC_CORE (x) BPF_CORE_READ((x), regs[2])#define PT_REGS_SP_CORE (x) BPF_CORE_READ((x), regs[29])#define PT_REGS_IP_CORE (x) BPF_CORE_READ((x), cp0_epc)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 336/464 MIPS: only register FTLBPar exception handler for supported models
In reply to Greg Kroah-HartmanFrom: WANG Xuerui <[email protected]>
[ Upstream commit efd1b4ad3d5178a74387bc5ff69a2d4585f586c6 ]
Previously ExcCode 16 is unconditionally treated as the FTLB parity exception (FTLBPar), but in fact its semantic is implementation- dependent. Looking at various manuals it seems the FTLBPar exception is only present on some recent MIPS Technologies cores, so only register the handler on these.
--- arch/mips/include/asm/cpu-features.h | 4 ++++ arch/mips/include/asm/cpu.h | 1 + arch/mips/kernel/cpu-probe.c | 13 +++++++++++++ arch/mips/kernel/traps.c | 3 ++- 4 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/include/asm/cpu-features.h +4 -0
@@ -568,6 +568,10 @@# define cpu_has_mac2008_only __opt(MIPS_CPU_MAC_2008_ONLY)#endif +#ifndef cpu_has_ftlbparex +# define cpu_has_ftlbparex __opt(MIPS_CPU_FTLBPAREX) +#endif +#ifdef CONFIG_SMP /* * Some systems share FTLB RAMs between threads within a core (siblings in
arch/mips/include/asm/cpu.h +1 -0
@@ -425,6 +425,7 @@ enum cpu_type_enum {#define MIPS_CPU_MM_SYSAD BIT_ULL(58)/* CPU supports write-through SysAD Valid merge */ #define MIPS_CPU_MM_FULL BIT_ULL(59)/* CPU supports write-through full merge */ #define MIPS_CPU_MAC_2008_ONLY BIT_ULL(60)/* CPU Only support MAC2008 Fused multiply-add instruction */ +#define MIPS_CPU_FTLBPAREX BIT_ULL(61)/* CPU has FTLB parity exception */ /* * CPU ASE encodings
arch/mips/kernel/cpu-probe.c +13 -0
@@ -1827,6 +1827,19 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)default :break ; } + +/* Recent MIPS cores use the implementation-dependent ExcCode 16 for +* cache/FTLB parity exceptions. +*/ +switch (__get_cpu_type (c->cputype)) { +case CPU_PROAPTIV : +case CPU_P5600 : +case CPU_P6600 : +case CPU_I6400 : +case CPU_I6500 : + c->options |=MIPS_CPU_FTLBPAREX ; +break ; + } }static inline void cpu_probe_alchemy (struct cpuinfo_mips *c,unsigned int cpu)
arch/mips/kernel/traps.c +2 -1
@@ -2457,7 +2457,8 @@ void __init trap_init(void)if (cpu_has_fpu && !cpu_has_nofpuex)set_except_vector (EXCCODE_FPE , handle_fpe); -set_except_vector (MIPS_EXCCODE_TLBPAR , handle_ftlb); +if (cpu_has_ftlbparex) +set_except_vector (MIPS_EXCCODE_TLBPAR , handle_ftlb);if (cpu_has_rixiex) {set_except_vector (EXCCODE_TLBRI , tlb_do_page_fault_0);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 337/464 ASoC: core: use less strict tests for dailink capabilities
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 4f8721542f7b75954bfad98c51aa59d683d35b50 ]
Previous updates to set dailink capabilities and check dailink capabilities were based on a flawed assumption that all dais support the same capabilities as the dailink. This is true for TDM configurations but existing configurations use an amplifier and a capture device on the same dailink, and the tests would prevent the card from probing.
This patch modifies the snd_soc_dai_link_set_capabilities() helper so that the dpcm_playback (resp. dpcm_capture) dailink capabilities are set if at least one dai supports playback (resp. capture).
Likewise the checks are modified so that an error is reported only when dpcm_playback (resp. dpcm_capture) is set but none of the CPU DAIs support playback (resp. capture).
--- sound/soc/soc-dai.c | 16 +++++++++------- sound/soc/soc-pcm.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 25 deletions(-)
sound/soc/soc-dai.c +9 -7
@@ -400,28 +400,30 @@ void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)struct snd_soc_dai_link_component *codec;struct snd_soc_dai *dai;bool supported[SNDRV_PCM_STREAM_LAST +1 ]; +bool supported_cpu; +bool supported_codec;int direction;int i;for_each_pcm_streams (direction) { - supported[direction] = true; + supported_cpu = false; + supported_codec = false;for_each_link_cpus (dai_link, i, cpu) { dai =snd_soc_find_dai (cpu); -if (!dai || !snd_soc_dai_stream_valid (dai, direction)) { - supported[direction] = false; +if (dai &&snd_soc_dai_stream_valid (dai, direction)) { + supported_cpu = true;break ; } } -if (!supported[direction]) -continue ;for_each_link_codecs (dai_link, i, codec) { dai =snd_soc_find_dai (codec); -if (!dai || !snd_soc_dai_stream_valid (dai, direction)) { - supported[direction] = false; +if (dai &&snd_soc_dai_stream_valid (dai, direction)) { + supported_codec = true;break ; } } + supported[direction] = supported_cpu && supported_codec; } dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK ];
sound/soc/soc-pcm.c +24 -18
54 lines not on this page · raw message
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 338/464 ASoC: meson: cards: deal dpcm flag change
In reply to Greg Kroah-HartmanFrom: Jerome Brunet <[email protected]>
[ Upstream commit da3f23fde9d7b4a7e0ca9a9a096cec3104df1b82 ]
Commit b73287f0b074 ("ASoC: soc-pcm: dpcm: fix playback/capture checks") changed the meaning of dpcm_playback/dpcm_capture and now requires the CPU DAI BE to aligned with those flags.
This broke all Amlogic cards with uni-directional backends (All gx and most axg cards).
While I'm still confused as to how this change is an improvement, those cards can't remain broken forever. Hopefully, next time an API change is done like that, all the users will be updated as part of the change, and not left to fend for themselves.
--- sound/soc/meson/axg-card.c | 18 ++++++++++-------- sound/soc/meson/gx-card.c | 18 +++++++++--------- sound/soc/meson/meson-card-utils.c | 4 ---- 3 files changed, 19 insertions(+), 21 deletions(-)
sound/soc/meson/axg-card.c +10 -8
@@ -327,20 +327,22 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,return ret;if (axg_card_cpu_is_playback_fe (dai_link->cpus->of_node)) - ret =meson_card_set_fe_link (card, dai_link, np, true); +return meson_card_set_fe_link (card, dai_link, np, true);else if (axg_card_cpu_is_capture_fe (dai_link->cpus->of_node)) - ret =meson_card_set_fe_link (card, dai_link, np, false); -else - ret =meson_card_set_be_link (card, dai_link, np); +return meson_card_set_fe_link (card, dai_link, np, false); + + ret =meson_card_set_be_link (card, dai_link, np);if (ret)return ret; -if (axg_card_cpu_is_tdm_iface (dai_link->cpus->of_node)) - ret =axg_card_parse_tdm (card, np, index); -else if (axg_card_cpu_is_codec (dai_link->cpus->of_node)) { +if (axg_card_cpu_is_codec (dai_link->cpus->of_node)) { dai_link->params = &codec_params; - dai_link->no_pcm =0 ;/* link is not a DPCM BE */ + }else { + dai_link->no_pcm =1 ; +snd_soc_dai_link_set_capabilities (dai_link); +if (axg_card_cpu_is_tdm_iface (dai_link->cpus->of_node)) + ret =axg_card_parse_tdm (card, np, index); }return ret;
sound/soc/meson/gx-card.c +9 -9
@@ -96,21 +96,21 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np,return ret;if (gx_card_cpu_identify (dai_link->cpus,"FIFO" )) - ret =meson_card_set_fe_link (card, dai_link, np, true); -else - ret =meson_card_set_be_link (card, dai_link, np); +return meson_card_set_fe_link (card, dai_link, np, true); + ret =meson_card_set_be_link (card, dai_link, np);if (ret)return ret; -/* Check if the cpu is the i2s encoder and parse i2s data */ -if (gx_card_cpu_identify (dai_link->cpus,"I2S Encoder" )) - ret =gx_card_parse_i2s (card, np, index); -/* Or apply codec to codec params if necessary */ -else if (gx_card_cpu_identify (dai_link->cpus,"CODEC CTRL" )) { +if (gx_card_cpu_identify (dai_link->cpus,"CODEC CTRL" )) { dai_link->params = &codec_params; - dai_link->no_pcm =0 ;/* link is not a DPCM BE */ + }else { + dai_link->no_pcm =1 ; +snd_soc_dai_link_set_capabilities (dai_link); +/* Check if the cpu is the i2s encoder and parse i2s data */ +if (gx_card_cpu_identify (dai_link->cpus,"I2S Encoder" )) + ret =gx_card_parse_i2s (card, np, index); }return ret;
sound/soc/meson/meson-card-utils.c +0 -4
@@ -147,10 +147,6 @@ int meson_card_set_be_link(struct snd_soc_card *card,struct device_node *np;int ret, num_codecs; - link->no_pcm =1 ; - link->dpcm_playback =1 ; - link->dpcm_capture =1 ; - num_codecs =of_get_child_count (node);if (!num_codecs) { dev_err(card->dev, "be link %s has no codec\n",
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 339/464 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 340/464 s390/qeth: tolerate pre-filled RX buffer
In reply to Greg Kroah-HartmanFrom: Julian Wiedmann <[email protected]>
[ Upstream commit eff73e16ee116f6eafa2be48fab42659a27cb453 ]
When preparing a buffer for RX refill, tolerate that it already has a pool_entry attached. Otherwise we could easily leak such a pool_entry when re-driving the RX refill after an error (from eg. do_qdio()).
This needs some minor adjustment in the code that drains RX buffer(s) prior to RX refill and during teardown, so that ->pool_entry is NULLed accordingly.
--- drivers/s390/net/qeth_core_main.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/s390/net/qeth_core_main.c +14 -6
@@ -204,12 +204,17 @@ EXPORT_SYMBOL_GPL(qeth_threads_running);void qeth_clear_working_pool_list (struct qeth_card *card) {struct qeth_buffer_pool_entry *pool_entry, *tmp; +struct qeth_qdio_q *queue = card->qdio.in_q; +unsigned int i;QETH_CARD_TEXT (card,5 ,"clwrklst" );list_for_each_entry_safe (pool_entry, tmp, &card->qdio.in_buf_pool.entry_list, list){list_del (&pool_entry->list); } + +for (i =0 ; i <ARRAY_SIZE (queue->bufs); i++) + queue->bufs[i].pool_entry =NULL ; }EXPORT_SYMBOL_GPL (qeth_clear_working_pool_list);
@@ -2951,7 +2956,7 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(static int qeth_init_input_buffer (struct qeth_card *card,struct qeth_qdio_buffer *buf) { -struct qeth_buffer_pool_entry *pool_entry; +struct qeth_buffer_pool_entry *pool_entry = buf->pool_entry;int i;if ((card->options.cq ==QETH_CQ_ENABLED ) && (!buf->rx_skb)) {
@@ -2962,9 +2967,13 @@ static int qeth_init_input_buffer(struct qeth_card *card,return -ENOMEM ; } - pool_entry =qeth_find_free_buffer_pool_entry (card); -if (!pool_entry) -return -ENOBUFS ; +if (!pool_entry) { + pool_entry =qeth_find_free_buffer_pool_entry (card); +if (!pool_entry) +return -ENOBUFS ; + + buf->pool_entry = pool_entry; + }/* * since the buffer is accessed only from the input_tasklet
@@ -2972,8 +2981,6 @@ static int qeth_init_input_buffer(struct qeth_card *card,* the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run out off * buffers */ - - buf->pool_entry = pool_entry;for (i =0 ; i <QETH_MAX_BUFFER_ELEMENTS (card); ++i) { buf->buffer->element[i].length =PAGE_SIZE ; buf->buffer->element[i].addr =
@@ -5802,6 +5809,7 @@ static unsigned int qeth_rx_poll(struct qeth_card *card, int budget)if (done) {QETH_CARD_STAT_INC (card, rx_bufs);qeth_put_buffer_pool_entry (card, buffer->pool_entry); + buffer->pool_entry =NULL ;qeth_queue_input_buffer (card, card->rx.b_index); card->rx.b_count--;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 341/464 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
@@ -1142,6 +1142,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 342/464 ice: Clear and free XLT entries on reset
In reply to Greg Kroah-HartmanFrom: Vignesh Sridhar <[email protected]>
[ Upstream commit ec1d1d2302067e3ccbc4d0adcd36d72410933b70 ]
This fix has been added to address memory leak issues resulting from triggering a sudden driver reset which does not allow us to follow our normal removal flows for SW XLT entries for advanced features.
- Adding call to destroy flow profile locks when clearing SW XLT tables.
- Extraction sequence entries were not correctly cleared previously which could cause ownership conflicts for repeated reset-replay calls.
--- 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
@@ -2922,6 +2922,8 @@ static void ice_free_flow_profs(struct ice_hw *hw, u8 blk_idx) ICE_FLOW_ENTRY_HNDL(e));list_del (&p->l_entry); + +mutex_destroy (&p->entries_lock);devm_kfree (ice_hw_to_dev (hw), p); }mutex_unlock (&hw->fl_profs_locks[blk_idx]);
@@ -3039,7 +3041,7 @@ void ice_clear_hw_tbls(struct ice_hw *hw)memset (prof_redir->t,0 , prof_redir->count *sizeof (*prof_redir->t)); -memset (es->t,0 , es->count *sizeof (*es->t)); +memset (es->t,0 , es->count *sizeof (*es->t) * es->fvw);memset (es->ref_count,0 , es->count *sizeof (*es->ref_count));memset (es->written,0 , es->count *sizeof (*es->written)); }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 343/464 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
@@ -3152,10 +3152,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 344/464 netfilter: nft_meta: fix iifgroup matching
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit 78470d9d0d9f2f8d16f28382a4071568e839c0d5 ]
iifgroup matching erroneously checks the output interface.
--- net/netfilter/nft_meta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nft_meta.c +1 -1
@@ -253,7 +253,7 @@ static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,return false;break ;case NFT_META_IIFGROUP : -if (!nft_meta_store_ifgroup (dest,nft_out (pkt))) +if (!nft_meta_store_ifgroup (dest,nft_in (pkt)))return false;break ;case NFT_META_OIFGROUP :
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 345/464 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
@@ -456,7 +456,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 346/464 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
@@ -722,8 +722,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 );
@@ -731,9 +729,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 )
@@ -775,12 +770,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 347/464 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
@@ -1934,7 +1934,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 348/464 qtnfmac: Missing platform_device_unregister() on error in qtnf_core_mac_alloc()
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit 141bc9abbbffa89d020957caa9ac4a61d0ef1e26 ]
Add the missing platform_device_unregister() before return from qtnf_core_mac_alloc() in the error handling case.
--- drivers/net/wireless/quantenna/qtnfmac/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/quantenna/qtnfmac/core.c +4 -1
@@ -446,8 +446,11 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus, } wiphy =qtnf_wiphy_allocate (bus, pdev); -if (!wiphy) +if (!wiphy) { +if (pdev) +platform_device_unregister (pdev);return ERR_PTR (-ENOMEM ); + } mac =wiphy_priv (wiphy);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 349/464 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 350/464 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 351/464 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
@@ -596,7 +596,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 352/464 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
@@ -279,29 +279,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 ;
@@ -354,6 +334,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 353/464 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
@@ -847,18 +847,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 354/464 ftrace: Fix ftrace_trace_task return value
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
[ Upstream commit c58b6b0372de0d4cd0536d6585addd1b36b151ae ]
I was attempting to use pid filtering with function_graph, but it wasn't allowing anything to make it through. Turns out ftrace_trace_task returns false if ftrace_ignore_pid is not-empty, which isn't correct anymore. We're now setting it to FTRACE_PID_IGNORE if we need to ignore that pid, otherwise it's set to the pid (which is weird considering the name) or to FTRACE_PID_TRACE. Fix the check to check for != FTRACE_PID_IGNORE. With this we can now use function_graph with pid filtering.
--- kernel/trace/ftrace.c | 3 --- kernel/trace/trace.h | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-)
kernel/trace/ftrace.c +0 -3
@@ -139,9 +139,6 @@ static inline void ftrace_ops_init(struct ftrace_ops *ops)#endif } -#define FTRACE_PID_IGNORE -1 -#define FTRACE_PID_TRACE -2 -static void ftrace_pid_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct pt_regs *regs) {
kernel/trace/trace.h +6 -1
@@ -1103,6 +1103,10 @@ print_graph_function_flags(struct trace_iterator *iter, u32 flags)extern struct list_head ftrace_pids; #ifdef CONFIG_FUNCTION_TRACER + +#define FTRACE_PID_IGNORE -1 +#define FTRACE_PID_TRACE -2 + struct ftrace_func_command { struct list_head list; char *name;
@@ -1114,7 +1118,8 @@ struct ftrace_func_command {extern bool ftrace_filter_param__initdata ;static inline int ftrace_trace_task (struct trace_array *tr) { -return !this_cpu_read (tr->array_buffer.data->ftrace_ignore_pid); +return this_cpu_read (tr->array_buffer.data->ftrace_ignore_pid) != +FTRACE_PID_IGNORE ; }extern int ftrace_is_dead (void ); int ftrace_create_function_files(struct trace_array *tr,
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 355/464 net: mvpp2: fix memory leak in mvpp2_rx
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit d6526926de7397a97308780911565e31a6b67b59 ]
Release skb memory in mvpp2_rx() if mvpp2_rx_refill routine fails
--- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +1 -0
@@ -2981,6 +2981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, err =mvpp2_rx_refill (port, bm_pool, pool);if (err) {netdev_err (port->dev,"failed to refill BM pools\n" ); +dev_kfree_skb_any (skb); goto err_drop_frame; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 356/464 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
@@ -782,7 +782,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 357/464 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 358/464 net: sgi: ioc3-eth: Fix the size used in some dma_free_coherent() calls
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit edab74e9cb1d073c70add0f9b75e17aebf0598ff ]
Update the size used in 'dma_free_coherent()' in order to match the one used in the corresponding 'dma_alloc_coherent()'.
--- drivers/net/ethernet/sgi/ioc3-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/sgi/ioc3-eth.c +2 -2
@@ -951,7 +951,7 @@ static int ioc3eth_probe(struct platform_device *pdev)dma_free_coherent (ip->dma_dev,RX_RING_SIZE , ip->rxr, ip->rxr_dma);if (ip->tx_ring) -dma_free_coherent (ip->dma_dev,TX_RING_SIZE , ip->tx_ring, +dma_free_coherent (ip->dma_dev,TX_RING_SIZE +SZ_16K -1 , ip->tx_ring, ip->txr_dma); out_free:free_netdev (dev);
@@ -964,7 +964,7 @@ static int ioc3eth_remove(struct platform_device *pdev)struct ioc3_private *ip =netdev_priv (dev);dma_free_coherent (ip->dma_dev,RX_RING_SIZE , ip->rxr, ip->rxr_dma); -dma_free_coherent (ip->dma_dev,TX_RING_SIZE , ip->tx_ring, ip->txr_dma); +dma_free_coherent (ip->dma_dev,TX_RING_SIZE +SZ_16K -1 , ip->tx_ring, ip->txr_dma);unregister_netdev (dev);del_timer_sync (&ip->ioc3_timer);
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 359/464 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 360/464 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
@@ -1398,8 +1398,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 361/464 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
@@ -1767,6 +1767,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;
@@ -1791,8 +1792,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 362/464 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
@@ -852,7 +852,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 363/464 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
@@ -1200,7 +1200,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 ;
@@ -1213,7 +1213,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
@@ -981,7 +981,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
@@ -626,7 +626,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 364/464 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 365/464 gpio: dont use same lockdep class for all devm_gpiochip_add_data users
In reply to Greg Kroah-HartmanFrom: Ahmad Fatoum <[email protected]>
[ Upstream commit 5f402bb17533113c21d61c2d4bc4ef4a6fa1c9a5 ]
Commit 959bc7b22bd2 ("gpio: Automatically add lockdep keys") documents in its commits message its intention to "create a unique class key for each driver".
It does so by having gpiochip_add_data add in-place the definition of two static lockdep classes for LOCKDEP use. That way, every caller of the macro adds their gpiochip with unique lockdep classes.
There are many indirect callers of gpiochip_add_data, however, via use of devm_gpiochip_add_data. devm_gpiochip_add_data has external linkage and all its users will share the same lockdep classes, which probably is not intended.
Fix this by replicating the gpio_chip_add_data statics-in-macro for the devm_ version as well.
--- drivers/gpio/gpiolib-devres.c | 13 ++++++++----- include/linux/gpio/driver.h | 13 +++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-)
drivers/gpio/gpiolib-devres.c +8 -5
@@ -487,10 +487,12 @@ static void devm_gpio_chip_release(struct device *dev, void *res) }/** -* devm_gpiochip_add_data() - Resource managed gpiochip_add_data() +* devm_gpiochip_add_data_with_key() - Resource managed gpiochip_add_data_with_key() * @dev: pointer to the device that gpio_chip belongs to. * @gc: the GPIO chip to register * @data: driver-private data associated with this chip +* @lock_key: lockdep class for IRQ lock +* @request_key: lockdep class for IRQ request * * Context: potentially before irqs will work *
@@ -501,8 +503,9 @@ static void devm_gpio_chip_release(struct device *dev, void *res)* gc->base is invalid or already associated with a different chip. * Otherwise it returns zero as a success code. */ -int devm_gpiochip_add_data (struct device *dev,struct gpio_chip *gc, -void *data) +int devm_gpiochip_add_data_with_key (struct device *dev,struct gpio_chip *gc,void *data, +struct lock_class_key *lock_key, +struct lock_class_key *request_key) {struct gpio_chip **ptr;int ret;
@@ -512,7 +515,7 @@ int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,if (!ptr)return -ENOMEM ; - ret =gpiochip_add_data (gc, data); + ret =gpiochip_add_data_with_key (gc, data, lock_key, request_key);if (ret <0 ) {devres_free (ptr);return ret;
@@ -523,4 +526,4 @@ int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,return 0 ; } -EXPORT_SYMBOL_GPL (devm_gpiochip_add_data); +EXPORT_SYMBOL_GPL (devm_gpiochip_add_data_with_key);
include/linux/gpio/driver.h +11 -2
@@ -509,8 +509,16 @@ extern int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,gpiochip_add_data_with_key (gc, data, &lock_key, \ &request_key); \ }) +#define devm_gpiochip_add_data (dev, gc, data) ({ \ + static struct lock_class_key lock_key; \ + static struct lock_class_key request_key; \ + devm_gpiochip_add_data_with_key(dev, gc, data, &lock_key, \ + &request_key); \ + })#else #define gpiochip_add_data (gc, data) gpiochip_add_data_with_key(gc, data, NULL, NULL) +#define devm_gpiochip_add_data (dev, gc, data) \ + devm_gpiochip_add_data_with_key(dev, gc, data, NULL, NULL)#endif /* CONFIG_LOCKDEP */ static inline int gpiochip_add (struct gpio_chip *gc)
@@ -518,8 +526,9 @@ static inline int gpiochip_add(struct gpio_chip *gc)return gpiochip_add_data (gc,NULL ); }extern void gpiochip_remove (struct gpio_chip *gc); -extern int devm_gpiochip_add_data (struct device *dev,struct gpio_chip *gc, -void *data); +extern int devm_gpiochip_add_data_with_key (struct device *dev,struct gpio_chip *gc,void *data, +struct lock_class_key *lock_key, +struct lock_class_key *request_key);extern struct gpio_chip *gpiochip_find (void *data,int (*match)(struct gpio_chip *gc,void *data));
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 366/464 net: thunderx: use spin_lock_bh in nicvf_set_rx_mode_task()
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
[ Upstream commit bab9693a9a8c6dd19f670408ec1e78e12a320682 ]
A dead lock was triggered on thunderx driver:
CPU0 CPU1
---- ----
[01] lock(&(&nic->rx_mode_wq_lock)->rlock);
[11] lock(&(&mc->mca_lock)->rlock);
[12] lock(&(&nic->rx_mode_wq_lock)->rlock);[02] <Interrupt> lock(&(&mc->mca_lock)->rlock);
The path for each is:
[01] worker_thread() -> process_one_work() -> nicvf_set_rx_mode_task()
[02] mld_ifc_timer_expire()
[11] ipv6_add_dev() -> ipv6_dev_mc_inc() -> igmp6_group_added() ->
[12] dev_mc_add() -> __dev_set_rx_mode() -> nicvf_set_rx_mode()
To fix it, it needs to disable bh on [1], so that the timer on [2] wouldn't be triggered until rx_mode_wq_lock is released. So change to use spin_lock_bh() instead of spin_lock().
Thanks to Paolo for helping with this.
v1->v2:
- post to netdev.
--- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/cavium/thunder/nicvf_main.c +2 -2
@@ -2042,11 +2042,11 @@ static void nicvf_set_rx_mode_task(struct work_struct *work_arg)/* Save message data locally to prevent them from * being overwritten by next ndo_set_rx_mode call(). */ -spin_lock (&nic->rx_mode_wq_lock); +spin_lock_bh (&nic->rx_mode_wq_lock); mode = vf_work->mode; mc = vf_work->mc; vf_work->mc =NULL ; -spin_unlock (&nic->rx_mode_wq_lock); +spin_unlock_bh (&nic->rx_mode_wq_lock);__nicvf_set_rx_mode_task (mode, mc, nic); }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 367/464 net: macb: Properly handle phylink on at91sam9x
In reply to Greg Kroah-HartmanFrom: Stefan Roese <[email protected]>
[ Upstream commit f7ba7dbf4f7af67b5936ff1cbd40a3254b409ebf ]
I just recently noticed that ethernet does not work anymore since v5.5 on the GARDENA smart Gateway, which is based on the AT91SAM9G25. Debugging showed that the "GEM bits" in the NCFGR register are now unconditionally accessed, which is incorrect for the !macb_is_gem() case.
This patch adds the macb_is_gem() checks back to the code (in macb_mac_config() & macb_mac_link_up()), so that the GEM register bits are not accessed in this case any more.
--- drivers/net/ethernet/cadence/macb_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/ethernet/cadence/macb_main.c +7 -4
@@ -578,7 +578,7 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,if (bp->caps &MACB_CAPS_MACB_IS_EMAC ) {if (state->interface ==PHY_INTERFACE_MODE_RMII ) ctrl |=MACB_BIT (RM9200_RMII ); - }else { + }else if (macb_is_gem (bp)) { ctrl &= ~(GEM_BIT (SGMIIEN ) |GEM_BIT (PCSSEL ));if (state->interface ==PHY_INTERFACE_MODE_SGMII )
@@ -639,10 +639,13 @@ static void macb_mac_link_up(struct phylink_config *config, ctrl |=MACB_BIT (FD );if (!(bp->caps &MACB_CAPS_MACB_IS_EMAC )) { - ctrl &= ~(GEM_BIT (GBE ) |MACB_BIT (PAE )); + ctrl &= ~MACB_BIT (PAE ); +if (macb_is_gem (bp)) { + ctrl &= ~GEM_BIT (GBE ); -if (speed ==SPEED_1000 ) - ctrl |=GEM_BIT (GBE ); +if (speed ==SPEED_1000 ) + ctrl |=GEM_BIT (GBE ); + }/* We do not support MLO_PAUSE_RX yet */ if (tx_pause)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 368/464 dpaa2-eth: Fix passing zero to PTR_ERR warning
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
[ Upstream commit 02afa9c66bb954c6959877c70d9e128dcf0adce7 ]
Fix smatch warning:
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c:2419
alloc_channel() warn: passing zero to 'ERR_PTR'
setup_dpcon() should return ERR_PTR(err) instead of zero in error handling case.
--- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +3 -3
@@ -2207,7 +2207,7 @@ static struct fsl_mc_device *setup_dpcon(struct dpaa2_eth_priv *priv) free:fsl_mc_object_free (dpcon); -return NULL ; +return ERR_PTR (err); } static void free_dpcon(struct dpaa2_eth_priv *priv,
@@ -2231,8 +2231,8 @@ alloc_channel(struct dpaa2_eth_priv *priv)return NULL ; channel->dpcon =setup_dpcon (priv); -if (IS_ERR_OR_NULL (channel->dpcon)) { - err =PTR_ERR_OR_ZERO (channel->dpcon); +if (IS_ERR (channel->dpcon)) { + err =PTR_ERR (channel->dpcon); goto err_setup; }
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 369/464 hv_netvsc: do not use VF device if link is down
In reply to Greg Kroah-HartmanFrom: Stephen Hemminger <[email protected]>
[ Upstream commit 7c9864bbccc23e1812ac82966555d68c13ea4006 ]
If the accelerated networking SRIOV VF device has lost carrier use the synthetic network device which is available as backup path. This is a rare case since if VF link goes down, normally the VMBus device will also loose external connectivity as well. But if the communication is between two VM's on the same host the VMBus device will still work.
--- drivers/net/hyperv/netvsc_drv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/hyperv/netvsc_drv.c +4 -3
@@ -532,12 +532,13 @@ static int netvsc_xmit(struct sk_buff *skb, struct net_device *net, bool xdp_tx)u32 hash;struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT ]; -/* if VF is present and up then redirect packets -* already called with rcu_read_lock_bh +/* If VF is present and up then redirect packets to it. +* Skip the VF if it is marked down or has no carrier. +* If netpoll is in uses, then VF can not be used either. */ vf_netdev =rcu_dereference_bh (net_device_ctx->vf_netdev);if (vf_netdev &&netif_running (vf_netdev) && - !netpoll_tx_running (net)) +netif_carrier_ok (vf_netdev) && !netpoll_tx_running (net))return netvsc_vf_xmit (net, vf_netdev, skb);/* We will atmost need two pages to describe the rndis
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 370/464 Revert "vxlan: fix tos value before xmit"
In reply to Greg Kroah-HartmanFrom: Hangbin Liu <[email protected]>
[ Upstream commit a0dced17ad9dc08b1b25e0065b54c97a318e6e8b ]
This reverts commit 71130f29979c7c7956b040673e6b9d5643003176.
In commit 71130f29979c ("vxlan: fix tos value before xmit") we want to make sure the tos value are filtered by RT_TOS() based on RFC1349.
0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| PRECEDENCE | TOS | MBZ |
+-----+-----+-----+-----+-----+-----+-----+-----+
But RFC1349 has been obsoleted by RFC2474. The new DSCP field defined like
0 1 2 3 4 5 6 7
+-----+-----+-----+-----+-----+-----+-----+-----+
| DS FIELD, DSCP | ECN FIELD |
+-----+-----+-----+-----+-----+-----+-----+-----+
So with
IPTOS_TOS_MASK 0x1ERT_TOS(tos) ((tos)&IPTOS_TOS_MASK)
the first 3 bits DSCP info will get lost.
To take all the DSCP info in xmit, we should revert the patch and just push all tos bits to ip_tunnel_ecn_encap(), which will handling ECN field later.
--- drivers/net/vxlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/vxlan.c +2 -2
@@ -2722,7 +2722,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ndst = &rt->dst;skb_tunnel_check_pmtu (skb, ndst,VXLAN_HEADROOM ); - tos =ip_tunnel_ecn_encap (RT_TOS (tos), old_iph, skb); + tos =ip_tunnel_ecn_encap (tos, old_iph, skb); ttl = ttl ? :ip4_dst_hoplimit (&rt->dst); err =vxlan_build_skb (skb, ndst,sizeof (struct iphdr ), vni, md, flags, udp_sum);
@@ -2762,7 +2762,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,skb_tunnel_check_pmtu (skb, ndst,VXLAN6_HEADROOM ); - tos =ip_tunnel_ecn_encap (RT_TOS (tos), old_iph, skb); + tos =ip_tunnel_ecn_encap (tos, old_iph, skb); ttl = ttl ? :ip6_dst_hoplimit (ndst);skb_scrub_packet (skb, xnet); err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 371/464 selftests/net: relax cpu affinity requirement in msg_zerocopy test
In reply to Greg Kroah-HartmanFrom: Willem de Bruijn <[email protected]>
[ Upstream commit 16f6458f2478b55e2b628797bc81a4455045c74e ]
The msg_zerocopy test pins the sender and receiver threads to separate cores to reduce variance between runs.
But it hardcodes the cores and skips core 0, so it fails on machines with the selected cores offline, or simply fewer cores.
The test mainly gives code coverage in automated runs. The throughput of zerocopy ('-z') and non-zerocopy runs is logged for manual inspection.
Continue even when sched_setaffinity fails. Just log to warn anyone interpreting the data.
--- tools/testing/selftests/net/msg_zerocopy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
tools/testing/selftests/net/msg_zerocopy.c +2 -3
@@ -125,9 +125,8 @@ static int do_setcpu(int cpu)CPU_ZERO (&mask);CPU_SET (cpu, &mask);if (sched_setaffinity (0 ,sizeof (mask), &mask)) -error (1 ,0 ,"setaffinity %d" , cpu); - -if (cfg_verbose) +fprintf (stderr,"cpu: unable to pin, may increase variance.\n" ); +else if (cfg_verbose)fprintf (stderr,"cpu: %u\n" , cpu);return 0 ;
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 372/464 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
@@ -2180,6 +2180,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) {
@@ -2256,7 +2259,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 373/464 media: mtk-mdp: Fix a refcounting bug on error in init
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit dd4eddc4ba31fbf4554fc5fa12d3a553b50e1469 ]
We need to call of_node_put(comp->dev_node); on the error paths in this function.
--- drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +12 -4
@@ -96,6 +96,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node, {struct device_node *larb_node;struct platform_device *larb_pdev; +int ret;int i;if (comp_id <0 || comp_id >=MTK_MDP_COMP_ID_MAX ) {
@@ -113,8 +114,8 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,if (IS_ERR (comp->clk[i])) {if (PTR_ERR (comp->clk[i]) != -EPROBE_DEFER )dev_err (dev,"Failed to get clock\n" ); - -return PTR_ERR (comp->clk[i]); + ret =PTR_ERR (comp->clk[i]); + goto put_dev; }/* Only RDMA needs two clocks */
@@ -133,20 +134,27 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,if (!larb_node) {dev_err (dev,"Missing mediadek,larb phandle in %pOF node\n" , node); -return -EINVAL ; + ret = -EINVAL ; + goto put_dev; } larb_pdev =of_find_device_by_node (larb_node);if (!larb_pdev) {dev_warn (dev,"Waiting for larb device %pOF\n" , larb_node);of_node_put (larb_node); -return -EPROBE_DEFER ; + ret = -EPROBE_DEFER ; + goto put_dev; }of_node_put (larb_node); comp->larb_dev = &larb_pdev->dev;return 0 ; + +put_dev: +of_node_put (comp->dev_node); + +return ret; }void mtk_mdp_comp_deinit (struct device *dev,struct mtk_mdp_comp *comp)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 374/464 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
@@ -622,6 +622,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);
@@ -629,9 +632,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 375/464 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 376/464 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 377/464 mtd: rawnand: brcmnand: Dont default to edu transfer
In reply to Greg Kroah-HartmanFrom: Kamal Dasu <[email protected]>
[ Upstream commit bee3ab8bdd3b13faf08e5b6e0218f59b0a49fcc3 ]
When flash-dma is absent do not default to using flash-edu. Make sure flash-edu is enabled before setting EDU transfer function.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +3 -2
@@ -3023,8 +3023,9 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)if (ret <0 ) goto err; -/* set edu transfer function to call */ - ctrl->dma_trans = brcmnand_edu_trans; +if (has_edu (ctrl)) +/* set edu transfer function to call */ + ctrl->dma_trans = brcmnand_edu_trans; }/* Disable automatic device ID config, direct addressing */
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 378/464 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
@@ -684,7 +684,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 ;
@@ -707,12 +706,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; }
@@ -807,6 +800,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
@@ -860,6 +873,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 379/464 nfsd: avoid a NULL dereference in __cld_pipe_upcall()
In reply to Greg Kroah-HartmanFrom: Scott Mayhew <[email protected]>
[ Upstream commit df60446cd1fb487becd1f36f4c0da9e0e523c0cf ]
If the rpc_pipefs is unmounted, then the rpc_pipe->dentry becomes NULL and dereferencing the dentry->d_sb will trigger an oops. The only reason we're doing that is to determine the nfsd_net, which could instead be passed in by the caller. So do that instead.
--- fs/nfsd/nfs4recover.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
fs/nfsd/nfs4recover.c +11 -13
@@ -747,13 +747,11 @@ struct cld_upcall { };static int -__cld_pipe_upcall (struct rpc_pipe *pipe,void *cmsg) +__cld_pipe_upcall (struct rpc_pipe *pipe,void *cmsg,struct nfsd_net *nn) {int ret;struct rpc_pipe_msg msg; struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u); -struct nfsd_net *nn =net_generic (pipe->dentry->d_sb->s_fs_info, - nfsd_net_id);memset (&msg,0 ,sizeof (msg)); msg.data = cmsg;
@@ -773,7 +771,7 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) }static int -cld_pipe_upcall (struct rpc_pipe *pipe,void *cmsg) +cld_pipe_upcall (struct rpc_pipe *pipe,void *cmsg,struct nfsd_net *nn) {int ret;
@@ -782,7 +780,7 @@ cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)* upcalls queued. */ do { - ret =__cld_pipe_upcall (pipe, cmsg); + ret =__cld_pipe_upcall (pipe, cmsg, nn); }while (ret == -EAGAIN );return ret;
@@ -1115,7 +1113,7 @@ nfsd4_cld_create(struct nfs4_client *clp)memcpy (cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) { ret = cup->cu_u.cu_msg.cm_status;set_bit (NFSD4_CLIENT_STABLE , &clp->cl_flags);
@@ -1180,7 +1178,7 @@ nfsd4_cld_create_v2(struct nfs4_client *clp) }else cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len =0 ; - ret =cld_pipe_upcall (cn->cn_pipe, cmsg); + ret =cld_pipe_upcall (cn->cn_pipe, cmsg, nn);if (!ret) { ret = cmsg->cm_status;set_bit (NFSD4_CLIENT_STABLE , &clp->cl_flags);
@@ -1218,7 +1216,7 @@ nfsd4_cld_remove(struct nfs4_client *clp)memcpy (cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) { ret = cup->cu_u.cu_msg.cm_status;clear_bit (NFSD4_CLIENT_STABLE , &clp->cl_flags);
@@ -1261,7 +1259,7 @@ nfsd4_cld_check_v0(struct nfs4_client *clp)memcpy (cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) { ret = cup->cu_u.cu_msg.cm_status;set_bit (NFSD4_CLIENT_STABLE , &clp->cl_flags);
@@ -1404,7 +1402,7 @@ nfsd4_cld_grace_start(struct nfsd_net *nn) } cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart; - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) ret = cup->cu_u.cu_msg.cm_status;
@@ -1432,7 +1430,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn) cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time; - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) ret = cup->cu_u.cu_msg.cm_status;
@@ -1460,7 +1458,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn) } cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) ret = cup->cu_u.cu_msg.cm_status;
@@ -1524,7 +1522,7 @@ nfsd4_cld_get_version(struct nfsd_net *nn) goto out_err; } cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion; - ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg); + ret =cld_pipe_upcall (cn->cn_pipe, &cup->cu_u.cu_msg, nn);if (!ret) { ret = cup->cu_u.cu_msg.cm_status;if (ret)
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerPATCH 380/464 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
@@ -958,7 +958,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 381/464 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
@@ -314,7 +314,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 382/464 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 383/464 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
@@ -942,6 +942,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);
@@ -989,6 +990,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;
@@ -2286,8 +2288,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);
@@ -2393,7 +2398,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 384/464 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 385/464 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
@@ -3443,6 +3443,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)
@@ -3513,7 +3523,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; } }
@@ -3521,15 +3531,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);
@@ -3553,12 +3563,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 386/464 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 387/464 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
@@ -616,7 +616,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 ;
@@ -650,10 +652,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 388/464 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
@@ -500,7 +500,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 389/464 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
@@ -561,7 +561,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;
@@ -576,6 +576,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 390/464 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
@@ -1664,6 +1664,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
@@ -301,24 +301,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
@@ -3694,22 +3694,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 391/464 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
@@ -886,7 +886,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 392/464 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
@@ -316,6 +316,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 393/464 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 394/464 vsock: fix potential null pointer dereference in vsock_poll()
In reply to Greg Kroah-HartmanFrom: Stefano Garzarella <[email protected]>
[ Upstream commit 1980c05844830a44708c98c96d600833aa3fae08 ]
syzbot reported this issue where in the vsock_poll() we find the socket state at TCP_ESTABLISHED, but 'transport' is null:
general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097] CPU: 0 PID: 8227 Comm: syz-executor.2 Not tainted 5.8.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:vsock_poll+0x75a/0x8e0 net/vmw_vsock/af_vsock.c:1038 Call Trace: sock_poll+0x159/0x460 net/socket.c:1266 vfs_poll include/linux/poll.h:90 [inline] do_pollfd fs/select.c:869 [inline] do_poll fs/select.c:917 [inline] do_sys_poll+0x607/0xd40 fs/select.c:1011 __do_sys_poll fs/select.c:1069 [inline] __se_sys_poll fs/select.c:1057 [inline] __x64_sys_poll+0x18c/0x440 fs/select.c:1057 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9
This issue can happen if the TCP_ESTABLISHED state is set after we read the vsk->transport in the vsock_poll().
We could put barriers to synchronize, but this can only happen during connection setup, so we can simply check that 'transport' is valid.
--- net/vmw_vsock/af_vsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/vmw_vsock/af_vsock.c +1 -1
@@ -1032,7 +1032,7 @@ static __poll_t vsock_poll(struct file * }/* Connected sockets that can produce data can be written. */ -if (sk->sk_state ==TCP_ESTABLISHED ) { +if (transport && sk->sk_state ==TCP_ESTABLISHED ) {if (!(sk->sk_shutdown &SEND_SHUTDOWN )) {bool space_avail_now = false; int ret = transport->notify_poll_out(
Greg Kroah-Hartman
maintainerPATCH 395/464 net: phy: marvell10g: fix null pointer dereference
In reply to Greg Kroah-HartmanFrom: "Marek Behún" <[email protected]>
[ Upstream commit 1b8ef1423dbfd34de2439a2db457b84480b7c8a8 ]
Commit c3e302edca24 ("net: phy: marvell10g: fix temperature sensor on 2110") added a check for PHY ID via phydev->drv->phy_id in a function which is called by devres at a time when phydev->drv is already set to null by phy_remove function.
This null pointer dereference can be triggered via SFP subsystem with a SFP module containing this Marvell PHY. When the SFP interface is put down, the SFP subsystem removes the PHY.
--- drivers/net/phy/marvell10g.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/net/phy/marvell10g.c +7 -11
@@ -205,13 +205,6 @@ static int mv3310_hwmon_config(struct ph MV_V2_TEMP_CTRL_MASK, val); } -static void mv3310_hwmon_disable (void *data) -{ -struct phy_device *phydev = data; - -mv3310_hwmon_config (phydev, false); -} -static int mv3310_hwmon_probe (struct phy_device *phydev) {struct device *dev = &phydev->mdio.dev;
@@ -235,10 +228,6 @@ static int mv3310_hwmon_probe(struct phyif (ret)return ret; - ret =devm_add_action_or_reset (dev, mv3310_hwmon_disable, phydev); -if (ret) -return ret; - priv->hwmon_dev =devm_hwmon_device_register_with_info (dev, priv->hwmon_name, phydev, &mv3310_hwmon_chip_info,NULL );
@@ -423,6 +412,11 @@ static int mv3310_probe(struct phy_devicreturn phy_sfp_probe (phydev, &mv3310_sfp_ops); } +static void mv3310_remove (struct phy_device *phydev) +{ +mv3310_hwmon_config (phydev, false); +} +static int mv3310_suspend (struct phy_device *phydev) {return mv3310_power_down (phydev);
@@ -762,6 +756,7 @@ static struct phy_driver mv3310_drivers[ .read_status = mv3310_read_status, .get_tunable = mv3310_get_tunable, .set_tunable = mv3310_set_tunable, + .remove = mv3310_remove, }, { .phy_id = MARVELL_PHY_ID_88E2110,
@@ -776,6 +771,7 @@ static struct phy_driver mv3310_drivers[ .read_status = mv3310_read_status, .get_tunable = mv3310_get_tunable, .set_tunable = mv3310_set_tunable, + .remove = mv3310_remove, }, };
Greg Kroah-Hartman
maintainerPATCH 396/464 r8152: Use MAC address from correct device tree node
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit b9b40ee4db6cb186341b97bca4f0d7aa2a042a66 ]
Query the USB device's device tree node when looking for a MAC address. The struct device embedded into the struct net_device does not have a device tree node attached at all.
The reason why this went unnoticed is because the system where this was tested was one of the few development units that had its OTP programmed, as opposed to production systems where the MAC address is stored in a separate EEPROM and is passed via device tree by the firmware.
--- drivers/net/usb/r8152.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/r8152.c +1 -1
@@ -1504,7 +1504,7 @@ static int determine_ethernet_addr(struc sa->sa_family = dev->type; - ret =eth_platform_get_mac_address (&dev->dev, sa->sa_data); + ret =eth_platform_get_mac_address (&tp->udev->dev, sa->sa_data);if (ret <0 ) {if (tp->version ==RTL_VER_01 ) { ret =pla_ocp_read (tp,PLA_IDR ,8 , sa->sa_data);
Greg Kroah-Hartman
maintainerPATCH 397/464 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 398/464 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 399/464 usb: cdns3: gadget: always zeroed TRB buffer when enable endpoint
In reply to Greg Kroah-HartmanFrom: Peter Chen <[email protected]>
commit 95f5acfc4f58f01a22b66d8c9c0ffb72aa96271c upstream.
During the endpoint dequeue operation, it changes dequeued TRB as link TRB, when the endpoint is disabled and re-enabled, the DMA fetches the TRB before the link TRB, after it handles current TRB, the DMA pointer will advance to the TRB after link TRB, but enqueue and dequene variables don't know it due to no hardware interrupt at the time, when the next TRB is added to link TRB position, the DMA will not handle this TRB due to its pointer is already at the next TRB. See the trace log like below:
file-storage-675 [001] d..1 86.585657: usb_ep_queue: ep0: req 00000000df9b3a4f length 0/0 sgs 0/0 stream 0 zsI status 0 --> 0
file-storage-675 [001] d..1 86.585663: cdns3_ep_queue: ep1out: req: 000000002ebce364, req buff 00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr (null)], flags:0 SID: 0
file-storage-675 [001] d..1 86.585671: cdns3_prepare_trb: ep1out: trb 000000007f770303, dma buf: 0xbd195800, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0
file-storage-675 [001] d..1 86.585676: cdns3_ring:
Ring contents for ep1out:
Ring deq index: 0, trb: 000000007f770303 (virt), 0xc4003000 (dma)
Ring enq index: 1, trb: 0000000049c1ba21 (virt), 0xc400300c (dma)
free trbs: 38, CCS=1, PCS=1
@0x00000000c4003000 bd195800 80020400 00000425
@0x00000000c400300c c4003018 80020400 00001811
@0x00000000c4003018 bcfcc000 0000001f 00000426
@0x00000000c4003024 bcfce800 0000001f 00000426
... irq/144-5b13000-698 [000] d... 87.619286: usb_gadget_giveback_request: ep1in: req 0000000031b832eb length 13/13 sgs 0/0 stream 0 zsI status 0 --> 0
file-storage-675 [001] d..1 87.619287: cdns3_ep_queue: ep1out: req: 000000002ebce364, req buff 00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr 0x80020400c400300c], flags:0 SID: 0
file-storage-675 [001] d..1 87.619294: cdns3_prepare_trb: ep1out: trb 0000000049c1ba21, dma buf: 0xbd198000, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0
file-storage-675 [001] d..1 87.619297: cdns3_ring:
Ring contents for ep1out:
Ring deq index: 1, trb: 0000000049c1ba21 (virt), 0xc400300c (dma)
Ring enq index: 2, trb: 0000000059b34b67 (virt), 0xc4003018 (dma)
free trbs: 38, CCS=1, PCS=1
@0x00000000c4003000 bd195800 0000001f 00000427
@0x00000000c400300c bd198000 80020400 00000425
@0x00000000c4003018 bcfcc000 0000001f 00000426
@0x00000000c4003024 bcfce800 0000001f 00000426
...
file-storage-675 [001] d..1 87.619305: cdns3_doorbell_epx: ep1out, ep_trbaddr c4003018
file-storage-675 [001] .... 87.619308: usb_ep_queue: ep1out: req 000000002ebce364 length 0/1024 sgs 0/0 stream 0 zsI status -115 --> 0
irq/144-5b13000-698 [000] d..1 87.619315: cdns3_epx_irq: IRQ for ep1out: 01000c80 TRBERR , ep_traddr: c4003018 ep_last_sid: 00000000 use_streams: 0
irq/144-5b13000-698 [000] d..1 87.619395: cdns3_usb_irq: IRQ 00000008 = Hot Reset--- drivers/usb/cdns3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/cdns3/gadget.c +2 -1
@@ -242,9 +242,10 @@ int cdns3_allocate_trb_pool(struct cdns3return -ENOMEM ; priv_ep->alloc_ring_size = ring_size; -memset (priv_ep->trb_pool,0 , ring_size); } +memset (priv_ep->trb_pool,0 , ring_size); + priv_ep->num_trbs = num_trbs;if (!priv_ep->num)
Greg Kroah-Hartman
maintainerPATCH 400/464 iommu/vt-d: Skip TE disabling on quirky gfx dedicated iommu
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
commit b1012ca8dc4f9b1a1fe8e2cb1590dd6d43ea3849 upstream.
The VT-d spec requires (10.4.4 Global Command Register, TE field) that:
Hardware implementations supporting DMA draining must drain any in-flight DMA read/write requests queued within the Root-Complex before completing the translation enable command and reflecting the status of the command through the TES field in the Global Status register.
Unfortunately, some integrated graphic devices fail to do so after some kind of power state transition. As the result, the system might stuck in iommu_disable_translation(), waiting for the completion of TE transition.
This provides a quirk list for those devices and skips TE disabling if the qurik hits.
--- drivers/iommu/intel/dmar.c | 1 + drivers/iommu/intel/iommu.c | 27 +++++++++++++++++++++++++++ include/linux/dmar.h | 1 + include/linux/intel-iommu.h | 2 ++ 4 files changed, 31 insertions(+)
drivers/iommu/intel/dmar.c +1 -0
@@ -1102,6 +1102,7 @@ static int alloc_iommu(struct dmar_drhd_ } drhd->iommu = iommu; + iommu->drhd = drhd;return 0 ;
drivers/iommu/intel/iommu.c +27 -0
@@ -356,6 +356,7 @@ static int intel_iommu_strict;static int intel_iommu_superpage =1 ;static int iommu_identity_mapping;static int intel_no_bounce; +static int iommu_skip_te_disable;#define IDENTMAP_GFX 2#define IDENTMAP_AZALIA 4
@@ -1629,6 +1630,10 @@ static void iommu_disable_translation(stu32 sts;unsigned long flag; +if (iommu_skip_te_disable && iommu->drhd->gfx_dedicated && + (cap_read_drain (iommu->cap) ||cap_write_drain (iommu->cap))) +return ; +raw_spin_lock_irqsave (&iommu->register_lock, flag); iommu->gcmd &= ~DMA_GCMD_TE ;writel (iommu->gcmd, iommu->reg +DMAR_GCMD_REG );
@@ -4039,6 +4044,7 @@ static void __init init_no_remapping_dev/* This IOMMU has *only* gfx devices. Either bypass it or set the gfx_mapped flag, as appropriate */ + drhd->gfx_dedicated =1 ;if (!dmar_map_gfx) { drhd->ignored =1 ; for_each_active_dev_scope(drhd->devices,
@@ -6182,6 +6188,27 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IDECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x0062 , quirk_calpella_no_shadow_gtt);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x006a , quirk_calpella_no_shadow_gtt); +static void quirk_igfx_skip_te_disable (struct pci_dev *dev) +{ +unsigned short ver; + +if (!IS_GFX_DEVICE (dev)) +return ; + + ver = (dev->device >>8 ) &0xff ; +if (ver !=0x45 && ver !=0x46 && ver !=0x4c && + ver !=0x4e && ver !=0x8a && ver !=0x98 && + ver !=0x9a ) +return ; + +if (risky_device (dev)) +return ; + +pci_info (dev,"Skip IOMMU disabling for graphics\n" ); + iommu_skip_te_disable =1 ; +} +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,PCI_ANY_ID , quirk_igfx_skip_te_disable); +/* On Tylersburg chipsets, some BIOSes have been known to enable the ISOCH DMAR unit for the Azalia sound device, but not give it any TLB entries, which causes it to deadlock. Check for that. We do
include/linux/dmar.h +1 -0
@@ -48,6 +48,7 @@ struct dmar_drhd_unit {u16 segment;/* PCI domain */ u8 ignored:1; /* ignore drhd */ u8 include_all:1; + u8 gfx_dedicated:1; /* graphic dedicated */struct intel_iommu *iommu; };
include/linux/intel-iommu.h +2 -0
@@ -600,6 +600,8 @@ struct intel_iommu {struct iommu_device iommu;/* IOMMU core code handle */ int node;u32 flags;/* Software defined flags */ + +struct dmar_drhd_unit *drhd; };/* PCI domain-device relationship */
Greg Kroah-Hartman
maintainerPATCH 401/464 vdpasim: protect concurrent access to iommu iotlb
In reply to Greg Kroah-HartmanFrom: Max Gurtovoy <[email protected]>
commit 0ea9ee430e74b16c6b17e70757d1c26d8d140e1f upstream.
Iommu iotlb can be accessed by different cores for performing IO using multiple virt queues. Add a spinlock to synchronize iotlb accesses.
This could be easily reproduced when using more than 1 pktgen threads to inject traffic to vdpa simulator.
--- drivers/vdpa/vdpa_sim/vdpa_sim.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
drivers/vdpa/vdpa_sim/vdpa_sim.c +27 -4
@@ -70,6 +70,8 @@ struct vdpasim {u32 status;u32 generation;u64 features; +/* spinlock to synchronize iommu table */ +spinlock_t iommu_lock; };static struct vdpasim *vdpasim_dev;
@@ -118,7 +120,9 @@ static void vdpasim_reset(struct vdpasimfor (i =0 ; i <VDPASIM_VQ_NUM ; i++)vdpasim_vq_reset (&vdpasim->vqs[i]); +spin_lock (&vdpasim->iommu_lock);vhost_iotlb_reset (vdpasim->iommu); +spin_unlock (&vdpasim->iommu_lock); vdpasim->features =0 ; vdpasim->status =0 ;
@@ -236,8 +240,10 @@ static dma_addr_t vdpasim_map_page(struc/* For simplicity, use identical mapping to avoid e.g iova * allocator. */ +spin_lock (&vdpasim->iommu_lock); ret =vhost_iotlb_add_range (iommu, pa, pa + size -1 , pa,dir_to_perm (dir)); +spin_unlock (&vdpasim->iommu_lock);if (ret)return DMA_MAPPING_ERROR ;
@@ -251,8 +257,10 @@ static void vdpasim_unmap_page(struct destruct vdpasim *vdpasim =dev_to_sim (dev);struct vhost_iotlb *iommu = vdpasim->iommu; +spin_lock (&vdpasim->iommu_lock);vhost_iotlb_del_range (iommu, (u64 )dma_addr, (u64 )dma_addr + size -1 ); +spin_unlock (&vdpasim->iommu_lock); } static void *vdpasim_alloc_coherent(struct device *dev, size_t size,
@@ -264,9 +272,10 @@ static void *vdpasim_alloc_coherent(struvoid *addr =kmalloc (size, flag);int ret; -if (!addr) +spin_lock (&vdpasim->iommu_lock); +if (!addr) { *dma_addr =DMA_MAPPING_ERROR ; -else { + }else {u64 pa =virt_to_phys (addr); ret = vhost_iotlb_add_range(iommu, (u64)pa,
@@ -279,6 +288,7 @@ static void *vdpasim_alloc_coherent(stru }else *dma_addr = (dma_addr_t )pa; } +spin_unlock (&vdpasim->iommu_lock);return addr; }
@@ -290,8 +300,11 @@ static void vdpasim_free_coherent(structstruct vdpasim *vdpasim =dev_to_sim (dev);struct vhost_iotlb *iommu = vdpasim->iommu; +spin_lock (&vdpasim->iommu_lock);vhost_iotlb_del_range (iommu, (u64 )dma_addr, (u64 )dma_addr + size -1 ); +spin_unlock (&vdpasim->iommu_lock); +kfree (phys_to_virt ((uintptr_t )dma_addr)); }
@@ -532,6 +545,7 @@ static int vdpasim_set_map(struct vdpa_du64 start =0ULL , last =0ULL -1 ;int ret; +spin_lock (&vdpasim->iommu_lock);vhost_iotlb_reset (vdpasim->iommu); for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
@@ -541,10 +555,12 @@ static int vdpasim_set_map(struct vdpa_dif (ret) goto err; } +spin_unlock (&vdpasim->iommu_lock);return 0 ; err:vhost_iotlb_reset (vdpasim->iommu); +spin_unlock (&vdpasim->iommu_lock);return ret; }
@@ -552,16 +568,23 @@ static int vdpasim_dma_map(struct vdpa_d u64 pa, u32 perm) {struct vdpasim *vdpasim =vdpa_to_sim (vdpa); +int ret; -return vhost_iotlb_add_range (vdpasim->iommu, iova, - iova + size -1 , pa, perm); +spin_lock (&vdpasim->iommu_lock); + ret =vhost_iotlb_add_range (vdpasim->iommu, iova, iova + size -1 , pa, + perm); +spin_unlock (&vdpasim->iommu_lock); + +return ret; }static int vdpasim_dma_unmap (struct vdpa_device *vdpa,u64 iova,u64 size) {struct vdpasim *vdpasim =vdpa_to_sim (vdpa); +spin_lock (&vdpasim->iommu_lock);vhost_iotlb_del_range (vdpasim->iommu, iova, iova + size -1 ); +spin_unlock (&vdpasim->iommu_lock);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 402/464 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
@@ -4426,6 +4426,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 403/464 ALSA: hda - reverse the setting value in the micmute_led_set
In reply to Greg Kroah-HartmanFrom: Hui Wang <[email protected]>
commit 404690649e6a52ee39817168f2d984726412e091 upstream.
Before the micmute_led_set() is introduced, the function of alc_gpio_micmute_update() will set the gpio value with the !micmute_led.led_value, and the machines have the correct micmute led status. After the micmute_led_set() is introduced, it sets the gpio value with !!micmute_led.led_value, so the led status is not correct anymore, we need to set micmute_led_polarity = 1 to workaround it.
Now we fix the micmute_led_set() and remove micmute_led_polarity = 1.
--- sound/pci/hda/patch_realtek.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
sound/pci/hda/patch_realtek.c +1 -4
@@ -4118,7 +4118,7 @@ static int micmute_led_set(struct led_clstruct alc_spec *spec = codec->spec;alc_update_gpio_led (codec, spec->gpio_mic_led_mask, - spec->micmute_led_polarity, !!brightness); + spec->micmute_led_polarity, !brightness);return 0 ; }
@@ -4173,8 +4173,6 @@ static void alc285_fixup_hp_gpio_led(str {struct alc_spec *spec = codec->spec; - spec->micmute_led_polarity =1 ; -alc_fixup_hp_gpio_led (codec, action,0x04 ,0x01 ); }
@@ -4426,7 +4424,6 @@ 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 404/464 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
@@ -185,6 +185,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 405/464 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
@@ -3645,7 +3645,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 406/464 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
@@ -137,6 +137,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
@@ -1420,6 +1420,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
@@ -1495,6 +1495,9 @@ void snd_usb_set_format_quirk(struct sndcase USB_ID (0x2b73 ,0x000a ):/* Pioneer DJ DJM-900NXS2 */ pioneer_djm_set_format_quirk (subs);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 407/464 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
@@ -3541,6 +3541,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 408/464 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
@@ -59,6 +59,9 @@ enum tpm_addr {#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;
@@ -228,7 +231,7 @@ unsigned long tpm2_calc_ordinal_durationint tpm2_probe (struct tpm_chip *chip);int tpm2_get_cc_attrs_tbl (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
@@ -96,6 +96,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 409/464 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
@@ -269,6 +269,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);
@@ -668,7 +671,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 410/464 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 411/464 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 412/464 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 413/464 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 skcint 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 414/464 tick/nohz: Narrow down noise while setting current tasks tick dependency
In reply to Greg Kroah-HartmanFrom: Frederic Weisbecker <[email protected]>
commit 3c8920e2dbd1a55f72dc14d656df9d0097cf5c72 upstream.
Setting a tick dependency on any task, including the case where a task sets that dependency on itself, triggers an IPI to all CPUs. That is of course suboptimal but it had previously not been an issue because it was only used by POSIX CPU timers on nohz_full, which apparently never occurs in latency-sensitive workloads in production. (Or users of such systems are suffering in silence on the one hand or venting their ire on the wrong people on the other.)
But RCU now sets a task tick dependency on the current task in order to fix stall issues that can occur during RCU callback processing. Thus, RCU callback processing triggers frequent system-wide IPIs from nohz_full CPUs. This is quite counter-productive, after all, avoiding IPIs is what nohz_full is supposed to be all about.
This commit therefore optimizes tasks' self-setting of a task tick dependency by using tick_nohz_full_kick() to avoid the system-wide IPI. Instead, only the execution of the one task is disturbed, which is acceptable given that this disturbance is well down into the noise compared to the degree to which the RCU callback processing itself disturbs execution.
--- kernel/time/tick-sched.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
kernel/time/tick-sched.c +15 -7
@@ -351,16 +351,24 @@ void tick_nohz_dep_clear_cpu(int cpu, enEXPORT_SYMBOL_GPL (tick_nohz_dep_clear_cpu);/* -* Set a per-task tick dependency. Posix CPU timers need this in order to elapse -* per task timers. +* Set a per-task tick dependency. RCU need this. Also posix CPU timers +* in order to elapse per task timers. */ void tick_nohz_dep_set_task (struct task_struct *tsk,enum tick_dep_bits bit) { -/* -* We could optimize this with just kicking the target running the task -* if that noise matters for nohz full users. -*/ -tick_nohz_dep_set_all (&tsk->tick_dep_mask, bit); +if (!atomic_fetch_or (BIT (bit), &tsk->tick_dep_mask)) { +if (tsk == current) { +preempt_disable (); +tick_nohz_full_kick (); +preempt_enable (); + }else { +/* +* Some future tick_nohz_full_kick_task() +* should optimize this. +*/ +tick_nohz_full_kick_all (); + } + } }EXPORT_SYMBOL_GPL (tick_nohz_dep_set_task);
Greg Kroah-Hartman
maintainerPATCH 415/464 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
@@ -77,7 +77,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 416/464 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 417/464 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 418/464 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 419/464 kvm: x86: replace kvm_spec_ctrl_test_value with runtime test on the host
In reply to Greg Kroah-HartmanFrom: Maxim Levitsky <[email protected]>
commit 841c2be09fe4f495fe5224952a419bd8c7e5b455 upstream.
To avoid complex and in some cases incorrect logic in kvm_spec_ctrl_test_value, just try the guest's given value on the host processor instead, and if it doesn't #GP, allow the guest to set it.
One such case is when host CPU supports STIBP mitigation but doesn't support IBRS (as is the case with some Zen2 AMD cpus), and in this case we were giving guest #GP when it tried to use STIBP
The reason why can can do the host test is that IA32_SPEC_CTRL msr is passed to the guest, after the guest sets it to a non zero value for the first time (due to performance reasons),
and as as result of this, it is pointless to emulate #GP condition on this first access, in a different way than what the host CPU does.
This is based on a patch from Sean Christopherson, who suggested this idea.
Message-Id: <[email protected]>
--- arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 2 +- arch/x86/kvm/x86.c | 40 ++++++++++++++++++++++------------------ arch/x86/kvm/x86.h | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-)
arch/x86/kvm/svm/svm.c +1 -1
@@ -2522,7 +2522,7 @@ static int svm_set_msr(struct kvm_vcpu * !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD))return 1 ; -if (data & ~kvm_spec_ctrl_valid_bits (vcpu)) +if (kvm_spec_ctrl_test_value (data))return 1 ; svm->spec_ctrl = data;
arch/x86/kvm/vmx/vmx.c +1 -1
@@ -2062,7 +2062,7 @@ static int vmx_set_msr(struct kvm_vcpu * !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))return 1 ; -if (data & ~kvm_spec_ctrl_valid_bits (vcpu)) +if (kvm_spec_ctrl_test_value (data))return 1 ; vmx->spec_ctrl = data;
arch/x86/kvm/x86.c +22 -18
@@ -10676,28 +10676,32 @@ bool kvm_arch_no_poll(struct kvm_vcpu *v }EXPORT_SYMBOL_GPL (kvm_arch_no_poll); -u64 kvm_spec_ctrl_valid_bits (struct kvm_vcpu *vcpu) + +int kvm_spec_ctrl_test_value (u64 value) { -uint64_t bits =SPEC_CTRL_IBRS |SPEC_CTRL_STIBP |SPEC_CTRL_SSBD ; +/* +* test that setting IA32_SPEC_CTRL to given value +* is allowed by the host processor +*/ + +u64 saved_value; +unsigned long flags; +int ret =0 ; + +local_irq_save (flags); + +if (rdmsrl_safe (MSR_IA32_SPEC_CTRL , &saved_value)) + ret =1 ; +else if (wrmsrl_safe (MSR_IA32_SPEC_CTRL , value)) + ret =1 ; +else +wrmsrl (MSR_IA32_SPEC_CTRL , saved_value); -/* The STIBP bit doesn't fault even if it's not advertised */ -if (!guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBRS )) - bits &= ~(SPEC_CTRL_IBRS |SPEC_CTRL_STIBP ); -if (!boot_cpu_has (X86_FEATURE_SPEC_CTRL ) && - !boot_cpu_has (X86_FEATURE_AMD_IBRS )) - bits &= ~(SPEC_CTRL_IBRS |SPEC_CTRL_STIBP ); - -if (!guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL_SSBD ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_SSBD )) - bits &= ~SPEC_CTRL_SSBD ; -if (!boot_cpu_has (X86_FEATURE_SPEC_CTRL_SSBD ) && - !boot_cpu_has (X86_FEATURE_AMD_SSBD )) - bits &= ~SPEC_CTRL_SSBD ; +local_irq_restore (flags); -return bits; +return ret; } -EXPORT_SYMBOL_GPL (kvm_spec_ctrl_valid_bits); +EXPORT_SYMBOL_GPL (kvm_spec_ctrl_test_value);EXPORT_TRACEPOINT_SYMBOL_GPL (kvm_exit);EXPORT_TRACEPOINT_SYMBOL_GPL (kvm_fast_mmio);
arch/x86/kvm/x86.h +1 -1
@@ -363,7 +363,7 @@ static inline bool kvm_dr7_valid(u64 datvoid kvm_load_guest_xsave_state (struct kvm_vcpu *vcpu);void kvm_load_host_xsave_state (struct kvm_vcpu *vcpu); -u64 kvm_spec_ctrl_valid_bits (struct kvm_vcpu *vcpu); +int kvm_spec_ctrl_test_value (u64 value);bool kvm_vcpu_exit_request (struct kvm_vcpu *vcpu);#endif
Greg Kroah-Hartman
maintainerPATCH 420/464 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 421/464 driver core: Fix probe_count imbalance in really_probe()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
commit b292b50b0efcc7095d8bf15505fba6909bb35dce upstream.
syzbot is reporting hung task in wait_for_device_probe() [1]. At least, we always need to decrement probe_count if we incremented probe_count in really_probe().
However, since I can't find "Resources present before probing" message in the console log, both "this message simply flowed off" and "syzbot is not hitting this path" will be possible. Therefore, while we are at it, let's also prepare for concurrent wait_for_device_probe() calls by replacing wake_up() with wake_up_all().
[1] https://syzkaller.appspot.com/bug?id=25c833f1983c9c1d512f4ff860dd0d7f5a2e2c0f
--- drivers/base/dd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/base/dd.c +4 -3
@@ -276,7 +276,7 @@ static void deferred_probe_timeout_work_list_for_each_entry_safe (private, p, &deferred_probe_pending_list, deferred_probe)dev_info (private->device,"deferred probe pending\n" ); -wake_up (&probe_timeout_waitqueue); +wake_up_all (&probe_timeout_waitqueue); } static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);
@@ -487,7 +487,8 @@ static int really_probe(struct device *d drv->bus->name, __func__, drv->name, dev_name(dev));if (!list_empty (&dev->devres_head)) {dev_crit (dev,"Resources present before probing\n" ); -return -EBUSY ; + ret = -EBUSY ; + goto done; } re_probe:
@@ -607,7 +608,7 @@ pinctrl_bind_failed: ret =0 ; done:atomic_dec (&probe_count); -wake_up (&probe_waitqueue); +wake_up_all (&probe_waitqueue);return ret; }
Greg Kroah-Hartman
maintainerPATCH 422/464 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 423/464 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
@@ -242,7 +242,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 ; }
@@ -266,7 +265,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 ; }
@@ -288,7 +286,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 424/464 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
@@ -7834,6 +7834,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 ;
@@ -7850,8 +7854,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 425/464 io_uring: use TWA_SIGNAL for task_work uncondtionally
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 0ba9c9edcd152158a0e321a4c13ac1dfc571ff3d upstream.
An earlier commit:
b7db41c9e03b ("io_uring: fix regression with always ignoring signals in io_cqring_wait()")
ensured that we didn't get stuck waiting for eventfd reads when it's registered with the io_uring ring for event notification, but we still have cases where the task can be waiting on other events in the kernel and need a bigger nudge to make forward progress. Or the task could be in the kernel and running, but on its way to blocking.
This means that TWA_RESUME cannot reliably be used to ensure we make progress. Use TWA_SIGNAL unconditionally.
--- fs/io_uring.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
fs/io_uring.c +8 -8
@@ -4100,22 +4100,22 @@ static int io_req_task_work_add(struct i {struct task_struct *tsk = req->task;struct io_ring_ctx *ctx = req->ctx; -int ret, notify =TWA_RESUME ; +int ret, notify;/* -* SQPOLL kernel thread doesn't need notification, just a wakeup. -* If we're not using an eventfd, then TWA_RESUME is always fine, -* as we won't have dependencies between request completions for -* other kernel wait conditions. +* SQPOLL kernel thread doesn't need notification, just a wakeup. For +* all other cases, use TWA_SIGNAL unconditionally to ensure we're +* processing task_work. There's no reliable way to tell if TWA_RESUME +* will do the job. */ -if (ctx->flags &IORING_SETUP_SQPOLL ) - notify =0 ; -else if (ctx->cq_ev_fd) + notify =0 ; +if (!(ctx->flags &IORING_SETUP_SQPOLL )) notify =TWA_SIGNAL ; ret =task_work_add (tsk, cb, notify);if (!ret)wake_up_process (tsk); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 426/464 io_uring: fail poll arm on queue proc failure
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit a36da65c46565d2527eec3efdb546251e38253fd upstream.
Check the ipt.error value, it must have been either cleared to zero or set to another error than the default -EINVAL if we don't go through the waitqueue proc addition. Just give up on poll at that point and return failure, this will fallback to async work.
io_poll_add() doesn't suffer from this failure case, as it returns the error value directly.
--- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/io_uring.c +1 -1
@@ -4483,7 +4483,7 @@ static bool io_arm_poll_handler(struct i ret =__io_arm_poll_handler (req, &apoll->poll, &ipt, mask, io_async_wake); -if (ret) { +if (ret || ipt.error) {io_poll_remove_double (req, apoll->double_poll);spin_unlock_irq (&ctx->completion_lock);if (req->flags &REQ_F_WORK_INITIALIZED )
Greg Kroah-Hartman
maintainerPATCH 427/464 io_uring: sanitize double poll handling
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit d4e7cd36a90e38e0276d6ce0c20f5ccef17ec38c upstream.
There's a bit of confusion on the matching pairs of poll vs double poll, depending on if the request is a pure poll (IORING_OP_POLL_ADD) or poll driven retry.
Add io_poll_get_double() that returns the double poll waitqueue, if any, and io_poll_get_single() that returns the original poll waitqueue. With that, remove the argument to io_poll_remove_double().
Finally ensure that wait->private is cleared once the double poll handler has run, so that remove knows it's already been seen.
--- fs/io_uring.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-)
fs/io_uring.c +25 -9
@@ -4172,9 +4172,24 @@ static bool io_poll_rewait(struct io_kioreturn false; } -static void io_poll_remove_double (struct io_kiocb *req,void *data) +static struct io_poll_iocb *io_poll_get_double (struct io_kiocb *req) { -struct io_poll_iocb *poll = data; +/* pure poll stashes this in ->io, poll driven retry elsewhere */ +if (req->opcode ==IORING_OP_POLL_ADD ) +return (struct io_poll_iocb *) req->io; +return req->apoll->double_poll; +} + +static struct io_poll_iocb *io_poll_get_single (struct io_kiocb *req) +{ +if (req->opcode ==IORING_OP_POLL_ADD ) +return &req->poll; +return &req->apoll->poll; +} + +static void io_poll_remove_double (struct io_kiocb *req) +{ +struct io_poll_iocb *poll =io_poll_get_double (req);lockdep_assert_held (&req->ctx->completion_lock);
@@ -4194,7 +4209,7 @@ static void io_poll_complete(struct io_k {struct io_ring_ctx *ctx = req->ctx; -io_poll_remove_double (req, req->io); +io_poll_remove_double (req); req->poll.done = true;io_cqring_fill_event (req, error ? error :mangle_poll (mask));io_commit_cqring (ctx);
@@ -4236,7 +4251,7 @@ static int io_poll_double_wake(struct wa int sync, void *key) { struct io_kiocb *req = wait->private; -struct io_poll_iocb *poll = req->apoll->double_poll; +struct io_poll_iocb *poll =io_poll_get_single (req);__poll_t mask =key_to_poll (key);/* for instances that support it check for an event match first: */
@@ -4250,6 +4265,8 @@ static int io_poll_double_wake(struct wa done =list_empty (&poll->wait.entry);if (!done)list_del_init (&poll->wait.entry); +/* make sure double remove sees this as being gone */ + wait->private =NULL ;spin_unlock (&poll->head->lock);if (!done)__io_async_wake (req, poll, mask, io_poll_task_func);
@@ -4358,7 +4375,7 @@ static void io_async_task_func(struct ca } } -io_poll_remove_double (req, apoll->double_poll); +io_poll_remove_double (req);spin_unlock_irq (&ctx->completion_lock);/* restore ->work in case we need to retry again */
@@ -4484,7 +4501,7 @@ static bool io_arm_poll_handler(struct i ret =__io_arm_poll_handler (req, &apoll->poll, &ipt, mask, io_async_wake);if (ret || ipt.error) { -io_poll_remove_double (req, apoll->double_poll); +io_poll_remove_double (req);spin_unlock_irq (&ctx->completion_lock);if (req->flags &REQ_F_WORK_INITIALIZED )memcpy (&req->work, &apoll->work,sizeof (req->work));
@@ -4518,14 +4535,13 @@ static bool io_poll_remove_one(struct io {bool do_complete; +io_poll_remove_double (req); +if (req->opcode ==IORING_OP_POLL_ADD ) { -io_poll_remove_double (req, req->io); do_complete =__io_poll_remove_one (req, &req->poll); }else {struct async_poll *apoll = req->apoll; -io_poll_remove_double (req, apoll->double_poll); -/* non-poll requests have submit ref still */ do_complete =__io_poll_remove_one (req, &apoll->poll);if (do_complete) {
Greg Kroah-Hartman
maintainerPATCH 428/464 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
@@ -2392,16 +2392,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
@@ -2438,7 +2428,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 429/464 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
@@ -1226,31 +1226,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 430/464 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
@@ -621,6 +621,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 ))
@@ -640,28 +658,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); }/**
@@ -815,12 +819,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;
@@ -1058,15 +1064,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 ; }
@@ -1089,7 +1097,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 431/464 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 432/464 MIPS: VZ: Only include loongson_regs.h for CPU_LOONGSON64
In reply to Greg Kroah-HartmanFrom: Huacai Chen <[email protected]>
commit cf99c505cf7a5b6d3deee91e3571871f20320d31 upstream.
Only Loongson64 platform has and needs loongson_regs.h, including it unconditionally will cause build errors.
Message-Id: <[email protected]>
--- arch/mips/kvm/vz.c | 2 ++ 1 file changed, 2 insertions(+)
arch/mips/kvm/vz.c +2 -0
@@ -29,7 +29,9 @@#include <linux/kvm_host.h> #include "interrupt.h" +#ifdef CONFIG_CPU_LOONGSON64 #include "loongson_regs.h" +#endif #include "trace.h"
Greg Kroah-Hartman
maintainerPATCH 433/464 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
@@ -375,6 +375,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 434/464 PM / devfreq: rk3399_dmc: Fix kernel oops when rockchip,pmu is absent
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit 63ef91f24f9bfc70b6446319f6cabfd094481372 upstream.
Booting a recent kernel on a rk3399-based system (nanopc-t4), equipped with a recent u-boot and ATF results in an Oops due to a NULL pointer dereference.
This turns out to be due to the rk3399-dmc driver looking for an *undocumented* property (rockchip,pmu), and happily using a NULL pointer when the property isn't there.
Instead, make most of what was brought in with 9173c5ceb035 ("PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.") conditioned on finding this property in the device-tree, preventing the driver from exploding.
--- drivers/devfreq/rk3399_dmc.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
drivers/devfreq/rk3399_dmc.c +23 -19
@@ -95,18 +95,20 @@ static int rk3399_dmcfreq_target(structmutex_lock (&dmcfreq->lock); -if (target_rate >= dmcfreq->odt_dis_freq) - odt_enable = true; - -/* -* This makes a SMC call to the TF-A to set the DDR PD (power-down) -* timings and to enable or disable the ODT (on-die termination) -* resistors. -*/ -arm_smccc_smc (ROCKCHIP_SIP_DRAM_FREQ , dmcfreq->odt_pd_arg0, - dmcfreq->odt_pd_arg1, -ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD , - odt_enable,0 ,0 ,0 , &res); +if (dmcfreq->regmap_pmu) { +if (target_rate >= dmcfreq->odt_dis_freq) + odt_enable = true; + +/* +* This makes a SMC call to the TF-A to set the DDR PD +* (power-down) timings and to enable or disable the +* ODT (on-die termination) resistors. +*/ +arm_smccc_smc (ROCKCHIP_SIP_DRAM_FREQ , dmcfreq->odt_pd_arg0, + dmcfreq->odt_pd_arg1, +ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD , + odt_enable,0 ,0 ,0 , &res); + }/* * If frequency scaling from low to high, adjust voltage first.
@@ -371,13 +373,14 @@ static int rk3399_dmcfreq_probe(struct p } node =of_parse_phandle (np,"rockchip,pmu" ,0 ); -if (node) { - data->regmap_pmu =syscon_node_to_regmap (node); -of_node_put (node); -if (IS_ERR (data->regmap_pmu)) { - ret =PTR_ERR (data->regmap_pmu); - goto err_edev; - } +if (!node) + goto no_pmu; + + data->regmap_pmu =syscon_node_to_regmap (node); +of_node_put (node); +if (IS_ERR (data->regmap_pmu)) { + ret =PTR_ERR (data->regmap_pmu); + goto err_edev; }regmap_read (data->regmap_pmu,RK3399_PMUGRF_OS_REG2 , &val);
@@ -399,6 +402,7 @@ static int rk3399_dmcfreq_probe(struct p goto err_edev; }; +no_pmu:arm_smccc_smc (ROCKCHIP_SIP_DRAM_FREQ ,0 ,0 ,ROCKCHIP_SIP_CONFIG_DRAM_INIT ,0 ,0 ,0 ,0 , &res);
Greg Kroah-Hartman
maintainerPATCH 435/464 PM / devfreq: Fix indentaion of devfreq_summary debugfs node
In reply to Greg Kroah-HartmanFrom: Chanwoo Choi <[email protected]>
commit 0aae11bcdefb4894b6100656ad24cbd85ff34b52 upstream.
The commit 66d0e797bf09 ("Revert "PM / devfreq: Modify the device name as devfreq(X) for sysfs"") roll back the device name from 'devfreqX' to device name explained in DT. After applied commit 66d0e797bf09, the indentation of devfreq_summary debugfs node was broken.
So, fix indentaion of devfreq_summary debugfs node as following:
For example on Exynos5422-based Odroid-XU3 board,
$ cat /sys/kernel/debug/devfreq/devfreq_summary dev parent_dev governor polling_ms cur_freq_Hz min_freq_Hz max_freq_Hz ------------------------------ ------------------------------ --------------- ---------- ------------ ------------ ------------ 10c20000.memory-controller null simple_ondemand 0 413000000 165000000 825000000 soc:bus_wcore null simple_ondemand 50 88700000 88700000 532000000 soc:bus_noc soc:bus_wcore passive 0 66600000 66600000 111000000 soc:bus_fsys_apb soc:bus_wcore passive 0 111000000 111000000 222000000 soc:bus_fsys soc:bus_wcore passive 0 75000000 75000000 200000000 soc:bus_fsys2 soc:bus_wcore passive 0 75000000 75000000 200000000 soc:bus_mfc soc:bus_wcore passive 0 83250000 83250000 333000000 soc:bus_gen soc:bus_wcore passive 0 88700000 88700000 266000000 soc:bus_peri soc:bus_wcore passive 0 66600000 66600000 66600000 soc:bus_g2d soc:bus_wcore passive 0 83250000 83250000 333000000 soc:bus_g2d_acp soc:bus_wcore passive 0 0 66500000 266000000 soc:bus_jpeg soc:bus_wcore passive 0 0 75000000 300000000 soc:bus_jpeg_apb soc:bus_wcore passive 0 0 83250000 166500000 soc:bus_disp1_fimd soc:bus_wcore passive 0 0 120000000 200000000 soc:bus_disp1 soc:bus_wcore passive 0 0 120000000 300000000 soc:bus_gscl_scaler soc:bus_wcore passive 0 0 150000000 300000000 soc:bus_mscl soc:bus_wcore passive 0 0 84000000 666000000
--- drivers/devfreq/devfreq.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/devfreq/devfreq.c +4 -7
@@ -1657,8 +1657,7 @@ static int devfreq_summary_show(struct sunsigned long cur_freq, min_freq, max_freq;unsigned int polling_ms; - seq_printf(s, "%-30s %-10s %-10s %-15s %10s %12s %12s %12s\n", - "dev_name", + seq_printf(s, "%-30s %-30s %-15s %10s %12s %12s %12s\n", "dev", "parent_dev", "governor",
@@ -1666,10 +1665,9 @@ static int devfreq_summary_show(struct s"cur_freq_Hz" ,"min_freq_Hz" , "max_freq_Hz"); - seq_printf(s, "%30s %10s %10s %15s %10s %12s %12s %12s\n", + seq_printf(s, "%30s %30s %15s %10s %12s %12s %12s\n", + "------------------------------", "------------------------------", - "----------", - "----------", "---------------", "----------", "------------",
@@ -1698,8 +1696,7 @@ static int devfreq_summary_show(struct smutex_unlock (&devfreq->lock); seq_printf(s, - "%-30s %-10s %-10s %-15s %10d %12ld %12ld %12ld\n", - dev_name(devfreq->dev.parent), + "%-30s %-30s %-15s %10d %12ld %12ld %12ld\n", dev_name(&devfreq->dev), p_devfreq ? dev_name(&p_devfreq->dev) : "null", devfreq->governor_name,
Greg Kroah-Hartman
maintainerPATCH 436/464 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
@@ -224,6 +224,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;
@@ -239,17 +244,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;
@@ -259,7 +264,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;
@@ -293,16 +298,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 437/464 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; };
@@ -2774,7 +2776,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 );
@@ -3035,12 +3038,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 438/464 mtd: spi-nor: intel-spi: Simulate WRDI command
In reply to Greg Kroah-HartmanFrom: Alexander Sverdlin <[email protected]>
commit 44a80df4bfce02f5d51fe5040bdbdf10d0d78f4e upstream.
After spi_nor_write_disable() return code checks were introduced in the spi-nor front end intel-spi backend stopped to work because WRDI was never supported and always failed.
Just pretend it was sucessful and ignore the command itself. HW sequencer shall do the right thing automatically, while with SW sequencer we cannot do it anyway, because the only tool we had was preopcode and it makes no sense for WRDI.
--- drivers/mtd/spi-nor/controllers/intel-spi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/mtd/spi-nor/controllers/intel-spi.c +9 -0
@@ -612,6 +612,15 @@ static int intel_spi_write_reg(struct spreturn 0 ; } +/* +* We hope that HW sequencer will do the right thing automatically and +* with the SW sequencer we cannot use preopcode anyway, so just ignore +* the Write Disable operation and pretend it was completed +* successfully. +*/ +if (opcode ==SPINOR_OP_WRDI ) +return 0 ; +writel (0 , ispi->base +FADDR );/* Write the value beforehand */
Greg Kroah-Hartman
maintainerPATCH 439/464 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 440/464 Revert "mm/vmstat.c: do not show lowmem reserve protection information of empty zone"
In reply to Greg Kroah-HartmanFrom: Baoquan He <[email protected]>
commit a8a4b7aeaf841311cb13ff0f6c4710c7a00e68d4 upstream.
This reverts commit 26e7deadaae175.
Sonny reported that one of their tests started failing on the latest kernel on their Chrome OS platform. The root cause is that the above commit removed the protection line of empty zone, while the parser used in the test relies on the protection line to mark the end of each zone.
Let's revert it to avoid breaking userspace testing or applications.
--- mm/vmstat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
mm/vmstat.c +6 -6
@@ -1596,12 +1596,6 @@ static void zoneinfo_show_print(struct s zone->present_pages, zone_managed_pages(zone)); -/* If unpopulated, no other information is useful */ -if (!populated_zone (zone)) { -seq_putc (m,'\n' ); -return ; - } -seq_printf (m,"\n protection: (%ld" , zone->lowmem_reserve[0 ]);
@@ -1609,6 +1603,12 @@ static void zoneinfo_show_print(struct sseq_printf (m,", %ld" , zone->lowmem_reserve[i]);seq_putc (m,')' ); +/* If unpopulated, no other information is useful */ +if (!populated_zone (zone)) { +seq_putc (m,'\n' ); +return ; + } +for (i =0 ; i <NR_VM_ZONE_STAT_ITEMS ; i++)seq_printf (m,"\n %-12s %lu" ,zone_stat_name (i),zone_page_state (zone, i));
Greg Kroah-Hartman
maintainerPATCH 441/464 Revert "parisc: Improve interrupt handling in arch_spin_lock_flags()"
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 3d05b8aebc5f10ee3ab129b61100196855dd7249 upstream.
This reverts commit 2772f0efd5bbd5413db3d22e363b779ca0fa5310. It turns out that we want to implement the spinlock code differently.
--- arch/parisc/include/asm/spinlock.h | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-)
arch/parisc/include/asm/spinlock.h +8 -17
@@ -10,34 +10,25 @@static inline int arch_spin_is_locked (arch_spinlock_t *x) {volatile unsigned int *a =__ldcw_align (x); -smp_mb ();return *a ==0 ; } -static inline void arch_spin_lock (arch_spinlock_t *x) -{ -volatile unsigned int *a; - - a =__ldcw_align (x); -while (__ldcw (a) ==0 ) -while (*a ==0 ) -cpu_relax (); -} +#define arch_spin_lock (lock) arch_spin_lock_flags(lock, 0)static inline void arch_spin_lock_flags (arch_spinlock_t *x,unsigned long flags) {volatile unsigned int *a; -unsigned long flags_dis; a =__ldcw_align (x); -while (__ldcw (a) ==0 ) { -local_save_flags (flags_dis); -local_irq_restore (flags); +while (__ldcw (a) ==0 )while (*a ==0 ) -cpu_relax (); -local_irq_restore (flags_dis); - } +if (flags &PSW_SM_I ) { +local_irq_enable (); +cpu_relax (); +local_irq_disable (); + }else +cpu_relax (); }#define arch_spin_lock_flags arch_spin_lock_flags
Greg Kroah-Hartman
maintainerPATCH 442/464 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 443/464 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 444/464 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 445/464 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 446/464 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 447/464 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 448/464 ARM: dts: exynos: Extend all Exynos5800 A15s OPPs with max voltage data
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
commit d644853ff8fcbb7a4e3757f9d8ccc39d930b7e3c upstream.
On Exynos5422/5800 the regulator supply for the A15 cores ("vdd_arm") is coupled with the regulator supply for the SoC internal circuits ("vdd_int"), thus all operating points that modify one of those supplies have to specify a triplet of the min/target/max values to properly work with regulator coupling.
--- arch/arm/boot/dts/exynos5800.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/boot/dts/exynos5800.dtsi +3 -3
@@ -23,17 +23,17 @@ &cluster_a15_opp_table { opp-2000000000 { opp-hz = /bits/ 64 <2000000000>; - opp-microvolt = <1312500>; + opp-microvolt = <1312500 1312500 1500000>; clock-latency-ns = <140000>; }; opp-1900000000 { opp-hz = /bits/ 64 <1900000000>; - opp-microvolt = <1262500>; + opp-microvolt = <1262500 1262500 1500000>; clock-latency-ns = <140000>; }; opp-1800000000 { opp-hz = /bits/ 64 <1800000000>; - opp-microvolt = <1237500>; + opp-microvolt = <1237500 1237500 1500000>; clock-latency-ns = <140000>; }; opp-1700000000 {
Greg Kroah-Hartman
maintainerPATCH 449/464 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 450/464 firmware: qcom_scm: Fix legacy convention SCM accessors
In reply to Greg Kroah-HartmanFrom: Jonathan McDowell <[email protected]>
commit b88c28280c3f7097546db93824686db1e7dceee1 upstream.
The move to a combined driver for the QCOM SCM hardware changed the io_writel and io_readl helpers to use non-atomic calls, despite the commit message saying that atomic was a better option. This breaks these helpers on hardware that uses the old legacy convention (access fails with a -95 return code). Switch back to using the atomic calls.
Observed as a failure routing GPIO interrupts to the Apps processor on an IPQ8064; fix is confirmed as correctly allowing the interrupts to be routed and observed.
--- drivers/firmware/qcom_scm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/firmware/qcom_scm.c +3 -4
@@ -391,7 +391,7 @@ static int __qcom_scm_set_dload_mode(str desc.args[1 ] = enable ?QCOM_SCM_BOOT_SET_DLOAD_MODE :0 ; -return qcom_scm_call (__scm->dev, &desc,NULL ); +return qcom_scm_call_atomic (__scm->dev, &desc,NULL ); }static void qcom_scm_set_download_mode (bool enable)
@@ -650,7 +650,7 @@ int qcom_scm_io_readl(phys_addr_t addr,int ret; - ret =qcom_scm_call (__scm->dev, &desc, &res); + ret =qcom_scm_call_atomic (__scm->dev, &desc, &res);if (ret >=0 ) *val = res.result[0 ];
@@ -669,8 +669,7 @@ int qcom_scm_io_writel(phys_addr_t addr, .owner = ARM_SMCCC_OWNER_SIP, }; - -return qcom_scm_call (__scm->dev, &desc,NULL ); +return qcom_scm_call_atomic (__scm->dev, &desc,NULL ); }EXPORT_SYMBOL (qcom_scm_io_writel);
Greg Kroah-Hartman
maintainerPATCH 451/464 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/mfd/ioc3.c | 6 ++++++ drivers/pci/controller/vmd.c | 3 +++ 5 files changed, 25 insertions(+)
arch/mips/pci/pci-xtalk-bridge.c +3 -0
@@ -728,6 +728,7 @@ err_free_resource:pci_free_resource_list (&host->windows); err_remove_domain:irq_domain_remove (domain); +irq_domain_free_fwnode (fn);return err; }
@@ -735,8 +736,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
@@ -2335,8 +2335,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/mfd/ioc3.c +6 -0
@@ -616,7 +616,10 @@ static int ioc3_mfd_probe(struct pci_dev/* Remove all already added MFD devices */ mfd_remove_devices (&ipd->pdev->dev);if (ipd->domain) { +struct fwnode_handle *fn = ipd->domain->fwnode; +irq_domain_remove (ipd->domain); +irq_domain_free_fwnode (fn);free_irq (ipd->domain_irq, (void *)ipd); }pci_iounmap (pdev, regs);
@@ -643,7 +646,10 @@ static void ioc3_mfd_remove(struct pci_d/* Release resources */ mfd_remove_devices (&ipd->pdev->dev);if (ipd->domain) { +struct fwnode_handle *fn = ipd->domain->fwnode; +irq_domain_remove (ipd->domain); +irq_domain_free_fwnode (fn);free_irq (ipd->domain_irq, (void *)ipd); }pci_iounmap (pdev, ipd->regs);
drivers/pci/controller/vmd.c +3 -0
@@ -560,6 +560,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 ; }
@@ -673,6 +674,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);
@@ -680,6 +682,7 @@ static void vmd_remove(struct pci_dev *dvmd_cleanup_srcu (vmd);vmd_detach_resources (vmd);irq_domain_remove (vmd->irq_domain); +irq_domain_free_fwnode (fn); }#ifdef CONFIG_PM_SLEEP
Greg Kroah-Hartman
maintainerPATCH 452/464 firmware_loader: EFI firmware loader must handle pre-allocated buffer
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit 4fb60b158afd3ac9e0fe9975aa476213f5cc0a4d upstream.
The EFI platform firmware fallback would clobber any pre-allocated buffers. Instead, correctly refuse to reallocate when too small (as already done in the sysfs fallback), or perform allocation normally when needed.
--- drivers/base/firmware_loader/fallback_platform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/base/firmware_loader/fallback_platform.c +4 -1
@@ -25,7 +25,10 @@ int firmware_fallback_platform(struct fwif (rc)return rc;/* rc == -ENOENT when the fw was not found */ - fw_priv->data =vmalloc (size); +if (fw_priv->data && size > fw_priv->allocated_size) +return -ENOMEM ; +if (!fw_priv->data) + fw_priv->data =vmalloc (size);if (!fw_priv->data)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 453/464 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
@@ -630,6 +630,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 454/464 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
@@ -568,11 +568,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 455/464 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
@@ -613,6 +613,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 456/464 drm/xen-front: Fix misused IS_ERR_OR_NULL checks
In reply to Greg Kroah-HartmanFrom: Oleksandr Andrushchenko <[email protected]>
commit 14dee058610446aa464254fc5c8e88c7535195e0 upstream.
The patch c575b7eeb89f: "drm/xen-front: Add support for Xen PV display frontend" from Apr 3, 2018, leads to the following static checker warning:
drivers/gpu/drm/xen/xen_drm_front_gem.c:140 xen_drm_front_gem_create() warn: passing zero to 'ERR_CAST'
drivers/gpu/drm/xen/xen_drm_front_gem.c
133 struct drm_gem_object *xen_drm_front_gem_create(struct drm_device *dev,
134 size_t size)
135 {
136 struct xen_gem_object *xen_obj;
137
138 xen_obj = gem_create(dev, size);
139 if (IS_ERR_OR_NULL(xen_obj))
140 return ERR_CAST(xen_obj);
Fix this and the rest of misused places with IS_ERR_OR_NULL in the driver.
--- drivers/gpu/drm/xen/xen_drm_front.c | 4 ++-- drivers/gpu/drm/xen/xen_drm_front_gem.c | 8 ++++---- drivers/gpu/drm/xen/xen_drm_front_kms.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-)
drivers/gpu/drm/xen/xen_drm_front.c +2 -2
@@ -400,8 +400,8 @@ static int xen_drm_drv_dumb_create(struc args->size = args->pitch * args->height; obj =xen_drm_front_gem_create (dev, args->size); -if (IS_ERR_OR_NULL (obj)) { - ret =PTR_ERR_OR_ZERO (obj); +if (IS_ERR (obj)) { + ret =PTR_ERR (obj); goto fail; }
drivers/gpu/drm/xen/xen_drm_front_gem.c +4 -4
@@ -83,7 +83,7 @@ static struct xen_gem_object *gem_create size =round_up (size,PAGE_SIZE ); xen_obj =gem_create_obj (dev, size); -if (IS_ERR_OR_NULL (xen_obj)) +if (IS_ERR (xen_obj))return xen_obj;if (drm_info->front_info->cfg.be_alloc) {
@@ -117,7 +117,7 @@ static struct xen_gem_object *gem_create*/ xen_obj->num_pages =DIV_ROUND_UP (size,PAGE_SIZE ); xen_obj->pages =drm_gem_get_pages (&xen_obj->base); -if (IS_ERR_OR_NULL (xen_obj->pages)) { +if (IS_ERR (xen_obj->pages)) { ret =PTR_ERR (xen_obj->pages); xen_obj->pages =NULL ; goto fail;
@@ -136,7 +136,7 @@ struct drm_gem_object *xen_drm_front_gemstruct xen_gem_object *xen_obj; xen_obj =gem_create (dev, size); -if (IS_ERR_OR_NULL (xen_obj)) +if (IS_ERR (xen_obj))return ERR_CAST (xen_obj);return &xen_obj->base;
@@ -194,7 +194,7 @@ xen_drm_front_gem_import_sg_table(struct size = attach->dmabuf->size; xen_obj =gem_create_obj (dev, size); -if (IS_ERR_OR_NULL (xen_obj)) +if (IS_ERR (xen_obj))return ERR_CAST (xen_obj); ret =gem_alloc_pages_array (xen_obj, size);
drivers/gpu/drm/xen/xen_drm_front_kms.c +1 -1
@@ -60,7 +60,7 @@ fb_create(struct drm_device *dev, structint ret; fb =drm_gem_fb_create_with_funcs (dev, filp, mode_cmd, &fb_funcs); -if (IS_ERR_OR_NULL (fb)) +if (IS_ERR (fb))return fb; gem_obj = fb->obj[0 ];
Greg Kroah-Hartman
maintainerPATCH 457/464 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 458/464 s390/numa: set node distance to LOCAL_DISTANCE
In reply to Greg Kroah-HartmanFrom: Alexander Gordeev <[email protected]>
commit 535e4fc623fab2e09a0653fc3a3e17f382ad0251 upstream.
The node distance is hardcoded to 0, which causes a trouble for some user-level applications. In particular, "libnuma" expects the distance of a node to itself as LOCAL_DISTANCE. This update removes the offending node distance override.
--- arch/s390/include/asm/topology.h | 6 ------ 1 file changed, 6 deletions(-)
arch/s390/include/asm/topology.h +0 -6
@@ -86,12 +86,6 @@ static inline const struct cpumask *cpum#define pcibus_to_node (bus) __pcibus_to_node(bus) -#define node_distance (a, b) __node_distance(a, b) -static inline int __node_distance (int a,int b) -{ -return 0 ; -} -#else /* !CONFIG_NUMA */ #define numa_node_id numa_node_id
Greg Kroah-Hartman
maintainerPATCH 459/464 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 460/464 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
@@ -2673,8 +2673,10 @@ static int io_read(struct io_kiocb *req,if (req->file->f_op->read_iter) ret2 =call_read_iter (req->file, kiocb, &iter); -else +else if (req->file->f_op->read) ret2 =loop_rw_iter (READ , req->file, kiocb, &iter); +else + ret2 = -EINVAL ;/* Catch -EAGAIN return for forced non-blocking submission */ if (!force_nonblock || ret2 != -EAGAIN ) {
@@ -2788,8 +2790,10 @@ static int io_write(struct io_kiocb *reqif (req->file->f_op->write_iter) ret2 =call_write_iter (req->file, kiocb, &iter); -else +else if (req->file->f_op->write) ret2 =loop_rw_iter (WRITE , req->file, kiocb, &iter); +else + ret2 = -EINVAL ;if (!force_nonblock) current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ;
Greg Kroah-Hartman
maintainerPATCH 461/464 io_uring: hold ctx reference around task_work queue + execute
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 6d816e088c359866f9867057e04f244c608c42fe upstream.
We're holding the request reference, but we need to go one higher to ensure that the ctx remains valid after the request has finished. If the ring is closed with pending task_work inflight, and the given io_kiocb finishes sync during issue, then we need a reference to the ring itself around the task_work execution cycle.
--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/io_uring.c +6 -0
@@ -4140,6 +4140,8 @@ static int __io_async_wake(struct io_kio tsk = req->task; req->result = mask;init_task_work (&req->task_work, func); +percpu_ref_get (&req->ctx->refs); +/* * If this fails, then the task is exiting. When a task exits, the * work gets canceled, so just cancel this request as well instead
@@ -4239,6 +4241,7 @@ static void io_poll_task_handler(structstatic void io_poll_task_func (struct callback_head *cb) { struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work); +struct io_ring_ctx *ctx = req->ctx;struct io_kiocb *nxt =NULL ;io_poll_task_handler (req, &nxt);
@@ -4249,6 +4252,7 @@ static void io_poll_task_func(struct cal__io_queue_sqe (nxt,NULL );mutex_unlock (&ctx->uring_lock); } +percpu_ref_put (&ctx->refs); } static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
@@ -4365,6 +4369,7 @@ static void io_async_task_func(struct caif (io_poll_rewait (req, &apoll->poll)) {spin_unlock_irq (&ctx->completion_lock); +percpu_ref_put (&ctx->refs);return ; }
@@ -4402,6 +4407,7 @@ end_req:req_set_fail_links (req);io_double_put_req (req); } +percpu_ref_put (&ctx->refs); } static int io_async_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
Greg Kroah-Hartman
maintainerPATCH 462/464 io_uring: add missing REQ_F_COMP_LOCKED for nested requests
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 9b7adba9eaec28e0e4343c96d0dbeb9578802f5f upstream.
When we traverse into failing links or timeouts, we need to ensure we propagate the REQ_F_COMP_LOCKED flag to ensure that we correctly signal to the completion side that we already hold the completion lock.
--- fs/io_uring.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
fs/io_uring.c +19 -5
@@ -1549,12 +1549,9 @@ static void io_req_link_next(struct io_k/* * Called if REQ_F_LINK_HEAD is set, and we fail the head request */ -static void io_fail_links (struct io_kiocb *req) +static void __io_fail_links (struct io_kiocb *req) {struct io_ring_ctx *ctx = req->ctx; -unsigned long flags; - -spin_lock_irqsave (&ctx->completion_lock, flags);while (!list_empty (&req->link_list)) { struct io_kiocb *link = list_first_entry(&req->link_list,
@@ -1568,13 +1565,29 @@ static void io_fail_links(struct io_kiocio_link_cancel_timeout (link); }else {io_cqring_fill_event (link, -ECANCELED ); + link->flags |=REQ_F_COMP_LOCKED ;__io_double_put_req (link); } req->flags &= ~REQ_F_LINK_TIMEOUT ; }io_commit_cqring (ctx); -spin_unlock_irqrestore (&ctx->completion_lock, flags); +} + +static void io_fail_links (struct io_kiocb *req) +{ +struct io_ring_ctx *ctx = req->ctx; + +if (!(req->flags &REQ_F_COMP_LOCKED )) { +unsigned long flags; + +spin_lock_irqsave (&ctx->completion_lock, flags); +__io_fail_links (req); +spin_unlock_irqrestore (&ctx->completion_lock, flags); + }else { +__io_fail_links (req); + } +io_cqring_ev_posted (ctx); }
@@ -4767,6 +4780,7 @@ static int io_timeout_cancel(struct io_rreturn -EALREADY ;req_set_fail_links (req); + req->flags |=REQ_F_COMP_LOCKED ;io_cqring_fill_event (req, -ECANCELED );io_put_req (req);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 463/464 io_uring: enable lookup of links holding inflight files
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit f254ac04c8744cf7bfed012717eac34eacc65dfb upstream.
When a process exits, we cancel whatever requests it has pending that are referencing the file table. However, if a link is holding a reference, then we cannot find it by simply looking at the inflight list.
Enable checking of the poll and timeout list to find the link, and cancel it appropriately.
--- fs/io_uring.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 10 deletions(-)
fs/io_uring.c +87 -10
@@ -4586,6 +4586,7 @@ static bool io_poll_remove_one(struct ioio_cqring_fill_event (req, -ECANCELED );io_commit_cqring (req->ctx); req->flags |=REQ_F_COMP_LOCKED ; +req_set_fail_links (req);io_put_req (req); }
@@ -4759,6 +4760,23 @@ static enum hrtimer_restart io_timeout_freturn HRTIMER_NORESTART ; } +static int __io_timeout_cancel (struct io_kiocb *req) +{ +int ret; + +list_del_init (&req->list); + + ret =hrtimer_try_to_cancel (&req->io->timeout.timer); +if (ret ==-1 ) +return -EALREADY ; + +req_set_fail_links (req); + req->flags |=REQ_F_COMP_LOCKED ; +io_cqring_fill_event (req, -ECANCELED ); +io_put_req (req); +return 0 ; +} +static int io_timeout_cancel (struct io_ring_ctx *ctx,__u64 user_data) {struct io_kiocb *req;
@@ -4766,7 +4784,6 @@ static int io_timeout_cancel(struct io_rlist_for_each_entry (req, &ctx->timeout_list, list) {if (user_data == req->user_data) { -list_del_init (&req->list); ret =0 ;break ; }
@@ -4775,15 +4792,7 @@ static int io_timeout_cancel(struct io_rif (ret == -ENOENT )return ret; - ret =hrtimer_try_to_cancel (&req->io->timeout.timer); -if (ret ==-1 ) -return -EALREADY ; - -req_set_fail_links (req); - req->flags |=REQ_F_COMP_LOCKED ; -io_cqring_fill_event (req, -ECANCELED ); -io_put_req (req); -return 0 ; +return __io_timeout_cancel (req); } static int io_timeout_remove_prep(struct io_kiocb *req,
@@ -7535,6 +7544,71 @@ static bool io_wq_files_match(struct io_return work->files == files; } +/* +* Returns true if 'preq' is the link parent of 'req' +*/ +static bool io_match_link (struct io_kiocb *preq,struct io_kiocb *req) +{ +struct io_kiocb *link; + +if (!(preq->flags &REQ_F_LINK_HEAD )) +return false; + +list_for_each_entry (link, &preq->link_list, link_list) { +if (link == req) +return true; + } + +return false; +} + +/* +* We're looking to cancel 'req' because it's holding on to our files, but +* 'req' could be a link to another request. See if it is, and cancel that +* parent request if so. +*/ +static bool io_poll_remove_link (struct io_ring_ctx *ctx,struct io_kiocb *req) +{ +struct hlist_node *tmp; +struct io_kiocb *preq; +bool found = false; +int i; + +spin_lock_irq (&ctx->completion_lock); +for (i =0 ; i < (1U << ctx->cancel_hash_bits); i++) { +struct hlist_head *list; + + list = &ctx->cancel_hash[i]; +hlist_for_each_entry_safe (preq, tmp, list, hash_node) { + found =io_match_link (preq, req); +if (found) { +io_poll_remove_one (preq); +break ; + } + } + } +spin_unlock_irq (&ctx->completion_lock); +return found; +} + +static bool io_timeout_remove_link (struct io_ring_ctx *ctx, +struct io_kiocb *req) +{ +struct io_kiocb *preq; +bool found = false; + +spin_lock_irq (&ctx->completion_lock); +list_for_each_entry (preq, &ctx->timeout_list, list) { + found =io_match_link (preq, req); +if (found) { +__io_timeout_cancel (preq); +break ; + } + } +spin_unlock_irq (&ctx->completion_lock); +return found; +} +static void io_uring_cancel_files (struct io_ring_ctx *ctx,struct files_struct *files) {
@@ -7592,6 +7666,9 @@ static void io_uring_cancel_files(struct } }else {io_wq_cancel_work (ctx->io_wq, &cancel_req->work); +/* could be a link, check and remove if it is */ +if (!io_poll_remove_link (ctx, cancel_req)) +io_timeout_remove_link (ctx, cancel_req);io_put_req (cancel_req); }
Greg Kroah-Hartman
maintainerPATCH 464/464 task_work: only grab task signal lock when needed
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit ebf0d100df0731901c16632f78d78d35f4123bc4 upstream.
If JOBCTL_TASK_WORK is already set on the targeted task, then we need not go through {lock,unlock}_task_sighand() to set it again and queue a signal wakeup. This is safe as we're checking it _after_ adding the new task_work with cmpxchg().
The ordering is as follows:
task_work_add() get_signal()
--------------------------------------------------------------STORE(task->task_works, new_work); STORE(task->jobctl);mb(); mb();LOAD(task->jobctl); LOAD(task->task_works);
This speeds up TWA_SIGNAL handling quite a bit, which is important now that io_uring is relying on it for all task_work deliveries.
--- kernel/signal.c | 16 +++++++++++++++- kernel/task_work.c | 8 +++++++- 2 files changed, 22 insertions(+), 2 deletions(-)
kernel/signal.c +15 -1
@@ -2541,7 +2541,21 @@ bool get_signal(struct ksignal *ksig) relock:spin_lock_irq (&sighand->siglock); - current->jobctl &= ~JOBCTL_TASK_WORK ; +/* +* Make sure we can safely read ->jobctl() in task_work add. As Oleg +* states: +* +* It pairs with mb (implied by cmpxchg) before READ_ONCE. So we +* roughly have +* +* task_work_add: get_signal: +* STORE(task->task_works, new_work); STORE(task->jobctl); +* mb(); mb(); +* LOAD(task->jobctl); LOAD(task->task_works); +* +* and we can rely on STORE-MB-LOAD [ in task_work_add]. +*/ +smp_store_mb (current->jobctl, current->jobctl & ~JOBCTL_TASK_WORK );if (unlikely (current->task_works)) {spin_unlock_irq (&sighand->siglock);task_work_run ();
kernel/task_work.c +7 -1
@@ -42,7 +42,13 @@ task_work_add(struct task_struct *task,set_notify_resume (task);break ;case TWA_SIGNAL : -if (lock_task_sighand (task, &flags)) { +/* +* Only grab the sighand lock if we don't already have some +* task_work pending. This pairs with the smp_store_mb() +* in get_signal(), see comment there. +*/ +if (!(READ_ONCE (task->jobctl) &JOBCTL_TASK_WORK ) && +lock_task_sighand (task, &flags)) { task->jobctl |=JOBCTL_TASK_WORK ;signal_wake_up (task,0 );unlock_task_sighand (task, &flags);
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.8.2 release. There are 464 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.8.2-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.8.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.8:
11 builds: 11 pass, 0 fail
26 boots: 26 pass, 0 fail
60 tests: 60 pass, 0 failLinux version: 5.8.2-rc1-gd74026bb5bef
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Greg Kroah-Hartman
maintainerQuoted 26 lines · Jon Hunter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.8.2 release. There are 464 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.8.2-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.8.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.8:
11 builds: 11 pass, 0 fail 26 boots: 26 pass, 0 fail 60 tests: 60 pass, 0 fail
Quoted 5 lines
Linux version: 5.8.2-rc1-gd74026bb5bef
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Thanks for testing all of these and letting me know.
greg k-h