From 9c28f2ece477ac3cb71e23d404329c1aed6bc270 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Fri, 26 Feb 2016 18:43:35 +0100 Subject: [PATCH] Lemaker Guitar upstream patches for legacy kernel --- patch/kernel/s500-next/patch-3.10.96-97.patch | 2341 +++++++++++++++++ patch/kernel/s500-next/patch-3.10.97-98.patch | 1792 +++++++++++++ 2 files changed, 4133 insertions(+) create mode 100644 patch/kernel/s500-next/patch-3.10.96-97.patch create mode 100644 patch/kernel/s500-next/patch-3.10.97-98.patch diff --git a/patch/kernel/s500-next/patch-3.10.96-97.patch b/patch/kernel/s500-next/patch-3.10.96-97.patch new file mode 100644 index 0000000000..487d76eb1e --- /dev/null +++ b/patch/kernel/s500-next/patch-3.10.96-97.patch @@ -0,0 +1,2341 @@ +diff --git a/Makefile b/Makefile +index c88ea5d8d19c..f26470169c70 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 96 ++SUBLEVEL = 97 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h +index 294d251ca7b2..2ae13ce592e8 100644 +--- a/arch/parisc/include/uapi/asm/mman.h ++++ b/arch/parisc/include/uapi/asm/mman.h +@@ -46,16 +46,6 @@ + #define MADV_DONTFORK 10 /* don't inherit across fork */ + #define MADV_DOFORK 11 /* do inherit across fork */ + +-/* The range 12-64 is reserved for page size specification. */ +-#define MADV_4K_PAGES 12 /* Use 4K pages */ +-#define MADV_16K_PAGES 14 /* Use 16K pages */ +-#define MADV_64K_PAGES 16 /* Use 64K pages */ +-#define MADV_256K_PAGES 18 /* Use 256K pages */ +-#define MADV_1M_PAGES 20 /* Use 1 Megabyte pages */ +-#define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */ +-#define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */ +-#define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */ +- + #define MADV_MERGEABLE 65 /* KSM may merge identical pages */ + #define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */ + +diff --git a/arch/parisc/include/uapi/asm/siginfo.h b/arch/parisc/include/uapi/asm/siginfo.h +index d7034728f377..1c75565d984b 100644 +--- a/arch/parisc/include/uapi/asm/siginfo.h ++++ b/arch/parisc/include/uapi/asm/siginfo.h +@@ -1,6 +1,10 @@ + #ifndef _PARISC_SIGINFO_H + #define _PARISC_SIGINFO_H + ++#if defined(__LP64__) ++#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) ++#endif ++ + #include + + #undef NSIGTRAP +diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c +index 940188d1942c..ae9aa83854c0 100644 +--- a/arch/parisc/kernel/signal.c ++++ b/arch/parisc/kernel/signal.c +@@ -449,6 +449,55 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, + regs->gr[28]); + } + ++/* ++ * Check how the syscall number gets loaded into %r20 within ++ * the delay branch in userspace and adjust as needed. ++ */ ++ ++static void check_syscallno_in_delay_branch(struct pt_regs *regs) ++{ ++ u32 opcode, source_reg; ++ u32 __user *uaddr; ++ int err; ++ ++ /* Usually we don't have to restore %r20 (the system call number) ++ * because it gets loaded in the delay slot of the branch external ++ * instruction via the ldi instruction. ++ * In some cases a register-to-register copy instruction might have ++ * been used instead, in which case we need to copy the syscall ++ * number into the source register before returning to userspace. ++ */ ++ ++ /* A syscall is just a branch, so all we have to do is fiddle the ++ * return pointer so that the ble instruction gets executed again. ++ */ ++ regs->gr[31] -= 8; /* delayed branching */ ++ ++ /* Get assembler opcode of code in delay branch */ ++ uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4); ++ err = get_user(opcode, uaddr); ++ if (err) ++ return; ++ ++ /* Check if delay branch uses "ldi int,%r20" */ ++ if ((opcode & 0xffff0000) == 0x34140000) ++ return; /* everything ok, just return */ ++ ++ /* Check if delay branch uses "nop" */ ++ if (opcode == INSN_NOP) ++ return; ++ ++ /* Check if delay branch uses "copy %rX,%r20" */ ++ if ((opcode & 0xffe0ffff) == 0x08000254) { ++ source_reg = (opcode >> 16) & 31; ++ regs->gr[source_reg] = regs->gr[20]; ++ return; ++ } ++ ++ pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n", ++ current->comm, task_pid_nr(current), opcode); ++} ++ + static inline void + syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) + { +@@ -471,10 +520,7 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) + } + /* fallthrough */ + case -ERESTARTNOINTR: +- /* A syscall is just a branch, so all +- * we have to do is fiddle the return pointer. +- */ +- regs->gr[31] -= 8; /* delayed branching */ ++ check_syscallno_in_delay_branch(regs); + break; + } + } +@@ -523,15 +569,9 @@ insert_restart_trampoline(struct pt_regs *regs) + } + case -ERESTARTNOHAND: + case -ERESTARTSYS: +- case -ERESTARTNOINTR: { +- /* Hooray for delayed branching. We don't +- * have to restore %r20 (the system call +- * number) because it gets loaded in the delay +- * slot of the branch external instruction. +- */ +- regs->gr[31] -= 8; ++ case -ERESTARTNOINTR: ++ check_syscallno_in_delay_branch(regs); + return; +- } + default: + break; + } +diff --git a/arch/sh/include/uapi/asm/unistd_64.h b/arch/sh/include/uapi/asm/unistd_64.h +index e6820c86e8c7..47ebd5b5ed55 100644 +--- a/arch/sh/include/uapi/asm/unistd_64.h ++++ b/arch/sh/include/uapi/asm/unistd_64.h +@@ -278,7 +278,7 @@ + #define __NR_fsetxattr 256 + #define __NR_getxattr 257 + #define __NR_lgetxattr 258 +-#define __NR_fgetxattr 269 ++#define __NR_fgetxattr 259 + #define __NR_listxattr 260 + #define __NR_llistxattr 261 + #define __NR_flistxattr 262 +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index 6ef6e2ad344e..0ca108f3c840 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -125,6 +125,23 @@ int af_alg_release(struct socket *sock) + } + EXPORT_SYMBOL_GPL(af_alg_release); + ++void af_alg_release_parent(struct sock *sk) ++{ ++ struct alg_sock *ask = alg_sk(sk); ++ bool last; ++ ++ sk = ask->parent; ++ ask = alg_sk(sk); ++ ++ lock_sock(sk); ++ last = !--ask->refcnt; ++ release_sock(sk); ++ ++ if (last) ++ sock_put(sk); ++} ++EXPORT_SYMBOL_GPL(af_alg_release_parent); ++ + static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + { + struct sock *sk = sock->sk; +@@ -132,6 +149,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + struct sockaddr_alg *sa = (void *)uaddr; + const struct af_alg_type *type; + void *private; ++ int err; + + if (sock->state == SS_CONNECTED) + return -EINVAL; +@@ -157,16 +175,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + return PTR_ERR(private); + } + ++ err = -EBUSY; + lock_sock(sk); ++ if (ask->refcnt) ++ goto unlock; + + swap(ask->type, type); + swap(ask->private, private); + ++ err = 0; ++ ++unlock: + release_sock(sk); + + alg_do_release(type, private); + +- return 0; ++ return err; + } + + static int alg_setkey(struct sock *sk, char __user *ukey, +@@ -199,11 +223,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + const struct af_alg_type *type; +- int err = -ENOPROTOOPT; ++ int err = -EBUSY; + + lock_sock(sk); ++ if (ask->refcnt) ++ goto unlock; ++ + type = ask->type; + ++ err = -ENOPROTOOPT; + if (level != SOL_ALG || !type) + goto unlock; + +@@ -247,14 +275,13 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) + security_sk_clone(sk, sk2); + + err = type->accept(ask->private, sk2); +- if (err) { +- sk_free(sk2); ++ if (err) + goto unlock; +- } + + sk2->sk_family = PF_ALG; + +- sock_hold(sk); ++ if (!ask->refcnt++) ++ sock_hold(sk); + alg_sk(sk2)->parent = sk; + alg_sk(sk2)->type = type; + +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index 850246206b12..c542c0d88afd 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -51,7 +51,8 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock, + + lock_sock(sk); + if (!ctx->more) { +- err = crypto_ahash_init(&ctx->req); ++ err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req), ++ &ctx->completion); + if (err) + goto unlock; + } +@@ -131,6 +132,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page, + } else { + if (!ctx->more) { + err = crypto_ahash_init(&ctx->req); ++ err = af_alg_wait_for_completion(err, &ctx->completion); + if (err) + goto unlock; + } +@@ -192,9 +194,14 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags) + struct sock *sk2; + struct alg_sock *ask2; + struct hash_ctx *ctx2; ++ bool more; + int err; + +- err = crypto_ahash_export(req, state); ++ lock_sock(sk); ++ more = ctx->more; ++ err = more ? crypto_ahash_export(req, state) : 0; ++ release_sock(sk); ++ + if (err) + return err; + +@@ -205,7 +212,10 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags) + sk2 = newsock->sk; + ask2 = alg_sk(sk2); + ctx2 = ask2->private; +- ctx2->more = 1; ++ ctx2->more = more; ++ ++ if (!more) ++ return err; + + err = crypto_ahash_import(&ctx2->req, state); + if (err) { +diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c +index c7666f401381..a3dfc0d83107 100644 +--- a/crypto/crypto_user.c ++++ b/crypto/crypto_user.c +@@ -477,6 +477,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + if (link->dump == NULL) + return -EINVAL; + ++ down_read(&crypto_alg_sem); + list_for_each_entry(alg, &crypto_alg_list, cra_list) + dump_alloc += CRYPTO_REPORT_MAXSIZE; + +@@ -486,8 +487,11 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + .done = link->done, + .min_dump_alloc = dump_alloc, + }; +- return netlink_dump_start(crypto_nlsk, skb, nlh, &c); ++ err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); + } ++ up_read(&crypto_alg_sem); ++ ++ return err; + } + + err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 9064a2f2760c..cb106934bf1c 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -247,6 +247,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ + { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ + { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */ ++ { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */ + { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index cf5f35877559..d04f5c8dbbdc 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -486,8 +486,8 @@ void ahci_save_initial_config(struct device *dev, + } + } + +- /* fabricate port_map from cap.nr_ports */ +- if (!port_map) { ++ /* fabricate port_map from cap.nr_ports for < AHCI 1.3 */ ++ if (!port_map && vers < 0x10300) { + port_map = (1 << ahci_nr_ports(cap)) - 1; + dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map); + +@@ -1244,6 +1244,15 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, + ata_tf_to_fis(tf, pmp, is_cmd, fis); + ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12)); + ++ /* set port value for softreset of Port Multiplier */ ++ if (pp->fbs_enabled && pp->fbs_last_dev != pmp) { ++ tmp = readl(port_mmio + PORT_FBS); ++ tmp &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC); ++ tmp |= pmp << PORT_FBS_DEV_OFFSET; ++ writel(tmp, port_mmio + PORT_FBS); ++ pp->fbs_last_dev = pmp; ++ } ++ + /* issue & wait */ + writel(1, port_mmio + PORT_CMD_ISSUE); + +diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c +index a6524c3efdf7..ce854bbd33ef 100644 +--- a/drivers/char/tpm/tpm_ibmvtpm.c ++++ b/drivers/char/tpm/tpm_ibmvtpm.c +@@ -529,7 +529,7 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, + } + ibmvtpm->rtce_size = be16_to_cpu(crq->len); + ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, +- GFP_KERNEL); ++ GFP_ATOMIC); + if (!ibmvtpm->rtce_buf) { + dev_err(ibmvtpm->dev, "Failed to allocate memory for rtce buffer\n"); + return; +diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c +index de904e6a4ab7..5da58e3899eb 100644 +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -490,8 +490,6 @@ static void hid_ctrl(struct urb *urb) + struct usbhid_device *usbhid = hid->driver_data; + int unplug = 0, status = urb->status; + +- spin_lock(&usbhid->lock); +- + switch (status) { + case 0: /* success */ + if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) +@@ -511,6 +509,8 @@ static void hid_ctrl(struct urb *urb) + hid_warn(urb->dev, "ctrl urb status %d received\n", status); + } + ++ spin_lock(&usbhid->lock); ++ + if (unplug) { + usbhid->ctrltail = usbhid->ctrlhead; + } else { +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index 0ba21b0f3972..eb7ddb20fd48 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1608,11 +1608,8 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, + /* + * Only pass ioctls through if the device sizes match exactly. + */ +- if (!bdev || ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) { +- int err = scsi_verify_blk_ioctl(NULL, cmd); +- if (err) +- r = err; +- } ++ if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) ++ r = scsi_verify_blk_ioctl(NULL, cmd); + + if (r == -ENOTCONN && !fatal_signal_pending(current)) + queue_work(kmultipathd, &m->process_queued_ios); +diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c +index b53669404cb5..6d7f4d950b8f 100644 +--- a/drivers/md/persistent-data/dm-btree.c ++++ b/drivers/md/persistent-data/dm-btree.c +@@ -455,8 +455,10 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root, + + r = insert_at(sizeof(__le64), pn, parent_index + 1, + le64_to_cpu(rn->keys[0]), &location); +- if (r) ++ if (r) { ++ unlock_block(s->info, right); + return r; ++ } + + if (key < le64_to_cpu(rn->keys[0])) { + unlock_block(s->info, right); +diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c +index dbcdfbf8aed0..11b0ef3a2858 100644 +--- a/drivers/media/pci/saa7134/saa7134-alsa.c ++++ b/drivers/media/pci/saa7134/saa7134-alsa.c +@@ -1145,6 +1145,8 @@ static int alsa_device_init(struct saa7134_dev *dev) + + static int alsa_device_exit(struct saa7134_dev *dev) + { ++ if (!snd_saa7134_cards[dev->nr]) ++ return 1; + + snd_card_free(snd_saa7134_cards[dev->nr]); + snd_saa7134_cards[dev->nr] = NULL; +@@ -1194,7 +1196,8 @@ static void saa7134_alsa_exit(void) + int idx; + + for (idx = 0; idx < SNDRV_CARDS; idx++) { +- snd_card_free(snd_saa7134_cards[idx]); ++ if (snd_saa7134_cards[idx]) ++ snd_card_free(snd_saa7134_cards[idx]); + } + + saa7134_dmasound_init = NULL; +diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +index e2b0a0969ebb..35fb8f0cb539 100644 +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -264,7 +264,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_ + + struct v4l2_standard32 { + __u32 index; +- __u32 id[2]; /* __u64 would get the alignment wrong */ ++ compat_u64 id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; +@@ -284,7 +284,7 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 + { + if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) || + put_user(kp->index, &up->index) || +- copy_to_user(up->id, &kp->id, sizeof(__u64)) || ++ put_user(kp->id, &up->id) || + copy_to_user(up->name, kp->name, 24) || + copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) || + put_user(kp->framelines, &up->framelines) || +@@ -576,10 +576,10 @@ struct v4l2_input32 { + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ +- v4l2_std_id std; ++ compat_u64 std; + __u32 status; + __u32 reserved[4]; +-} __attribute__ ((packed)); ++}; + + /* The 64-bit v4l2_input struct has extra padding at the end of the struct. + Otherwise it is identical to the 32-bit version. */ +@@ -719,6 +719,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext + struct v4l2_event32 { + __u32 type; + union { ++ compat_s64 value64; + __u8 data[64]; + } u; + __u32 pending; +diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c +index fd56f2563201..297fbc59a800 100644 +--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c ++++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c +@@ -117,7 +117,8 @@ static void vb2_dc_prepare(void *buf_priv) + if (!sgt || buf->db_attach) + return; + +- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); ++ dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, ++ buf->dma_dir); + } + + static void vb2_dc_finish(void *buf_priv) +@@ -129,7 +130,7 @@ static void vb2_dc_finish(void *buf_priv) + if (!sgt || buf->db_attach) + return; + +- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); ++ dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + } + + /*********************************************/ +diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c +index 301493382cd0..f8013c1d8cd5 100644 +--- a/drivers/mtd/mtdpart.c ++++ b/drivers/mtd/mtdpart.c +@@ -634,8 +634,10 @@ int add_mtd_partitions(struct mtd_info *master, + + for (i = 0; i < nbparts; i++) { + slave = allocate_partition(master, parts + i, i, cur_offset); +- if (IS_ERR(slave)) ++ if (IS_ERR(slave)) { ++ del_mtd_partitions(master); + return PTR_ERR(slave); ++ } + + mutex_lock(&mtd_partitions_mutex); + list_add(&slave->list, &mtd_partitions); +diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h +index af7d9f9b3b4d..beed58b0c795 100644 +--- a/drivers/net/wireless/ti/wlcore/io.h ++++ b/drivers/net/wireless/ti/wlcore/io.h +@@ -203,19 +203,23 @@ static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg, + + static inline void wl1271_power_off(struct wl1271 *wl) + { +- int ret; ++ int ret = 0; + + if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags)) + return; + +- ret = wl->if_ops->power(wl->dev, false); ++ if (wl->if_ops->power) ++ ret = wl->if_ops->power(wl->dev, false); + if (!ret) + clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + } + + static inline int wl1271_power_on(struct wl1271 *wl) + { +- int ret = wl->if_ops->power(wl->dev, true); ++ int ret = 0; ++ ++ if (wl->if_ops->power) ++ ret = wl->if_ops->power(wl->dev, true); + if (ret == 0) + set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + +diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c +index e26447832683..bfb57e671034 100644 +--- a/drivers/net/wireless/ti/wlcore/spi.c ++++ b/drivers/net/wireless/ti/wlcore/spi.c +@@ -72,7 +72,10 @@ + */ + #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) + +-#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) ++/* Maximum number of SPI write chunks */ ++#define WSPI_MAX_NUM_OF_CHUNKS \ ++ ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1) ++ + + struct wl12xx_spi_glue { + struct device *dev; +@@ -270,9 +273,10 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, + void *buf, size_t len, bool fixed) + { + struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); +- struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)]; ++ /* SPI write buffers - 2 for each chunk */ ++ struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; + struct spi_message m; +- u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; ++ u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */ + u32 *cmd; + u32 chunk_len; + int i; +diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c +index 157a57309601..4ef0dbdcace1 100644 +--- a/drivers/remoteproc/remoteproc_debugfs.c ++++ b/drivers/remoteproc/remoteproc_debugfs.c +@@ -156,7 +156,7 @@ rproc_recovery_write(struct file *filp, const char __user *user_buf, + char buf[10]; + int ret; + +- if (count > sizeof(buf)) ++ if (count < 1 || count > sizeof(buf)) + return count; + + ret = copy_from_user(buf, user_buf, count); +diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c +index 380387a47b1d..462af46ceee7 100644 +--- a/drivers/spi/spi-atmel.c ++++ b/drivers/spi/spi-atmel.c +@@ -594,7 +594,8 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, + + *plen = len; + +- if (atmel_spi_dma_slave_config(as, &slave_config, 8)) ++ if (atmel_spi_dma_slave_config(as, &slave_config, ++ xfer->bits_per_word)) + goto err_exit; + + /* Send both scatterlists */ +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 7c159634aaae..cc80ab14aa32 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -1047,7 +1047,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) + master->bus_num = -1; + master->num_chipselect = 1; + master->dev.class = &spi_master_class; +- master->dev.parent = get_device(dev); ++ master->dev.parent = dev; + spi_master_set_devdata(master, &master[1]); + + return master; +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 2967b6eb4c70..8977eaf24d9f 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -2576,6 +2576,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) + } + + /** ++ * tiocgetd - get line discipline ++ * @tty: tty device ++ * @p: pointer to user data ++ * ++ * Retrieves the line discipline id directly from the ldisc. ++ * ++ * Locking: waits for ldisc reference (in case the line discipline ++ * is changing or the tty is being hungup) ++ */ ++ ++static int tiocgetd(struct tty_struct *tty, int __user *p) ++{ ++ struct tty_ldisc *ld; ++ int ret; ++ ++ ld = tty_ldisc_ref_wait(tty); ++ ret = put_user(ld->ops->num, p); ++ tty_ldisc_deref(ld); ++ return ret; ++} ++ ++/** + * send_break - performed time break + * @tty: device to break on + * @duration: timeout in mS +@@ -2789,7 +2811,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + case TIOCGSID: + return tiocgsid(tty, real_tty, p); + case TIOCGETD: +- return put_user(tty->ldisc->ops->num, (int __user *)p); ++ return tiocgetd(tty, p); + case TIOCSETD: + return tiocsetd(tty, p); + case TIOCVHANGUP: +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 4dc18615cd0f..9dd6fa3a1260 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4788,6 +4788,9 @@ static int __init xhci_hcd_init(void) + { + int retval; + ++ if (usb_disabled()) ++ return -ENODEV; ++ + retval = xhci_register_pci(); + if (retval < 0) { + printk(KERN_DEBUG "Problem registering PCI driver."); +@@ -4816,9 +4819,6 @@ static int __init xhci_hcd_init(void) + /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ + BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + +- if (usb_disabled()) +- return -ENODEV; +- + return 0; + unreg_pci: + xhci_unregister_pci(); +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 72c14d7d604f..89ba7cfba5bc 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -98,6 +98,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ + { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ + { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ ++ { USB_DEVICE(0x10C4, 0x81D7) }, /* IAI Corp. RCB-CV-USB USB to RS485 Adaptor */ + { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ + { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ + { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 514f3117ee2b..4e865664699b 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -840,6 +840,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, ++ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) }, + { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, + + /* Papouch devices based on FTDI chip */ +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index bfb0ecd98808..3eff1d6a2b17 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -615,6 +615,7 @@ + */ + #define RATOC_VENDOR_ID 0x0584 + #define RATOC_PRODUCT_ID_USB60F 0xb020 ++#define RATOC_PRODUCT_ID_SCU18 0xb03a + + /* + * Infineon Technologies +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index bdbe642e6569..81f6a572f016 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -269,6 +269,8 @@ static void option_instat_callback(struct urb *urb); + #define TELIT_PRODUCT_CC864_SINGLE 0x1006 + #define TELIT_PRODUCT_DE910_DUAL 0x1010 + #define TELIT_PRODUCT_UE910_V2 0x1012 ++#define TELIT_PRODUCT_LE922_USBCFG0 0x1042 ++#define TELIT_PRODUCT_LE922_USBCFG3 0x1043 + #define TELIT_PRODUCT_LE920 0x1200 + #define TELIT_PRODUCT_LE910 0x1201 + +@@ -623,6 +625,16 @@ static const struct option_blacklist_info telit_le920_blacklist = { + .reserved = BIT(1) | BIT(5), + }; + ++static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { ++ .sendsetup = BIT(2), ++ .reserved = BIT(0) | BIT(1) | BIT(3), ++}; ++ ++static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = { ++ .sendsetup = BIT(0), ++ .reserved = BIT(1) | BIT(2) | BIT(3), ++}; ++ + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, +@@ -1168,6 +1180,10 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), ++ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3), ++ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), + .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), +@@ -1679,7 +1695,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index 4cc84c0c990d..0a7c68fa5e5e 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -158,7 +158,7 @@ static unsigned int product_5052_count; + /* the array dimension is the number of default entries plus */ + /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ + /* null entry */ +-static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { ++static struct usb_device_id ti_id_table_3410[16+TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, +@@ -184,7 +184,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, + }; + +-static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = { ++static struct usb_device_id ti_id_table_combined[20+2*TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, +diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c +index 727905de0ba4..605068e6acf2 100644 +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -551,6 +551,11 @@ static int treo_attach(struct usb_serial *serial) + (serial->num_interrupt_in == 0)) + return 0; + ++ if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) { ++ dev_err(&serial->interface->dev, "missing endpoints\n"); ++ return -ENODEV; ++ } ++ + /* + * It appears that Treos and Kyoceras want to use the + * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, +@@ -604,8 +609,10 @@ static int clie_5_attach(struct usb_serial *serial) + */ + + /* some sanity check */ +- if (serial->num_ports < 2) +- return -1; ++ if (serial->num_bulk_out < 2) { ++ dev_err(&serial->interface->dev, "missing bulk out endpoints\n"); ++ return -ENODEV; ++ } + + /* port 0 now uses the modified endpoint Address */ + port = serial->port[0]; +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 618bcc84a09e..948e6f21b594 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -682,16 +682,16 @@ static int load_elf_binary(struct linux_binprm *bprm) + */ + would_dump(bprm, interpreter); + +- retval = kernel_read(interpreter, 0, bprm->buf, +- BINPRM_BUF_SIZE); +- if (retval != BINPRM_BUF_SIZE) { ++ /* Get the exec headers */ ++ retval = kernel_read(interpreter, 0, ++ (void *)&loc->interp_elf_ex, ++ sizeof(loc->interp_elf_ex)); ++ if (retval != sizeof(loc->interp_elf_ex)) { + if (retval >= 0) + retval = -EIO; + goto out_free_dentry; + } + +- /* Get the exec headers */ +- loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); + break; + } + elf_ppnt++; +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 2a71466b0115..6f74b8919237 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -728,19 +729,55 @@ struct move_extent { + <= (EXT4_GOOD_OLD_INODE_SIZE + \ + (einode)->i_extra_isize)) \ + ++/* ++ * We use an encoding that preserves the times for extra epoch "00": ++ * ++ * extra msb of adjust for signed ++ * epoch 32-bit 32-bit tv_sec to ++ * bits time decoded 64-bit tv_sec 64-bit tv_sec valid time range ++ * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12-13..1969-12-31 ++ * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01-01..2038-01-19 ++ * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01-19..2106-02-07 ++ * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02-07..2174-02-25 ++ * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02-25..2242-03-16 ++ * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03-16..2310-04-04 ++ * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04-04..2378-04-22 ++ * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04-22..2446-05-10 ++ * ++ * Note that previous versions of the kernel on 64-bit systems would ++ * incorrectly use extra epoch bits 1,1 for dates between 1901 and ++ * 1970. e2fsck will correct this, assuming that it is run on the ++ * affected filesystem before 2242. ++ */ ++ + static inline __le32 ext4_encode_extra_time(struct timespec *time) + { +- return cpu_to_le32((sizeof(time->tv_sec) > 4 ? +- (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) | +- ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK)); ++ u32 extra = sizeof(time->tv_sec) > 4 ? ++ ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0; ++ return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS)); + } + + static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) + { +- if (sizeof(time->tv_sec) > 4) +- time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) +- << 32; +- time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; ++ if (unlikely(sizeof(time->tv_sec) > 4 && ++ (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) ++ /* Handle legacy encoding of pre-1970 dates with epoch ++ * bits 1,1. We assume that by kernel version 4.20, ++ * everyone will have run fsck over the affected ++ * filesystems to correct the problem. (This ++ * backwards compatibility may be removed before this ++ * time, at the discretion of the ext4 developers.) ++ */ ++ u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK; ++ if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0) ++ extra_bits = 0; ++ time->tv_sec += extra_bits << 32; ++#else ++ time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32; ++#endif ++ } ++ time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; + } + + #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index a69bd74ed390..fa7d2e668c3a 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1025,7 +1025,7 @@ exit_free: + * do not copy the full number of backups at this time. The resize + * which changed s_groups_count will backup again. + */ +-static void update_backups(struct super_block *sb, int blk_off, char *data, ++static void update_backups(struct super_block *sb, sector_t blk_off, char *data, + int size, int meta_bg) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); +@@ -1050,7 +1050,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data, + group = ext4_list_backups(sb, &three, &five, &seven); + last = sbi->s_groups_count; + } else { +- group = ext4_meta_bg_first_group(sb, group) + 1; ++ group = ext4_get_group_number(sb, blk_off) + 1; + last = (ext4_group_t)(group + EXT4_DESC_PER_BLOCK(sb) - 2); + } + +diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c +index e028b8eb1c40..0912b90e05bc 100644 +--- a/fs/fscache/netfs.c ++++ b/fs/fscache/netfs.c +@@ -45,9 +45,6 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) + netfs->primary_index->parent = &fscache_fsdef_index; + netfs->primary_index->netfs_data = netfs; + +- atomic_inc(&netfs->primary_index->parent->usage); +- atomic_inc(&netfs->primary_index->parent->n_children); +- + spin_lock_init(&netfs->primary_index->lock); + INIT_HLIST_HEAD(&netfs->primary_index->backing_objects); + +@@ -60,6 +57,9 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) + goto already_registered; + } + ++ atomic_inc(&netfs->primary_index->parent->usage); ++ atomic_inc(&netfs->primary_index->parent->n_children); ++ + list_add(&netfs->link, &fscache_netfs_list); + ret = 0; + +@@ -70,8 +70,7 @@ already_registered: + up_write(&fscache_addremove_sem); + + if (ret < 0) { +- netfs->primary_index->parent = NULL; +- __fscache_cookie_put(netfs->primary_index); ++ kmem_cache_free(fscache_cookie_jar, netfs->primary_index); + netfs->primary_index = NULL; + } + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index ec34e11d6854..21b828c713cc 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1936,6 +1936,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, + + if (!buffer_dirty(bh)) { + /* bdflush has written it. We can drop it now */ ++ __jbd2_journal_remove_checkpoint(jh); + goto zap_buffer; + } + +@@ -1965,6 +1966,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, + /* The orphan record's transaction has + * committed. We can cleanse this buffer */ + clear_buffer_jbddirty(bh); ++ __jbd2_journal_remove_checkpoint(jh); + goto zap_buffer; + } + } +diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c +index 2c119d5d04c9..d084200dbc4e 100644 +--- a/fs/ocfs2/dlm/dlmmaster.c ++++ b/fs/ocfs2/dlm/dlmmaster.c +@@ -2456,6 +2456,11 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, + spin_lock(&dlm->master_lock); + ret = dlm_add_migration_mle(dlm, res, mle, &oldmle, name, + namelen, target, dlm->node_num); ++ /* get an extra reference on the mle. ++ * otherwise the assert_master from the new ++ * master will destroy this. ++ */ ++ dlm_get_mle_inuse(mle); + spin_unlock(&dlm->master_lock); + spin_unlock(&dlm->spinlock); + +@@ -2491,6 +2496,7 @@ fail: + if (mle_added) { + dlm_mle_detach_hb_events(dlm, mle); + dlm_put_mle(mle); ++ dlm_put_mle_inuse(mle); + } else if (mle) { + kmem_cache_free(dlm_mle_cache, mle); + mle = NULL; +@@ -2508,17 +2514,6 @@ fail: + * ensure that all assert_master work is flushed. */ + flush_workqueue(dlm->dlm_worker); + +- /* get an extra reference on the mle. +- * otherwise the assert_master from the new +- * master will destroy this. +- * also, make sure that all callers of dlm_get_mle +- * take both dlm->spinlock and dlm->master_lock */ +- spin_lock(&dlm->spinlock); +- spin_lock(&dlm->master_lock); +- dlm_get_mle_inuse(mle); +- spin_unlock(&dlm->master_lock); +- spin_unlock(&dlm->spinlock); +- + /* notify new node and send all lock state */ + /* call send_one_lockres with migration flag. + * this serves as notice to the target node that a +@@ -3246,6 +3241,15 @@ top: + mle->new_master != dead_node) + continue; + ++ if (mle->new_master == dead_node && mle->inuse) { ++ mlog(ML_NOTICE, "%s: target %u died during " ++ "migration from %u, the MLE is " ++ "still keep used, ignore it!\n", ++ dlm->name, dead_node, ++ mle->master); ++ continue; ++ } ++ + /* If we have reached this point, this mle needs to be + * removed from the list and freed. */ + dlm_clean_migration_mle(dlm, mle); +diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c +index 9bd981cd3142..01c69f24e416 100644 +--- a/fs/ocfs2/dlm/dlmrecovery.c ++++ b/fs/ocfs2/dlm/dlmrecovery.c +@@ -2326,6 +2326,8 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) + break; + } + } ++ dlm_lockres_clear_refmap_bit(dlm, res, ++ dead_node); + spin_unlock(&res->spinlock); + continue; + } +diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c +index c327d4ee1235..7b3792e5844a 100644 +--- a/fs/sysv/inode.c ++++ b/fs/sysv/inode.c +@@ -161,14 +161,8 @@ void sysv_set_inode(struct inode *inode, dev_t rdev) + inode->i_fop = &sysv_dir_operations; + inode->i_mapping->a_ops = &sysv_aops; + } else if (S_ISLNK(inode->i_mode)) { +- if (inode->i_blocks) { +- inode->i_op = &sysv_symlink_inode_operations; +- inode->i_mapping->a_ops = &sysv_aops; +- } else { +- inode->i_op = &sysv_fast_symlink_inode_operations; +- nd_terminate_link(SYSV_I(inode)->i_data, inode->i_size, +- sizeof(SYSV_I(inode)->i_data) - 1); +- } ++ inode->i_op = &sysv_symlink_inode_operations; ++ inode->i_mapping->a_ops = &sysv_aops; + } else + init_special_inode(inode, inode->i_mode, rdev); + } +diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h +index d61c11170213..2f38daaab3d7 100644 +--- a/include/crypto/if_alg.h ++++ b/include/crypto/if_alg.h +@@ -30,6 +30,8 @@ struct alg_sock { + + struct sock *parent; + ++ unsigned int refcnt; ++ + const struct af_alg_type *type; + void *private; + }; +@@ -64,6 +66,7 @@ int af_alg_register_type(const struct af_alg_type *type); + int af_alg_unregister_type(const struct af_alg_type *type); + + int af_alg_release(struct socket *sock); ++void af_alg_release_parent(struct sock *sk); + int af_alg_accept(struct sock *sk, struct socket *newsock); + + int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, +@@ -80,11 +83,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk) + return (struct alg_sock *)sk; + } + +-static inline void af_alg_release_parent(struct sock *sk) +-{ +- sock_put(alg_sk(sk)->parent); +-} +- + static inline void af_alg_init_completion(struct af_alg_completion *completion) + { + init_completion(&completion->completion); +diff --git a/include/linux/signal.h b/include/linux/signal.h +index 2ac423bdb676..53944e50e421 100644 +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -247,7 +247,6 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); + extern void set_current_blocked(sigset_t *); + extern void __set_current_blocked(const sigset_t *); + extern int show_unhandled_signals; +-extern int sigsuspend(sigset_t *); + + struct sigaction { + #ifndef __ARCH_HAS_IRIX_SIGACTION +diff --git a/kernel/signal.c b/kernel/signal.c +index 2e51bcbea1e3..4d1f7fa3138d 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -3551,7 +3551,7 @@ SYSCALL_DEFINE0(pause) + + #endif + +-int sigsuspend(sigset_t *set) ++static int sigsuspend(sigset_t *set) + { + current->saved_sigmask = current->blocked; + set_current_blocked(set); +diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h +index 49b582a225b0..b9897e2be404 100644 +--- a/scripts/recordmcount.h ++++ b/scripts/recordmcount.h +@@ -377,7 +377,7 @@ static void nop_mcount(Elf_Shdr const *const relhdr, + + if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { + if (make_nop) +- ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset); ++ ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset)); + if (warn_on_notrace_sect && !once) { + printf("Section %s has mcount callers being ignored\n", + txtname); +diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c +index 3fdf998ad057..572f95175e97 100644 +--- a/sound/core/compress_offload.c ++++ b/sound/core/compress_offload.c +@@ -44,6 +44,13 @@ + #include + #include + ++/* struct snd_compr_codec_caps overflows the ioctl bit size for some ++ * architectures, so we need to disable the relevant ioctls. ++ */ ++#if _IOC_SIZEBITS < 14 ++#define COMPR_CODEC_CAPS_OVERFLOW ++#endif ++ + /* TODO: + * - add substream support for multiple devices in case of + * SND_DYNAMIC_MINORS is not used +@@ -427,6 +434,7 @@ out: + return retval; + } + ++#ifndef COMPR_CODEC_CAPS_OVERFLOW + static int + snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) + { +@@ -450,6 +458,7 @@ out: + kfree(caps); + return retval; + } ++#endif /* !COMPR_CODEC_CAPS_OVERFLOW */ + + /* revisit this with snd_pcm_preallocate_xxx */ + static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, +@@ -791,9 +800,11 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) + case _IOC_NR(SNDRV_COMPRESS_GET_CAPS): + retval = snd_compr_get_caps(stream, arg); + break; ++#ifndef COMPR_CODEC_CAPS_OVERFLOW + case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS): + retval = snd_compr_get_codec_caps(stream, arg); + break; ++#endif + case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS): + retval = snd_compr_set_params(stream, arg); + break; +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index 4c1cc51772e6..7417f96cea6e 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -834,7 +834,8 @@ static int choose_rate(struct snd_pcm_substream *substream, + return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); + } + +-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) ++static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, ++ bool trylock) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm_hw_params *params, *sparams; +@@ -848,7 +849,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) + struct snd_mask sformat_mask; + struct snd_mask mask; + +- if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ if (trylock) { ++ if (!(mutex_trylock(&runtime->oss.params_lock))) ++ return -EAGAIN; ++ } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -EINTR; + sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL); + params = kmalloc(sizeof(*params), GFP_KERNEL); +@@ -1091,7 +1095,7 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil + if (asubstream == NULL) + asubstream = substream; + if (substream->runtime->oss.params) { +- err = snd_pcm_oss_change_params(substream); ++ err = snd_pcm_oss_change_params(substream, false); + if (err < 0) + return err; + } +@@ -1130,7 +1134,7 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream) + return 0; + runtime = substream->runtime; + if (runtime->oss.params) { +- err = snd_pcm_oss_change_params(substream); ++ err = snd_pcm_oss_change_params(substream, false); + if (err < 0) + return err; + } +@@ -2168,7 +2172,7 @@ static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stre + runtime = substream->runtime; + + if (runtime->oss.params && +- (err = snd_pcm_oss_change_params(substream)) < 0) ++ (err = snd_pcm_oss_change_params(substream, false)) < 0) + return err; + + info.fragsize = runtime->oss.period_bytes; +@@ -2804,7 +2808,12 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) + return -EIO; + + if (runtime->oss.params) { +- if ((err = snd_pcm_oss_change_params(substream)) < 0) ++ /* use mutex_trylock() for params_lock for avoiding a deadlock ++ * between mmap_sem and params_lock taken by ++ * copy_from/to_user() in snd_pcm_oss_write/read() ++ */ ++ err = snd_pcm_oss_change_params(substream, true); ++ if (err < 0) + return err; + } + #ifdef CONFIG_SND_PCM_OSS_PLUGINS +diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c +index 7b596b5751db..500765f20843 100644 +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -934,31 +934,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, + unsigned long flags; + long result = 0, count1; + struct snd_rawmidi_runtime *runtime = substream->runtime; ++ unsigned long appl_ptr; + ++ spin_lock_irqsave(&runtime->lock, flags); + while (count > 0 && runtime->avail) { + count1 = runtime->buffer_size - runtime->appl_ptr; + if (count1 > count) + count1 = count; +- spin_lock_irqsave(&runtime->lock, flags); + if (count1 > (int)runtime->avail) + count1 = runtime->avail; ++ ++ /* update runtime->appl_ptr before unlocking for userbuf */ ++ appl_ptr = runtime->appl_ptr; ++ runtime->appl_ptr += count1; ++ runtime->appl_ptr %= runtime->buffer_size; ++ runtime->avail -= count1; ++ + if (kernelbuf) +- memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1); ++ memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1); + if (userbuf) { + spin_unlock_irqrestore(&runtime->lock, flags); + if (copy_to_user(userbuf + result, +- runtime->buffer + runtime->appl_ptr, count1)) { ++ runtime->buffer + appl_ptr, count1)) { + return result > 0 ? result : -EFAULT; + } + spin_lock_irqsave(&runtime->lock, flags); + } +- runtime->appl_ptr += count1; +- runtime->appl_ptr %= runtime->buffer_size; +- runtime->avail -= count1; +- spin_unlock_irqrestore(&runtime->lock, flags); + result += count1; + count -= count1; + } ++ spin_unlock_irqrestore(&runtime->lock, flags); + return result; + } + +@@ -1161,8 +1166,9 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, + unsigned long flags; + long count1, result; + struct snd_rawmidi_runtime *runtime = substream->runtime; ++ unsigned long appl_ptr; + +- if (snd_BUG_ON(!kernelbuf && !userbuf)) ++ if (!kernelbuf && !userbuf) + return -EINVAL; + if (snd_BUG_ON(!runtime->buffer)) + return -EINVAL; +@@ -1181,12 +1187,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, + count1 = count; + if (count1 > (long)runtime->avail) + count1 = runtime->avail; ++ ++ /* update runtime->appl_ptr before unlocking for userbuf */ ++ appl_ptr = runtime->appl_ptr; ++ runtime->appl_ptr += count1; ++ runtime->appl_ptr %= runtime->buffer_size; ++ runtime->avail -= count1; ++ + if (kernelbuf) +- memcpy(runtime->buffer + runtime->appl_ptr, ++ memcpy(runtime->buffer + appl_ptr, + kernelbuf + result, count1); + else if (userbuf) { + spin_unlock_irqrestore(&runtime->lock, flags); +- if (copy_from_user(runtime->buffer + runtime->appl_ptr, ++ if (copy_from_user(runtime->buffer + appl_ptr, + userbuf + result, count1)) { + spin_lock_irqsave(&runtime->lock, flags); + result = result > 0 ? result : -EFAULT; +@@ -1194,9 +1207,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, + } + spin_lock_irqsave(&runtime->lock, flags); + } +- runtime->appl_ptr += count1; +- runtime->appl_ptr %= runtime->buffer_size; +- runtime->avail -= count1; + result += count1; + count -= count1; + } +diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c +index c5b773a1eea9..4a09c3085ca4 100644 +--- a/sound/core/seq/oss/seq_oss_synth.c ++++ b/sound/core/seq/oss/seq_oss_synth.c +@@ -310,7 +310,7 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) + struct seq_oss_synth *rec; + struct seq_oss_synthinfo *info; + +- if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)) ++ if (snd_BUG_ON(dp->max_synthdev > SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)) + return; + for (i = 0; i < dp->max_synthdev; i++) { + info = &dp->synths[i]; +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index ecfbf5f39d38..08865dcbf5f1 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -678,6 +678,9 @@ static int deliver_to_subscribers(struct snd_seq_client *client, + else + down_read(&grp->list_mutex); + list_for_each_entry(subs, &grp->list_head, src_list) { ++ /* both ports ready? */ ++ if (atomic_read(&subs->ref_count) != 2) ++ continue; + event->dest = subs->info.dest; + if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) + /* convert time according to flag with subscription */ +diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c +index 9516e5ce3aad..67c91d226552 100644 +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -175,10 +175,6 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + } + + /* */ +-enum group_type { +- SRC_LIST, DEST_LIST +-}; +- + static int subscribe_port(struct snd_seq_client *client, + struct snd_seq_client_port *port, + struct snd_seq_port_subs_info *grp, +@@ -205,6 +201,20 @@ static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr, + return NULL; + } + ++static void delete_and_unsubscribe_port(struct snd_seq_client *client, ++ struct snd_seq_client_port *port, ++ struct snd_seq_subscribers *subs, ++ bool is_src, bool ack); ++ ++static inline struct snd_seq_subscribers * ++get_subscriber(struct list_head *p, bool is_src) ++{ ++ if (is_src) ++ return list_entry(p, struct snd_seq_subscribers, src_list); ++ else ++ return list_entry(p, struct snd_seq_subscribers, dest_list); ++} ++ + /* + * remove all subscribers on the list + * this is called from port_delete, for each src and dest list. +@@ -212,7 +222,7 @@ static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr, + static void clear_subscriber_list(struct snd_seq_client *client, + struct snd_seq_client_port *port, + struct snd_seq_port_subs_info *grp, +- int grptype) ++ int is_src) + { + struct list_head *p, *n; + +@@ -221,15 +231,13 @@ static void clear_subscriber_list(struct snd_seq_client *client, + struct snd_seq_client *c; + struct snd_seq_client_port *aport; + +- if (grptype == SRC_LIST) { +- subs = list_entry(p, struct snd_seq_subscribers, src_list); ++ subs = get_subscriber(p, is_src); ++ if (is_src) + aport = get_client_port(&subs->info.dest, &c); +- } else { +- subs = list_entry(p, struct snd_seq_subscribers, dest_list); ++ else + aport = get_client_port(&subs->info.sender, &c); +- } +- list_del(p); +- unsubscribe_port(client, port, grp, &subs->info, 0); ++ delete_and_unsubscribe_port(client, port, subs, is_src, false); ++ + if (!aport) { + /* looks like the connected port is being deleted. + * we decrease the counter, and when both ports are deleted +@@ -237,21 +245,14 @@ static void clear_subscriber_list(struct snd_seq_client *client, + */ + if (atomic_dec_and_test(&subs->ref_count)) + kfree(subs); +- } else { +- /* ok we got the connected port */ +- struct snd_seq_port_subs_info *agrp; +- agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src; +- down_write(&agrp->list_mutex); +- if (grptype == SRC_LIST) +- list_del(&subs->dest_list); +- else +- list_del(&subs->src_list); +- up_write(&agrp->list_mutex); +- unsubscribe_port(c, aport, agrp, &subs->info, 1); +- kfree(subs); +- snd_seq_port_unlock(aport); +- snd_seq_client_unlock(c); ++ continue; + } ++ ++ /* ok we got the connected port */ ++ delete_and_unsubscribe_port(c, aport, subs, !is_src, true); ++ kfree(subs); ++ snd_seq_port_unlock(aport); ++ snd_seq_client_unlock(c); + } + } + +@@ -264,8 +265,8 @@ static int port_delete(struct snd_seq_client *client, + snd_use_lock_sync(&port->use_lock); + + /* clear subscribers info */ +- clear_subscriber_list(client, port, &port->c_src, SRC_LIST); +- clear_subscriber_list(client, port, &port->c_dest, DEST_LIST); ++ clear_subscriber_list(client, port, &port->c_src, true); ++ clear_subscriber_list(client, port, &port->c_dest, false); + + if (port->private_free) + port->private_free(port->private_data); +@@ -484,85 +485,120 @@ static int match_subs_info(struct snd_seq_port_subscribe *r, + return 0; + } + +- +-/* connect two ports */ +-int snd_seq_port_connect(struct snd_seq_client *connector, +- struct snd_seq_client *src_client, +- struct snd_seq_client_port *src_port, +- struct snd_seq_client *dest_client, +- struct snd_seq_client_port *dest_port, +- struct snd_seq_port_subscribe *info) ++static int check_and_subscribe_port(struct snd_seq_client *client, ++ struct snd_seq_client_port *port, ++ struct snd_seq_subscribers *subs, ++ bool is_src, bool exclusive, bool ack) + { +- struct snd_seq_port_subs_info *src = &src_port->c_src; +- struct snd_seq_port_subs_info *dest = &dest_port->c_dest; +- struct snd_seq_subscribers *subs, *s; +- int err, src_called = 0; +- unsigned long flags; +- int exclusive; ++ struct snd_seq_port_subs_info *grp; ++ struct list_head *p; ++ struct snd_seq_subscribers *s; ++ int err; + +- subs = kzalloc(sizeof(*subs), GFP_KERNEL); +- if (! subs) +- return -ENOMEM; +- +- subs->info = *info; +- atomic_set(&subs->ref_count, 2); +- +- down_write(&src->list_mutex); +- down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); +- +- exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0; ++ grp = is_src ? &port->c_src : &port->c_dest; + err = -EBUSY; ++ down_write(&grp->list_mutex); + if (exclusive) { +- if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head)) ++ if (!list_empty(&grp->list_head)) + goto __error; + } else { +- if (src->exclusive || dest->exclusive) ++ if (grp->exclusive) + goto __error; + /* check whether already exists */ +- list_for_each_entry(s, &src->list_head, src_list) { +- if (match_subs_info(info, &s->info)) +- goto __error; +- } +- list_for_each_entry(s, &dest->list_head, dest_list) { +- if (match_subs_info(info, &s->info)) ++ list_for_each(p, &grp->list_head) { ++ s = get_subscriber(p, is_src); ++ if (match_subs_info(&subs->info, &s->info)) + goto __error; + } + } + +- if ((err = subscribe_port(src_client, src_port, src, info, +- connector->number != src_client->number)) < 0) +- goto __error; +- src_called = 1; +- +- if ((err = subscribe_port(dest_client, dest_port, dest, info, +- connector->number != dest_client->number)) < 0) ++ err = subscribe_port(client, port, grp, &subs->info, ack); ++ if (err < 0) { ++ grp->exclusive = 0; + goto __error; ++ } + + /* add to list */ +- write_lock_irqsave(&src->list_lock, flags); +- // write_lock(&dest->list_lock); // no other lock yet +- list_add_tail(&subs->src_list, &src->list_head); +- list_add_tail(&subs->dest_list, &dest->list_head); +- // write_unlock(&dest->list_lock); // no other lock yet +- write_unlock_irqrestore(&src->list_lock, flags); ++ write_lock_irq(&grp->list_lock); ++ if (is_src) ++ list_add_tail(&subs->src_list, &grp->list_head); ++ else ++ list_add_tail(&subs->dest_list, &grp->list_head); ++ grp->exclusive = exclusive; ++ atomic_inc(&subs->ref_count); ++ write_unlock_irq(&grp->list_lock); ++ err = 0; ++ ++ __error: ++ up_write(&grp->list_mutex); ++ return err; ++} + +- src->exclusive = dest->exclusive = exclusive; ++static void delete_and_unsubscribe_port(struct snd_seq_client *client, ++ struct snd_seq_client_port *port, ++ struct snd_seq_subscribers *subs, ++ bool is_src, bool ack) ++{ ++ struct snd_seq_port_subs_info *grp; ++ ++ grp = is_src ? &port->c_src : &port->c_dest; ++ down_write(&grp->list_mutex); ++ write_lock_irq(&grp->list_lock); ++ if (is_src) ++ list_del(&subs->src_list); ++ else ++ list_del(&subs->dest_list); ++ grp->exclusive = 0; ++ write_unlock_irq(&grp->list_lock); ++ up_write(&grp->list_mutex); ++ ++ unsubscribe_port(client, port, grp, &subs->info, ack); ++} ++ ++/* connect two ports */ ++int snd_seq_port_connect(struct snd_seq_client *connector, ++ struct snd_seq_client *src_client, ++ struct snd_seq_client_port *src_port, ++ struct snd_seq_client *dest_client, ++ struct snd_seq_client_port *dest_port, ++ struct snd_seq_port_subscribe *info) ++{ ++ struct snd_seq_subscribers *subs; ++ bool exclusive; ++ int err; ++ ++ subs = kzalloc(sizeof(*subs), GFP_KERNEL); ++ if (!subs) ++ return -ENOMEM; ++ ++ subs->info = *info; ++ atomic_set(&subs->ref_count, 0); ++ INIT_LIST_HEAD(&subs->src_list); ++ INIT_LIST_HEAD(&subs->dest_list); ++ ++ exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE); ++ ++ err = check_and_subscribe_port(src_client, src_port, subs, true, ++ exclusive, ++ connector->number != src_client->number); ++ if (err < 0) ++ goto error; ++ err = check_and_subscribe_port(dest_client, dest_port, subs, false, ++ exclusive, ++ connector->number != dest_client->number); ++ if (err < 0) ++ goto error_dest; + +- up_write(&dest->list_mutex); +- up_write(&src->list_mutex); + return 0; + +- __error: +- if (src_called) +- unsubscribe_port(src_client, src_port, src, info, +- connector->number != src_client->number); ++ error_dest: ++ delete_and_unsubscribe_port(src_client, src_port, subs, true, ++ connector->number != src_client->number); ++ error: + kfree(subs); +- up_write(&dest->list_mutex); +- up_write(&src->list_mutex); + return err; + } + +- + /* remove the connection */ + int snd_seq_port_disconnect(struct snd_seq_client *connector, + struct snd_seq_client *src_client, +@@ -572,37 +608,28 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, + struct snd_seq_port_subscribe *info) + { + struct snd_seq_port_subs_info *src = &src_port->c_src; +- struct snd_seq_port_subs_info *dest = &dest_port->c_dest; + struct snd_seq_subscribers *subs; + int err = -ENOENT; +- unsigned long flags; + + down_write(&src->list_mutex); +- down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); +- + /* look for the connection */ + list_for_each_entry(subs, &src->list_head, src_list) { + if (match_subs_info(info, &subs->info)) { +- write_lock_irqsave(&src->list_lock, flags); +- // write_lock(&dest->list_lock); // no lock yet +- list_del(&subs->src_list); +- list_del(&subs->dest_list); +- // write_unlock(&dest->list_lock); +- write_unlock_irqrestore(&src->list_lock, flags); +- src->exclusive = dest->exclusive = 0; +- unsubscribe_port(src_client, src_port, src, info, +- connector->number != src_client->number); +- unsubscribe_port(dest_client, dest_port, dest, info, +- connector->number != dest_client->number); +- kfree(subs); ++ atomic_dec(&subs->ref_count); /* mark as not ready */ + err = 0; + break; + } + } +- +- up_write(&dest->list_mutex); + up_write(&src->list_mutex); +- return err; ++ if (err < 0) ++ return err; ++ ++ delete_and_unsubscribe_port(src_client, src_port, subs, true, ++ connector->number != src_client->number); ++ delete_and_unsubscribe_port(dest_client, dest_port, subs, false, ++ connector->number != dest_client->number); ++ kfree(subs); ++ return 0; + } + + +diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c +index 24d44b2f61ac..6ec30a98a92a 100644 +--- a/sound/core/seq/seq_timer.c ++++ b/sound/core/seq/seq_timer.c +@@ -92,6 +92,9 @@ void snd_seq_timer_delete(struct snd_seq_timer **tmr) + + void snd_seq_timer_defaults(struct snd_seq_timer * tmr) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tmr->lock, flags); + /* setup defaults */ + tmr->ppq = 96; /* 96 PPQ */ + tmr->tempo = 500000; /* 120 BPM */ +@@ -107,21 +110,25 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr) + tmr->preferred_resolution = seq_default_timer_resolution; + + tmr->skew = tmr->skew_base = SKEW_BASE; ++ spin_unlock_irqrestore(&tmr->lock, flags); + } + +-void snd_seq_timer_reset(struct snd_seq_timer * tmr) ++static void seq_timer_reset(struct snd_seq_timer *tmr) + { +- unsigned long flags; +- +- spin_lock_irqsave(&tmr->lock, flags); +- + /* reset time & songposition */ + tmr->cur_time.tv_sec = 0; + tmr->cur_time.tv_nsec = 0; + + tmr->tick.cur_tick = 0; + tmr->tick.fraction = 0; ++} ++ ++void snd_seq_timer_reset(struct snd_seq_timer *tmr) ++{ ++ unsigned long flags; + ++ spin_lock_irqsave(&tmr->lock, flags); ++ seq_timer_reset(tmr); + spin_unlock_irqrestore(&tmr->lock, flags); + } + +@@ -140,8 +147,11 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, + tmr = q->timer; + if (tmr == NULL) + return; +- if (!tmr->running) ++ spin_lock_irqsave(&tmr->lock, flags); ++ if (!tmr->running) { ++ spin_unlock_irqrestore(&tmr->lock, flags); + return; ++ } + + resolution *= ticks; + if (tmr->skew != tmr->skew_base) { +@@ -150,8 +160,6 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, + (((resolution & 0xffff) * tmr->skew) >> 16); + } + +- spin_lock_irqsave(&tmr->lock, flags); +- + /* update timer */ + snd_seq_inc_time_nsec(&tmr->cur_time, resolution); + +@@ -298,26 +306,30 @@ int snd_seq_timer_open(struct snd_seq_queue *q) + t->callback = snd_seq_timer_interrupt; + t->callback_data = q; + t->flags |= SNDRV_TIMER_IFLG_AUTO; ++ spin_lock_irq(&tmr->lock); + tmr->timeri = t; ++ spin_unlock_irq(&tmr->lock); + return 0; + } + + int snd_seq_timer_close(struct snd_seq_queue *q) + { + struct snd_seq_timer *tmr; ++ struct snd_timer_instance *t; + + tmr = q->timer; + if (snd_BUG_ON(!tmr)) + return -EINVAL; +- if (tmr->timeri) { +- snd_timer_stop(tmr->timeri); +- snd_timer_close(tmr->timeri); +- tmr->timeri = NULL; +- } ++ spin_lock_irq(&tmr->lock); ++ t = tmr->timeri; ++ tmr->timeri = NULL; ++ spin_unlock_irq(&tmr->lock); ++ if (t) ++ snd_timer_close(t); + return 0; + } + +-int snd_seq_timer_stop(struct snd_seq_timer * tmr) ++static int seq_timer_stop(struct snd_seq_timer *tmr) + { + if (! tmr->timeri) + return -EINVAL; +@@ -328,6 +340,17 @@ int snd_seq_timer_stop(struct snd_seq_timer * tmr) + return 0; + } + ++int snd_seq_timer_stop(struct snd_seq_timer *tmr) ++{ ++ unsigned long flags; ++ int err; ++ ++ spin_lock_irqsave(&tmr->lock, flags); ++ err = seq_timer_stop(tmr); ++ spin_unlock_irqrestore(&tmr->lock, flags); ++ return err; ++} ++ + static int initialize_timer(struct snd_seq_timer *tmr) + { + struct snd_timer *t; +@@ -360,13 +383,13 @@ static int initialize_timer(struct snd_seq_timer *tmr) + return 0; + } + +-int snd_seq_timer_start(struct snd_seq_timer * tmr) ++static int seq_timer_start(struct snd_seq_timer *tmr) + { + if (! tmr->timeri) + return -EINVAL; + if (tmr->running) +- snd_seq_timer_stop(tmr); +- snd_seq_timer_reset(tmr); ++ seq_timer_stop(tmr); ++ seq_timer_reset(tmr); + if (initialize_timer(tmr) < 0) + return -EINVAL; + snd_timer_start(tmr->timeri, tmr->ticks); +@@ -375,14 +398,25 @@ int snd_seq_timer_start(struct snd_seq_timer * tmr) + return 0; + } + +-int snd_seq_timer_continue(struct snd_seq_timer * tmr) ++int snd_seq_timer_start(struct snd_seq_timer *tmr) ++{ ++ unsigned long flags; ++ int err; ++ ++ spin_lock_irqsave(&tmr->lock, flags); ++ err = seq_timer_start(tmr); ++ spin_unlock_irqrestore(&tmr->lock, flags); ++ return err; ++} ++ ++static int seq_timer_continue(struct snd_seq_timer *tmr) + { + if (! tmr->timeri) + return -EINVAL; + if (tmr->running) + return -EBUSY; + if (! tmr->initialized) { +- snd_seq_timer_reset(tmr); ++ seq_timer_reset(tmr); + if (initialize_timer(tmr) < 0) + return -EINVAL; + } +@@ -392,11 +426,24 @@ int snd_seq_timer_continue(struct snd_seq_timer * tmr) + return 0; + } + ++int snd_seq_timer_continue(struct snd_seq_timer *tmr) ++{ ++ unsigned long flags; ++ int err; ++ ++ spin_lock_irqsave(&tmr->lock, flags); ++ err = seq_timer_continue(tmr); ++ spin_unlock_irqrestore(&tmr->lock, flags); ++ return err; ++} ++ + /* return current 'real' time. use timeofday() to get better granularity. */ + snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr) + { + snd_seq_real_time_t cur_time; ++ unsigned long flags; + ++ spin_lock_irqsave(&tmr->lock, flags); + cur_time = tmr->cur_time; + if (tmr->running) { + struct timeval tm; +@@ -412,7 +459,7 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr) + } + snd_seq_sanity_real_time(&cur_time); + } +- ++ spin_unlock_irqrestore(&tmr->lock, flags); + return cur_time; + } + +diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c +index 4b50e604276d..0fa691e01384 100644 +--- a/sound/core/seq/seq_virmidi.c ++++ b/sound/core/seq/seq_virmidi.c +@@ -254,9 +254,13 @@ static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream) + */ + static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) + { ++ struct snd_virmidi_dev *rdev = substream->rmidi->private_data; + struct snd_virmidi *vmidi = substream->runtime->private_data; +- snd_midi_event_free(vmidi->parser); ++ ++ write_lock_irq(&rdev->filelist_lock); + list_del(&vmidi->list); ++ write_unlock_irq(&rdev->filelist_lock); ++ snd_midi_event_free(vmidi->parser); + substream->runtime->private_data = NULL; + kfree(vmidi); + return 0; +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 4e436fe53afa..d90d8f4b85fe 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -300,8 +300,7 @@ int snd_timer_open(struct snd_timer_instance **ti, + return 0; + } + +-static int _snd_timer_stop(struct snd_timer_instance *timeri, +- int keep_flag, int event); ++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event); + + /* + * close a timer instance +@@ -343,7 +342,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) + spin_unlock_irq(&timer->lock); + mutex_lock(®ister_mutex); + list_del(&timeri->open_list); +- if (timer && list_empty(&timer->open_list_head) && ++ if (list_empty(&timer->open_list_head) && + timer->hw.close) + timer->hw.close(timer); + /* remove slave links */ +@@ -415,7 +414,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) + spin_lock_irqsave(&timer->lock, flags); + list_for_each_entry(ts, &ti->slave_active_head, active_list) + if (ts->ccallback) +- ts->ccallback(ti, event + 100, &tstamp, resolution); ++ ts->ccallback(ts, event + 100, &tstamp, resolution); + spin_unlock_irqrestore(&timer->lock, flags); + } + +@@ -444,6 +443,10 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) + unsigned long flags; + + spin_lock_irqsave(&slave_active_lock, flags); ++ if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { ++ spin_unlock_irqrestore(&slave_active_lock, flags); ++ return -EBUSY; ++ } + timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; + if (timeri->master && timeri->timer) { + spin_lock(&timeri->timer->lock); +@@ -468,23 +471,30 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks) + return -EINVAL; + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { + result = snd_timer_start_slave(timeri); +- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); ++ if (result >= 0) ++ snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); + return result; + } + timer = timeri->timer; + if (timer == NULL) + return -EINVAL; + spin_lock_irqsave(&timer->lock, flags); ++ if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | ++ SNDRV_TIMER_IFLG_START)) { ++ result = -EBUSY; ++ goto unlock; ++ } + timeri->ticks = timeri->cticks = ticks; + timeri->pticks = 0; + result = snd_timer_start1(timer, timeri, ticks); ++ unlock: + spin_unlock_irqrestore(&timer->lock, flags); +- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); ++ if (result >= 0) ++ snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); + return result; + } + +-static int _snd_timer_stop(struct snd_timer_instance * timeri, +- int keep_flag, int event) ++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) + { + struct snd_timer *timer; + unsigned long flags; +@@ -493,19 +503,30 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, + return -ENXIO; + + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { +- if (!keep_flag) { +- spin_lock_irqsave(&slave_active_lock, flags); +- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; +- list_del_init(&timeri->ack_list); +- list_del_init(&timeri->active_list); ++ spin_lock_irqsave(&slave_active_lock, flags); ++ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { + spin_unlock_irqrestore(&slave_active_lock, flags); ++ return -EBUSY; + } ++ if (timeri->timer) ++ spin_lock(&timeri->timer->lock); ++ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; ++ list_del_init(&timeri->ack_list); ++ list_del_init(&timeri->active_list); ++ if (timeri->timer) ++ spin_unlock(&timeri->timer->lock); ++ spin_unlock_irqrestore(&slave_active_lock, flags); + goto __end; + } + timer = timeri->timer; + if (!timer) + return -EINVAL; + spin_lock_irqsave(&timer->lock, flags); ++ if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | ++ SNDRV_TIMER_IFLG_START))) { ++ spin_unlock_irqrestore(&timer->lock, flags); ++ return -EBUSY; ++ } + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); + if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && +@@ -520,9 +541,7 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, + } + } + } +- if (!keep_flag) +- timeri->flags &= +- ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); ++ timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); + spin_unlock_irqrestore(&timer->lock, flags); + __end: + if (event != SNDRV_TIMER_EVENT_RESOLUTION) +@@ -541,7 +560,7 @@ int snd_timer_stop(struct snd_timer_instance *timeri) + unsigned long flags; + int err; + +- err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP); ++ err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP); + if (err < 0) + return err; + timer = timeri->timer; +@@ -571,10 +590,15 @@ int snd_timer_continue(struct snd_timer_instance *timeri) + if (! timer) + return -EINVAL; + spin_lock_irqsave(&timer->lock, flags); ++ if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { ++ result = -EBUSY; ++ goto unlock; ++ } + if (!timeri->cticks) + timeri->cticks = 1; + timeri->pticks = 0; + result = snd_timer_start1(timer, timeri, timer->sticks); ++ unlock: + spin_unlock_irqrestore(&timer->lock, flags); + snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE); + return result; +@@ -585,7 +609,7 @@ int snd_timer_continue(struct snd_timer_instance *timeri) + */ + int snd_timer_pause(struct snd_timer_instance * timeri) + { +- return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE); ++ return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE); + } + + /* +@@ -702,8 +726,8 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) + ti->cticks = ti->ticks; + } else { + ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; +- if (--timer->running) +- list_del_init(&ti->active_list); ++ --timer->running; ++ list_del_init(&ti->active_list); + } + if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || + (ti->flags & SNDRV_TIMER_IFLG_FAST)) +diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c +index fd798f753609..982a2c2faf24 100644 +--- a/sound/drivers/dummy.c ++++ b/sound/drivers/dummy.c +@@ -109,6 +109,9 @@ struct dummy_timer_ops { + snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); + }; + ++#define get_dummy_ops(substream) \ ++ (*(const struct dummy_timer_ops **)(substream)->runtime->private_data) ++ + struct dummy_model { + const char *name; + int (*playback_constraints)(struct snd_pcm_runtime *runtime); +@@ -137,7 +140,6 @@ struct snd_dummy { + int iobox; + struct snd_kcontrol *cd_volume_ctl; + struct snd_kcontrol *cd_switch_ctl; +- const struct dummy_timer_ops *timer_ops; + }; + + /* +@@ -231,6 +233,8 @@ struct dummy_model *dummy_models[] = { + */ + + struct dummy_systimer_pcm { ++ /* ops must be the first item */ ++ const struct dummy_timer_ops *timer_ops; + spinlock_t lock; + struct timer_list timer; + unsigned long base_time; +@@ -368,6 +372,8 @@ static struct dummy_timer_ops dummy_systimer_ops = { + */ + + struct dummy_hrtimer_pcm { ++ /* ops must be the first item */ ++ const struct dummy_timer_ops *timer_ops; + ktime_t base_time; + ktime_t period_time; + atomic_t running; +@@ -494,31 +500,25 @@ static struct dummy_timer_ops dummy_hrtimer_ops = { + + static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + { +- struct snd_dummy *dummy = snd_pcm_substream_chip(substream); +- + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: +- return dummy->timer_ops->start(substream); ++ return get_dummy_ops(substream)->start(substream); + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: +- return dummy->timer_ops->stop(substream); ++ return get_dummy_ops(substream)->stop(substream); + } + return -EINVAL; + } + + static int dummy_pcm_prepare(struct snd_pcm_substream *substream) + { +- struct snd_dummy *dummy = snd_pcm_substream_chip(substream); +- +- return dummy->timer_ops->prepare(substream); ++ return get_dummy_ops(substream)->prepare(substream); + } + + static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) + { +- struct snd_dummy *dummy = snd_pcm_substream_chip(substream); +- +- return dummy->timer_ops->pointer(substream); ++ return get_dummy_ops(substream)->pointer(substream); + } + + static struct snd_pcm_hardware dummy_pcm_hardware = { +@@ -564,17 +564,19 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream) + struct snd_dummy *dummy = snd_pcm_substream_chip(substream); + struct dummy_model *model = dummy->model; + struct snd_pcm_runtime *runtime = substream->runtime; ++ const struct dummy_timer_ops *ops; + int err; + +- dummy->timer_ops = &dummy_systimer_ops; ++ ops = &dummy_systimer_ops; + #ifdef CONFIG_HIGH_RES_TIMERS + if (hrtimer) +- dummy->timer_ops = &dummy_hrtimer_ops; ++ ops = &dummy_hrtimer_ops; + #endif + +- err = dummy->timer_ops->create(substream); ++ err = ops->create(substream); + if (err < 0) + return err; ++ get_dummy_ops(substream) = ops; + + runtime->hw = dummy->pcm_hw; + if (substream->pcm->device & 1) { +@@ -596,7 +598,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream) + err = model->capture_constraints(substream->runtime); + } + if (err < 0) { +- dummy->timer_ops->free(substream); ++ get_dummy_ops(substream)->free(substream); + return err; + } + return 0; +@@ -604,8 +606,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream) + + static int dummy_pcm_close(struct snd_pcm_substream *substream) + { +- struct snd_dummy *dummy = snd_pcm_substream_chip(substream); +- dummy->timer_ops->free(substream); ++ get_dummy_ops(substream)->free(substream); + return 0; + } + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 69a2aafb0b0f..babbf238a648 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -2188,6 +2188,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { + SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), + SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), + SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), ++ SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), + + /* All Apple entries are in codec SSIDs */ + SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 02d26915b61d..c6d408c819b1 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -1248,7 +1248,8 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && +- (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && ++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) + continue; + + dev_dbg(be->dev, "ASoC: hw_free BE %s\n", +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index dabbe05d17f5..37ecba340876 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -2291,7 +2291,6 @@ int snd_usbmidi_create(struct snd_card *card, + else + err = snd_usbmidi_create_endpoints(umidi, endpoints); + if (err < 0) { +- snd_usbmidi_free(umidi); + return err; + } + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 94cd28c2bd8d..44550a4cf893 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -900,8 +900,12 @@ void snd_usb_set_interface_quirk(struct usb_device *dev) + * "Playback Design" products need a 50ms delay after setting the + * USB interface. + */ +- if (le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) ++ switch (le16_to_cpu(dev->descriptor.idVendor)) { ++ case 0x23ba: /* Playback Design */ ++ case 0x0644: /* TEAC Corp. */ + mdelay(50); ++ break; ++ } + } + + void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, +@@ -916,6 +920,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, + (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) + mdelay(20); + ++ /* ++ * "TEAC Corp." products need a 20ms delay after each ++ * class compliant request ++ */ ++ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x0644) && ++ (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) ++ mdelay(20); ++ + /* Marantz/Denon devices with USB DAC functionality need a delay + * after each class compliant request + */ diff --git a/patch/kernel/s500-next/patch-3.10.97-98.patch b/patch/kernel/s500-next/patch-3.10.97-98.patch new file mode 100644 index 0000000000..332f8fede4 --- /dev/null +++ b/patch/kernel/s500-next/patch-3.10.97-98.patch @@ -0,0 +1,1792 @@ +diff --git a/Makefile b/Makefile +index f26470169c70..dadd1edc6f84 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 10 +-SUBLEVEL = 97 ++SUBLEVEL = 98 + EXTRAVERSION = + NAME = TOSSUG Baby Fish + +diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c +index 2dc6da70ae59..d7ed252708c5 100644 +--- a/arch/arm/common/icst.c ++++ b/arch/arm/common/icst.c +@@ -16,7 +16,7 @@ + */ + #include + #include +- ++#include + #include + + /* +@@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div); + + unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) + { +- return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); ++ u64 dividend = p->ref * 2 * (u64)(vco.v + 8); ++ u32 divisor = (vco.r + 2) * p->s2div[vco.s]; ++ ++ do_div(dividend, divisor); ++ return (unsigned long)dividend; + } + + EXPORT_SYMBOL(icst_hz); +@@ -58,6 +62,7 @@ icst_hz_to_vco(const struct icst_params *p, unsigned long freq) + + if (f > p->vco_min && f <= p->vco_max) + break; ++ i++; + } while (i < 8); + + if (i >= 8) +diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c +index 0392112a5d70..a5ecef7188ba 100644 +--- a/arch/m32r/kernel/setup.c ++++ b/arch/m32r/kernel/setup.c +@@ -81,7 +81,10 @@ static struct resource code_resource = { + }; + + unsigned long memory_start; ++EXPORT_SYMBOL(memory_start); ++ + unsigned long memory_end; ++EXPORT_SYMBOL(memory_end); + + void __init setup_arch(char **); + int get_cpuinfo(char *); +diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h +index c48a95035a77..4dde707a6ff7 100644 +--- a/arch/x86/include/asm/segment.h ++++ b/arch/x86/include/asm/segment.h +@@ -212,8 +212,19 @@ + #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) + + #ifdef __KERNEL__ ++ ++/* ++ * early_idt_handler_array is an array of entry points referenced in the ++ * early IDT. For simplicity, it's a real array with one entry point ++ * every nine bytes. That leaves room for an optional 'push $0' if the ++ * vector has no error code (two bytes), a 'push $vector_number' (two ++ * bytes), and a jump to the common entry code (up to five bytes). ++ */ ++#define EARLY_IDT_HANDLER_SIZE 9 ++ + #ifndef __ASSEMBLY__ +-extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; ++ ++extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; + + /* + * Load a segment. Fall back on loading the zero +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 55b67614ed94..3b861b7661ee 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * real_mode_data) + clear_bss(); + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) +- set_intr_gate(i, &early_idt_handlers[i]); ++ set_intr_gate(i, &early_idt_handler_array[i]); + load_idt((const struct desc_ptr *)&idt_descr); + + copy_bootdata(__va(real_mode_data)); +diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S +index df63cae573e0..8060c8b95b3a 100644 +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -499,21 +499,22 @@ check_x87: + __INIT + setup_once: + /* +- * Set up a idt with 256 entries pointing to ignore_int, +- * interrupt gates. It doesn't actually load idt - that needs +- * to be done on each CPU. Interrupts are enabled elsewhere, +- * when we can be relatively sure everything is ok. ++ * Set up a idt with 256 interrupt gates that push zero if there ++ * is no error code and then jump to early_idt_handler_common. ++ * It doesn't actually load the idt - that needs to be done on ++ * each CPU. Interrupts are enabled elsewhere, when we can be ++ * relatively sure everything is ok. + */ + + movl $idt_table,%edi +- movl $early_idt_handlers,%eax ++ movl $early_idt_handler_array,%eax + movl $NUM_EXCEPTION_VECTORS,%ecx + 1: + movl %eax,(%edi) + movl %eax,4(%edi) + /* interrupt gate, dpl=0, present */ + movl $(0x8E000000 + __KERNEL_CS),2(%edi) +- addl $9,%eax ++ addl $EARLY_IDT_HANDLER_SIZE,%eax + addl $8,%edi + loop 1b + +@@ -545,26 +546,28 @@ setup_once: + andl $0,setup_once_ref /* Once is enough, thanks */ + ret + +-ENTRY(early_idt_handlers) ++ENTRY(early_idt_handler_array) + # 36(%esp) %eflags + # 32(%esp) %cs + # 28(%esp) %eip + # 24(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushl $0 # Dummy error code, to make stack frame uniform + .endif + pushl $i # 20(%esp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr +-ENDPROC(early_idt_handlers) ++ENDPROC(early_idt_handler_array) + +- /* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%esp) # X86_TRAP_NMI +@@ -624,7 +627,7 @@ ex_entry: + is_nmi: + addl $8,%esp /* drop vector number and error code */ + iret +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + /* This is the default interrupt "handler" :-) */ + ALIGN +diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S +index 3280489905a8..54bf9c2d0d13 100644 +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -329,26 +329,28 @@ bad_address: + jmp bad_address + + __INIT +- .globl early_idt_handlers +-early_idt_handlers: ++ENTRY(early_idt_handler_array) + # 104(%rsp) %rflags + # 96(%rsp) %cs + # 88(%rsp) %rip + # 80(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushq $0 # Dummy error code, to make stack frame uniform + .endif + pushq $i # 72(%rsp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr ++ENDPROC(early_idt_handler_array) + +-/* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%rsp) # X86_TRAP_NMI +@@ -420,7 +422,7 @@ ENTRY(early_idt_handler) + is_nmi: + addq $16,%rsp # drop vector number and error code + INTERRUPT_RETURN +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + __INITDATA + +diff --git a/block/blk-core.c b/block/blk-core.c +index 5a750b18172e..9ae84ae05e6a 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -3097,6 +3097,9 @@ int blk_pre_runtime_suspend(struct request_queue *q) + { + int ret = 0; + ++ if (!q->dev) ++ return ret; ++ + spin_lock_irq(q->queue_lock); + if (q->nr_pending) { + ret = -EBUSY; +@@ -3124,6 +3127,9 @@ EXPORT_SYMBOL(blk_pre_runtime_suspend); + */ + void blk_post_runtime_suspend(struct request_queue *q, int err) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + if (!err) { + q->rpm_status = RPM_SUSPENDED; +@@ -3148,6 +3154,9 @@ EXPORT_SYMBOL(blk_post_runtime_suspend); + */ + void blk_pre_runtime_resume(struct request_queue *q) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + q->rpm_status = RPM_RESUMING; + spin_unlock_irq(q->queue_lock); +@@ -3170,6 +3179,9 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); + */ + void blk_post_runtime_resume(struct request_queue *q, int err) + { ++ if (!q->dev) ++ return; ++ + spin_lock_irq(q->queue_lock); + if (!err) { + q->rpm_status = RPM_ACTIVE; +diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c +index 334e31ff7a4e..6bd0c1ade9f2 100644 +--- a/drivers/iio/adc/ad7793.c ++++ b/drivers/iio/adc/ad7793.c +@@ -101,7 +101,7 @@ + #define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */ + + /* ID Register Bit Designations (AD7793_REG_ID) */ +-#define AD7785_ID 0xB ++#define AD7785_ID 0x3 + #define AD7792_ID 0xA + #define AD7793_ID 0xB + #define AD7794_ID 0xF +diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c +index aa26d50ab638..4eda4ea037b7 100644 +--- a/drivers/iio/dac/ad5064.c ++++ b/drivers/iio/dac/ad5064.c +@@ -602,10 +602,16 @@ static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd, + unsigned int addr, unsigned int val) + { + struct i2c_client *i2c = to_i2c_client(st->dev); ++ int ret; + + st->data.i2c[0] = (cmd << 4) | addr; + put_unaligned_be16(val, &st->data.i2c[1]); +- return i2c_master_send(i2c, st->data.i2c, 3); ++ ++ ret = i2c_master_send(i2c, st->data.i2c, 3); ++ if (ret < 0) ++ return ret; ++ ++ return 0; + } + + static int ad5064_i2c_probe(struct i2c_client *i2c, +diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c +index a612ec766d96..029207bbf03d 100644 +--- a/drivers/iio/dac/mcp4725.c ++++ b/drivers/iio/dac/mcp4725.c +@@ -166,6 +166,7 @@ static int mcp4725_probe(struct i2c_client *client, + data->client = client; + + indio_dev->dev.parent = &client->dev; ++ indio_dev->name = id->name; + indio_dev->info = &mcp4725_info; + indio_dev->channels = &mcp4725_channel; + indio_dev->num_channels = 1; +diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c +index 99d8e0b0dd34..d0538bcdc1b8 100644 +--- a/drivers/iio/imu/adis_buffer.c ++++ b/drivers/iio/imu/adis_buffer.c +@@ -43,7 +43,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, + return -ENOMEM; + + rx = adis->buffer; +- tx = rx + indio_dev->scan_bytes; ++ tx = rx + scan_count; + + spi_message_init(&adis->msg); + +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index 02099afb6c79..77f06d001a66 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1081,7 +1081,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) + input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, + ETP_WMAX_V2, 0, 0); + } +- input_mt_init_slots(dev, 2, 0); ++ input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT); + input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); + break; +@@ -1357,6 +1357,13 @@ static const struct dmi_system_id no_hw_res_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "U2442"), + }, + }, ++ { ++ /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), ++ }, ++ }, + #endif + { } + }; +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 4de2571938b8..5102b4f68f18 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -258,6 +258,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { + }, + }, + { ++ /* Fujitsu Lifebook U745 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), ++ }, ++ }, ++ { + /* Fujitsu T70H */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c +index a7967ceb79e6..3d4622cae2cf 100644 +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -968,7 +968,7 @@ void dmar_disable_qi(struct intel_iommu *iommu) + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + +- sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); ++ sts = readl(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_QIES)) + goto end; + +diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c +index 45011f63ad16..990cc298824a 100644 +--- a/drivers/iommu/intel_irq_remapping.c ++++ b/drivers/iommu/intel_irq_remapping.c +@@ -495,7 +495,7 @@ static void iommu_disable_irq_remapping(struct intel_iommu *iommu) + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + +- sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); ++ sts = readl(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_IRES)) + goto end; + +diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c +index 5895f1978691..e98de425f8e0 100644 +--- a/drivers/net/wan/x25_asy.c ++++ b/drivers/net/wan/x25_asy.c +@@ -545,16 +545,12 @@ static void x25_asy_receive_buf(struct tty_struct *tty, + + static int x25_asy_open_tty(struct tty_struct *tty) + { +- struct x25_asy *sl = tty->disc_data; ++ struct x25_asy *sl; + int err; + + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + +- /* First make sure we're not already connected. */ +- if (sl && sl->magic == X25_ASY_MAGIC) +- return -EEXIST; +- + /* OK. Find a free X.25 channel to use. */ + sl = x25_asy_alloc(); + if (sl == NULL) +diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c +index 02bc5a6343c3..aa454241489c 100644 +--- a/drivers/platform/x86/intel_scu_ipcutil.c ++++ b/drivers/platform/x86/intel_scu_ipcutil.c +@@ -49,7 +49,7 @@ struct scu_ipc_data { + + static int scu_reg_access(u32 cmd, struct scu_ipc_data *data) + { +- int count = data->count; ++ unsigned int count = data->count; + + if (count == 0 || count == 3 || count > 4) + return -EINVAL; +diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c +index 69c915aa77c2..d661fcda1932 100644 +--- a/drivers/scsi/device_handler/scsi_dh_rdac.c ++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c +@@ -569,7 +569,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev, + /* + * Command Lock contention + */ +- err = SCSI_DH_RETRY; ++ err = SCSI_DH_IMM_RETRY; + break; + default: + break; +@@ -619,6 +619,8 @@ retry: + err = mode_select_handle_sense(sdev, h->sense); + if (err == SCSI_DH_RETRY && retry_cnt--) + goto retry; ++ if (err == SCSI_DH_IMM_RETRY) ++ goto retry; + } + if (err == SCSI_DH_OK) { + h->state = RDAC_STATE_ACTIVE; +diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c +index 3cafe0d784b8..3020f1ff4abb 100644 +--- a/drivers/scsi/hosts.c ++++ b/drivers/scsi/hosts.c +@@ -305,6 +305,17 @@ static void scsi_host_dev_release(struct device *dev) + kfree(queuedata); + } + ++ if (shost->shost_state == SHOST_CREATED) { ++ /* ++ * Free the shost_dev device name here if scsi_host_alloc() ++ * and scsi_host_put() have been called but neither ++ * scsi_host_add() nor scsi_host_remove() has been called. ++ * This avoids that the memory allocated for the shost_dev ++ * name is leaked. ++ */ ++ kfree(dev_name(&shost->shost_dev)); ++ } ++ + scsi_destroy_command_freelist(shost); + if (shost->bqt) + blk_free_tags(shost->bqt); +diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c +index 9e2dd478dd15..135d7b56fbe6 100644 +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -789,7 +789,7 @@ sdev_store_queue_ramp_up_period(struct device *dev, + return -EINVAL; + + sdev->queue_ramp_up_period = msecs_to_jiffies(period); +- return period; ++ return count; + } + + static struct device_attribute sdev_attr_queue_ramp_up_period = +@@ -1030,31 +1030,25 @@ static void __scsi_remove_target(struct scsi_target *starget) + void scsi_remove_target(struct device *dev) + { + struct Scsi_Host *shost = dev_to_shost(dev->parent); +- struct scsi_target *starget, *last = NULL; ++ struct scsi_target *starget, *last_target = NULL; + unsigned long flags; + +- /* remove targets being careful to lookup next entry before +- * deleting the last +- */ ++restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { +- if (starget->state == STARGET_DEL) ++ if (starget->state == STARGET_DEL || ++ starget == last_target) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { +- /* assuming new targets arrive at the end */ + kref_get(&starget->reap_ref); ++ last_target = starget; + spin_unlock_irqrestore(shost->host_lock, flags); +- if (last) +- scsi_target_reap(last); +- last = starget; + __scsi_remove_target(starget); +- spin_lock_irqsave(shost->host_lock, flags); ++ scsi_target_reap(starget); ++ goto restart; + } + } + spin_unlock_irqrestore(shost->host_lock, flags); +- +- if (last) +- scsi_target_reap(last); + } + EXPORT_SYMBOL(scsi_remove_target); + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 26b543bc4f53..4afce0e838a2 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3090,8 +3090,8 @@ static int sd_suspend(struct device *dev) + struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + int ret = 0; + +- if (!sdkp) +- return 0; /* this can happen */ ++ if (!sdkp) /* E.g.: runtime suspend following sd_remove() */ ++ return 0; + + if (sdkp->WCE) { + sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); +@@ -3115,6 +3115,9 @@ static int sd_resume(struct device *dev) + struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + int ret = 0; + ++ if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ ++ return 0; ++ + if (!sdkp->device->manage_start_stop) + goto done; + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 721d839d6c54..0be16bf5f0cd 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -1258,7 +1258,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) + } + + sfp->mmap_called = 1; +- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; ++ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_private_data = sfp; + vma->vm_ops = &sg_mmap_vm_ops; + return 0; +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 119d67f9c47e..1ac9943cbb93 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -142,6 +142,9 @@ static int sr_runtime_suspend(struct device *dev) + { + struct scsi_cd *cd = dev_get_drvdata(dev); + ++ if (!cd) /* E.g.: runtime suspend following sr_remove() */ ++ return 0; ++ + if (cd->media_present) + return -EBUSY; + else +@@ -1006,6 +1009,7 @@ static int sr_remove(struct device *dev) + + blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); + del_gendisk(cd->disk); ++ dev_set_drvdata(dev, NULL); + + mutex_lock(&sr_ref_mutex); + kref_put(&cd->kref, sr_kref_release); +diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c +index 2f2f7fdd0691..9cbe2dd70499 100644 +--- a/drivers/staging/iio/adc/lpc32xx_adc.c ++++ b/drivers/staging/iio/adc/lpc32xx_adc.c +@@ -76,7 +76,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, + + if (mask == IIO_CHAN_INFO_RAW) { + mutex_lock(&indio_dev->mlock); +- clk_enable(info->clk); ++ clk_prepare_enable(info->clk); + /* Measurement setup */ + __raw_writel(AD_INTERNAL | (chan->address) | AD_REFp | AD_REFm, + LPC32XX_ADC_SELECT(info->adc_base)); +@@ -84,7 +84,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, + __raw_writel(AD_PDN_CTRL | AD_STROBE, + LPC32XX_ADC_CTRL(info->adc_base)); + wait_for_completion(&info->completion); /* set by ISR */ +- clk_disable(info->clk); ++ clk_disable_unprepare(info->clk); + *val = info->value; + mutex_unlock(&indio_dev->mlock); + +diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c +index b9359753784e..364978e63d8d 100644 +--- a/drivers/staging/speakup/selection.c ++++ b/drivers/staging/speakup/selection.c +@@ -139,7 +139,9 @@ static void __speakup_paste_selection(struct work_struct *work) + struct tty_ldisc *ld; + DECLARE_WAITQUEUE(wait, current); + +- ld = tty_ldisc_ref_wait(tty); ++ ld = tty_ldisc_ref(tty); ++ if (!ld) ++ goto tty_unref; + + /* FIXME: this is completely unsafe */ + add_wait_queue(&vc->paste_wait, &wait); +@@ -158,6 +160,7 @@ static void __speakup_paste_selection(struct work_struct *work) + current->state = TASK_RUNNING; + + tty_ldisc_deref(ld); ++tty_unref: + tty_kref_put(tty); + } + +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 06cd916f91fe..d74da9598d58 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3960,6 +3960,17 @@ reject: + return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); + } + ++static bool iscsi_target_check_conn_state(struct iscsi_conn *conn) ++{ ++ bool ret; ++ ++ spin_lock_bh(&conn->state_lock); ++ ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN); ++ spin_unlock_bh(&conn->state_lock); ++ ++ return ret; ++} ++ + int iscsi_target_rx_thread(void *arg) + { + int ret, rc; +@@ -3977,7 +3988,7 @@ int iscsi_target_rx_thread(void *arg) + * incoming iscsi/tcp socket I/O, and/or failing the connection. + */ + rc = wait_for_completion_interruptible(&conn->rx_login_comp); +- if (rc < 0) ++ if (rc < 0 || iscsi_target_check_conn_state(conn)) + return 0; + + if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { +diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c +index c45b3365d63d..200d779d0c03 100644 +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -1730,7 +1730,8 @@ static void lio_tpg_release_fabric_acl( + } + + /* +- * Called with spin_lock_bh(struct se_portal_group->session_lock) held.. ++ * Called with spin_lock_irq(struct se_portal_group->session_lock) held ++ * or not held. + * + * Also, this function calls iscsit_inc_session_usage_count() on the + * struct iscsi_session in question. +@@ -1738,19 +1739,32 @@ static void lio_tpg_release_fabric_acl( + static int lio_tpg_shutdown_session(struct se_session *se_sess) + { + struct iscsi_session *sess = se_sess->fabric_sess_ptr; ++ struct se_portal_group *se_tpg = se_sess->se_tpg; ++ bool local_lock = false; ++ ++ if (!spin_is_locked(&se_tpg->session_lock)) { ++ spin_lock_irq(&se_tpg->session_lock); ++ local_lock = true; ++ } + + spin_lock(&sess->conn_lock); + if (atomic_read(&sess->session_fall_back_to_erl0) || + atomic_read(&sess->session_logout) || + (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { + spin_unlock(&sess->conn_lock); ++ if (local_lock) ++ spin_unlock_irq(&sess->conn_lock); + return 0; + } + atomic_set(&sess->session_reinstatement, 1); + spin_unlock(&sess->conn_lock); + + iscsit_stop_time2retain_timer(sess); ++ spin_unlock_irq(&se_tpg->session_lock); ++ + iscsit_stop_session(sess, 1, 1); ++ if (!local_lock) ++ spin_lock_irq(&se_tpg->session_lock); + + return 1; + } +diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c +index 77c276acccb6..2a61a01142e9 100644 +--- a/drivers/target/iscsi/iscsi_target_nego.c ++++ b/drivers/target/iscsi/iscsi_target_nego.c +@@ -384,6 +384,7 @@ err: + if (login->login_complete) { + if (conn->rx_thread && conn->rx_thread_active) { + send_sig(SIGINT, conn->rx_thread, 1); ++ complete(&conn->rx_login_comp); + kthread_stop(conn->rx_thread); + } + if (conn->tx_thread && conn->tx_thread_active) { +diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c +index 7cb36813aac2..deee2b81afff 100644 +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -623,7 +623,14 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) + /* this is called once with whichever end is closed last */ + static void pty_unix98_shutdown(struct tty_struct *tty) + { +- devpts_kill_index(tty->driver_data, tty->index); ++ struct inode *ptmx_inode; ++ ++ if (tty->driver->subtype == PTY_TYPE_MASTER) ++ ptmx_inode = tty->driver_data; ++ else ++ ptmx_inode = tty->link->driver_data; ++ devpts_kill_index(ptmx_inode, tty->index); ++ devpts_del_ref(ptmx_inode); + } + + static const struct tty_operations ptm_unix98_ops = { +@@ -714,6 +721,18 @@ static int ptmx_open(struct inode *inode, struct file *filp) + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ + tty->driver_data = inode; + ++ /* ++ * In the case where all references to ptmx inode are dropped and we ++ * still have /dev/tty opened pointing to the master/slave pair (ptmx ++ * is closed/released before /dev/tty), we must make sure that the inode ++ * is still valid when we call the final pty_unix98_shutdown, thus we ++ * hold an additional reference to the ptmx inode. For the same /dev/tty ++ * last close case, we also need to make sure the super_block isn't ++ * destroyed (devpts instance unmounted), before /dev/tty is closed and ++ * on its release devpts_kill_index is called. ++ */ ++ devpts_add_ref(inode); ++ + tty_add_file(tty, filp); + + slave_inode = devpts_pty_new(inode, +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 9dd6fa3a1260..507677b9bdc7 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1502,7 +1502,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { + xhci_dbg(xhci, "HW died, freeing TD.\n"); + urb_priv = urb->hcpriv; +- for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { ++ for (i = urb_priv->td_cnt; ++ i < urb_priv->length && xhci->devs[urb->dev->slot_id]; ++ i++) { + td = urb_priv->td[i]; + if (!list_empty(&td->td_list)) + list_del_init(&td->td_list); +diff --git a/fs/aio.c b/fs/aio.c +index ded94c4fa30d..9798d4edfd8f 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -977,12 +977,17 @@ static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) + + static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb) + { +- if (unlikely(!access_ok(!rw, kiocb->ki_buf, kiocb->ki_nbytes))) +- return -EFAULT; ++ size_t len = kiocb->ki_nbytes; ++ ++ if (len > MAX_RW_COUNT) ++ len = MAX_RW_COUNT; ++ ++ if (unlikely(!access_ok(!rw, kiocb->ki_buf, len))) ++ return -EFAULT; + + kiocb->ki_iovec = &kiocb->ki_inline_vec; + kiocb->ki_iovec->iov_base = kiocb->ki_buf; +- kiocb->ki_iovec->iov_len = kiocb->ki_nbytes; ++ kiocb->ki_iovec->iov_len = len; + kiocb->ki_nr_segs = 1; + return 0; + } +diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c +index d85f90c92bb4..bca854b44056 100644 +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -1228,7 +1228,8 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, + read_extent_buffer(eb, dest + bytes_left, + name_off, name_len); + if (eb != eb_in) { +- btrfs_tree_read_unlock_blocking(eb); ++ if (!path->skip_locking) ++ btrfs_tree_read_unlock_blocking(eb); + free_extent_buffer(eb); + } + ret = inode_ref_info(parent, 0, fs_root, path, &found_key); +@@ -1247,9 +1248,10 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, + eb = path->nodes[0]; + /* make sure we can use eb after releasing the path */ + if (eb != eb_in) { +- atomic_inc(&eb->refs); +- btrfs_tree_read_lock(eb); +- btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); ++ if (!path->skip_locking) ++ btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); ++ path->nodes[0] = NULL; ++ path->locks[0] = 0; + } + btrfs_release_path(path); + iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index 5c807b23ca67..182e82f22b3a 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -591,7 +591,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) + + ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); + if (!ses->auth_key.response) { +- rc = ENOMEM; ++ rc = -ENOMEM; + ses->auth_key.len = 0; + goto setup_ntlmv2_rsp_ret; + } +diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c +index a726b9f29cb7..61af24e379ad 100644 +--- a/fs/devpts/inode.c ++++ b/fs/devpts/inode.c +@@ -564,6 +564,26 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) + mutex_unlock(&allocated_ptys_lock); + } + ++/* ++ * pty code needs to hold extra references in case of last /dev/tty close ++ */ ++ ++void devpts_add_ref(struct inode *ptmx_inode) ++{ ++ struct super_block *sb = pts_sb_from_inode(ptmx_inode); ++ ++ atomic_inc(&sb->s_active); ++ ihold(ptmx_inode); ++} ++ ++void devpts_del_ref(struct inode *ptmx_inode) ++{ ++ struct super_block *sb = pts_sb_from_inode(ptmx_inode); ++ ++ iput(ptmx_inode); ++ deactivate_super(sb); ++} ++ + /** + * devpts_pty_new -- create a new inode in /dev/pts/ + * @ptmx_inode: inode of the master +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index fa7d2e668c3a..cf0a70486618 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -181,7 +181,7 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) + if (flex_gd == NULL) + goto out3; + +- if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data)) ++ if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data)) + goto out2; + flex_gd->count = flexbg_size; + +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 4fafb8484bbc..35f604b5f408 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -993,6 +993,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, + + mark_page_accessed(page); + ++ iov_iter_advance(ii, tmp); + if (!tmp) { + unlock_page(page); + page_cache_release(page); +@@ -1005,7 +1006,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, + req->page_descs[req->num_pages].length = tmp; + req->num_pages++; + +- iov_iter_advance(ii, tmp); + count += tmp; + pos += tmp; + offset += tmp; +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 78679b489484..d8ac734a1e44 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1005,6 +1005,7 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s + * Protect the call to nfs4_state_set_mode_locked and + * serialise the stateid update + */ ++ spin_lock(&state->owner->so_lock); + write_seqlock(&state->seqlock); + if (deleg_stateid != NULL) { + nfs4_stateid_copy(&state->stateid, deleg_stateid); +@@ -1013,7 +1014,6 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s + if (open_stateid != NULL) + nfs_set_open_stateid_locked(state, open_stateid, fmode); + write_sequnlock(&state->seqlock); +- spin_lock(&state->owner->so_lock); + update_open_stateflags(state, fmode); + spin_unlock(&state->owner->so_lock); + } +diff --git a/fs/proc/array.c b/fs/proc/array.c +index 09f0d9c374a3..5c45eb5e4e0d 100644 +--- a/fs/proc/array.c ++++ b/fs/proc/array.c +@@ -398,7 +398,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, + + state = *get_task_state(task); + vsize = eip = esp = 0; +- permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT); ++ permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT); + mm = get_task_mm(task); + if (mm) { + vsize = task_vsize(mm); +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 8fc784aef0b8..7b5d453ebf53 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -239,7 +239,7 @@ out: + + static int proc_pid_auxv(struct task_struct *task, char *buffer) + { +- struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ); ++ struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS); + int res = PTR_ERR(mm); + if (mm && !IS_ERR(mm)) { + unsigned int nwords = 0; +@@ -269,7 +269,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer) + wchan = get_wchan(task); + + if (lookup_symbol_name(wchan, symname) < 0) +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + return 0; + else + return sprintf(buffer, "%lu", wchan); +@@ -283,7 +283,7 @@ static int lock_trace(struct task_struct *task) + int err = mutex_lock_killable(&task->signal->cred_guard_mutex); + if (err) + return err; +- if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) { ++ if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) { + mutex_unlock(&task->signal->cred_guard_mutex); + return -EPERM; + } +@@ -557,7 +557,7 @@ static int proc_fd_access_allowed(struct inode *inode) + */ + task = get_proc_task(inode); + if (task) { +- allowed = ptrace_may_access(task, PTRACE_MODE_READ); ++ allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); + put_task_struct(task); + } + return allowed; +@@ -592,7 +592,7 @@ static bool has_pid_permissions(struct pid_namespace *pid, + return true; + if (in_group_p(pid->pid_gid)) + return true; +- return ptrace_may_access(task, PTRACE_MODE_READ); ++ return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); + } + + +@@ -707,7 +707,7 @@ static int __mem_open(struct inode *inode, struct file *file, unsigned int mode) + if (!task) + return -ESRCH; + +- mm = mm_access(task, mode); ++ mm = mm_access(task, mode | PTRACE_MODE_FSCREDS); + put_task_struct(task); + + if (IS_ERR(mm)) +@@ -1761,7 +1761,7 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags) + if (!task) + goto out_notask; + +- mm = mm_access(task, PTRACE_MODE_READ); ++ mm = mm_access(task, PTRACE_MODE_READ_FSCREDS); + if (IS_ERR_OR_NULL(mm)) + goto out; + +@@ -1896,7 +1896,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, + goto out; + + result = ERR_PTR(-EACCES); +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + result = ERR_PTR(-ENOENT); +@@ -1952,7 +1952,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) + goto out; + + ret = -EACCES; +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + ret = 0; +@@ -2488,7 +2488,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) + if (result) + return result; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) { ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) { + result = -EACCES; + goto out_unlock; + } +diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c +index 54bdc6701e9f..ac49a8d4aaf8 100644 +--- a/fs/proc/namespaces.c ++++ b/fs/proc/namespaces.c +@@ -125,7 +125,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd) + if (!task) + goto out; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops); +@@ -158,7 +158,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl + if (!task) + goto out; + +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put_task; + + len = -ENOENT; +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index 789814f27438..5c1120a5fa42 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -2055,14 +2055,29 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos, + epos->offset += adsize; + } + ++/* ++ * Only 1 indirect extent in a row really makes sense but allow upto 16 in case ++ * someone does some weird stuff. ++ */ ++#define UDF_MAX_INDIR_EXTS 16 ++ + int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int inc) + { + int8_t etype; ++ unsigned int indirections = 0; + + while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == + (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { + int block; ++ ++ if (++indirections > UDF_MAX_INDIR_EXTS) { ++ udf_err(inode->i_sb, ++ "too many indirect extents in inode %lu\n", ++ inode->i_ino); ++ return -1; ++ } ++ + epos->block = *eloc; + epos->offset = sizeof(struct allocExtDesc); + brelse(epos->bh); +diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c +index 44b815e57f94..685fbd8a2937 100644 +--- a/fs/udf/unicode.c ++++ b/fs/udf/unicode.c +@@ -132,11 +132,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) + if (c < 0x80U) + utf_o->u_name[utf_o->u_len++] = (uint8_t)c; + else if (c < 0x800U) { ++ if (utf_o->u_len > (UDF_NAME_LEN - 4)) ++ break; + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0xc0 | (c >> 6)); + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0x80 | (c & 0x3f)); + } else { ++ if (utf_o->u_len > (UDF_NAME_LEN - 5)) ++ break; + utf_o->u_name[utf_o->u_len++] = + (uint8_t)(0xe0 | (c >> 12)); + utf_o->u_name[utf_o->u_len++] = +@@ -177,17 +181,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) + static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) + { + unsigned c, i, max_val, utf_char; +- int utf_cnt, u_len; ++ int utf_cnt, u_len, u_ch; + + memset(ocu, 0, sizeof(dstring) * length); + ocu[0] = 8; + max_val = 0xffU; ++ u_ch = 1; + + try_again: + u_len = 0U; + utf_char = 0U; + utf_cnt = 0U; + for (i = 0U; i < utf->u_len; i++) { ++ /* Name didn't fit? */ ++ if (u_len + 1 + u_ch >= length) ++ return 0; ++ + c = (uint8_t)utf->u_name[i]; + + /* Complete a multi-byte UTF-8 character */ +@@ -229,6 +238,7 @@ try_again: + if (max_val == 0xffU) { + max_val = 0xffffU; + ocu[0] = (uint8_t)0x10U; ++ u_ch = 2; + goto try_again; + } + goto error_out; +@@ -281,7 +291,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, + c = (c << 8) | ocu[i++]; + + len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], +- UDF_NAME_LEN - utf_o->u_len); ++ UDF_NAME_LEN - 2 - utf_o->u_len); + /* Valid character? */ + if (len >= 0) + utf_o->u_len += len; +@@ -299,15 +309,19 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, + int len; + unsigned i, max_val; + uint16_t uni_char; +- int u_len; ++ int u_len, u_ch; + + memset(ocu, 0, sizeof(dstring) * length); + ocu[0] = 8; + max_val = 0xffU; ++ u_ch = 1; + + try_again: + u_len = 0U; + for (i = 0U; i < uni->u_len; i++) { ++ /* Name didn't fit? */ ++ if (u_len + 1 + u_ch >= length) ++ return 0; + len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); + if (!len) + continue; +@@ -320,6 +334,7 @@ try_again: + if (uni_char > max_val) { + max_val = 0xffffU; + ocu[0] = (uint8_t)0x10U; ++ u_ch = 2; + goto try_again; + } + +diff --git a/include/linux/compiler.h b/include/linux/compiler.h +index a2329c5e6206..a2ce6f8871c4 100644 +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -131,7 +131,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); + */ + #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) ) + #define __trace_if(cond) \ +- if (__builtin_constant_p((cond)) ? !!(cond) : \ ++ if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ + ({ \ + int ______r; \ + static struct ftrace_branch_data \ +diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h +index 251a2090a554..e0ee0b3000b2 100644 +--- a/include/linux/devpts_fs.h ++++ b/include/linux/devpts_fs.h +@@ -19,6 +19,8 @@ + + int devpts_new_index(struct inode *ptmx_inode); + void devpts_kill_index(struct inode *ptmx_inode, int idx); ++void devpts_add_ref(struct inode *ptmx_inode); ++void devpts_del_ref(struct inode *ptmx_inode); + /* mknod in devpts */ + struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, + void *priv); +@@ -32,6 +34,8 @@ void devpts_pty_kill(struct inode *inode); + /* Dummy stubs in the no-pty case */ + static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } + static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } ++static inline void devpts_add_ref(struct inode *ptmx_inode) { } ++static inline void devpts_del_ref(struct inode *ptmx_inode) { } + static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, + dev_t device, int index, void *priv) + { +diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h +index bb980ae6d9d3..6af8988f5ddd 100644 +--- a/include/linux/ptrace.h ++++ b/include/linux/ptrace.h +@@ -56,7 +56,29 @@ extern void exit_ptrace(struct task_struct *tracer); + #define PTRACE_MODE_READ 0x01 + #define PTRACE_MODE_ATTACH 0x02 + #define PTRACE_MODE_NOAUDIT 0x04 +-/* Returns true on success, false on denial. */ ++#define PTRACE_MODE_FSCREDS 0x08 ++#define PTRACE_MODE_REALCREDS 0x10 ++ ++/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */ ++#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS) ++#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS) ++#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS) ++#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS) ++ ++/** ++ * ptrace_may_access - check whether the caller is permitted to access ++ * a target task. ++ * @task: target task ++ * @mode: selects type of access and caller credentials ++ * ++ * Returns true on success, false on denial. ++ * ++ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must ++ * be set in @mode to specify whether the access was requested through ++ * a filesystem syscall (should use effective capabilities and fsuid ++ * of the caller) or through an explicit syscall such as ++ * process_vm_writev or ptrace (and should use the real credentials). ++ */ + extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); + + static inline int ptrace_reparented(struct task_struct *child) +diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h +index ffc444c38b0a..e02e09f85fad 100644 +--- a/include/linux/radix-tree.h ++++ b/include/linux/radix-tree.h +@@ -322,12 +322,28 @@ void **radix_tree_next_chunk(struct radix_tree_root *root, + struct radix_tree_iter *iter, unsigned flags); + + /** ++ * radix_tree_iter_retry - retry this chunk of the iteration ++ * @iter: iterator state ++ * ++ * If we iterate over a tree protected only by the RCU lock, a race ++ * against deletion or creation may result in seeing a slot for which ++ * radix_tree_deref_retry() returns true. If so, call this function ++ * and continue the iteration. ++ */ ++static inline __must_check ++void **radix_tree_iter_retry(struct radix_tree_iter *iter) ++{ ++ iter->next_index = iter->index; ++ return NULL; ++} ++ ++/** + * radix_tree_chunk_size - get current chunk size + * + * @iter: pointer to radix tree iterator + * Returns: current chunk size + */ +-static __always_inline unsigned ++static __always_inline long + radix_tree_chunk_size(struct radix_tree_iter *iter) + { + return iter->next_index - iter->index; +@@ -361,9 +377,9 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags) + return slot + offset + 1; + } + } else { +- unsigned size = radix_tree_chunk_size(iter) - 1; ++ long size = radix_tree_chunk_size(iter); + +- while (size--) { ++ while (--size > 0) { + slot++; + iter->index++; + if (likely(*slot)) +diff --git a/kernel/events/core.c b/kernel/events/core.c +index d9b0aad17dbf..0f5207839673 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2938,7 +2938,7 @@ find_lively_task_by_vpid(pid_t vpid) + + /* Reuse ptrace permission checks for now. */ + err = -EACCES; +- if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) + goto errout; + + return task; +@@ -5639,6 +5639,10 @@ static int perf_tp_filter_match(struct perf_event *event, + { + void *record = data->raw->data; + ++ /* only top level events have filters set */ ++ if (event->parent) ++ event = event->parent; ++ + if (likely(!event->filter) || filter_match_preds(event->filter, record)) + return 1; + return 0; +diff --git a/kernel/futex.c b/kernel/futex.c +index 625a4e659e7a..edc4beae4df1 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2494,6 +2494,11 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); ++ /* ++ * Drop the reference to the pi state which ++ * the requeue_pi() code acquired for us. ++ */ ++ free_pi_state(q.pi_state); + spin_unlock(q.lock_ptr); + } + } else { +@@ -2620,7 +2625,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pid, + } + + ret = -EPERM; +- if (!ptrace_may_access(p, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) + goto err_unlock; + + head = p->robust_list; +diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c +index f9f44fd4d34d..3888617a1f9e 100644 +--- a/kernel/futex_compat.c ++++ b/kernel/futex_compat.c +@@ -155,7 +155,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, + } + + ret = -EPERM; +- if (!ptrace_may_access(p, PTRACE_MODE_READ)) ++ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) + goto err_unlock; + + head = p->compat_robust_list; +diff --git a/kernel/kcmp.c b/kernel/kcmp.c +index 0aa69ea1d8fd..3a47fa998fe0 100644 +--- a/kernel/kcmp.c ++++ b/kernel/kcmp.c +@@ -122,8 +122,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type, + &task2->signal->cred_guard_mutex); + if (ret) + goto err; +- if (!ptrace_may_access(task1, PTRACE_MODE_READ) || +- !ptrace_may_access(task2, PTRACE_MODE_READ)) { ++ if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) || ++ !ptrace_may_access(task2, PTRACE_MODE_READ_REALCREDS)) { + ret = -EPERM; + goto err_unlock; + } +diff --git a/kernel/module.c b/kernel/module.c +index fd2afdf48a89..70a4754c001f 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -3398,6 +3398,11 @@ static inline int is_arm_mapping_symbol(const char *str) + && (str[2] == '\0' || str[2] == '.'); + } + ++static const char *symname(struct module *mod, unsigned int symnum) ++{ ++ return mod->strtab + mod->symtab[symnum].st_name; ++} ++ + static const char *get_ksymbol(struct module *mod, + unsigned long addr, + unsigned long *size, +@@ -3420,15 +3425,15 @@ static const char *get_ksymbol(struct module *mod, + + /* We ignore unnamed symbols: they're uninformative + * and inserted at a whim. */ ++ if (*symname(mod, i) == '\0' ++ || is_arm_mapping_symbol(symname(mod, i))) ++ continue; ++ + if (mod->symtab[i].st_value <= addr +- && mod->symtab[i].st_value > mod->symtab[best].st_value +- && *(mod->strtab + mod->symtab[i].st_name) != '\0' +- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) ++ && mod->symtab[i].st_value > mod->symtab[best].st_value) + best = i; + if (mod->symtab[i].st_value > addr +- && mod->symtab[i].st_value < nextval +- && *(mod->strtab + mod->symtab[i].st_name) != '\0' +- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) ++ && mod->symtab[i].st_value < nextval) + nextval = mod->symtab[i].st_value; + } + +@@ -3439,7 +3444,7 @@ static const char *get_ksymbol(struct module *mod, + *size = nextval - mod->symtab[best].st_value; + if (offset) + *offset = addr - mod->symtab[best].st_value; +- return mod->strtab + mod->symtab[best].st_name; ++ return symname(mod, best); + } + + /* For kallsyms to ask for address resolution. NULL means not found. Careful +@@ -3540,8 +3545,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, + if (symnum < mod->num_symtab) { + *value = mod->symtab[symnum].st_value; + *type = mod->symtab[symnum].st_info; +- strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, +- KSYM_NAME_LEN); ++ strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN); + strlcpy(module_name, mod->name, MODULE_NAME_LEN); + *exported = is_exported(name, *value, mod); + preempt_enable(); +@@ -3558,7 +3562,7 @@ static unsigned long mod_find_symname(struct module *mod, const char *name) + unsigned int i; + + for (i = 0; i < mod->num_symtab; i++) +- if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && ++ if (strcmp(name, symname(mod, i)) == 0 && + mod->symtab[i].st_info != 'U') + return mod->symtab[i].st_value; + return 0; +@@ -3602,7 +3606,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + if (mod->state == MODULE_STATE_UNFORMED) + continue; + for (i = 0; i < mod->num_symtab; i++) { +- ret = fn(data, mod->strtab + mod->symtab[i].st_name, ++ ret = fn(data, symname(mod, i), + mod, mod->symtab[i].st_value); + if (ret != 0) + return ret; +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index 30ab20623bca..72b0b3e0e065 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -225,6 +225,14 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode) + static int __ptrace_may_access(struct task_struct *task, unsigned int mode) + { + const struct cred *cred = current_cred(), *tcred; ++ int dumpable = 0; ++ kuid_t caller_uid; ++ kgid_t caller_gid; ++ ++ if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) { ++ WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n"); ++ return -EPERM; ++ } + + /* May we inspect the given task? + * This check is used both for attaching with ptrace +@@ -234,18 +242,33 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode) + * because setting up the necessary parent/child relationship + * or halting the specified task is impossible. + */ +- int dumpable = 0; ++ + /* Don't let security modules deny introspection */ + if (same_thread_group(task, current)) + return 0; + rcu_read_lock(); ++ if (mode & PTRACE_MODE_FSCREDS) { ++ caller_uid = cred->fsuid; ++ caller_gid = cred->fsgid; ++ } else { ++ /* ++ * Using the euid would make more sense here, but something ++ * in userland might rely on the old behavior, and this ++ * shouldn't be a security problem since ++ * PTRACE_MODE_REALCREDS implies that the caller explicitly ++ * used a syscall that requests access to another process ++ * (and not a filesystem syscall to procfs). ++ */ ++ caller_uid = cred->uid; ++ caller_gid = cred->gid; ++ } + tcred = __task_cred(task); +- if (uid_eq(cred->uid, tcred->euid) && +- uid_eq(cred->uid, tcred->suid) && +- uid_eq(cred->uid, tcred->uid) && +- gid_eq(cred->gid, tcred->egid) && +- gid_eq(cred->gid, tcred->sgid) && +- gid_eq(cred->gid, tcred->gid)) ++ if (uid_eq(caller_uid, tcred->euid) && ++ uid_eq(caller_uid, tcred->suid) && ++ uid_eq(caller_uid, tcred->uid) && ++ gid_eq(caller_gid, tcred->egid) && ++ gid_eq(caller_gid, tcred->sgid) && ++ gid_eq(caller_gid, tcred->gid)) + goto ok; + if (ptrace_has_cap(tcred->user_ns, mode)) + goto ok; +@@ -312,7 +335,7 @@ static int ptrace_attach(struct task_struct *task, long request, + goto out; + + task_lock(task); +- retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); ++ retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS); + task_unlock(task); + if (retval) + goto unlock_creds; +diff --git a/lib/dma-debug.c b/lib/dma-debug.c +index d87a17a819d0..eb43517bf261 100644 +--- a/lib/dma-debug.c ++++ b/lib/dma-debug.c +@@ -962,7 +962,7 @@ static inline bool overlap(void *addr, unsigned long len, void *start, void *end + + static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len) + { +- if (overlap(addr, len, _text, _etext) || ++ if (overlap(addr, len, _stext, _etext) || + overlap(addr, len, __start_rodata, __end_rodata)) + err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len); + } +diff --git a/lib/klist.c b/lib/klist.c +index 358a368a2947..2e59aecbec0d 100644 +--- a/lib/klist.c ++++ b/lib/klist.c +@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist *k, struct klist_iter *i, + struct klist_node *n) + { + i->i_klist = k; +- i->i_cur = n; +- if (n) +- kref_get(&n->n_ref); ++ i->i_cur = NULL; ++ if (n && kref_get_unless_zero(&n->n_ref)) ++ i->i_cur = n; + } + EXPORT_SYMBOL_GPL(klist_iter_init_node); + +diff --git a/lib/radix-tree.c b/lib/radix-tree.c +index e7964296fd50..936a02c1c77b 100644 +--- a/lib/radix-tree.c ++++ b/lib/radix-tree.c +@@ -1015,9 +1015,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, + return 0; + + radix_tree_for_each_slot(slot, root, &iter, first_index) { +- results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); ++ results[ret] = rcu_dereference_raw(*slot); + if (!results[ret]) + continue; ++ if (radix_tree_is_indirect_ptr(results[ret])) { ++ slot = radix_tree_iter_retry(&iter); ++ continue; ++ } + if (++ret == max_items) + break; + } +@@ -1094,9 +1098,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, + return 0; + + radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) { +- results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); ++ results[ret] = rcu_dereference_raw(*slot); + if (!results[ret]) + continue; ++ if (radix_tree_is_indirect_ptr(results[ret])) { ++ slot = radix_tree_iter_retry(&iter); ++ continue; ++ } + if (++ret == max_items) + break; + } +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index eaa3accb01e7..437ae2cbe102 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5790,16 +5790,17 @@ static void mem_cgroup_usage_unregister_event(struct cgroup *cgrp, + swap_buffers: + /* Swap primary and spare array */ + thresholds->spare = thresholds->primary; +- /* If all events are unregistered, free the spare array */ +- if (!new) { +- kfree(thresholds->spare); +- thresholds->spare = NULL; +- } + + rcu_assign_pointer(thresholds->primary, new); + + /* To be sure that nobody uses thresholds */ + synchronize_rcu(); ++ ++ /* If all events are unregistered, free the spare array */ ++ if (!new) { ++ kfree(thresholds->spare); ++ thresholds->spare = NULL; ++ } + unlock: + mutex_unlock(&memcg->thresholds_lock); + } +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index f97d709594e6..37df20faddd5 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1472,7 +1472,7 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) + * Did it turn free? + */ + ret = __get_any_page(page, pfn, 0); +- if (!PageLRU(page)) { ++ if (ret == 1 && !PageLRU(page)) { + /* Drop page reference which is from __get_any_page() */ + put_page(page); + pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index d85d3a0e06ce..7f1bf93fa87f 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1209,23 +1209,30 @@ int is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) + */ + static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn) + { +- unsigned long pfn; ++ unsigned long pfn, sec_end_pfn; + struct zone *zone = NULL; + struct page *page; + int i; +- for (pfn = start_pfn; ++ for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn); + pfn < end_pfn; +- pfn += MAX_ORDER_NR_PAGES) { +- i = 0; +- /* This is just a CONFIG_HOLES_IN_ZONE check.*/ +- while ((i < MAX_ORDER_NR_PAGES) && !pfn_valid_within(pfn + i)) +- i++; +- if (i == MAX_ORDER_NR_PAGES) ++ pfn = sec_end_pfn + 1, sec_end_pfn += PAGES_PER_SECTION) { ++ /* Make sure the memory section is present first */ ++ if (!present_section_nr(pfn_to_section_nr(pfn))) + continue; +- page = pfn_to_page(pfn + i); +- if (zone && page_zone(page) != zone) +- return 0; +- zone = page_zone(page); ++ for (; pfn < sec_end_pfn && pfn < end_pfn; ++ pfn += MAX_ORDER_NR_PAGES) { ++ i = 0; ++ /* This is just a CONFIG_HOLES_IN_ZONE check.*/ ++ while ((i < MAX_ORDER_NR_PAGES) && ++ !pfn_valid_within(pfn + i)) ++ i++; ++ if (i == MAX_ORDER_NR_PAGES) ++ continue; ++ page = pfn_to_page(pfn + i); ++ if (zone && page_zone(page) != zone) ++ return 0; ++ zone = page_zone(page); ++ } + } + return 1; + } +diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c +index fd26d0433509..e739825be8b3 100644 +--- a/mm/process_vm_access.c ++++ b/mm/process_vm_access.c +@@ -298,7 +298,7 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, + goto free_proc_pages; + } + +- mm = mm_access(task, PTRACE_MODE_ATTACH); ++ mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS); + if (!mm || IS_ERR(mm)) { + rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; + /* +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 9ec416552cc5..8d69df16f6a8 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -336,7 +336,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) + + static void ip6mr_free_table(struct mr6_table *mrt) + { +- del_timer(&mrt->ipmr_expire_timer); ++ del_timer_sync(&mrt->ipmr_expire_timer); + mroute_clean_tables(mrt, true); + kfree(mrt); + } +diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter +index 6129020c41a9..81228a443122 100755 +--- a/scripts/bloat-o-meter ++++ b/scripts/bloat-o-meter +@@ -55,8 +55,8 @@ for name in common: + delta.sort() + delta.reverse() + +-print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ +- (add, remove, grow, shrink, up, -down, up-down) +-print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta") ++print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ ++ (add, remove, grow, shrink, up, -down, up-down)) ++print("%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")) + for d, n in delta: +- if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d) ++ if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) +diff --git a/security/commoncap.c b/security/commoncap.c +index c9219a66b7c6..4fd7bf2b19e1 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -142,12 +142,17 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) + { + int ret = 0; + const struct cred *cred, *child_cred; ++ const kernel_cap_t *caller_caps; + + rcu_read_lock(); + cred = current_cred(); + child_cred = __task_cred(child); ++ if (mode & PTRACE_MODE_FSCREDS) ++ caller_caps = &cred->cap_effective; ++ else ++ caller_caps = &cred->cap_permitted; + if (cred->user_ns == child_cred->user_ns && +- cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) ++ cap_issubset(child_cred->cap_permitted, *caller_caps)) + goto out; + if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE)) + goto out; +diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c +index 67c91d226552..ee0522a8f730 100644 +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -540,19 +540,22 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client, + bool is_src, bool ack) + { + struct snd_seq_port_subs_info *grp; ++ struct list_head *list; ++ bool empty; + + grp = is_src ? &port->c_src : &port->c_dest; ++ list = is_src ? &subs->src_list : &subs->dest_list; + down_write(&grp->list_mutex); + write_lock_irq(&grp->list_lock); +- if (is_src) +- list_del(&subs->src_list); +- else +- list_del(&subs->dest_list); ++ empty = list_empty(list); ++ if (!empty) ++ list_del_init(list); + grp->exclusive = 0; + write_unlock_irq(&grp->list_lock); + up_write(&grp->list_mutex); + +- unsubscribe_port(client, port, grp, &subs->info, ack); ++ if (!empty) ++ unsubscribe_port(client, port, grp, &subs->info, ack); + } + + /* connect two ports */ +diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c +index 82b0606dcb8a..c3efcf2f816b 100644 +--- a/tools/lib/traceevent/event-parse.c ++++ b/tools/lib/traceevent/event-parse.c +@@ -4190,13 +4190,12 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event + sizeof(long) != 8) { + char *p; + +- ls = 2; + /* make %l into %ll */ +- p = strchr(format, 'l'); +- if (p) ++ if (ls == 1 && (p = strchr(format, 'l'))) + memmove(p+1, p, strlen(p)+1); + else if (strcmp(format, "%p") == 0) + strcpy(format, "0x%llx"); ++ ls = 2; + } + switch (ls) { + case -2: