diff options
author | Mike Pagano <mpagano@gentoo.org> | 2020-12-11 07:56:04 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2020-12-11 07:56:04 -0500 |
commit | e16ae6bcae07ef8229217db510288389a1193dcc (patch) | |
tree | 6e5a61ae71a32a25e6211466d6fa9779d0a509fb | |
parent | Linux patch 4.19.162 (diff) | |
download | linux-patches-4.19-162.tar.gz linux-patches-4.19-162.tar.bz2 linux-patches-4.19-162.zip |
Linux patch 4.19.1634.19-162
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1162_linux-4.19.163.patch | 1389 |
2 files changed, 1393 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 9a36e6f4..e1c06276 100644 --- a/0000_README +++ b/0000_README @@ -687,6 +687,10 @@ Patch: 1161_linux-4.19.162.patch From: https://www.kernel.org Desc: Linux 4.19.162 +Patch: 1162_linux-4.19.163.patch +From: https://www.kernel.org +Desc: Linux 4.19.163 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1162_linux-4.19.163.patch b/1162_linux-4.19.163.patch new file mode 100644 index 00000000..b2252ce8 --- /dev/null +++ b/1162_linux-4.19.163.patch @@ -0,0 +1,1389 @@ +diff --git a/Makefile b/Makefile +index 71e55c5cd74a0..b651d77eb2df9 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 162 ++SUBLEVEL = 163 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h +index c2c01f84df75f..3e0e18d376d2c 100644 +--- a/arch/x86/include/asm/insn.h ++++ b/arch/x86/include/asm/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate(struct insn *insn) + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + +diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c +index 420aa7d3a2e6b..ae9e806a11def 100644 +--- a/arch/x86/kernel/uprobes.c ++++ b/arch/x86/kernel/uprobes.c +@@ -268,12 +268,13 @@ static volatile u32 good_2byte_insns[256 / 32] = { + + static bool is_prefix_bad(struct insn *insn) + { ++ insn_byte_t p; + int i; + +- for (i = 0; i < insn->prefixes.nbytes; i++) { ++ for_each_insn_prefix(insn, i, p) { + insn_attr_t attr; + +- attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]); ++ attr = inat_get_opcode_attribute(p); + switch (attr) { + case INAT_MAKE_PREFIX(INAT_PFX_ES): + case INAT_MAKE_PREFIX(INAT_PFX_CS): +@@ -728,6 +729,7 @@ static const struct uprobe_xol_ops push_xol_ops = { + static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) + { + u8 opc1 = OPCODE1(insn); ++ insn_byte_t p; + int i; + + switch (opc1) { +@@ -758,8 +760,8 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) + * Intel and AMD behavior differ in 64-bit mode: Intel ignores 66 prefix. + * No one uses these insns, reject any branch insns with such prefix. + */ +- for (i = 0; i < insn->prefixes.nbytes; i++) { +- if (insn->prefixes.bytes[i] == 0x66) ++ for_each_insn_prefix(insn, i, p) { ++ if (p == 0x66) + return -ENOTSUPP; + } + +diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c +index 87dcba101e562..3172eaf4ec5e3 100644 +--- a/arch/x86/lib/insn-eval.c ++++ b/arch/x86/lib/insn-eval.c +@@ -70,14 +70,15 @@ static int get_seg_reg_override_idx(struct insn *insn) + { + int idx = INAT_SEG_REG_DEFAULT; + int num_overrides = 0, i; ++ insn_byte_t p; + + insn_get_prefixes(insn); + + /* Look for any segment override prefixes. */ +- for (i = 0; i < insn->prefixes.nbytes; i++) { ++ for_each_insn_prefix(insn, i, p) { + insn_attr_t attr; + +- attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]); ++ attr = inat_get_opcode_attribute(p); + switch (attr) { + case INAT_MAKE_PREFIX(INAT_PFX_CS): + idx = INAT_SEG_REG_CS; +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index 0e7f9bd17a91a..83c246e30399a 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -404,6 +404,19 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx) + dma->chan_using = NULL; + } + ++static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits) ++{ ++ unsigned int temp; ++ ++ /* ++ * i2sr_clr_opcode is the value to clear all interrupts. Here we want to ++ * clear only <bits>, so we write ~i2sr_clr_opcode with just <bits> ++ * toggled. This is required because i.MX needs W0C and Vybrid uses W1C. ++ */ ++ temp = ~i2c_imx->hwdata->i2sr_clr_opcode ^ bits; ++ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); ++} ++ + static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) + { + unsigned long orig_jiffies = jiffies; +@@ -416,8 +429,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) + + /* check for arbitration lost */ + if (temp & I2SR_IAL) { +- temp &= ~I2SR_IAL; +- imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); ++ i2c_imx_clear_irq(i2c_imx, I2SR_IAL); + return -EAGAIN; + } + +@@ -448,6 +460,16 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx) + dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__); + return -ETIMEDOUT; + } ++ ++ /* check for arbitration lost */ ++ if (i2c_imx->i2csr & I2SR_IAL) { ++ dev_dbg(&i2c_imx->adapter.dev, "<%s> Arbitration lost\n", __func__); ++ i2c_imx_clear_irq(i2c_imx, I2SR_IAL); ++ ++ i2c_imx->i2csr = 0; ++ return -EAGAIN; ++ } ++ + dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__); + i2c_imx->i2csr = 0; + return 0; +@@ -557,6 +579,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) + /* Stop I2C transaction */ + dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); ++ if (!(temp & I2CR_MSTA)) ++ i2c_imx->stopped = 1; + temp &= ~(I2CR_MSTA | I2CR_MTX); + if (i2c_imx->dma) + temp &= ~I2CR_DMAEN; +@@ -587,9 +611,7 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id) + if (temp & I2SR_IIF) { + /* save status register */ + i2c_imx->i2csr = temp; +- temp &= ~I2SR_IIF; +- temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF); +- imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); ++ i2c_imx_clear_irq(i2c_imx, I2SR_IIF); + wake_up(&i2c_imx->queue); + return IRQ_HANDLED; + } +@@ -722,9 +744,12 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, + */ + dev_dbg(dev, "<%s> clear MSTA\n", __func__); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); ++ if (!(temp & I2CR_MSTA)) ++ i2c_imx->stopped = 1; + temp &= ~(I2CR_MSTA | I2CR_MTX); + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); +- i2c_imx_bus_busy(i2c_imx, 0); ++ if (!i2c_imx->stopped) ++ i2c_imx_bus_busy(i2c_imx, 0); + } else { + /* + * For i2c master receiver repeat restart operation like: +@@ -847,9 +872,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo + dev_dbg(&i2c_imx->adapter.dev, + "<%s> clear MSTA\n", __func__); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); ++ if (!(temp & I2CR_MSTA)) ++ i2c_imx->stopped = 1; + temp &= ~(I2CR_MSTA | I2CR_MTX); + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); +- i2c_imx_bus_busy(i2c_imx, 0); ++ if (!i2c_imx->stopped) ++ i2c_imx_bus_busy(i2c_imx, 0); + } else { + /* + * For i2c master receiver repeat restart operation like: +diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c +index e09cd0775ae91..3417f7dffa943 100644 +--- a/drivers/i2c/busses/i2c-qup.c ++++ b/drivers/i2c/busses/i2c-qup.c +@@ -806,7 +806,8 @@ static int qup_i2c_bam_schedule_desc(struct qup_i2c_dev *qup) + if (ret || qup->bus_err || qup->qup_err) { + reinit_completion(&qup->xfer); + +- if (qup_i2c_change_state(qup, QUP_RUN_STATE)) { ++ ret = qup_i2c_change_state(qup, QUP_RUN_STATE); ++ if (ret) { + dev_err(qup->dev, "change to run state timed out"); + goto desc_err; + } +diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c +index fef3b4064f187..c60593c8d2be5 100644 +--- a/drivers/input/serio/i8042.c ++++ b/drivers/input/serio/i8042.c +@@ -1472,7 +1472,8 @@ static int __init i8042_setup_aux(void) + if (error) + goto err_free_ports; + +- if (aux_enable()) ++ error = aux_enable(); ++ if (error) + goto err_free_irq; + + i8042_aux_irq_registered = true; +diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h +index df6f3cc958e5e..0948c425d6528 100644 +--- a/drivers/iommu/amd_iommu_types.h ++++ b/drivers/iommu/amd_iommu_types.h +@@ -259,7 +259,7 @@ + #define DTE_IRQ_REMAP_INTCTL_MASK (0x3ULL << 60) + #define DTE_IRQ_TABLE_LEN_MASK (0xfULL << 1) + #define DTE_IRQ_REMAP_INTCTL (2ULL << 60) +-#define DTE_IRQ_TABLE_LEN (8ULL << 1) ++#define DTE_IRQ_TABLE_LEN (9ULL << 1) + #define DTE_IRQ_REMAP_ENABLE 1ULL + + #define PAGE_MODE_NONE 0x00 +diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c +index 776aaf5951e4a..a1d4166864d03 100644 +--- a/drivers/md/dm-writecache.c ++++ b/drivers/md/dm-writecache.c +@@ -318,7 +318,7 @@ err1: + #else + static int persistent_memory_claim(struct dm_writecache *wc) + { +- BUG(); ++ return -EOPNOTSUPP; + } + #endif + +@@ -1883,7 +1883,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) + struct wc_memory_superblock s; + + static struct dm_arg _args[] = { +- {0, 10, "Invalid number of feature args"}, ++ {0, 16, "Invalid number of feature args"}, + }; + + as.argc = argc; +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 874bd542a7445..6c755eb0263fb 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -462,7 +462,6 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) + + static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx, + struct block_device **bdev) +- __acquires(md->io_barrier) + { + struct dm_target *tgt; + struct dm_table *map; +@@ -496,7 +495,6 @@ retry: + } + + static void dm_unprepare_ioctl(struct mapped_device *md, int srcu_idx) +- __releases(md->io_barrier) + { + dm_put_live_table(md, srcu_idx); + } +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 69660102182bb..2e2afc824a6a8 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -256,21 +256,11 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, + skb_dst_set(skb, &tun_dst->dst); + + /* Ignore packet loops (and multicast echo) */ +- if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) +- goto rx_error; +- +- switch (skb_protocol(skb, true)) { +- case htons(ETH_P_IP): +- if (pskb_may_pull(skb, sizeof(struct iphdr))) +- goto rx_error; +- break; +- case htons(ETH_P_IPV6): +- if (pskb_may_pull(skb, sizeof(struct ipv6hdr))) +- goto rx_error; +- break; +- default: +- goto rx_error; ++ if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) { ++ geneve->dev->stats.rx_errors++; ++ goto drop; + } ++ + oiph = skb_network_header(skb); + skb_reset_network_header(skb); + +@@ -311,8 +301,6 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, + u64_stats_update_end(&stats->syncp); + } + return; +-rx_error: +- geneve->dev->stats.rx_errors++; + drop: + /* Consume bad packet */ + kfree_skb(skb); +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index acb02a7aa9496..1b00a3f3b419c 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -1009,6 +1009,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, + pm_runtime_put(&vg->pdev->dev); + } + ++static void byt_gpio_direct_irq_check(struct byt_gpio *vg, ++ unsigned int offset) ++{ ++ void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); ++ ++ /* ++ * Before making any direction modifications, do a check if gpio is set ++ * for direct IRQ. On Bay Trail, setting GPIO to output does not make ++ * sense, so let's at least inform the caller before they shoot ++ * themselves in the foot. ++ */ ++ if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) ++ dev_info_once(&vg->pdev->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); ++} ++ + static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset, +@@ -1016,7 +1031,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + { + struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); +- void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + +@@ -1027,14 +1041,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + if (input) + value |= BYT_OUTPUT_EN; + else +- /* +- * Before making any direction modifications, do a check if gpio +- * is set for direct IRQ. On baytrail, setting GPIO to output +- * does not make sense, so let's at least warn the caller before +- * they shoot themselves in the foot. +- */ +- WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, +- "Potential Error: Setting GPIO with direct_irq_en to output"); ++ byt_gpio_direct_irq_check(vg, offset); ++ + writel(value, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); +@@ -1374,19 +1382,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) + + static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) + { +- return pinctrl_gpio_direction_input(chip->base + offset); ++ struct byt_gpio *vg = gpiochip_get_data(chip); ++ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); ++ unsigned long flags; ++ u32 reg; ++ ++ raw_spin_lock_irqsave(&byt_lock, flags); ++ ++ reg = readl(val_reg); ++ reg &= ~BYT_DIR_MASK; ++ reg |= BYT_OUTPUT_EN; ++ writel(reg, val_reg); ++ ++ raw_spin_unlock_irqrestore(&byt_lock, flags); ++ return 0; + } + ++/* ++ * Note despite the temptation this MUST NOT be converted into a call to ++ * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this ++ * MUST be done as a single BYT_VAL_REG register write. ++ * See the commit message of the commit adding this comment for details. ++ */ + static int byt_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) + { +- int ret = pinctrl_gpio_direction_output(chip->base + offset); ++ struct byt_gpio *vg = gpiochip_get_data(chip); ++ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); ++ unsigned long flags; ++ u32 reg; + +- if (ret) +- return ret; ++ raw_spin_lock_irqsave(&byt_lock, flags); + +- byt_gpio_set(chip, offset, value); ++ byt_gpio_direct_irq_check(vg, offset); + ++ reg = readl(val_reg); ++ reg &= ~BYT_DIR_MASK; ++ if (value) ++ reg |= BYT_LEVEL; ++ else ++ reg &= ~BYT_LEVEL; ++ ++ writel(reg, val_reg); ++ ++ raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; + } + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 07345016fd9c7..8cfb4f12c68cb 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -654,7 +654,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + struct _pcie_device *pcie_device = NULL; + u32 ioc_state; + u16 smid; +- u8 timeout; ++ unsigned long timeout; + u8 issue_reset; + u32 sz, sz_arg; + void *psge; +diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c +index 2145a70dac691..4ee92f7ca20bd 100644 +--- a/drivers/spi/spi-bcm-qspi.c ++++ b/drivers/spi/spi-bcm-qspi.c +@@ -1223,7 +1223,7 @@ int bcm_qspi_probe(struct platform_device *pdev, + if (!of_match_node(bcm_qspi_of_match, dev->of_node)) + return -ENODEV; + +- master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); ++ master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi)); + if (!master) { + dev_err(dev, "error allocating spi_master\n"); + return -ENOMEM; +@@ -1257,21 +1257,17 @@ int bcm_qspi_probe(struct platform_device *pdev, + + if (res) { + qspi->base[MSPI] = devm_ioremap_resource(dev, res); +- if (IS_ERR(qspi->base[MSPI])) { +- ret = PTR_ERR(qspi->base[MSPI]); +- goto qspi_resource_err; +- } ++ if (IS_ERR(qspi->base[MSPI])) ++ return PTR_ERR(qspi->base[MSPI]); + } else { +- goto qspi_resource_err; ++ return 0; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); + if (res) { + qspi->base[BSPI] = devm_ioremap_resource(dev, res); +- if (IS_ERR(qspi->base[BSPI])) { +- ret = PTR_ERR(qspi->base[BSPI]); +- goto qspi_resource_err; +- } ++ if (IS_ERR(qspi->base[BSPI])) ++ return PTR_ERR(qspi->base[BSPI]); + qspi->bspi_mode = true; + } else { + qspi->bspi_mode = false; +@@ -1282,18 +1278,14 @@ int bcm_qspi_probe(struct platform_device *pdev, + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); + if (res) { + qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); +- if (IS_ERR(qspi->base[CHIP_SELECT])) { +- ret = PTR_ERR(qspi->base[CHIP_SELECT]); +- goto qspi_resource_err; +- } ++ if (IS_ERR(qspi->base[CHIP_SELECT])) ++ return PTR_ERR(qspi->base[CHIP_SELECT]); + } + + qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), + GFP_KERNEL); +- if (!qspi->dev_ids) { +- ret = -ENOMEM; +- goto qspi_resource_err; +- } ++ if (!qspi->dev_ids) ++ return -ENOMEM; + + for (val = 0; val < num_irqs; val++) { + irq = -1; +@@ -1369,7 +1361,7 @@ int bcm_qspi_probe(struct platform_device *pdev, + qspi->xfer_mode.addrlen = -1; + qspi->xfer_mode.hp = -1; + +- ret = devm_spi_register_master(&pdev->dev, master); ++ ret = spi_register_master(master); + if (ret < 0) { + dev_err(dev, "can't register master\n"); + goto qspi_reg_err; +@@ -1382,8 +1374,6 @@ qspi_reg_err: + clk_disable_unprepare(qspi->clk); + qspi_probe_err: + kfree(qspi->dev_ids); +-qspi_resource_err: +- spi_master_put(master); + return ret; + } + /* probe function to be called by SoC specific platform driver probe */ +@@ -1393,10 +1383,10 @@ int bcm_qspi_remove(struct platform_device *pdev) + { + struct bcm_qspi *qspi = platform_get_drvdata(pdev); + ++ spi_unregister_master(qspi->master); + bcm_qspi_hw_uninit(qspi); + clk_disable_unprepare(qspi->clk); + kfree(qspi->dev_ids); +- spi_unregister_master(qspi->master); + + return 0; + } +diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c +index df6abc75bc167..6824beae18e4a 100644 +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -737,7 +737,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) + struct resource *res; + int err; + +- master = spi_alloc_master(&pdev->dev, sizeof(*bs)); ++ master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs)); + if (!master) { + dev_err(&pdev->dev, "spi_alloc_master() failed\n"); + return -ENOMEM; +@@ -759,23 +759,20 @@ static int bcm2835_spi_probe(struct platform_device *pdev) + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + bs->regs = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(bs->regs)) { +- err = PTR_ERR(bs->regs); +- goto out_master_put; +- } ++ if (IS_ERR(bs->regs)) ++ return PTR_ERR(bs->regs); + + bs->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(bs->clk)) { + err = PTR_ERR(bs->clk); + dev_err(&pdev->dev, "could not get clk: %d\n", err); +- goto out_master_put; ++ return err; + } + + bs->irq = platform_get_irq(pdev, 0); + if (bs->irq <= 0) { + dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); +- err = bs->irq ? bs->irq : -ENODEV; +- goto out_master_put; ++ return bs->irq ? bs->irq : -ENODEV; + } + + clk_prepare_enable(bs->clk); +@@ -790,21 +787,20 @@ static int bcm2835_spi_probe(struct platform_device *pdev) + dev_name(&pdev->dev), master); + if (err) { + dev_err(&pdev->dev, "could not request IRQ: %d\n", err); +- goto out_clk_disable; ++ goto out_dma_release; + } + + err = spi_register_master(master); + if (err) { + dev_err(&pdev->dev, "could not register SPI master: %d\n", err); +- goto out_clk_disable; ++ goto out_dma_release; + } + + return 0; + +-out_clk_disable: ++out_dma_release: ++ bcm2835_dma_release(master); + clk_disable_unprepare(bs->clk); +-out_master_put: +- spi_master_put(master); + return err; + } + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 1fd529a2d2f6b..fbc5444bd9cbd 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2050,6 +2050,49 @@ struct spi_controller *__spi_alloc_controller(struct device *dev, + } + EXPORT_SYMBOL_GPL(__spi_alloc_controller); + ++static void devm_spi_release_controller(struct device *dev, void *ctlr) ++{ ++ spi_controller_put(*(struct spi_controller **)ctlr); ++} ++ ++/** ++ * __devm_spi_alloc_controller - resource-managed __spi_alloc_controller() ++ * @dev: physical device of SPI controller ++ * @size: how much zeroed driver-private data to allocate ++ * @slave: whether to allocate an SPI master (false) or SPI slave (true) ++ * Context: can sleep ++ * ++ * Allocate an SPI controller and automatically release a reference on it ++ * when @dev is unbound from its driver. Drivers are thus relieved from ++ * having to call spi_controller_put(). ++ * ++ * The arguments to this function are identical to __spi_alloc_controller(). ++ * ++ * Return: the SPI controller structure on success, else NULL. ++ */ ++struct spi_controller *__devm_spi_alloc_controller(struct device *dev, ++ unsigned int size, ++ bool slave) ++{ ++ struct spi_controller **ptr, *ctlr; ++ ++ ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr), ++ GFP_KERNEL); ++ if (!ptr) ++ return NULL; ++ ++ ctlr = __spi_alloc_controller(dev, size, slave); ++ if (ctlr) { ++ *ptr = ctlr; ++ devres_add(dev, ptr); ++ } else { ++ devres_free(ptr); ++ } ++ ++ return ctlr; ++} ++EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller); ++ + #ifdef CONFIG_OF + static int of_spi_register_master(struct spi_controller *ctlr) + { +@@ -2300,6 +2343,11 @@ int devm_spi_register_controller(struct device *dev, + } + EXPORT_SYMBOL_GPL(devm_spi_register_controller); + ++static int devm_spi_match_controller(struct device *dev, void *res, void *ctlr) ++{ ++ return *(struct spi_controller **)res == ctlr; ++} ++ + static int __unregister(struct device *dev, void *null) + { + spi_unregister_device(to_spi_device(dev)); +@@ -2341,7 +2389,15 @@ void spi_unregister_controller(struct spi_controller *ctlr) + list_del(&ctlr->list); + mutex_unlock(&board_lock); + +- device_unregister(&ctlr->dev); ++ device_del(&ctlr->dev); ++ ++ /* Release the last reference on the controller if its driver ++ * has not yet been converted to devm_spi_alloc_master/slave(). ++ */ ++ if (!devres_find(ctlr->dev.parent, devm_spi_release_controller, ++ devm_spi_match_controller, ctlr)) ++ put_device(&ctlr->dev); ++ + /* free bus id */ + mutex_lock(&board_lock); + if (found == ctlr) +diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c +index 6c754ddf12571..5c282e8522fb3 100644 +--- a/drivers/staging/speakup/spk_ttyio.c ++++ b/drivers/staging/speakup/spk_ttyio.c +@@ -47,27 +47,20 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) + { + struct spk_ldisc_data *ldisc_data; + ++ if (tty != speakup_tty) ++ /* Somebody tried to use this line discipline outside speakup */ ++ return -ENODEV; ++ + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + +- mutex_lock(&speakup_tty_mutex); +- if (speakup_tty) { +- mutex_unlock(&speakup_tty_mutex); +- return -EBUSY; +- } +- speakup_tty = tty; +- + ldisc_data = kmalloc(sizeof(struct spk_ldisc_data), GFP_KERNEL); +- if (!ldisc_data) { +- speakup_tty = NULL; +- mutex_unlock(&speakup_tty_mutex); ++ if (!ldisc_data) + return -ENOMEM; +- } + + sema_init(&ldisc_data->sem, 0); + ldisc_data->buf_free = true; +- speakup_tty->disc_data = ldisc_data; +- mutex_unlock(&speakup_tty_mutex); ++ tty->disc_data = ldisc_data; + + return 0; + } +@@ -187,9 +180,25 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) + + tty_unlock(tty); + ++ mutex_lock(&speakup_tty_mutex); ++ speakup_tty = tty; + ret = tty_set_ldisc(tty, N_SPEAKUP); + if (ret) +- pr_err("speakup: Failed to set N_SPEAKUP on tty\n"); ++ speakup_tty = NULL; ++ mutex_unlock(&speakup_tty_mutex); ++ ++ if (!ret) ++ /* Success */ ++ return 0; ++ ++ pr_err("speakup: Failed to set N_SPEAKUP on tty\n"); ++ ++ tty_lock(tty); ++ if (tty->ops->close) ++ tty->ops->close(tty, NULL); ++ tty_unlock(tty); ++ ++ tty_kclose(tty); + + return ret; + } +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index ac8025cd4a1fe..ff6a360eef1ed 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -2747,10 +2747,14 @@ void __do_SAK(struct tty_struct *tty) + struct task_struct *g, *p; + struct pid *session; + int i; ++ unsigned long flags; + + if (!tty) + return; +- session = tty->session; ++ ++ spin_lock_irqsave(&tty->ctrl_lock, flags); ++ session = get_pid(tty->session); ++ spin_unlock_irqrestore(&tty->ctrl_lock, flags); + + tty_ldisc_flush(tty); + +@@ -2782,6 +2786,7 @@ void __do_SAK(struct tty_struct *tty) + task_unlock(p); + } while_each_thread(g, p); + read_unlock(&tasklist_lock); ++ put_pid(session); + #endif + } + +diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c +index c4ecd66fafefd..ffcab80ba77d9 100644 +--- a/drivers/tty/tty_jobctrl.c ++++ b/drivers/tty/tty_jobctrl.c +@@ -103,8 +103,8 @@ static void __proc_set_tty(struct tty_struct *tty) + put_pid(tty->session); + put_pid(tty->pgrp); + tty->pgrp = get_pid(task_pgrp(current)); +- spin_unlock_irqrestore(&tty->ctrl_lock, flags); + tty->session = get_pid(task_session(current)); ++ spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (current->signal->tty) { + tty_debug(tty, "current tty %s not NULL!!\n", + current->signal->tty->name); +@@ -293,20 +293,23 @@ void disassociate_ctty(int on_exit) + spin_lock_irq(¤t->sighand->siglock); + put_pid(current->signal->tty_old_pgrp); + current->signal->tty_old_pgrp = NULL; +- + tty = tty_kref_get(current->signal->tty); ++ spin_unlock_irq(¤t->sighand->siglock); ++ + if (tty) { + unsigned long flags; ++ ++ tty_lock(tty); + spin_lock_irqsave(&tty->ctrl_lock, flags); + put_pid(tty->session); + put_pid(tty->pgrp); + tty->session = NULL; + tty->pgrp = NULL; + spin_unlock_irqrestore(&tty->ctrl_lock, flags); ++ tty_unlock(tty); + tty_kref_put(tty); + } + +- spin_unlock_irq(¤t->sighand->siglock); + /* Now clear signal->tty under the lock */ + read_lock(&tasklist_lock); + session_clear_tty(task_session(current)); +@@ -477,14 +480,19 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t + return -ENOTTY; + if (retval) + return retval; +- if (!current->signal->tty || +- (current->signal->tty != real_tty) || +- (real_tty->session != task_session(current))) +- return -ENOTTY; ++ + if (get_user(pgrp_nr, p)) + return -EFAULT; + if (pgrp_nr < 0) + return -EINVAL; ++ ++ spin_lock_irq(&real_tty->ctrl_lock); ++ if (!current->signal->tty || ++ (current->signal->tty != real_tty) || ++ (real_tty->session != task_session(current))) { ++ retval = -ENOTTY; ++ goto out_unlock_ctrl; ++ } + rcu_read_lock(); + pgrp = find_vpid(pgrp_nr); + retval = -ESRCH; +@@ -494,12 +502,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t + if (session_of_pgrp(pgrp) != task_session(current)) + goto out_unlock; + retval = 0; +- spin_lock_irq(&tty->ctrl_lock); + put_pid(real_tty->pgrp); + real_tty->pgrp = get_pid(pgrp); +- spin_unlock_irq(&tty->ctrl_lock); + out_unlock: + rcu_read_unlock(); ++out_unlock_ctrl: ++ spin_unlock_irq(&real_tty->ctrl_lock); + return retval; + } + +@@ -511,20 +519,30 @@ out_unlock: + * + * Obtain the session id of the tty. If there is no session + * return an error. +- * +- * Locking: none. Reference to current->signal->tty is safe. + */ + static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) + { ++ unsigned long flags; ++ pid_t sid; ++ + /* + * (tty == real_tty) is a cheap way of + * testing if the tty is NOT a master pty. + */ + if (tty == real_tty && current->signal->tty != real_tty) + return -ENOTTY; ++ ++ spin_lock_irqsave(&real_tty->ctrl_lock, flags); + if (!real_tty->session) +- return -ENOTTY; +- return put_user(pid_vnr(real_tty->session), p); ++ goto err; ++ sid = pid_vnr(real_tty->session); ++ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); ++ ++ return put_user(sid, p); ++ ++err: ++ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); ++ return -ENOTTY; + } + + /* +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index 11a501d0664cc..bb2edfc77627b 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1243,7 +1243,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, + case FUNCTIONFS_ENDPOINT_DESC: + { + int desc_idx; +- struct usb_endpoint_descriptor *desc; ++ struct usb_endpoint_descriptor desc1, *desc; + + switch (epfile->ffs->gadget->speed) { + case USB_SPEED_SUPER: +@@ -1255,10 +1255,12 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, + default: + desc_idx = 0; + } ++ + desc = epfile->ep->descs[desc_idx]; ++ memcpy(&desc1, desc, desc->bLength); + + spin_unlock_irq(&epfile->ffs->eps_lock); +- ret = copy_to_user((void __user *)value, desc, desc->bLength); ++ ret = copy_to_user((void __user *)value, &desc1, desc1.bLength); + if (ret) + ret = -EFAULT; + return ret; +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index efadf2f6afa1c..c6bdf533016a5 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -80,10 +80,11 @@ + #define CH341_LCR_CS5 0x00 + + static const struct usb_device_id id_table[] = { +- { USB_DEVICE(0x4348, 0x5523) }, ++ { USB_DEVICE(0x1a86, 0x5512) }, ++ { USB_DEVICE(0x1a86, 0x5523) }, + { USB_DEVICE(0x1a86, 0x7522) }, + { USB_DEVICE(0x1a86, 0x7523) }, +- { USB_DEVICE(0x1a86, 0x5523) }, ++ { USB_DEVICE(0x4348, 0x5523) }, + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c +index 5ee48b0650c45..5f6b82ebccc5a 100644 +--- a/drivers/usb/serial/kl5kusb105.c ++++ b/drivers/usb/serial/kl5kusb105.c +@@ -276,12 +276,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) + priv->cfg.unknown2 = cfg->unknown2; + spin_unlock_irqrestore(&priv->lock, flags); + ++ kfree(cfg); ++ + /* READ_ON and urb submission */ + rc = usb_serial_generic_open(tty, port); +- if (rc) { +- retval = rc; +- goto err_free_cfg; +- } ++ if (rc) ++ return rc; + + rc = usb_control_msg(port->serial->dev, + usb_sndctrlpipe(port->serial->dev, 0), +@@ -324,8 +324,6 @@ err_disable_read: + KLSI_TIMEOUT); + err_generic_close: + usb_serial_generic_close(port); +-err_free_cfg: +- kfree(cfg); + + return retval; + } +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index f28344f03141d..73cd2f8f0f65a 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -419,6 +419,7 @@ static void option_instat_callback(struct urb *urb); + #define CINTERION_PRODUCT_PH8 0x0053 + #define CINTERION_PRODUCT_AHXX 0x0055 + #define CINTERION_PRODUCT_PLXX 0x0060 ++#define CINTERION_PRODUCT_EXS82 0x006c + #define CINTERION_PRODUCT_PH8_2RMNET 0x0082 + #define CINTERION_PRODUCT_PH8_AUDIO 0x0083 + #define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 +@@ -1105,9 +1106,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff), + .driver_info = NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96, 0xff, 0xff, 0xff), +- .driver_info = NUMEP2 }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96, 0xff, 0, 0) }, ++ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, +@@ -1902,6 +1902,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff), + .driver_info = RSVD(0) | RSVD(4) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EXS82, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, +@@ -2046,12 +2047,13 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, + { USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */ + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, +- { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 */ ++ { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ + .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, + { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 6335ca143292f..6285085195c15 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -777,6 +777,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) + list_del_init(&server->tcp_ses_list); + spin_unlock(&cifs_tcp_ses_lock); + ++ cancel_delayed_work_sync(&server->echo); ++ + spin_lock(&GlobalMid_Lock); + server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index de9b561b1c385..054fdfd4fb8b3 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -1009,6 +1009,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip) + if (error < 0) + return error; + ++ if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) { ++ fs_err(sdp, "no resource groups found in the file system.\n"); ++ return -ENOENT; ++ } + set_rgrp_preferences(sdp); + + sdp->sd_rindex_uptodate = 1; +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index a64235e053216..8ceba9b8e51e3 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -634,6 +634,25 @@ static inline struct spi_controller *spi_alloc_slave(struct device *host, + return __spi_alloc_controller(host, size, true); + } + ++struct spi_controller *__devm_spi_alloc_controller(struct device *dev, ++ unsigned int size, ++ bool slave); ++ ++static inline struct spi_controller *devm_spi_alloc_master(struct device *dev, ++ unsigned int size) ++{ ++ return __devm_spi_alloc_controller(dev, size, false); ++} ++ ++static inline struct spi_controller *devm_spi_alloc_slave(struct device *dev, ++ unsigned int size) ++{ ++ if (!IS_ENABLED(CONFIG_SPI_SLAVE)) ++ return NULL; ++ ++ return __devm_spi_alloc_controller(dev, size, true); ++} ++ + extern int spi_register_controller(struct spi_controller *ctlr); + extern int devm_spi_register_controller(struct device *dev, + struct spi_controller *ctlr); +diff --git a/include/linux/tty.h b/include/linux/tty.h +index 74226a8f919c1..d808ab9c9aff2 100644 +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -306,6 +306,10 @@ struct tty_struct { + struct termiox *termiox; /* May be NULL for unsupported */ + char name[64]; + struct pid *pgrp; /* Protected by ctrl lock */ ++ /* ++ * Writes protected by both ctrl lock and legacy mutex, readers must use ++ * at least one of them. ++ */ + struct pid *session; + unsigned long flags; + int count; +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 992d48774c9e9..cce526755471f 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1650,6 +1650,8 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec) + static struct ftrace_ops * + ftrace_find_tramp_ops_any(struct dyn_ftrace *rec); + static struct ftrace_ops * ++ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_exclude); ++static struct ftrace_ops * + ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops); + + static bool __ftrace_hash_rec_update(struct ftrace_ops *ops, +@@ -1787,7 +1789,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops, + * to it. + */ + if (ftrace_rec_count(rec) == 1 && +- ftrace_find_tramp_ops_any(rec)) ++ ftrace_find_tramp_ops_any_other(rec, ops)) + rec->flags |= FTRACE_FL_TRAMP; + else + rec->flags &= ~FTRACE_FL_TRAMP; +@@ -2215,6 +2217,24 @@ ftrace_find_tramp_ops_any(struct dyn_ftrace *rec) + return NULL; + } + ++static struct ftrace_ops * ++ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_exclude) ++{ ++ struct ftrace_ops *op; ++ unsigned long ip = rec->ip; ++ ++ do_for_each_ftrace_op(op, ftrace_ops_list) { ++ ++ if (op == op_exclude || !op->trampoline) ++ continue; ++ ++ if (hash_contains_ip(ip, op->func_hash)) ++ return op; ++ } while_for_each_ftrace_op(op); ++ ++ return NULL; ++} ++ + static struct ftrace_ops * + ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, + struct ftrace_ops *op) +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index c3cc6aaa6f79d..d6f1e305bb3db 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2416,7 +2416,7 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr, + * two. They are not that meaningful. + */ + ftrace_trace_stack(tr, buffer, flags, regs ? 0 : STACK_SKIP, pc, regs); +- ftrace_trace_userstack(buffer, flags, pc); ++ ftrace_trace_userstack(tr, buffer, flags, pc); + } + + /* +@@ -2736,14 +2736,15 @@ void trace_dump_stack(int skip) + static DEFINE_PER_CPU(int, user_stack_count); + + void +-ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) ++ftrace_trace_userstack(struct trace_array *tr, ++ struct ring_buffer *buffer, unsigned long flags, int pc) + { + struct trace_event_call *call = &event_user_stack; + struct ring_buffer_event *event; + struct userstack_entry *entry; + struct stack_trace trace; + +- if (!(global_trace.trace_flags & TRACE_ITER_USERSTACKTRACE)) ++ if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE)) + return; + + /* +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index 01475411fd1b2..afaeef6c15b30 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -745,13 +745,15 @@ void update_max_tr_single(struct trace_array *tr, + #endif /* CONFIG_TRACER_MAX_TRACE */ + + #ifdef CONFIG_STACKTRACE +-void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, ++void ftrace_trace_userstack(struct trace_array *tr, ++ struct ring_buffer *buffer, unsigned long flags, + int pc); + + void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, + int pc); + #else +-static inline void ftrace_trace_userstack(struct ring_buffer *buffer, ++static inline void ftrace_trace_userstack(struct trace_array *tr, ++ struct ring_buffer *buffer, + unsigned long flags, int pc) + { + } +diff --git a/mm/list_lru.c b/mm/list_lru.c +index 758653dd14431..f7d2ffc209fbd 100644 +--- a/mm/list_lru.c ++++ b/mm/list_lru.c +@@ -542,7 +542,6 @@ static void memcg_drain_list_lru_node(struct list_lru *lru, int nid, + struct list_lru_node *nlru = &lru->node[nid]; + int dst_idx = dst_memcg->kmemcg_id; + struct list_lru_one *src, *dst; +- bool set; + + /* + * Since list_lru_{add,del} may be called under an IRQ-safe lock, +@@ -554,11 +553,12 @@ static void memcg_drain_list_lru_node(struct list_lru *lru, int nid, + dst = list_lru_from_memcg_idx(nlru, dst_idx); + + list_splice_init(&src->list, &dst->list); +- set = (!dst->nr_items && src->nr_items); +- dst->nr_items += src->nr_items; +- if (set) ++ ++ if (src->nr_items) { ++ dst->nr_items += src->nr_items; + memcg_set_shrinker_bit(dst_memcg, nid, lru_shrinker_id(lru)); +- src->nr_items = 0; ++ src->nr_items = 0; ++ } + + spin_unlock_irq(&nlru->lock); + } +diff --git a/mm/swapfile.c b/mm/swapfile.c +index adeb49fcad23e..130e2e41a48ce 100644 +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -2825,6 +2825,7 @@ late_initcall(max_swapfiles_check); + static struct swap_info_struct *alloc_swap_info(void) + { + struct swap_info_struct *p; ++ struct swap_info_struct *defer = NULL; + unsigned int type; + int i; + int size = sizeof(*p) + nr_node_ids * sizeof(struct plist_node); +@@ -2854,7 +2855,7 @@ static struct swap_info_struct *alloc_swap_info(void) + smp_wmb(); + WRITE_ONCE(nr_swapfiles, nr_swapfiles + 1); + } else { +- kvfree(p); ++ defer = p; + p = swap_info[type]; + /* + * Do not memset this entry: a racing procfs swap_next() +@@ -2867,6 +2868,7 @@ static struct swap_info_struct *alloc_swap_info(void) + plist_node_init(&p->avail_lists[i], 0); + p->flags = SWP_USED; + spin_unlock(&swap_lock); ++ kvfree(defer); + spin_lock_init(&p->lock); + spin_lock_init(&p->cont_lock); + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 5b4632826dc66..9cc8e92f4b000 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -532,7 +532,8 @@ static void nft_request_module(struct net *net, const char *fmt, ...) + static void lockdep_nfnl_nft_mutex_not_held(void) + { + #ifdef CONFIG_PROVE_LOCKING +- WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES)); ++ if (debug_locks) ++ WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES)); + #endif + } + +diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c +index 97adb7e340f99..0a196be90b2e5 100644 +--- a/sound/pci/hda/hda_generic.c ++++ b/sound/pci/hda/hda_generic.c +@@ -1376,16 +1376,20 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, + struct nid_path *path; + hda_nid_t pin = pins[i]; + +- path = snd_hda_get_path_from_idx(codec, path_idx[i]); +- if (path) { +- badness += assign_out_path_ctls(codec, path); +- continue; ++ if (!spec->obey_preferred_dacs) { ++ path = snd_hda_get_path_from_idx(codec, path_idx[i]); ++ if (path) { ++ badness += assign_out_path_ctls(codec, path); ++ continue; ++ } + } + + dacs[i] = get_preferred_dac(codec, pin); + if (dacs[i]) { + if (is_dac_already_used(codec, dacs[i])) + badness += bad->shared_primary; ++ } else if (spec->obey_preferred_dacs) { ++ badness += BAD_NO_PRIMARY_DAC; + } + + if (!dacs[i]) +diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h +index 8933c0f64cc4a..2ccdd92c8c7fd 100644 +--- a/sound/pci/hda/hda_generic.h ++++ b/sound/pci/hda/hda_generic.h +@@ -240,6 +240,7 @@ struct hda_gen_spec { + unsigned int power_down_unused:1; /* power down unused widgets */ + unsigned int dac_min_mute:1; /* minimal = mute for DACs */ + unsigned int suppress_vmaster:1; /* don't create vmaster kctls */ ++ unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */ + + /* other internal flags */ + unsigned int no_analog:1; /* digital I/O only */ +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 935ca7989cfd5..790a2e79aba54 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -439,6 +439,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + alc_update_coef_idx(codec, 0x7, 1<<5, 0); + break; + case 0x10ec0892: ++ case 0x10ec0897: + alc_update_coef_idx(codec, 0x7, 1<<5, 0); + break; + case 0x10ec0899: +@@ -7068,6 +7069,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), + SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), ++ SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), +@@ -7777,6 +7779,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC292_STANDARD_PINS, + {0x13, 0x90a60140}), ++ SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_HPE, ++ {0x17, 0x90170110}, ++ {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC, + {0x14, 0x90170110}, + {0x1b, 0x90a70130}, +@@ -9162,6 +9167,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { + HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882), + HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882), + HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662), ++ HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662), + HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882), + HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882), + HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882), +diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h +index c2c01f84df75f..3e0e18d376d2c 100644 +--- a/tools/objtool/arch/x86/include/asm/insn.h ++++ b/tools/objtool/arch/x86/include/asm/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate(struct insn *insn) + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + +diff --git a/tools/perf/util/intel-pt-decoder/insn.h b/tools/perf/util/intel-pt-decoder/insn.h +index 2669c9f748e4d..1a01d0a41ab8e 100644 +--- a/tools/perf/util/intel-pt-decoder/insn.h ++++ b/tools/perf/util/intel-pt-decoder/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate(struct insn *insn) + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + |