Linux 5.10.6
Greg Kroah-Hartman
maintainerI'm announcing the release of the 5.10.6 kernel.
All users of the 5.10 kernel series must upgrade.
The updated 5.10.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.10.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Documentation/devicetree/bindings/rtc/rtc.yaml | 5 + Makefile | 2 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 41 +++++++----- drivers/infiniband/core/device.c | 43 ++++++------ drivers/infiniband/core/rw.c | 5 + drivers/infiniband/sw/rdmavt/Kconfig | 1 drivers/infiniband/sw/rdmavt/mr.c | 6 - drivers/infiniband/sw/rdmavt/vt.c | 8 -- drivers/infiniband/sw/rxe/Kconfig | 1 drivers/infiniband/sw/rxe/rxe_net.c | 12 --- drivers/infiniband/sw/rxe/rxe_verbs.c | 8 -- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 drivers/infiniband/sw/siw/Kconfig | 1 drivers/infiniband/sw/siw/siw.h | 1 drivers/infiniband/sw/siw/siw_main.c | 26 ------- drivers/mtd/nand/spi/core.c | 4 - drivers/net/wireless/marvell/mwifiex/join.c | 2 drivers/nvme/target/rdma.c | 3 drivers/rtc/rtc-pcf2127.c | 57 +++++++++-------- drivers/scsi/ufs/ufs-mediatek.c | 4 - drivers/scsi/ufs/ufs-qcom.c | 6 + drivers/scsi/ufs/ufshcd.h | 16 +++- fs/exec.c | 12 +-- fs/fuse/acl.c | 6 + fs/fuse/dir.c | 37 +++++++++-- fs/fuse/file.c | 19 +++-- fs/fuse/fuse_i.h | 12 +++ fs/fuse/inode.c | 4 - fs/fuse/readdir.c | 4 - fs/fuse/xattr.c | 9 ++ fs/proc/base.c | 10 +-- include/linux/kdev_t.h | 22 +++--- include/linux/rwsem.h | 3 include/linux/sched/signal.h | 11 +-- include/rdma/ib_verbs.h | 73 +++++++++++++++------- init/init_task.c | 2 kernel/events/core.c | 52 +++++++-------- kernel/fork.c | 6 - kernel/kcmp.c | 30 ++++----- kernel/locking/rwsem.c | 40 ++++++++++++ kernel/pid.c | 4 - net/bluetooth/hci_core.c | 2 sound/pci/hda/patch_hdmi.c | 2 sound/pci/hda/patch_realtek.c | 2 45 files changed, 362 insertions(+), 256 deletions(-)
Adrian Hunter (1):
scsi: ufs: Allow an error return value from ->device_reset()
Alex Deucher (1):
Revert "drm/amd/display: Fix memory leaks in S3 resume"
Christoph Hellwig (1):
RDMA/core: remove use of dma_virt_ops
Edward Vear (1):
Bluetooth: Fix attempting to set RPA timeout when unsupported
Eric W. Biederman (3):
rwsem: Implement down_read_killable_nested
rwsem: Implement down_read_interruptible
exec: Transform exec_update_mutex into a rw_semaphore
Felix Fietkau (1):
Revert "mtd: spinand: Fix OOB read"
Greg Kroah-Hartman (1):
Linux 5.10.6
Imre Deak (1):
drm/i915/tgl: Fix Combo PHY DPLL fractional divider for 38.4MHz ref clock
Jason Gunthorpe (1):
RDMA/siw,rxe: Make emulated devices virtual in the device tree
Josh Poimboeuf (1):
kdev_t: always inline major/minor helper functions
Kailang Yang (1):
ALSA: hda/realtek - Modify Dell platform name
Miklos Szeredi (1):
fuse: fix bad inode
Rasmus Villemoes (1):
dt-bindings: rtc: add reset-source property
Stanley Chu (1):
scsi: ufs: Re-enable WriteBooster after device reset
Takashi Iwai (1):
ALSA: hda/hdmi: Fix incorrect mutex unlock in silent_stream_disable()
Uwe Kleine-König (2):
rtc: pcf2127: move watchdog initialisation to a separate function
rtc: pcf2127: only use watchdog when explicitly available
Zhang Xiaohui (1):
mwifiex: Fix possible buffer overflows in mwifiex_cmd_802_11_ad_hoc_start
[email protected] (1):
perf: Break deadlock involving exec_update_mutex
Greg Kroah-Hartman
maintainerDocumentation/devicetree/bindings/rtc/rtc.yaml +5 -0
@@ -63,6 +63,11 @@ properties: description: Enables wake up of host system on alarm. + reset-source: + $ref: /schemas/types.yaml#/definitions/flag + description: + The RTC is able to reset the machine. + additionalProperties: true ...
Makefile +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 5 +SUBLEVEL = 6 EXTRAVERSION = NAME = Kleptomaniac Octopus
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -2
@@ -2278,8 +2278,7 @@ void amdgpu_dm_update_connector_after_detect(drm_connector_update_edid_property (connector, aconnector->edid); - aconnector->num_modes =drm_add_edid_modes (connector, aconnector->edid); -drm_connector_list_update (connector); +drm_add_edid_modes (connector, aconnector->edid);if (aconnector->dc_link->aux_mode) drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
drivers/gpu/drm/i915/display/intel_dpll_mgr.c +25 -16
83 lines not on this page · raw message
drivers/infiniband/core/device.c +23 -20
61 lines not on this page · raw message
drivers/infiniband/core/rw.c +4 -1
@@ -285,8 +285,11 @@ static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg,static int rdma_rw_map_sg (struct ib_device *dev,struct scatterlist *sg,u32 sg_cnt,enum dma_data_direction dir) { -if (is_pci_p2pdma_page (sg_page (sg))) +if (is_pci_p2pdma_page (sg_page (sg))) { +if (WARN_ON_ONCE (ib_uses_virt_dma (dev))) +return 0 ;return pci_p2pdma_map_sg (dev->dma_device, sg, sg_cnt, dir); + }return ib_dma_map_sg (dev, sg, sg_cnt, dir); }
drivers/infiniband/sw/rdmavt/Kconfig +0 -1
@@ -4,6 +4,5 @@ config INFINIBAND_RDMAVT depends on INFINIBAND_VIRT_DMA depends on X86_64 depends on PCI - select DMA_VIRT_OPS help This is a common software verbs provider for RDMA networks.
drivers/infiniband/sw/rdmavt/mr.c +2 -4
@@ -324,8 +324,6 @@ static void __rvt_free_mr(struct rvt_mr *mr)* @acc: access flags * * Return: the memory region on success, otherwise returns an errno. -* Note that all DMA addresses should be created via the functions in -* struct dma_virt_ops. */ struct ib_mr *rvt_get_dma_mr (struct ib_pd *pd,int acc) {
@@ -766,7 +764,7 @@ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,/* * We use LKEY == zero for kernel virtual addresses -* (see rvt_get_dma_mr() and dma_virt_ops). +* (see rvt_get_dma_mr()). */ if (sge->lkey ==0 ) {struct rvt_dev_info *dev =ib_to_rvt (pd->ibpd.device);
@@ -877,7 +875,7 @@ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge,/* * We use RKEY == zero for kernel virtual addresses -* (see rvt_get_dma_mr() and dma_virt_ops). +* (see rvt_get_dma_mr()). */ rcu_read_lock ();if (rkey ==0 ) {
drivers/infiniband/sw/rdmavt/vt.c +0 -8
@@ -524,7 +524,6 @@ static noinline int check_support(struct rvt_dev_info *rdi, int verb)int rvt_register_device (struct rvt_dev_info *rdi) {int ret =0 , i; -u64 dma_mask;if (!rdi)return -EINVAL ;
@@ -579,13 +578,6 @@ int rvt_register_device(struct rvt_dev_info *rdi)/* Completion queues */ spin_lock_init (&rdi->n_cqs_lock); -/* DMA Operations */ - rdi->ibdev.dev.dma_parms = rdi->ibdev.dev.parent->dma_parms; - dma_mask =IS_ENABLED (CONFIG_64BIT ) ?DMA_BIT_MASK (64 ) :DMA_BIT_MASK (32 ); - ret =dma_coerce_mask_and_coherent (&rdi->ibdev.dev, dma_mask); -if (ret) - goto bail_wss; -/* Protection Domain */ spin_lock_init (&rdi->n_pds_lock); rdi->n_pds_allocated =0 ;
drivers/infiniband/sw/rxe/Kconfig +0 -1
@@ -5,7 +5,6 @@ config RDMA_RXE depends on INFINIBAND_VIRT_DMA select NET_UDP_TUNNEL select CRYPTO_CRC32 - select DMA_VIRT_OPS help This driver implements the InfiniBand RDMA transport over the Linux network stack. It enables a system with a
drivers/infiniband/sw/rxe/rxe_net.c +0 -12
@@ -20,18 +20,6 @@static struct rxe_recv_sockets recv_sockets; -struct device *rxe_dma_device (struct rxe_dev *rxe) -{ -struct net_device *ndev; - - ndev = rxe->ndev; - -if (is_vlan_dev (ndev)) - ndev =vlan_dev_real_dev (ndev); - -return ndev->dev.parent; -} -int rxe_mcast_add (struct rxe_dev *rxe,union ib_gid *mgid) {int err;
drivers/infiniband/sw/rxe/rxe_verbs.c +0 -8
@@ -1118,23 +1118,15 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name)int err;struct ib_device *dev = &rxe->ib_dev;struct crypto_shash *tfm; -u64 dma_mask;strlcpy (dev->node_desc,"rxe" ,sizeof (dev->node_desc)); dev->node_type =RDMA_NODE_IB_CA ; dev->phys_port_cnt =1 ; dev->num_comp_vectors =num_possible_cpus (); - dev->dev.parent =rxe_dma_device (rxe); dev->local_dma_lkey =0 ;addrconf_addr_eui48 ((unsigned char *)&dev->node_guid, rxe->ndev->dev_addr); - dev->dev.dma_parms = &rxe->dma_parms; -dma_set_max_seg_size (&dev->dev,UINT_MAX ); - dma_mask =IS_ENABLED (CONFIG_64BIT ) ?DMA_BIT_MASK (64 ) :DMA_BIT_MASK (32 ); - err =dma_coerce_mask_and_coherent (&dev->dev, dma_mask); -if (err) -return err; dev->uverbs_cmd_mask =BIT_ULL (IB_USER_VERBS_CMD_GET_CONTEXT ) |BIT_ULL (IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL )
drivers/infiniband/sw/rxe/rxe_verbs.h +0 -1
@@ -352,7 +352,6 @@ struct rxe_port {struct rxe_dev {struct ib_device ib_dev;struct ib_device_attr attr; -struct device_dma_parameters dma_parms;int max_ucontext;int max_inline_data;struct mutex usdev_lock;
drivers/infiniband/sw/siw/Kconfig +0 -1
@@ -2,7 +2,6 @@ config RDMA_SIW tristate "Software RDMA over TCP/IP (iWARP) driver" depends on INET && INFINIBAND && LIBCRC32C depends on INFINIBAND_VIRT_DMA - select DMA_VIRT_OPS help This driver implements the iWARP RDMA transport over the Linux TCP/IP network stack. It enables a system with a
drivers/infiniband/sw/siw/siw.h +0 -1
@@ -69,7 +69,6 @@ struct siw_pd {struct siw_device {struct ib_device base_dev; -struct device_dma_parameters dma_parms;struct net_device *netdev;struct siw_dev_cap attrs;
drivers/infiniband/sw/siw/siw_main.c +1 -25
@@ -305,25 +305,8 @@ static struct siw_device *siw_device_create(struct net_device *netdev) {struct siw_device *sdev =NULL ;struct ib_device *base_dev; -struct device *parent = netdev->dev.parent; -u64 dma_mask;int rv; -if (!parent) { -/* -* The loopback device has no parent device, -* so it appears as a top-level device. To support -* loopback device connectivity, take this device -* as the parent device. Skip all other devices -* w/o parent device. -*/ -if (netdev->type !=ARPHRD_LOOPBACK ) { -pr_warn ("siw: device %s error: no parent device\n" , - netdev->name); -return NULL ; - } - parent = &netdev->dev; - } sdev =ib_alloc_device (siw_device, base_dev);if (!sdev)return NULL ;
@@ -382,13 +365,6 @@ static struct siw_device *siw_device_create(struct net_device *netdev)* per physical port. */ base_dev->phys_port_cnt =1 ; - base_dev->dev.parent = parent; - base_dev->dev.dma_parms = &sdev->dma_parms; -dma_set_max_seg_size (&base_dev->dev,UINT_MAX ); - dma_mask =IS_ENABLED (CONFIG_64BIT ) ?DMA_BIT_MASK (64 ) :DMA_BIT_MASK (32 ); -if (dma_coerce_mask_and_coherent (&base_dev->dev, dma_mask)) - goto error; - base_dev->num_comp_vectors =num_possible_cpus ();xa_init_flags (&sdev->qp_xa,XA_FLAGS_ALLOC1 );
@@ -430,7 +406,7 @@ static struct siw_device *siw_device_create(struct net_device *netdev)atomic_set (&sdev->num_mr,0 );atomic_set (&sdev->num_pd,0 ); - sdev->numa_node =dev_to_node (parent); + sdev->numa_node =dev_to_node (&netdev->dev);spin_lock_init (&sdev->lock);return sdev;
drivers/mtd/nand/spi/core.c +0 -4
@@ -318,10 +318,6 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand, buf += ret; } -if (req->ooblen) -memcpy (req->oobbuf.in, spinand->oobbuf + req->ooboffs, - req->ooblen); -return 0 ; }
drivers/net/wireless/marvell/mwifiex/join.c +2 -0
@@ -877,6 +877,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,memset (adhoc_start->ssid,0 ,IEEE80211_MAX_SSID_LEN ); +if (req_ssid->ssid_len >IEEE80211_MAX_SSID_LEN ) + req_ssid->ssid_len =IEEE80211_MAX_SSID_LEN ;memcpy (adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: SSID = %s\n",
drivers/nvme/target/rdma.c +2 -1
@@ -414,7 +414,8 @@ static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev,if (ib_dma_mapping_error (ndev->device, r->send_sge.addr)) goto out_free_rsp; - r->req.p2p_client = &ndev->device->dev; +if (!ib_uses_virt_dma (ndev->device)) + r->req.p2p_client = &ndev->device->dev; r->send_sge.length =sizeof (*r->req.cqe); r->send_sge.lkey = ndev->pd->local_dma_lkey;
drivers/rtc/rtc-pcf2127.c +32 -25
81 lines not on this page · raw message
drivers/scsi/ufs/ufs-mediatek.c +3 -1
@@ -743,7 +743,7 @@ static int ufs_mtk_link_startup_notify(struct ufs_hba *hba,return ret; } -static void ufs_mtk_device_reset (struct ufs_hba *hba) +static int ufs_mtk_device_reset (struct ufs_hba *hba) {struct arm_smccc_res res;
@@ -764,6 +764,8 @@ static void ufs_mtk_device_reset(struct ufs_hba *hba)usleep_range (10000 ,15000 );dev_info (hba->dev,"device reset done\n" ); + +return 0 ; }static int ufs_mtk_link_set_hpm (struct ufs_hba *hba)
drivers/scsi/ufs/ufs-qcom.c +4 -2
@@ -1421,13 +1421,13 @@ static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)* * Toggles the (optional) reset line to reset the attached device. */ -static void ufs_qcom_device_reset (struct ufs_hba *hba) +static int ufs_qcom_device_reset (struct ufs_hba *hba) {struct ufs_qcom_host *host =ufshcd_get_variant (hba);/* reset gpio is optional */ if (!host->device_reset) -return ; +return -EOPNOTSUPP ;/* * The UFS device shall detect reset pulses of 1us, sleep for 10us to
@@ -1438,6 +1438,8 @@ static void ufs_qcom_device_reset(struct ufs_hba *hba)gpiod_set_value_cansleep (host->device_reset,0 );usleep_range (10 ,15 ); + +return 0 ; }#if IS_ENABLED (CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND )
drivers/scsi/ufs/ufshcd.h +12 -4
@@ -318,7 +318,7 @@ struct ufs_hba_variant_ops {int (*resume)(struct ufs_hba *,enum ufs_pm_op );void (*dbg_register_dump)(struct ufs_hba *hba);int (*phy_initialization)(struct ufs_hba *); -void (*device_reset)(struct ufs_hba *hba); +int (*device_reset)(struct ufs_hba *hba);void (*config_scaling_param)(struct ufs_hba *hba,struct devfreq_dev_profile *profile,void *data);
@@ -1181,9 +1181,17 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)static inline void ufshcd_vops_device_reset (struct ufs_hba *hba) {if (hba->vops && hba->vops->device_reset) { - hba->vops->device_reset (hba); -ufshcd_set_ufs_dev_active (hba); -ufshcd_update_reg_hist (&hba->ufs_stats.dev_reset,0 ); +int err = hba->vops->device_reset (hba); + +if (!err) { +ufshcd_set_ufs_dev_active (hba); +if (ufshcd_is_wb_allowed (hba)) { + hba->wb_enabled = false; + hba->wb_buf_flush_enabled = false; + } + } +if (err != -EOPNOTSUPP ) +ufshcd_update_reg_hist (&hba->ufs_stats.dev_reset, err); } }
fs/exec.c +6 -6
@@ -965,8 +965,8 @@ EXPORT_SYMBOL(read_code);/* * Maps the mm_struct mm into the current task struct. -* On success, this function returns with the mutex -* exec_update_mutex locked. +* On success, this function returns with exec_update_lock +* held for writing. */ static int exec_mmap (struct mm_struct *mm) {
@@ -981,7 +981,7 @@ static int exec_mmap(struct mm_struct *mm)if (old_mm)sync_mm_rss (old_mm); - ret =mutex_lock_killable (&tsk->signal->exec_update_mutex); + ret =down_write_killable (&tsk->signal->exec_update_lock);if (ret)return ret;
@@ -995,7 +995,7 @@ static int exec_mmap(struct mm_struct *mm)mmap_read_lock (old_mm);if (unlikely (old_mm->core_state)) {mmap_read_unlock (old_mm); -mutex_unlock (&tsk->signal->exec_update_mutex); +up_write (&tsk->signal->exec_update_lock);return -EINTR ; } }
@@ -1382,7 +1382,7 @@ int begin_new_exec(struct linux_binprm * bprm)return 0 ; out_unlock: -mutex_unlock (&me->signal->exec_update_mutex); +up_write (&me->signal->exec_update_lock); out:return retval; }
@@ -1423,7 +1423,7 @@ void setup_new_exec(struct linux_binprm * bprm)* some architectures like powerpc */ me->mm->task_size =TASK_SIZE ; -mutex_unlock (&me->signal->exec_update_mutex); +up_write (&me->signal->exec_update_lock);mutex_unlock (&me->signal->cred_guard_mutex); }EXPORT_SYMBOL (setup_new_exec);
fs/fuse/acl.c +6 -0
@@ -19,6 +19,9 @@ struct posix_acl *fuse_get_acl(struct inode *inode, int type)void *value =NULL ;struct posix_acl *acl; +if (fuse_is_bad (inode)) +return ERR_PTR (-EIO ); +if (!fc->posix_acl || fc->no_getxattr)return NULL ;
@@ -53,6 +56,9 @@ int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type)const char *name;int ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fc->posix_acl || fc->no_setxattr)return -EOPNOTSUPP ;
fs/fuse/dir.c +32 -5
@@ -202,7 +202,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)int ret; inode =d_inode_rcu (entry); -if (inode &&is_bad_inode (inode)) +if (inode &&fuse_is_bad (inode)) goto invalid;else if (time_before64 (fuse_dentry_time (entry),get_jiffies_64 ()) || (flags &LOOKUP_REVAL )) {
@@ -463,6 +463,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,bool outarg_valid = true;bool locked; +if (fuse_is_bad (dir)) +return ERR_PTR (-EIO ); + locked =fuse_lock_inode (dir); err =fuse_lookup_name (dir->i_sb,get_node_id (dir), &entry->d_name, &outarg, &inode);
@@ -606,6 +609,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,struct fuse_conn *fc =get_fuse_conn (dir);struct dentry *res =NULL ; +if (fuse_is_bad (dir)) +return -EIO ; +if (d_in_lookup (entry)) { res =fuse_lookup (dir, entry,0 );if (IS_ERR (res))
@@ -654,6 +660,9 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,int err;struct fuse_forget_link *forget; +if (fuse_is_bad (dir)) +return -EIO ; + forget =fuse_alloc_forget ();if (!forget)return -ENOMEM ;
@@ -781,6 +790,9 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)struct fuse_mount *fm =get_fuse_mount (dir);FUSE_ARGS (args); +if (fuse_is_bad (dir)) +return -EIO ; + args.opcode =FUSE_UNLINK ; args.nodeid =get_node_id (dir); args.in_numargs =1 ;
@@ -817,6 +829,9 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)struct fuse_mount *fm =get_fuse_mount (dir);FUSE_ARGS (args); +if (fuse_is_bad (dir)) +return -EIO ; + args.opcode =FUSE_RMDIR ; args.nodeid =get_node_id (dir); args.in_numargs =1 ;
@@ -895,6 +910,9 @@ static int fuse_rename2(struct inode *olddir, struct dentry *oldent,struct fuse_conn *fc =get_fuse_conn (olddir);int err; +if (fuse_is_bad (olddir)) +return -EIO ; +if (flags & ~(RENAME_NOREPLACE |RENAME_EXCHANGE |RENAME_WHITEOUT ))return -EINVAL ;
@@ -1030,7 +1048,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,if (!err) {if (fuse_invalid_attr (&outarg.attr) || (inode->i_mode ^ outarg.attr.mode) &S_IFMT ) { -make_bad_inode (inode); +fuse_make_bad (inode); err = -EIO ; }else { fuse_change_attributes(inode, &outarg.attr,
@@ -1232,6 +1250,9 @@ static int fuse_permission(struct inode *inode, int mask)bool refreshed = false;int err =0 ; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fc))return -EACCES ;
@@ -1327,7 +1348,7 @@ static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,int err; err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out_err;if (fc->cache_symlinks)
@@ -1375,7 +1396,7 @@ static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,struct fuse_conn *fc =get_fuse_conn (inode);int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;if (fc->no_fsyncdir)
@@ -1664,7 +1685,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,if (fuse_invalid_attr (&outarg.attr) || (inode->i_mode ^ outarg.attr.mode) &S_IFMT ) { -make_bad_inode (inode); +fuse_make_bad (inode); err = -EIO ; goto error; }
@@ -1727,6 +1748,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)struct file *file = (attr->ia_valid &ATTR_FILE ) ? attr->ia_file :NULL ;int ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (get_fuse_conn (inode)))return -EACCES ;
@@ -1785,6 +1809,9 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,struct inode *inode =d_inode (path->dentry);struct fuse_conn *fc =get_fuse_conn (inode); +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fc)) {if (!request_mask) {/*
fs/fuse/file.c +11 -8
@@ -226,6 +226,9 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)bool dax_truncate = (file->f_flags &O_TRUNC ) && fc->atomic_o_trunc &&FUSE_IS_DAX (inode); +if (fuse_is_bad (inode)) +return -EIO ; + err =generic_file_open (inode, file);if (err)return err;
@@ -463,7 +466,7 @@ static int fuse_flush(struct file *file, fl_owner_t id)FUSE_ARGS (args);int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ; err =write_inode_now (inode,1 );
@@ -535,7 +538,7 @@ static int fuse_fsync(struct file *file, loff_t start, loff_t end,struct fuse_conn *fc =get_fuse_conn (inode);int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;inode_lock (inode);
@@ -859,7 +862,7 @@ static int fuse_readpage(struct file *file, struct page *page)int err; err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out; err =fuse_do_readpage (file, page);
@@ -952,7 +955,7 @@ static void fuse_readahead(struct readahead_control *rac)struct fuse_conn *fc =get_fuse_conn (inode);unsigned int i, max_pages, nr_pages =0 ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return ; max_pages = min_t(unsigned int, fc->max_pages,
@@ -1555,7 +1558,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)struct fuse_file *ff = file->private_data;struct inode *inode =file_inode (file); -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;if (FUSE_IS_DAX (inode))
@@ -1573,7 +1576,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)struct fuse_file *ff = file->private_data;struct inode *inode =file_inode (file); -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;if (FUSE_IS_DAX (inode))
@@ -2172,7 +2175,7 @@ static int fuse_writepages(struct address_space *mapping,int err; err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out; data.inode = inode;
@@ -2954,7 +2957,7 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd,if (!fuse_allow_current_process (fc))return -EACCES ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;return fuse_do_ioctl (file, cmd, arg, flags);
fs/fuse/fuse_i.h +12 -0
@@ -172,6 +172,8 @@ enum {FUSE_I_INIT_RDPLUS ,/** An operation changing file size is in progress */ FUSE_I_SIZE_UNSTABLE , +/* Bad inode */ + FUSE_I_BAD, };struct fuse_conn ;
@@ -858,6 +860,16 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc)return atomic64_read (&fc->attr_version); } +static inline void fuse_make_bad (struct inode *inode) +{ +set_bit (FUSE_I_BAD , &get_fuse_inode (inode)->state); +} + +static inline bool fuse_is_bad (struct inode *inode) +{ +return unlikely (test_bit (FUSE_I_BAD , &get_fuse_inode (inode)->state)); +} +/** Device operations */ extern const struct file_operations fuse_dev_operations;
fs/fuse/inode.c +2 -2
@@ -132,7 +132,7 @@ static void fuse_evict_inode(struct inode *inode) fi->forget =NULL ; } } -if (S_ISREG (inode->i_mode) && !is_bad_inode (inode)) { +if (S_ISREG (inode->i_mode) && !fuse_is_bad (inode)) {WARN_ON (!list_empty (&fi->write_files));WARN_ON (!list_empty (&fi->queued_writes)); }
@@ -342,7 +342,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,unlock_new_inode (inode); }else if ((inode->i_mode ^ attr->mode) &S_IFMT ) {/* Inode has changed type, any I/O on the old should fail */ -make_bad_inode (inode); +fuse_make_bad (inode);iput (inode); goto retry; }
fs/fuse/readdir.c +2 -2
@@ -207,7 +207,7 @@ static int fuse_direntplus_link(struct file *file,dput (dentry); goto retry; } -if (is_bad_inode (inode)) { +if (fuse_is_bad (inode)) {dput (dentry);return -EIO ; }
@@ -568,7 +568,7 @@ int fuse_readdir(struct file *file, struct dir_context *ctx)struct inode *inode =file_inode (file);int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;mutex_lock (&ff->readdir.lock);
fs/fuse/xattr.c +9 -0
@@ -113,6 +113,9 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)struct fuse_getxattr_out outarg;ssize_t ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fm->fc))return -EACCES ;
@@ -178,6 +181,9 @@ static int fuse_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) { + if (fuse_is_bad(inode)) + return -EIO; +return fuse_getxattr (inode, name, value, size); }
@@ -186,6 +192,9 @@ static int fuse_xattr_set(const struct xattr_handler *handler, const char *name, const void *value, size_t size, int flags) { + if (fuse_is_bad(inode)) + return -EIO; +if (!value)return fuse_removexattr (inode, name);
fs/proc/base.c +5 -5
@@ -405,11 +405,11 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,static int lock_trace (struct task_struct *task) { -int err =mutex_lock_killable (&task->signal->exec_update_mutex); +int err =down_read_killable (&task->signal->exec_update_lock);if (err)return err;if (!ptrace_may_access (task,PTRACE_MODE_ATTACH_FSCREDS )) { -mutex_unlock (&task->signal->exec_update_mutex); +up_read (&task->signal->exec_update_lock);return -EPERM ; }return 0 ;
@@ -417,7 +417,7 @@ static int lock_trace(struct task_struct *task)static void unlock_trace (struct task_struct *task) { -mutex_unlock (&task->signal->exec_update_mutex); +up_read (&task->signal->exec_update_lock); }#ifdef CONFIG_STACKTRACE
@@ -2930,7 +2930,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whunsigned long flags;int result; - result =mutex_lock_killable (&task->signal->exec_update_mutex); + result =down_read_killable (&task->signal->exec_update_lock);if (result)return result;
@@ -2966,7 +2966,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh result =0 ; out_unlock: -mutex_unlock (&task->signal->exec_update_mutex); +up_read (&task->signal->exec_update_lock);return result; }
include/linux/kdev_t.h +11 -11
@@ -21,61 +21,61 @@ })/* acceptable for old filesystems */ -static inline bool old_valid_dev (dev_t dev) +static __always_inline bool old_valid_dev(dev_t dev) {return MAJOR (dev) <256 &&MINOR (dev) <256 ; } -static inline u16 old_encode_dev (dev_t dev) +static __always_inline u16 old_encode_dev(dev_t dev) {return (MAJOR (dev) <<8 ) |MINOR (dev); } -static inline dev_t old_decode_dev (u16 val) +static __always_inline dev_t old_decode_dev(u16 val) {return MKDEV ((val >>8 ) &255 , val &255 ); } -static inline u32 new_encode_dev (dev_t dev) +static __always_inline u32 new_encode_dev(dev_t dev) {unsigned major =MAJOR (dev);unsigned minor =MINOR (dev);return (minor &0xff ) | (major <<8 ) | ((minor & ~0xff ) <<12 ); } -static inline dev_t new_decode_dev (u32 dev) +static __always_inline dev_t new_decode_dev(u32 dev) {unsigned major = (dev &0xfff00 ) >>8 ;unsigned minor = (dev &0xff ) | ((dev >>12 ) &0xfff00 );return MKDEV (major, minor); } -static inline u64 huge_encode_dev (dev_t dev) +static __always_inline u64 huge_encode_dev(dev_t dev) {return new_encode_dev (dev); } -static inline dev_t huge_decode_dev (u64 dev) +static __always_inline dev_t huge_decode_dev(u64 dev) {return new_decode_dev (dev); } -static inline int sysv_valid_dev (dev_t dev) +static __always_inline int sysv_valid_dev(dev_t dev) {return MAJOR (dev) < (1 <<14 ) &&MINOR (dev) < (1 <<18 ); } -static inline u32 sysv_encode_dev (dev_t dev) +static __always_inline u32 sysv_encode_dev(dev_t dev) {return MINOR (dev) | (MAJOR (dev) <<18 ); } -static inline unsigned sysv_major (u32 dev) +static __always_inline unsigned sysv_major (u32 dev) {return (dev >>18 ) &0x3fff ; } -static inline unsigned sysv_minor (u32 dev) +static __always_inline unsigned sysv_minor (u32 dev) {return dev &0x3ffff ; }
include/linux/rwsem.h +3 -0
@@ -123,6 +123,7 @@ static inline int rwsem_is_contended(struct rw_semaphore *sem)* lock for reading */ extern void down_read (struct rw_semaphore *sem); +extern int __must_check down_read_interruptible (struct rw_semaphore *sem);extern int __must_check down_read_killable (struct rw_semaphore *sem);/*
@@ -171,6 +172,7 @@ extern void downgrade_write(struct rw_semaphore *sem);* See Documentation/locking/lockdep-design.rst for more details.) */ extern void down_read_nested (struct rw_semaphore *sem,int subclass); +extern int __must_check down_read_killable_nested (struct rw_semaphore *sem,int subclass);extern void down_write_nested (struct rw_semaphore *sem,int subclass);extern int down_write_killable_nested (struct rw_semaphore *sem,int subclass);extern void _down_write_nest_lock (struct rw_semaphore *sem,struct lockdep_map *nest_lock);
@@ -191,6 +193,7 @@ extern void down_read_non_owner(struct rw_semaphore *sem);extern void up_read_non_owner (struct rw_semaphore *sem);#else # define down_read_nested (sem, subclass) down_read(sem) +# define down_read_killable_nested (sem, subclass) down_read_killable(sem)# define down_write_nest_lock (sem, nest_lock) down_write(sem)# define down_write_nested (sem, subclass) down_write(sem)# define down_write_killable_nested (sem, subclass) down_write_killable(sem)
include/linux/sched/signal.h +6 -5
@@ -228,12 +228,13 @@ struct signal_struct {* credential calculations * (notably. ptrace) * Deprecated do not use in new code. -* Use exec_update_mutex instead. -*/ -struct mutex exec_update_mutex;/* Held while task_struct is being -* updated during exec, and may have -* inconsistent permissions. +* Use exec_update_lock instead. */ +struct rw_semaphore exec_update_lock;/* Held while task_struct is +* being updated during exec, +* and may have inconsistent +* permissions. +*/ } __randomize_layout;/*
include/rdma/ib_verbs.h +50 -23
139 lines not on this page · raw message
init/init_task.c +1 -1
@@ -26,7 +26,7 @@ static struct signal_struct init_signals = { .multiprocess = HLIST_HEAD_INIT, .rlim = INIT_RLIMITS, .cred_guard_mutex = __MUTEX_INITIALIZER(init_signals.cred_guard_mutex), - .exec_update_mutex =__MUTEX_INITIALIZER (init_signals.exec_update_mutex), + .exec_update_lock =__RWSEM_INITIALIZER (init_signals.exec_update_lock), #ifdef CONFIG_POSIX_TIMERS .posix_timers =LIST_HEAD_INIT (init_signals.posix_timers), .cputimer = {
kernel/events/core.c +26 -26
100 lines not on this page · raw message
kernel/fork.c +3 -3
@@ -1222,7 +1222,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)struct mm_struct *mm;int err; - err =mutex_lock_killable (&task->signal->exec_update_mutex); + err =down_read_killable (&task->signal->exec_update_lock);if (err)return ERR_PTR (err);
@@ -1232,7 +1232,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)mmput (mm); mm =ERR_PTR (-EACCES ); } -mutex_unlock (&task->signal->exec_update_mutex); +up_read (&task->signal->exec_update_lock);return mm; }
@@ -1592,7 +1592,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) sig->oom_score_adj_min = current->signal->oom_score_adj_min;mutex_init (&sig->cred_guard_mutex); -mutex_init (&sig->exec_update_mutex); +init_rwsem (&sig->exec_update_lock);return 0 ; }
kernel/kcmp.c +15 -15
@@ -75,25 +75,25 @@ get_file_raw_ptr(struct task_struct *task, unsigned int idx)return file; } -static void kcmp_unlock (struct mutex *m1,struct mutex *m2) +static void kcmp_unlock (struct rw_semaphore *l1,struct rw_semaphore *l2) { -if (likely (m2 != m1)) -mutex_unlock (m2); -mutex_unlock (m1); +if (likely (l2 != l1)) +up_read (l2); +up_read (l1); } -static int kcmp_lock (struct mutex *m1,struct mutex *m2) +static int kcmp_lock (struct rw_semaphore *l1,struct rw_semaphore *l2) {int err; -if (m2 > m1) -swap (m1, m2); +if (l2 > l1) +swap (l1, l2); - err =mutex_lock_killable (m1); -if (!err &&likely (m1 != m2)) { - err =mutex_lock_killable_nested (m2,SINGLE_DEPTH_NESTING ); + err =down_read_killable (l1); +if (!err &&likely (l1 != l2)) { + err =down_read_killable_nested (l2,SINGLE_DEPTH_NESTING );if (err) -mutex_unlock (m1); +up_read (l1); }return err;
@@ -173,8 +173,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,/* * One should have enough rights to inspect task details. */ - ret =kcmp_lock (&task1->signal->exec_update_mutex, - &task2->signal->exec_update_mutex); + ret =kcmp_lock (&task1->signal->exec_update_lock, + &task2->signal->exec_update_lock);if (ret) goto err; if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) ||
@@ -229,8 +229,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type, } err_unlock: -kcmp_unlock (&task1->signal->exec_update_mutex, - &task2->signal->exec_update_mutex); +kcmp_unlock (&task1->signal->exec_update_lock, + &task2->signal->exec_update_lock); err:put_task_struct (task1);put_task_struct (task2);
kernel/locking/rwsem.c +40 -0
@@ -1345,6 +1345,18 @@ static inline void __down_read(struct rw_semaphore *sem) } } +static inline int __down_read_interruptible (struct rw_semaphore *sem) +{ +if (!rwsem_read_trylock (sem)) { +if (IS_ERR (rwsem_down_read_slowpath (sem,TASK_INTERRUPTIBLE ))) +return -EINTR ; +DEBUG_RWSEMS_WARN_ON (!is_rwsem_reader_owned (sem), sem); + }else { +rwsem_set_reader_owned (sem); + } +return 0 ; +} +static inline int __down_read_killable (struct rw_semaphore *sem) {if (!rwsem_read_trylock (sem)) {
@@ -1495,6 +1507,20 @@ void __sched down_read(struct rw_semaphore *sem) }EXPORT_SYMBOL (down_read); +int __sched down_read_interruptible(struct rw_semaphore *sem) +{ +might_sleep (); +rwsem_acquire_read (&sem->dep_map,0 ,0 , _RET_IP_); + +if (LOCK_CONTENDED_RETURN (sem, __down_read_trylock, __down_read_interruptible)) { +rwsem_release (&sem->dep_map, _RET_IP_); +return -EINTR ; + } + +return 0 ; +} +EXPORT_SYMBOL (down_read_interruptible); + int __sched down_read_killable(struct rw_semaphore *sem) {might_sleep ();
@@ -1605,6 +1631,20 @@ void down_read_nested(struct rw_semaphore *sem, int subclass) }EXPORT_SYMBOL (down_read_nested); +int down_read_killable_nested (struct rw_semaphore *sem,int subclass) +{ +might_sleep (); +rwsem_acquire_read (&sem->dep_map, subclass,0 , _RET_IP_); + +if (LOCK_CONTENDED_RETURN (sem, __down_read_trylock, __down_read_killable)) { +rwsem_release (&sem->dep_map, _RET_IP_); +return -EINTR ; + } + +return 0 ; +} +EXPORT_SYMBOL (down_read_killable_nested); +void _down_write_nest_lock (struct rw_semaphore *sem,struct lockdep_map *nest) {might_sleep ();
kernel/pid.c +2 -2
@@ -628,7 +628,7 @@ static struct file *__pidfd_fget(struct task_struct *task, int fd)struct file *file;int ret; - ret =mutex_lock_killable (&task->signal->exec_update_mutex); + ret =down_read_killable (&task->signal->exec_update_lock);if (ret)return ERR_PTR (ret);
@@ -637,7 +637,7 @@ static struct file *__pidfd_fget(struct task_struct *task, int fd)else file =ERR_PTR (-EPERM ); -mutex_unlock (&task->signal->exec_update_mutex); +up_read (&task->signal->exec_update_lock);return file ?:ERR_PTR (-EBADF ); }
net/bluetooth/hci_core.c +1 -1
@@ -763,7 +763,7 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)hci_req_add (req,HCI_OP_LE_CLEAR_RESOLV_LIST ,0 ,NULL ); } -if (hdev->commands[35 ] &0x40 ) { +if (hdev->commands[35 ] &0x04 ) {__le16 rpa_timeout =cpu_to_le16 (hdev->rpa_timeout);/* Set RPA timeout */
sound/pci/hda/patch_hdmi.c +1 -1
@@ -1736,7 +1736,7 @@ static void silent_stream_disable(struct hda_codec *codec, per_pin->silent_stream = false; unlock_out: -mutex_unlock (&spec->pcm_lock); +mutex_unlock (&per_pin->lock); }/* update ELD and jack state via audio component */
sound/pci/hda/patch_realtek.c +1 -1
@@ -7885,7 +7885,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1028 ,0x09bf ,"Dell Precision" ,ALC233_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x0a2e ,"Dell" ,ALC236_FIXUP_DELL_AIO_HEADSET_MIC ),SND_PCI_QUIRK (0x1028 ,0x0a30 ,"Dell" ,ALC236_FIXUP_DELL_AIO_HEADSET_MIC ), -SND_PCI_QUIRK (0x1028 ,0x0a58 ,"Dell Precision 3650 Tower" ,ALC255_FIXUP_DELL_HEADSET_MIC ), +SND_PCI_QUIRK (0x1028 ,0x0a58 ,"Dell" ,ALC255_FIXUP_DELL_HEADSET_MIC ),SND_PCI_QUIRK (0x1028 ,0x164a ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x164b ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),