diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.181-182.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.181-182.patch new file mode 100644 index 0000000000..286bae77c9 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.181-182.patch @@ -0,0 +1,2110 @@ +diff --git a/Makefile b/Makefile +index afe2420bb3de0..8750309fc42ac 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 181 ++SUBLEVEL = 182 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c +index 237d20dd5622d..286cec4d86d7b 100644 +--- a/arch/parisc/kernel/unaligned.c ++++ b/arch/parisc/kernel/unaligned.c +@@ -340,7 +340,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) + : "r" (val), "r" (regs->ior), "r" (regs->isr) + : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); + +- return 0; ++ return ret; + } + static int emulate_std(struct pt_regs *regs, int frreg, int flop) + { +@@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) + __asm__ __volatile__ ( + " mtsp %4, %%sr1\n" + " zdep %2, 29, 2, %%r19\n" +-" dep %%r0, 31, 2, %2\n" ++" dep %%r0, 31, 2, %3\n" + " mtsar %%r19\n" + " zvdepi -2, 32, %%r19\n" + "1: ldw 0(%%sr1,%3),%%r20\n" +@@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) + " andcm %%r21, %%r19, %%r21\n" + " or %1, %%r20, %1\n" + " or %2, %%r21, %2\n" +-"3: stw %1,0(%%sr1,%1)\n" ++"3: stw %1,0(%%sr1,%3)\n" + "4: stw %%r1,4(%%sr1,%3)\n" + "5: stw %2,8(%%sr1,%3)\n" + " copy %%r0, %0\n" +@@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs) + ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ + break; + } +-#ifdef CONFIG_PA20 + switch (regs->iir & OPCODE2_MASK) + { + case OPCODE_FLDD_L: +@@ -607,22 +606,23 @@ void handle_unaligned(struct pt_regs *regs) + flop=1; + ret = emulate_std(regs, R2(regs->iir),1); + break; ++#ifdef CONFIG_PA20 + case OPCODE_LDD_L: + ret = emulate_ldd(regs, R2(regs->iir),0); + break; + case OPCODE_STD_L: + ret = emulate_std(regs, R2(regs->iir),0); + break; +- } + #endif ++ } + switch (regs->iir & OPCODE3_MASK) + { + case OPCODE_FLDW_L: + flop=1; +- ret = emulate_ldw(regs, R2(regs->iir),0); ++ ret = emulate_ldw(regs, R2(regs->iir), 1); + break; + case OPCODE_LDW_M: +- ret = emulate_ldw(regs, R2(regs->iir),1); ++ ret = emulate_ldw(regs, R2(regs->iir), 0); + break; + + case OPCODE_FSTW_L: +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index 03b3de491b5e6..5ed702e2c55f4 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -560,9 +560,11 @@ static inline void __fpregs_load_activate(void) + * The FPU context is only stored/restored for a user task and + * PF_KTHREAD is used to distinguish between kernel and user threads. + */ +-static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) ++static inline void switch_fpu_prepare(struct task_struct *prev, int cpu) + { +- if (static_cpu_has(X86_FEATURE_FPU) && !(current->flags & PF_KTHREAD)) { ++ struct fpu *old_fpu = &prev->thread.fpu; ++ ++ if (static_cpu_has(X86_FEATURE_FPU) && !(prev->flags & PF_KTHREAD)) { + if (!copy_fpregs_to_fpstate(old_fpu)) + old_fpu->last_cpu = -1; + else +@@ -581,10 +583,11 @@ static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) + * Load PKRU from the FPU context if available. Delay loading of the + * complete FPU state until the return to userland. + */ +-static inline void switch_fpu_finish(struct fpu *new_fpu) ++static inline void switch_fpu_finish(struct task_struct *next) + { + u32 pkru_val = init_pkru_value; + struct pkru_state *pk; ++ struct fpu *next_fpu = &next->thread.fpu; + + if (!static_cpu_has(X86_FEATURE_FPU)) + return; +@@ -598,7 +601,7 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) + * PKRU state is switched eagerly because it needs to be valid before we + * return to userland e.g. for a copy_to_user() operation. + */ +- if (!(current->flags & PF_KTHREAD)) { ++ if (!(next->flags & PF_KTHREAD)) { + /* + * If the PKRU bit in xsave.header.xfeatures is not set, + * then the PKRU component was in init state, which means +@@ -607,7 +610,7 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) + * in memory is not valid. This means pkru_val has to be + * set to 0 and not to init_pkru_value. + */ +- pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); ++ pk = get_xsave_addr(&next_fpu->state.xsave, XFEATURE_PKRU); + pkru_val = pk ? pk->pkru : 0; + } + __write_pkru(pkru_val); +diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c +index b8ceec4974fe3..352f876950ab3 100644 +--- a/arch/x86/kernel/process_32.c ++++ b/arch/x86/kernel/process_32.c +@@ -229,14 +229,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + { + struct thread_struct *prev = &prev_p->thread, + *next = &next_p->thread; +- struct fpu *prev_fpu = &prev->fpu; +- struct fpu *next_fpu = &next->fpu; + int cpu = smp_processor_id(); + + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ + + if (!test_thread_flag(TIF_NEED_FPU_LOAD)) +- switch_fpu_prepare(prev_fpu, cpu); ++ switch_fpu_prepare(prev_p, cpu); + + /* + * Save away %gs. No need to save %fs, as it was saved on the +@@ -292,7 +290,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + + this_cpu_write(current_task, next_p); + +- switch_fpu_finish(next_fpu); ++ switch_fpu_finish(next_p); + + /* Load the Intel cache allocation PQR MSR. */ + resctrl_sched_in(); +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index da3cc3a10d63f..633788362906a 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -505,15 +505,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + { + struct thread_struct *prev = &prev_p->thread; + struct thread_struct *next = &next_p->thread; +- struct fpu *prev_fpu = &prev->fpu; +- struct fpu *next_fpu = &next->fpu; + int cpu = smp_processor_id(); + + WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) && + this_cpu_read(irq_count) != -1); + + if (!test_thread_flag(TIF_NEED_FPU_LOAD)) +- switch_fpu_prepare(prev_fpu, cpu); ++ switch_fpu_prepare(prev_p, cpu); + + /* We must save %fs and %gs before load_TLS() because + * %fs and %gs may be cleared by load_TLS(). +@@ -565,7 +563,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + this_cpu_write(current_task, next_p); + this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p)); + +- switch_fpu_finish(next_fpu); ++ switch_fpu_finish(next_p); + + /* Reload sp0. */ + update_task_stack(next_p); +diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c +index fad6c6a873130..499a947d56ddb 100644 +--- a/drivers/ata/pata_hpt37x.c ++++ b/drivers/ata/pata_hpt37x.c +@@ -917,6 +917,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) + irqmask &= ~0x10; + pci_write_config_byte(dev, 0x5a, irqmask); + ++ /* ++ * HPT371 chips physically have only one channel, the secondary one, ++ * but the primary channel registers do exist! Go figure... ++ * So, we manually disable the non-existing channel here ++ * (if the BIOS hasn't done this already). ++ */ ++ if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { ++ u8 mcr1; ++ ++ pci_read_config_byte(dev, 0x50, &mcr1); ++ mcr1 &= ~0x04; ++ pci_write_config_byte(dev, 0x50, mcr1); ++ } ++ + /* + * default to pci clock. make sure MA15/16 are set to output + * to prevent drives having problems with 40-pin cables. Needed +diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c +index a3b4635f62784..97afabb7fe8e5 100644 +--- a/drivers/clk/ingenic/jz4725b-cgu.c ++++ b/drivers/clk/ingenic/jz4725b-cgu.c +@@ -135,11 +135,10 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { + }, + + [JZ4725B_CLK_I2S] = { +- "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, ++ "i2s", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 }, + .mux = { CGU_REG_CPCCR, 31, 1 }, + .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, +- .gate = { CGU_REG_CLKGR, 6 }, + }, + + [JZ4725B_CLK_SPI] = { +diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c +index a9058fda187e3..a41e1ddf9e6fc 100644 +--- a/drivers/gpio/gpio-tegra186.c ++++ b/drivers/gpio/gpio-tegra186.c +@@ -234,9 +234,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip, + return offset + pin; + } + ++#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio) ++ + static void tegra186_irq_ack(struct irq_data *data) + { +- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); ++ struct tegra_gpio *gpio = to_tegra_gpio(gc); + void __iomem *base; + + base = tegra186_gpio_get_base(gpio, data->hwirq); +@@ -248,7 +251,8 @@ static void tegra186_irq_ack(struct irq_data *data) + + static void tegra186_irq_mask(struct irq_data *data) + { +- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); ++ struct tegra_gpio *gpio = to_tegra_gpio(gc); + void __iomem *base; + u32 value; + +@@ -263,7 +267,8 @@ static void tegra186_irq_mask(struct irq_data *data) + + static void tegra186_irq_unmask(struct irq_data *data) + { +- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); ++ struct tegra_gpio *gpio = to_tegra_gpio(gc); + void __iomem *base; + u32 value; + +@@ -278,7 +283,8 @@ static void tegra186_irq_unmask(struct irq_data *data) + + static int tegra186_irq_set_type(struct irq_data *data, unsigned int type) + { +- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(data); ++ struct tegra_gpio *gpio = to_tegra_gpio(gc); + void __iomem *base; + u32 value; + +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index 6ff1d308623a7..b368496ed6858 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -1143,8 +1143,11 @@ static int soc15_common_early_init(void *handle) + AMD_CG_SUPPORT_SDMA_MGCG | + AMD_CG_SUPPORT_SDMA_LS; + ++ /* ++ * MMHUB PG needs to be disabled for Picasso for ++ * stability reasons. ++ */ + adev->pg_flags = AMD_PG_SUPPORT_SDMA | +- AMD_PG_SUPPORT_MMHUB | + AMD_PG_SUPPORT_VCN; + } else { + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 9b69e55ad7010..3f0a798906004 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -4659,6 +4659,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi + if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) + return quirks; + ++ info->color_formats |= DRM_COLOR_FORMAT_RGB444; + drm_parse_cea_ext(connector, edid); + + /* +@@ -4707,7 +4708,6 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi + DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", + connector->name, info->bpc); + +- info->color_formats |= DRM_COLOR_FORMAT_RGB444; + if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) + info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; + if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +index 105b4be467a3e..ea2e11771bca5 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +@@ -88,13 +88,20 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) + return 0; + } + +-static void ++static int + nvkm_pmu_reset(struct nvkm_pmu *pmu) + { + struct nvkm_device *device = pmu->subdev.device; + + if (!pmu->func->enabled(pmu)) +- return; ++ return 0; ++ ++ /* Inhibit interrupts, and wait for idle. */ ++ nvkm_wr32(device, 0x10a014, 0x0000ffff); ++ nvkm_msec(device, 2000, ++ if (!nvkm_rd32(device, 0x10a04c)) ++ break; ++ ); + + /* Reset. */ + if (pmu->func->reset) +@@ -105,37 +112,25 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu) + if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006)) + break; + ); ++ ++ return 0; + } + + static int + nvkm_pmu_preinit(struct nvkm_subdev *subdev) + { + struct nvkm_pmu *pmu = nvkm_pmu(subdev); +- nvkm_pmu_reset(pmu); +- return 0; ++ return nvkm_pmu_reset(pmu); + } + + static int + nvkm_pmu_init(struct nvkm_subdev *subdev) + { + struct nvkm_pmu *pmu = nvkm_pmu(subdev); +- struct nvkm_device *device = pmu->subdev.device; +- +- if (!pmu->func->init) +- return 0; +- +- if (pmu->func->enabled(pmu)) { +- /* Inhibit interrupts, and wait for idle. */ +- nvkm_wr32(device, 0x10a014, 0x0000ffff); +- nvkm_msec(device, 2000, +- if (!nvkm_rd32(device, 0x10a04c)) +- break; +- ); +- +- nvkm_pmu_reset(pmu); +- } +- +- return pmu->func->init(pmu); ++ int ret = nvkm_pmu_reset(pmu); ++ if (ret == 0 && pmu->func->init) ++ ret = pmu->func->init(pmu); ++ return ret; + } + + static int +diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c +index bcdf25f32e220..a05d55125d13a 100644 +--- a/drivers/iio/accel/bmc150-accel-core.c ++++ b/drivers/iio/accel/bmc150-accel-core.c +@@ -1649,11 +1649,14 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "Unable to register iio device\n"); +- goto err_trigger_unregister; ++ goto err_pm_cleanup; + } + + return 0; + ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(dev); ++ pm_runtime_disable(dev); + err_trigger_unregister: + bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); + err_buffer_cleanup: +diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c +index 6ff6f625bbf69..bd762976a3815 100644 +--- a/drivers/iio/accel/kxcjk-1013.c ++++ b/drivers/iio/accel/kxcjk-1013.c +@@ -1409,11 +1409,14 @@ static int kxcjk1013_probe(struct i2c_client *client, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); +- goto err_buffer_cleanup; ++ goto err_pm_cleanup; + } + + return 0; + ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(&client->dev); ++ pm_runtime_disable(&client->dev); + err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + err_trigger_unregister: +diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c +index 99e4a21ca9421..8315c7ee66cf3 100644 +--- a/drivers/iio/accel/mma9551.c ++++ b/drivers/iio/accel/mma9551.c +@@ -496,11 +496,14 @@ static int mma9551_probe(struct i2c_client *client, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); +- goto out_poweroff; ++ goto err_pm_cleanup; + } + + return 0; + ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(&client->dev); ++ pm_runtime_disable(&client->dev); + out_poweroff: + mma9551_set_device_state(client, false); + +diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c +index 312070dcf035a..73e85196d0bd3 100644 +--- a/drivers/iio/accel/mma9553.c ++++ b/drivers/iio/accel/mma9553.c +@@ -1135,12 +1135,15 @@ static int mma9553_probe(struct i2c_client *client, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "unable to register iio device\n"); +- goto out_poweroff; ++ goto err_pm_cleanup; + } + + dev_dbg(&indio_dev->dev, "Registered device %s\n", name); + return 0; + ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(&client->dev); ++ pm_runtime_disable(&client->dev); + out_poweroff: + mma9551_set_device_state(client, false); + return ret; +diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c +index fa808f9c0d9af..635cc1e7b1234 100644 +--- a/drivers/iio/adc/ad7124.c ++++ b/drivers/iio/adc/ad7124.c +@@ -63,7 +63,7 @@ + #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) + #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) + #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) +-#define AD7124_CONFIG_IN_BUFF_MSK GENMASK(7, 6) ++#define AD7124_CONFIG_IN_BUFF_MSK GENMASK(6, 5) + #define AD7124_CONFIG_IN_BUFF(x) FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x) + + /* AD7124_FILTER_X */ +diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c +index 3b2fbb7ce4310..26caee73b7641 100644 +--- a/drivers/iio/adc/men_z188_adc.c ++++ b/drivers/iio/adc/men_z188_adc.c +@@ -103,6 +103,7 @@ static int men_z188_probe(struct mcb_device *dev, + struct z188_adc *adc; + struct iio_dev *indio_dev; + struct resource *mem; ++ int ret; + + indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc)); + if (!indio_dev) +@@ -129,8 +130,14 @@ static int men_z188_probe(struct mcb_device *dev, + adc->mem = mem; + mcb_set_drvdata(dev, indio_dev); + +- return iio_device_register(indio_dev); ++ ret = iio_device_register(indio_dev); ++ if (ret) ++ goto err_unmap; ++ ++ return 0; + ++err_unmap: ++ iounmap(adc->base); + err: + mcb_release_mem(mem); + return -ENXIO; +diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c +index 276bed47e8d66..bf1355360c518 100644 +--- a/drivers/iio/gyro/bmg160_core.c ++++ b/drivers/iio/gyro/bmg160_core.c +@@ -1173,11 +1173,14 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "unable to register iio device\n"); +- goto err_buffer_cleanup; ++ goto err_pm_cleanup; + } + + return 0; + ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(dev); ++ pm_runtime_disable(dev); + err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + err_trigger_unregister: +diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c +index e67466100aff4..c7d19f9ca7652 100644 +--- a/drivers/iio/imu/kmx61.c ++++ b/drivers/iio/imu/kmx61.c +@@ -1393,7 +1393,7 @@ static int kmx61_probe(struct i2c_client *client, + ret = iio_device_register(data->acc_indio_dev); + if (ret < 0) { + dev_err(&client->dev, "Failed to register acc iio device\n"); +- goto err_buffer_cleanup_mag; ++ goto err_pm_cleanup; + } + + ret = iio_device_register(data->mag_indio_dev); +@@ -1406,6 +1406,9 @@ static int kmx61_probe(struct i2c_client *client, + + err_iio_unregister_acc: + iio_device_unregister(data->acc_indio_dev); ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(&client->dev); ++ pm_runtime_disable(&client->dev); + err_buffer_cleanup_mag: + if (client->irq > 0) + iio_triggered_buffer_cleanup(data->mag_indio_dev); +diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c +index 087dc16c2185c..ef8f429cc96f0 100644 +--- a/drivers/iio/magnetometer/bmc150_magn.c ++++ b/drivers/iio/magnetometer/bmc150_magn.c +@@ -944,13 +944,14 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(dev, "unable to register iio device\n"); +- goto err_disable_runtime_pm; ++ goto err_pm_cleanup; + } + + dev_dbg(dev, "Registered device %s\n", name); + return 0; + +-err_disable_runtime_pm: ++err_pm_cleanup: ++ pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); + err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 8708ed5477e99..dac806b715afa 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -4222,9 +4222,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data) + spin_unlock(&host->target_lock); + + /* +- * Wait for tl_err and target port removal tasks. ++ * srp_queue_remove_work() queues a call to ++ * srp_remove_target(). The latter function cancels ++ * target->tl_err_work so waiting for the remove works to ++ * finish is sufficient. + */ +- flush_workqueue(system_long_wq); + flush_workqueue(srp_remove_wq); + + kfree(host); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index e3dc2cbdc9f6c..e92cc60eade3f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -1683,7 +1683,7 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev, + if (size_read < 0) { + netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n", + __func__, size_read); +- return 0; ++ return size_read; + } + + i += size_read; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 7cc80dc4e6d89..31c832e5256e8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -1977,10 +1977,6 @@ esw_check_vport_match_metadata_supported(const struct mlx5_eswitch *esw) + if (!MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source)) + return false; + +- if (mlx5_core_is_ecpf_esw_manager(esw->dev) || +- mlx5_ecpf_vport_exists(esw->dev)) +- return false; +- + return true; + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 5fe4e028567a9..5baf2c666d293 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -1947,6 +1947,8 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle) + fte->node.del_hw_func = NULL; + up_write_ref_node(&fte->node, false); + tree_put_node(&fte->node, false); ++ } else { ++ up_write_ref_node(&fte->node, false); + } + kfree(handle); + } +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 22beeb5be9c41..c69ffcfe61689 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -916,8 +916,7 @@ static int lan743x_phy_reset(struct lan743x_adapter *adapter) + } + + static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter, +- u8 duplex, u16 local_adv, +- u16 remote_adv) ++ u16 local_adv, u16 remote_adv) + { + struct lan743x_phy *phy = &adapter->phy; + u8 cap; +@@ -944,22 +943,17 @@ static void lan743x_phy_link_status_change(struct net_device *netdev) + + phy_print_status(phydev); + if (phydev->state == PHY_RUNNING) { +- struct ethtool_link_ksettings ksettings; + int remote_advertisement = 0; + int local_advertisement = 0; + +- memset(&ksettings, 0, sizeof(ksettings)); +- phy_ethtool_get_link_ksettings(netdev, &ksettings); + local_advertisement = + linkmode_adv_to_mii_adv_t(phydev->advertising); + remote_advertisement = + linkmode_adv_to_mii_adv_t(phydev->lp_advertising); + +- lan743x_phy_update_flowcontrol(adapter, +- ksettings.base.duplex, +- local_advertisement, ++ lan743x_phy_update_flowcontrol(adapter, local_advertisement, + remote_advertisement); +- lan743x_ptp_update_latency(adapter, ksettings.base.speed); ++ lan743x_ptp_update_latency(adapter, phydev->speed); + } + } + +diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +index f8c8451919cb6..26772c3310f09 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +@@ -588,8 +588,8 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, + int port, bool mod) + { + struct nfp_flower_priv *priv = app->priv; +- int ida_idx = NFP_MAX_MAC_INDEX, err; + struct nfp_tun_offloaded_mac *entry; ++ int ida_idx = -1, err; + u16 nfp_mac_idx = 0; + + entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); +@@ -663,7 +663,7 @@ err_remove_hash: + err_free_entry: + kfree(entry); + err_free_ida: +- if (ida_idx != NFP_MAX_MAC_INDEX) ++ if (ida_idx != -1) + ida_simple_remove(&priv->tun.mac_off_ids, ida_idx); + + return err; +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index bddd64e918ce0..a109438f4a78e 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1345,6 +1345,8 @@ static int temac_probe(struct platform_device *pdev) + lp->indirect_lock = devm_kmalloc(&pdev->dev, + sizeof(*lp->indirect_lock), + GFP_KERNEL); ++ if (!lp->indirect_lock) ++ return -ENOMEM; + spin_lock_init(lp->indirect_lock); + } + +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 8325f6d65dccc..eee402a59f6da 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -571,6 +571,11 @@ static const struct usb_device_id products[] = { + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ + .bInterfaceProtocol = USB_CDC_PROTO_NONE + ++#define ZAURUS_FAKE_INTERFACE \ ++ .bInterfaceClass = USB_CLASS_COMM, \ ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE ++ + /* SA-1100 based Sharp Zaurus ("collie"), or compatible; + * wire-incompatible with true CDC Ethernet implementations. + * (And, it seems, needlessly so...) +@@ -624,6 +629,13 @@ static const struct usb_device_id products[] = { + .idProduct = 0x9032, /* SL-6000 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x9032, /* SL-6000 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c +index e04c8054c2cf3..fce6713e970ba 100644 +--- a/drivers/net/usb/sr9700.c ++++ b/drivers/net/usb/sr9700.c +@@ -410,7 +410,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + /* ignore the CRC length */ + len = (skb->data[1] | (skb->data[2] << 8)) - 4; + +- if (len > ETH_FRAME_LEN) ++ if (len > ETH_FRAME_LEN || len > skb->len) + return 0; + + /* the last packet of current skb */ +diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c +index 8e717a0b559b3..7984f2157d222 100644 +--- a/drivers/net/usb/zaurus.c ++++ b/drivers/net/usb/zaurus.c +@@ -256,6 +256,11 @@ static const struct usb_device_id products [] = { + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ + .bInterfaceProtocol = USB_CDC_PROTO_NONE + ++#define ZAURUS_FAKE_INTERFACE \ ++ .bInterfaceClass = USB_CLASS_COMM, \ ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE ++ + /* SA-1100 based Sharp Zaurus ("collie"), or compatible. */ + { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO +@@ -313,6 +318,13 @@ static const struct usb_device_id products [] = { + .idProduct = 0x9032, /* SL-6000 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x9032, /* SL-6000 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c +index 1ced6eb8b3303..b3588240eb39b 100644 +--- a/drivers/spi/spi-zynq-qspi.c ++++ b/drivers/spi/spi-zynq-qspi.c +@@ -558,6 +558,9 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, + + if (op->dummy.nbytes) { + tmpbuf = kzalloc(op->dummy.nbytes, GFP_KERNEL); ++ if (!tmpbuf) ++ return -ENOMEM; ++ + memset(tmpbuf, 0xff, op->dummy.nbytes); + reinit_completion(&xqspi->data_completion); + xqspi->txbuf = tmpbuf; +diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c +index 5eaef45799e61..344f48c909181 100644 +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -552,6 +552,7 @@ static struct optee *optee_probe(struct device_node *np) + struct optee *optee = NULL; + void *memremaped_shm = NULL; + struct tee_device *teedev; ++ struct tee_context *ctx; + u32 sec_caps; + int rc; + +@@ -631,6 +632,12 @@ static struct optee *optee_probe(struct device_node *np) + optee_supp_init(&optee->supp); + optee->memremaped_shm = memremaped_shm; + optee->pool = pool; ++ ctx = teedev_open(optee->teedev); ++ if (IS_ERR(ctx)) { ++ rc = PTR_ERR(ctx); ++ goto err; ++ } ++ optee->ctx = ctx; + + /* + * Ensure that there are no pre-existing shm objects before enabling +@@ -667,6 +674,7 @@ err: + + static void optee_remove(struct optee *optee) + { ++ teedev_close_context(optee->ctx); + /* + * Ask OP-TEE to free all cached shared memory objects to decrease + * reference counters and also avoid wild pointers in secure world +diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h +index 54c3fa01d0024..0250cfde6312d 100644 +--- a/drivers/tee/optee/optee_private.h ++++ b/drivers/tee/optee/optee_private.h +@@ -69,6 +69,7 @@ struct optee_supp { + * struct optee - main service struct + * @supp_teedev: supplicant device + * @teedev: client device ++ * @ctx: driver internal TEE context + * @invoke_fn: function to issue smc or hvc + * @call_queue: queue of threads waiting to call @invoke_fn + * @wait_queue: queue of threads from secure world waiting for a +@@ -83,6 +84,7 @@ struct optee { + struct tee_device *supp_teedev; + struct tee_device *teedev; + optee_invoke_fn *invoke_fn; ++ struct tee_context *ctx; + struct optee_call_queue call_queue; + struct optee_wait_queue wait_queue; + struct optee_supp supp; +diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c +index aecf62016e7b8..be45ee6202991 100644 +--- a/drivers/tee/optee/rpc.c ++++ b/drivers/tee/optee/rpc.c +@@ -191,6 +191,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz) + } + + static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, ++ struct optee *optee, + struct optee_msg_arg *arg, + struct optee_call_ctx *call_ctx) + { +@@ -220,7 +221,8 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, + shm = cmd_alloc_suppl(ctx, sz); + break; + case OPTEE_MSG_RPC_SHM_TYPE_KERNEL: +- shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV); ++ shm = tee_shm_alloc(optee->ctx, sz, ++ TEE_SHM_MAPPED | TEE_SHM_PRIV); + break; + default: + arg->ret = TEEC_ERROR_BAD_PARAMETERS; +@@ -377,7 +379,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee, + break; + case OPTEE_MSG_RPC_CMD_SHM_ALLOC: + free_pages_list(call_ctx); +- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx); ++ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx); + break; + case OPTEE_MSG_RPC_CMD_SHM_FREE: + handle_rpc_func_cmd_shm_free(ctx, arg); +@@ -405,7 +407,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param, + + switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) { + case OPTEE_SMC_RPC_FUNC_ALLOC: +- shm = tee_shm_alloc(ctx, param->a1, ++ shm = tee_shm_alloc(optee->ctx, param->a1, + TEE_SHM_MAPPED | TEE_SHM_PRIV); + if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) { + reg_pair_from_64(¶m->a1, ¶m->a2, pa); +diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c +index 85e0cef9e917e..a7ccd4d2bd106 100644 +--- a/drivers/tee/tee_core.c ++++ b/drivers/tee/tee_core.c +@@ -28,7 +28,7 @@ static DEFINE_SPINLOCK(driver_lock); + static struct class *tee_class; + static dev_t tee_devt; + +-static struct tee_context *teedev_open(struct tee_device *teedev) ++struct tee_context *teedev_open(struct tee_device *teedev) + { + int rc; + struct tee_context *ctx; +@@ -56,6 +56,7 @@ err: + return ERR_PTR(rc); + + } ++EXPORT_SYMBOL_GPL(teedev_open); + + void teedev_ctx_get(struct tee_context *ctx) + { +@@ -82,13 +83,14 @@ void teedev_ctx_put(struct tee_context *ctx) + kref_put(&ctx->refcount, teedev_ctx_release); + } + +-static void teedev_close_context(struct tee_context *ctx) ++void teedev_close_context(struct tee_context *ctx) + { + struct tee_device *teedev = ctx->teedev; + + teedev_ctx_put(ctx); + tee_device_put(teedev); + } ++EXPORT_SYMBOL_GPL(teedev_close_context); + + static int tee_open(struct inode *inode, struct file *filp) + { +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 3d3d616e58989..f4fe73ce57108 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -428,7 +428,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci) + modembits |= MDM_RTR; + if (dlci->modem_tx & TIOCM_RI) + modembits |= MDM_IC; +- if (dlci->modem_tx & TIOCM_CD) ++ if (dlci->modem_tx & TIOCM_CD || dlci->gsm->initiator) + modembits |= MDM_DV; + return modembits; + } +@@ -1490,7 +1490,7 @@ static void gsm_dlci_t1(struct timer_list *t) + dlci->mode = DLCI_MODE_ADM; + gsm_dlci_open(dlci); + } else { +- gsm_dlci_close(dlci); ++ gsm_dlci_begin_close(dlci); /* prevent half open link */ + } + + break; +@@ -1722,7 +1722,12 @@ static void gsm_dlci_release(struct gsm_dlci *dlci) + gsm_destroy_network(dlci); + mutex_unlock(&dlci->mutex); + +- tty_hangup(tty); ++ /* We cannot use tty_hangup() because in tty_kref_put() the tty ++ * driver assumes that the hangup queue is free and reuses it to ++ * queue release_one_tty() -> NULL pointer panic in ++ * process_one_work(). ++ */ ++ tty_vhangup(tty); + + tty_port_tty_set(&dlci->port, NULL); + tty_kref_put(tty); +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index 5a7c152c9ee39..99964f96ff747 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -81,8 +81,8 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = { + static struct gpiod_lookup_table platform_bytcr_gpios = { + .dev_id = "0000:00:16.0", + .table = { +- GPIO_LOOKUP("INT33FC:00", 54, "reset", GPIO_ACTIVE_HIGH), +- GPIO_LOOKUP("INT33FC:02", 14, "cs", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("INT33FC:00", 54, "cs", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("INT33FC:02", 14, "reset", GPIO_ACTIVE_HIGH), + {} + }, + }; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 2367bf5a13107..a1d8cb69d229d 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -3529,9 +3529,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt) + unsigned long flags; + irqreturn_t ret = IRQ_NONE; + ++ local_bh_disable(); + spin_lock_irqsave(&dwc->lock, flags); + ret = dwc3_process_event_buf(evt); + spin_unlock_irqrestore(&dwc->lock, flags); ++ local_bh_enable(); + + return ret; + } +diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c +index ab827c1badc50..970ed1514f0bc 100644 +--- a/drivers/usb/gadget/function/rndis.c ++++ b/drivers/usb/gadget/function/rndis.c +@@ -922,6 +922,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) + params->resp_avail = resp_avail; + params->v = v; + INIT_LIST_HEAD(¶ms->resp_queue); ++ spin_lock_init(¶ms->resp_lock); + pr_debug("%s: configNr = %d\n", __func__, i); + + return params; +@@ -1015,12 +1016,14 @@ void rndis_free_response(struct rndis_params *params, u8 *buf) + { + rndis_resp_t *r, *n; + ++ spin_lock(¶ms->resp_lock); + list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) { + if (r->buf == buf) { + list_del(&r->list); + kfree(r); + } + } ++ spin_unlock(¶ms->resp_lock); + } + EXPORT_SYMBOL_GPL(rndis_free_response); + +@@ -1030,14 +1033,17 @@ u8 *rndis_get_next_response(struct rndis_params *params, u32 *length) + + if (!length) return NULL; + ++ spin_lock(¶ms->resp_lock); + list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) { + if (!r->send) { + r->send = 1; + *length = r->length; ++ spin_unlock(¶ms->resp_lock); + return r->buf; + } + } + ++ spin_unlock(¶ms->resp_lock); + return NULL; + } + EXPORT_SYMBOL_GPL(rndis_get_next_response); +@@ -1054,7 +1060,9 @@ static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length) + r->length = length; + r->send = 0; + ++ spin_lock(¶ms->resp_lock); + list_add_tail(&r->list, ¶ms->resp_queue); ++ spin_unlock(¶ms->resp_lock); + return r; + } + +diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h +index c7e3a70ce6c1f..c996ba28bcb77 100644 +--- a/drivers/usb/gadget/function/rndis.h ++++ b/drivers/usb/gadget/function/rndis.h +@@ -174,6 +174,7 @@ typedef struct rndis_params { + void (*resp_avail)(void *v); + void *v; + struct list_head resp_queue; ++ spinlock_t resp_lock; + } rndis_params; + + /* RNDIS Message parser and other useless functions */ +diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c +index 29d8e5f8bb583..de22dd5436538 100644 +--- a/drivers/usb/gadget/udc/udc-xilinx.c ++++ b/drivers/usb/gadget/udc/udc-xilinx.c +@@ -1613,6 +1613,8 @@ static void xudc_getstatus(struct xusb_udc *udc) + break; + case USB_RECIP_ENDPOINT: + epnum = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK; ++ if (epnum >= XUSB_MAX_ENDPOINTS) ++ goto stall; + target_ep = &udc->ep[epnum]; + epcfgreg = udc->read_fn(udc->addr + target_ep->offset); + halt = epcfgreg & XUSB_EP_CFG_STALL_MASK; +@@ -1680,6 +1682,10 @@ static void xudc_set_clear_feature(struct xusb_udc *udc) + case USB_RECIP_ENDPOINT: + if (!udc->setup.wValue) { + endpoint = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK; ++ if (endpoint >= XUSB_MAX_ENDPOINTS) { ++ xudc_ep0_stall(udc); ++ return; ++ } + target_ep = &udc->ep[endpoint]; + outinbit = udc->setup.wIndex & USB_ENDPOINT_DIR_MASK; + outinbit = outinbit >> 7; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 1c8070023161f..8f029d44e9c9e 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1091,6 +1091,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + int retval = 0; + bool comp_timer_running = false; + bool pending_portevent = false; ++ bool reinit_xhc = false; + + if (!hcd->state) + return 0; +@@ -1107,10 +1108,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); + + spin_lock_irq(&xhci->lock); +- if ((xhci->quirks & XHCI_RESET_ON_RESUME) || xhci->broken_suspend) +- hibernated = true; + +- if (!hibernated) { ++ if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend) ++ reinit_xhc = true; ++ ++ if (!reinit_xhc) { + /* + * Some controllers might lose power during suspend, so wait + * for controller not ready bit to clear, just as in xHC init. +@@ -1143,12 +1145,17 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + spin_unlock_irq(&xhci->lock); + return -ETIMEDOUT; + } +- temp = readl(&xhci->op_regs->status); + } + +- /* If restore operation fails, re-initialize the HC during resume */ +- if ((temp & STS_SRE) || hibernated) { ++ temp = readl(&xhci->op_regs->status); + ++ /* re-initialize the HC on Restore Error, or Host Controller Error */ ++ if (temp & (STS_SRE | STS_HCE)) { ++ reinit_xhc = true; ++ xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp); ++ } ++ ++ if (reinit_xhc) { + if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && + !(xhci_all_ports_seen_u0(xhci))) { + del_timer_sync(&xhci->comp_mode_recovery_timer); +@@ -1480,9 +1487,12 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + struct urb_priv *urb_priv; + int num_tds; + +- if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, +- true, true, __func__) <= 0) ++ if (!urb) + return -EINVAL; ++ ret = xhci_check_args(hcd, urb->dev, urb->ep, ++ true, true, __func__); ++ if (ret <= 0) ++ return ret ? ret : -EINVAL; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); +@@ -3282,7 +3292,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, + return -EINVAL; + ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); + if (ret <= 0) +- return -EINVAL; ++ return ret ? ret : -EINVAL; + if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) { + xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" + " descriptor for ep 0x%x does not support streams\n", +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index a5c10fe9f72a1..f06a09e59d8ba 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -80,7 +80,6 @@ + #define CH341_LCR_CS5 0x00 + + static const struct usb_device_id id_table[] = { +- { USB_DEVICE(0x1a86, 0x5512) }, + { USB_DEVICE(0x1a86, 0x5523) }, + { USB_DEVICE(0x1a86, 0x7522) }, + { USB_DEVICE(0x1a86, 0x7523) }, +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 81e7833910ca8..839eac04b5e30 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -198,6 +198,8 @@ static void option_instat_callback(struct urb *urb); + + #define DELL_PRODUCT_5821E 0x81d7 + #define DELL_PRODUCT_5821E_ESIM 0x81e0 ++#define DELL_PRODUCT_5829E_ESIM 0x81e4 ++#define DELL_PRODUCT_5829E 0x81e6 + + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da +@@ -1063,6 +1065,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5821E_ESIM), + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, ++ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E), ++ .driver_info = RSVD(0) | RSVD(6) }, ++ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), ++ .driver_info = RSVD(0) | RSVD(6) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -1273,10 +1279,16 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ + .driver_info = NCTRL(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701a, 0xff), /* Telit LE910R1 (RNDIS) */ ++ .driver_info = NCTRL(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff), /* Telit LE910R1 (ECM) */ ++ .driver_info = NCTRL(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ + .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9200), /* Telit LE910S1 flashing device */ + .driver_info = NCTRL(0) | ZLP }, ++ { USB_DEVICE(TELIT_VENDOR_ID, 0x9201), /* Telit LE910R1 flashing device */ ++ .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) }, +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index 2bf7cb01da9a3..308df62655dd2 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -570,16 +570,18 @@ err: + return ret; + } + +-static int vhost_vsock_stop(struct vhost_vsock *vsock) ++static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner) + { + size_t i; +- int ret; ++ int ret = 0; + + mutex_lock(&vsock->dev.mutex); + +- ret = vhost_dev_check_owner(&vsock->dev); +- if (ret) +- goto err; ++ if (check_owner) { ++ ret = vhost_dev_check_owner(&vsock->dev); ++ if (ret) ++ goto err; ++ } + + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { + struct vhost_virtqueue *vq = &vsock->vqs[i]; +@@ -694,7 +696,12 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) + * inefficient. Room for improvement here. */ + vsock_for_each_connected_socket(vhost_vsock_reset_orphans); + +- vhost_vsock_stop(vsock); ++ /* Don't check the owner, because we are in the release path, so we ++ * need to stop the vsock device in any case. ++ * vhost_vsock_stop() can not fail in this case, so we don't need to ++ * check the return code. ++ */ ++ vhost_vsock_stop(vsock, false); + vhost_vsock_flush(vsock); + vhost_dev_stop(&vsock->dev); + +@@ -792,7 +799,7 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl, + if (start) + return vhost_vsock_start(vsock); + else +- return vhost_vsock_stop(vsock); ++ return vhost_vsock_stop(vsock, true); + case VHOST_GET_FEATURES: + features = VHOST_VSOCK_FEATURES; + if (copy_to_user(argp, &features, sizeof(features))) +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index 2992cebb78661..d73d88d9c2598 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -36,6 +36,14 @@ + */ + DEFINE_SPINLOCK(configfs_dirent_lock); + ++/* ++ * All of link_obj/unlink_obj/link_group/unlink_group require that ++ * subsys->su_mutex is held. ++ * But parent configfs_subsystem is NULL when config_item is root. ++ * Use this mutex when config_item is root. ++ */ ++static DEFINE_MUTEX(configfs_subsystem_mutex); ++ + static void configfs_d_iput(struct dentry * dentry, + struct inode * inode) + { +@@ -1884,7 +1892,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + group->cg_item.ci_name = group->cg_item.ci_namebuf; + + sd = root->d_fsdata; ++ mutex_lock(&configfs_subsystem_mutex); + link_group(to_config_group(sd->s_element), group); ++ mutex_unlock(&configfs_subsystem_mutex); + + inode_lock_nested(d_inode(root), I_MUTEX_PARENT); + +@@ -1909,7 +1919,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + inode_unlock(d_inode(root)); + + if (err) { ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + put_fragment(frag); +@@ -1956,7 +1968,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) + + dput(dentry); + ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + +diff --git a/fs/file.c b/fs/file.c +index 09cefc944f86d..51f53a7dc2218 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -706,28 +706,69 @@ void do_close_on_exec(struct files_struct *files) + spin_unlock(&files->file_lock); + } + +-static struct file *__fget(unsigned int fd, fmode_t mask, unsigned int refs) ++static inline struct file *__fget_files_rcu(struct files_struct *files, ++ unsigned int fd, fmode_t mask, unsigned int refs) + { +- struct files_struct *files = current->files; +- struct file *file; ++ for (;;) { ++ struct file *file; ++ struct fdtable *fdt = rcu_dereference_raw(files->fdt); ++ struct file __rcu **fdentry; + +- rcu_read_lock(); +-loop: +- file = fcheck_files(files, fd); +- if (file) { +- /* File object ref couldn't be taken. +- * dup2() atomicity guarantee is the reason +- * we loop to catch the new file (or NULL pointer) ++ if (unlikely(fd >= fdt->max_fds)) ++ return NULL; ++ ++ fdentry = fdt->fd + array_index_nospec(fd, fdt->max_fds); ++ file = rcu_dereference_raw(*fdentry); ++ if (unlikely(!file)) ++ return NULL; ++ ++ if (unlikely(file->f_mode & mask)) ++ return NULL; ++ ++ /* ++ * Ok, we have a file pointer. However, because we do ++ * this all locklessly under RCU, we may be racing with ++ * that file being closed. ++ * ++ * Such a race can take two forms: ++ * ++ * (a) the file ref already went down to zero, ++ * and get_file_rcu_many() fails. Just try ++ * again: ++ */ ++ if (unlikely(!get_file_rcu_many(file, refs))) ++ continue; ++ ++ /* ++ * (b) the file table entry has changed under us. ++ * Note that we don't need to re-check the 'fdt->fd' ++ * pointer having changed, because it always goes ++ * hand-in-hand with 'fdt'. ++ * ++ * If so, we need to put our refs and try again. + */ +- if (file->f_mode & mask) +- file = NULL; +- else if (!get_file_rcu_many(file, refs)) +- goto loop; +- else if (__fcheck_files(files, fd) != file) { ++ if (unlikely(rcu_dereference_raw(files->fdt) != fdt) || ++ unlikely(rcu_dereference_raw(*fdentry) != file)) { + fput_many(file, refs); +- goto loop; ++ continue; + } ++ ++ /* ++ * Ok, we have a ref to the file, and checked that it ++ * still exists. ++ */ ++ return file; + } ++} ++ ++ ++static struct file *__fget(unsigned int fd, fmode_t mask, unsigned int refs) ++{ ++ struct files_struct *files = current->files; ++ struct file *file; ++ ++ rcu_read_lock(); ++ file = __fget_files_rcu(files, fd, mask, refs); + rcu_read_unlock(); + + return file; +diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c +index 3fdbbc7a9848e..7878f145bf1bf 100644 +--- a/fs/tracefs/inode.c ++++ b/fs/tracefs/inode.c +@@ -262,7 +262,6 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) + if (!gid_valid(gid)) + return -EINVAL; + opts->gid = gid; +- set_gid(tracefs_mount->mnt_root, gid); + break; + case Opt_mode: + if (match_octal(&args[0], &option)) +@@ -289,7 +288,9 @@ static int tracefs_apply_options(struct super_block *sb) + inode->i_mode |= opts->mode; + + inode->i_uid = opts->uid; +- inode->i_gid = opts->gid; ++ ++ /* Set all the group ids to the mount option */ ++ set_gid(sb->s_root, opts->gid); + + return 0; + } +diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h +index e08ace76eba6a..8868337e9445b 100644 +--- a/include/linux/tee_drv.h ++++ b/include/linux/tee_drv.h +@@ -579,4 +579,18 @@ struct tee_client_driver { + #define to_tee_client_driver(d) \ + container_of(d, struct tee_client_driver, driver) + ++/** ++ * teedev_open() - Open a struct tee_device ++ * @teedev: Device to open ++ * ++ * @return a pointer to struct tee_context on success or an ERR_PTR on failure. ++ */ ++struct tee_context *teedev_open(struct tee_device *teedev); ++ ++/** ++ * teedev_close_context() - closes a struct tee_context ++ * @ctx: The struct tee_context to close ++ */ ++void teedev_close_context(struct tee_context *ctx); ++ + #endif /*__TEE_DRV_H*/ +diff --git a/include/net/checksum.h b/include/net/checksum.h +index 97bf4885a962f..e13d5ecf71cdb 100644 +--- a/include/net/checksum.h ++++ b/include/net/checksum.h +@@ -22,7 +22,7 @@ + #include + + #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +-static inline ++static __always_inline + __wsum csum_and_copy_from_user (const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) + { +@@ -37,7 +37,7 @@ __wsum csum_and_copy_from_user (const void __user *src, void *dst, + #endif + + #ifndef HAVE_CSUM_COPY_USER +-static __inline__ __wsum csum_and_copy_to_user ++static __always_inline __wsum csum_and_copy_to_user + (const void *src, void __user *dst, int len, __wsum sum, int *err_ptr) + { + sum = csum_partial(src, len, sum); +@@ -54,7 +54,7 @@ static __inline__ __wsum csum_and_copy_to_user + #endif + + #ifndef HAVE_ARCH_CSUM_ADD +-static inline __wsum csum_add(__wsum csum, __wsum addend) ++static __always_inline __wsum csum_add(__wsum csum, __wsum addend) + { + u32 res = (__force u32)csum; + res += (__force u32)addend; +@@ -62,12 +62,12 @@ static inline __wsum csum_add(__wsum csum, __wsum addend) + } + #endif + +-static inline __wsum csum_sub(__wsum csum, __wsum addend) ++static __always_inline __wsum csum_sub(__wsum csum, __wsum addend) + { + return csum_add(csum, ~addend); + } + +-static inline __sum16 csum16_add(__sum16 csum, __be16 addend) ++static __always_inline __sum16 csum16_add(__sum16 csum, __be16 addend) + { + u16 res = (__force u16)csum; + +@@ -75,12 +75,12 @@ static inline __sum16 csum16_add(__sum16 csum, __be16 addend) + return (__force __sum16)(res + (res < (__force u16)addend)); + } + +-static inline __sum16 csum16_sub(__sum16 csum, __be16 addend) ++static __always_inline __sum16 csum16_sub(__sum16 csum, __be16 addend) + { + return csum16_add(csum, ~addend); + } + +-static inline __wsum ++static __always_inline __wsum + csum_block_add(__wsum csum, __wsum csum2, int offset) + { + u32 sum = (__force u32)csum2; +@@ -92,36 +92,37 @@ csum_block_add(__wsum csum, __wsum csum2, int offset) + return csum_add(csum, (__force __wsum)sum); + } + +-static inline __wsum ++static __always_inline __wsum + csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len) + { + return csum_block_add(csum, csum2, offset); + } + +-static inline __wsum ++static __always_inline __wsum + csum_block_sub(__wsum csum, __wsum csum2, int offset) + { + return csum_block_add(csum, ~csum2, offset); + } + +-static inline __wsum csum_unfold(__sum16 n) ++static __always_inline __wsum csum_unfold(__sum16 n) + { + return (__force __wsum)n; + } + +-static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum) ++static __always_inline ++__wsum csum_partial_ext(const void *buff, int len, __wsum sum) + { + return csum_partial(buff, len, sum); + } + + #define CSUM_MANGLED_0 ((__force __sum16)0xffff) + +-static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff) ++static __always_inline void csum_replace_by_diff(__sum16 *sum, __wsum diff) + { + *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum))); + } + +-static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) ++static __always_inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) + { + __wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from); + +@@ -134,11 +135,16 @@ static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to) + * m : old value of a 16bit field + * m' : new value of a 16bit field + */ +-static inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new) ++static __always_inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new) + { + *sum = ~csum16_add(csum16_sub(~(*sum), old), new); + } + ++static inline void csum_replace(__wsum *csum, __wsum old, __wsum new) ++{ ++ *csum = csum_add(csum_sub(*csum, old), new); ++} ++ + struct sk_buff; + void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, + __be32 from, __be32 to, bool pseudohdr); +@@ -148,16 +154,16 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, + void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, + __wsum diff, bool pseudohdr); + +-static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, +- __be16 from, __be16 to, +- bool pseudohdr) ++static __always_inline ++void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, ++ __be16 from, __be16 to, bool pseudohdr) + { + inet_proto_csum_replace4(sum, skb, (__force __be32)from, + (__force __be32)to, pseudohdr); + } + +-static inline __wsum remcsum_adjust(void *ptr, __wsum csum, +- int start, int offset) ++static __always_inline __wsum remcsum_adjust(void *ptr, __wsum csum, ++ int start, int offset) + { + __sum16 *psum = (__sum16 *)(ptr + offset); + __wsum delta; +@@ -173,7 +179,7 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum, + return delta; + } + +-static inline void remcsum_unadjust(__sum16 *psum, __wsum delta) ++static __always_inline void remcsum_unadjust(__sum16 *psum, __wsum delta) + { + *psum = csum_fold(csum_sub(delta, (__force __wsum)*psum)); + } +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index f694f08ad635b..886866bee8b27 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -805,7 +805,7 @@ struct nft_expr_ops { + int (*offload)(struct nft_offload_ctx *ctx, + struct nft_flow_rule *flow, + const struct nft_expr *expr); +- u32 offload_flags; ++ bool (*offload_action)(const struct nft_expr *expr); + const struct nft_expr_type *type; + void *data; + }; +diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h +index d0bb9e3bcec1c..a9989ca6e5af7 100644 +--- a/include/net/netfilter/nf_tables_offload.h ++++ b/include/net/netfilter/nf_tables_offload.h +@@ -60,8 +60,6 @@ struct nft_flow_rule { + struct flow_rule *rule; + }; + +-#define NFT_OFFLOAD_F_ACTION (1 << 0) +- + void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow, + enum flow_dissector_key_id addr_type); + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index ad9dffed8411d..3674798ade1fc 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2204,6 +2204,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) + cgroup_taskset_first(tset, &css); + cs = css_cs(css); + ++ cpus_read_lock(); + percpu_down_write(&cpuset_rwsem); + + /* prepare for attach */ +@@ -2259,6 +2260,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) + wake_up(&cpuset_attach_wq); + + percpu_up_write(&cpuset_rwsem); ++ cpus_read_unlock(); + } + + /* The various types of files and directories in a cpuset file system */ +diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c +index e913d41a41949..3105dbf6c0e96 100644 +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -940,6 +940,16 @@ static void + traceon_trigger(struct event_trigger_data *data, void *rec, + struct ring_buffer_event *event) + { ++ struct trace_event_file *file = data->private_data; ++ ++ if (file) { ++ if (tracer_tracing_is_on(file->tr)) ++ return; ++ ++ tracer_tracing_on(file->tr); ++ return; ++ } ++ + if (tracing_is_on()) + return; + +@@ -950,8 +960,15 @@ static void + traceon_count_trigger(struct event_trigger_data *data, void *rec, + struct ring_buffer_event *event) + { +- if (tracing_is_on()) +- return; ++ struct trace_event_file *file = data->private_data; ++ ++ if (file) { ++ if (tracer_tracing_is_on(file->tr)) ++ return; ++ } else { ++ if (tracing_is_on()) ++ return; ++ } + + if (!data->count) + return; +@@ -959,13 +976,26 @@ traceon_count_trigger(struct event_trigger_data *data, void *rec, + if (data->count != -1) + (data->count)--; + +- tracing_on(); ++ if (file) ++ tracer_tracing_on(file->tr); ++ else ++ tracing_on(); + } + + static void + traceoff_trigger(struct event_trigger_data *data, void *rec, + struct ring_buffer_event *event) + { ++ struct trace_event_file *file = data->private_data; ++ ++ if (file) { ++ if (!tracer_tracing_is_on(file->tr)) ++ return; ++ ++ tracer_tracing_off(file->tr); ++ return; ++ } ++ + if (!tracing_is_on()) + return; + +@@ -976,8 +1006,15 @@ static void + traceoff_count_trigger(struct event_trigger_data *data, void *rec, + struct ring_buffer_event *event) + { +- if (!tracing_is_on()) +- return; ++ struct trace_event_file *file = data->private_data; ++ ++ if (file) { ++ if (!tracer_tracing_is_on(file->tr)) ++ return; ++ } else { ++ if (!tracing_is_on()) ++ return; ++ } + + if (!data->count) + return; +@@ -985,7 +1022,10 @@ traceoff_count_trigger(struct event_trigger_data *data, void *rec, + if (data->count != -1) + (data->count)--; + +- tracing_off(); ++ if (file) ++ tracer_tracing_off(file->tr); ++ else ++ tracing_off(); + } + + static int +diff --git a/mm/memblock.c b/mm/memblock.c +index 38cef8b6df050..a75cc65f03307 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -348,14 +348,20 @@ void __init memblock_discard(void) + addr = __pa(memblock.reserved.regions); + size = PAGE_ALIGN(sizeof(struct memblock_region) * + memblock.reserved.max); +- __memblock_free_late(addr, size); ++ if (memblock_reserved_in_slab) ++ kfree(memblock.reserved.regions); ++ else ++ __memblock_free_late(addr, size); + } + + if (memblock.memory.regions != memblock_memory_init_regions) { + addr = __pa(memblock.memory.regions); + size = PAGE_ALIGN(sizeof(struct memblock_region) * + memblock.memory.max); +- __memblock_free_late(addr, size); ++ if (memblock_memory_in_slab) ++ kfree(memblock.memory.regions); ++ else ++ __memblock_free_late(addr, size); + } + } + #endif +diff --git a/net/core/filter.c b/net/core/filter.c +index 92ce4d46f02e4..d39518f691b4b 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2516,6 +2516,9 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + if (unlikely(flags)) + return -EINVAL; + ++ if (unlikely(len == 0)) ++ return 0; ++ + /* First find the starting scatterlist element */ + i = msg->sg.start; + do { +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index ac083685214e0..5bdb3cd20d619 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2139,7 +2139,7 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta) + /* Free pulled out fragments. */ + while ((list = skb_shinfo(skb)->frag_list) != insp) { + skb_shinfo(skb)->frag_list = list->next; +- kfree_skb(list); ++ consume_skb(list); + } + /* And insert new clone at head. */ + if (clone) { +@@ -5846,7 +5846,7 @@ static int pskb_carve_frag_list(struct sk_buff *skb, + /* Free pulled out fragments. */ + while ((list = shinfo->frag_list) != insp) { + shinfo->frag_list = list->next; +- kfree_skb(list); ++ consume_skb(list); + } + /* And insert new clone at head. */ + if (clone) { +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index c800220c404d5..a7a6b1adb698b 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1344,8 +1344,11 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, + } + + ops = rcu_dereference(inet_offloads[proto]); +- if (likely(ops && ops->callbacks.gso_segment)) ++ if (likely(ops && ops->callbacks.gso_segment)) { + segs = ops->callbacks.gso_segment(skb, features); ++ if (!segs) ++ skb->network_header = skb_mac_header(skb) + nhoff - skb->head; ++ } + + if (IS_ERR_OR_NULL(segs)) + goto out; +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 2a359d0dfe7e8..33e6392e8b820 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -187,7 +187,6 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) + (int)ident, &ipv6_hdr(skb)->daddr, dif); + #endif + } else { +- pr_err("ping: protocol(%x) is not supported\n", ntohs(skb->protocol)); + return NULL; + } + +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index 7fbb44736a34b..b7b4ba68f3a20 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -111,6 +111,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, + if (likely(ops && ops->callbacks.gso_segment)) { + skb_reset_transport_header(skb); + segs = ops->callbacks.gso_segment(skb, features); ++ if (!segs) ++ skb->network_header = skb_mac_header(skb) + nhoff - skb->head; + } + + if (IS_ERR_OR_NULL(segs)) +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 373ea0e49f12d..545da270e8020 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -5184,12 +5184,15 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, + { + struct nft_object *newobj; + struct nft_trans *trans; +- int err; ++ int err = -ENOMEM; ++ ++ if (!try_module_get(type->owner)) ++ return -ENOENT; + + trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ, + sizeof(struct nft_trans_obj)); + if (!trans) +- return -ENOMEM; ++ goto err_trans; + + newobj = nft_obj_init(ctx, type, attr); + if (IS_ERR(newobj)) { +@@ -5206,6 +5209,8 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, + + err_free_trans: + kfree(trans); ++err_trans: ++ module_put(type->owner); + return err; + } + +@@ -6544,7 +6549,7 @@ static void nft_obj_commit_update(struct nft_trans *trans) + if (obj->ops->update) + obj->ops->update(obj, newobj); + +- kfree(newobj); ++ nft_obj_destroy(&trans->ctx, newobj); + } + + static void nft_commit_release(struct nft_trans *trans) +@@ -7109,7 +7114,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) + break; + case NFT_MSG_NEWOBJ: + if (nft_trans_obj_update(trans)) { +- kfree(nft_trans_obj_newobj(trans)); ++ nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans)); + nft_trans_destroy(trans); + } else { + trans->ctx.table->use--; +diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c +index 3aa4306ca39f6..2d3bc22c855c7 100644 +--- a/net/netfilter/nf_tables_offload.c ++++ b/net/netfilter/nf_tables_offload.c +@@ -55,7 +55,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net, + + expr = nft_expr_first(rule); + while (nft_expr_more(rule, expr)) { +- if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION) ++ if (expr->ops->offload_action && ++ expr->ops->offload_action(expr)) + num_actions++; + + expr = nft_expr_next(expr); +diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c +index c2e78c160fd7c..6007089e1c2f7 100644 +--- a/net/netfilter/nft_dup_netdev.c ++++ b/net/netfilter/nft_dup_netdev.c +@@ -67,6 +67,11 @@ static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx, + return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED, oif); + } + ++static bool nft_dup_netdev_offload_action(const struct nft_expr *expr) ++{ ++ return true; ++} ++ + static struct nft_expr_type nft_dup_netdev_type; + static const struct nft_expr_ops nft_dup_netdev_ops = { + .type = &nft_dup_netdev_type, +@@ -75,6 +80,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = { + .init = nft_dup_netdev_init, + .dump = nft_dup_netdev_dump, + .offload = nft_dup_netdev_offload, ++ .offload_action = nft_dup_netdev_offload_action, + }; + + static struct nft_expr_type nft_dup_netdev_type __read_mostly = { +diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c +index b77985986b24e..3b0dcd170551b 100644 +--- a/net/netfilter/nft_fwd_netdev.c ++++ b/net/netfilter/nft_fwd_netdev.c +@@ -77,6 +77,11 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx, + return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_REDIRECT, oif); + } + ++static bool nft_fwd_netdev_offload_action(const struct nft_expr *expr) ++{ ++ return true; ++} ++ + struct nft_fwd_neigh { + enum nft_registers sreg_dev:8; + enum nft_registers sreg_addr:8; +@@ -219,6 +224,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = { + .dump = nft_fwd_netdev_dump, + .validate = nft_fwd_validate, + .offload = nft_fwd_netdev_offload, ++ .offload_action = nft_fwd_netdev_offload_action, + }; + + static const struct nft_expr_ops * +diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c +index c7f0ef73d9397..98a8149be094b 100644 +--- a/net/netfilter/nft_immediate.c ++++ b/net/netfilter/nft_immediate.c +@@ -163,6 +163,16 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx, + return 0; + } + ++static bool nft_immediate_offload_action(const struct nft_expr *expr) ++{ ++ const struct nft_immediate_expr *priv = nft_expr_priv(expr); ++ ++ if (priv->dreg == NFT_REG_VERDICT) ++ return true; ++ ++ return false; ++} ++ + static const struct nft_expr_ops nft_imm_ops = { + .type = &nft_imm_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)), +@@ -173,7 +183,7 @@ static const struct nft_expr_ops nft_imm_ops = { + .dump = nft_immediate_dump, + .validate = nft_immediate_validate, + .offload = nft_immediate_offload, +- .offload_flags = NFT_OFFLOAD_F_ACTION, ++ .offload_action = nft_immediate_offload_action, + }; + + struct nft_expr_type nft_imm_type __read_mostly = { +diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c +index 5c68f9ea98810..2c0f8cbc5c43b 100644 +--- a/net/openvswitch/actions.c ++++ b/net/openvswitch/actions.c +@@ -427,12 +427,43 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto, + memcpy(addr, new_addr, sizeof(__be32[4])); + } + +-static void set_ipv6_fl(struct ipv6hdr *nh, u32 fl, u32 mask) ++static void set_ipv6_dsfield(struct sk_buff *skb, struct ipv6hdr *nh, u8 ipv6_tclass, u8 mask) + { ++ u8 old_ipv6_tclass = ipv6_get_dsfield(nh); ++ ++ ipv6_tclass = OVS_MASKED(old_ipv6_tclass, ipv6_tclass, mask); ++ ++ if (skb->ip_summed == CHECKSUM_COMPLETE) ++ csum_replace(&skb->csum, (__force __wsum)(old_ipv6_tclass << 12), ++ (__force __wsum)(ipv6_tclass << 12)); ++ ++ ipv6_change_dsfield(nh, ~mask, ipv6_tclass); ++} ++ ++static void set_ipv6_fl(struct sk_buff *skb, struct ipv6hdr *nh, u32 fl, u32 mask) ++{ ++ u32 ofl; ++ ++ ofl = nh->flow_lbl[0] << 16 | nh->flow_lbl[1] << 8 | nh->flow_lbl[2]; ++ fl = OVS_MASKED(ofl, fl, mask); ++ + /* Bits 21-24 are always unmasked, so this retains their values. */ +- OVS_SET_MASKED(nh->flow_lbl[0], (u8)(fl >> 16), (u8)(mask >> 16)); +- OVS_SET_MASKED(nh->flow_lbl[1], (u8)(fl >> 8), (u8)(mask >> 8)); +- OVS_SET_MASKED(nh->flow_lbl[2], (u8)fl, (u8)mask); ++ nh->flow_lbl[0] = (u8)(fl >> 16); ++ nh->flow_lbl[1] = (u8)(fl >> 8); ++ nh->flow_lbl[2] = (u8)fl; ++ ++ if (skb->ip_summed == CHECKSUM_COMPLETE) ++ csum_replace(&skb->csum, (__force __wsum)htonl(ofl), (__force __wsum)htonl(fl)); ++} ++ ++static void set_ipv6_ttl(struct sk_buff *skb, struct ipv6hdr *nh, u8 new_ttl, u8 mask) ++{ ++ new_ttl = OVS_MASKED(nh->hop_limit, new_ttl, mask); ++ ++ if (skb->ip_summed == CHECKSUM_COMPLETE) ++ csum_replace(&skb->csum, (__force __wsum)(nh->hop_limit << 8), ++ (__force __wsum)(new_ttl << 8)); ++ nh->hop_limit = new_ttl; + } + + static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl, +@@ -550,18 +581,17 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, + } + } + if (mask->ipv6_tclass) { +- ipv6_change_dsfield(nh, ~mask->ipv6_tclass, key->ipv6_tclass); ++ set_ipv6_dsfield(skb, nh, key->ipv6_tclass, mask->ipv6_tclass); + flow_key->ip.tos = ipv6_get_dsfield(nh); + } + if (mask->ipv6_label) { +- set_ipv6_fl(nh, ntohl(key->ipv6_label), ++ set_ipv6_fl(skb, nh, ntohl(key->ipv6_label), + ntohl(mask->ipv6_label)); + flow_key->ipv6.label = + *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL); + } + if (mask->ipv6_hlimit) { +- OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit, +- mask->ipv6_hlimit); ++ set_ipv6_ttl(skb, nh, key->ipv6_hlimit, mask->ipv6_hlimit); + flow_key->ip.ttl = nh->hop_limit; + } + return 0; +diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c +index 66a65c2cdb23c..c52083522b28e 100644 +--- a/net/tipc/name_table.c ++++ b/net/tipc/name_table.c +@@ -812,7 +812,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, + list_for_each_entry(p, &sr->all_publ, all_publ) + if (p->key == *last_key) + break; +- if (p->key != *last_key) ++ if (list_entry_is_head(p, &sr->all_publ, all_publ)) + return -EPIPE; + } else { + p = list_first_entry(&sr->all_publ, +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index fbbac9ba2862f..f4217673eee70 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -3590,7 +3590,7 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb, + if (p->key == *last_publ) + break; + } +- if (p->key != *last_publ) { ++ if (list_entry_is_head(p, &tsk->publications, binding_sock)) { + /* We never set seq or call nl_dump_check_consistent() + * this means that setting prev_seq here will cause the + * consistence check to fail in the netlink callback +diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c +index a3f912615690f..3c874f52f1a25 100644 +--- a/tools/perf/util/data.c ++++ b/tools/perf/util/data.c +@@ -44,10 +44,6 @@ int perf_data__create_dir(struct perf_data *data, int nr) + if (!files) + return -ENOMEM; + +- data->dir.version = PERF_DIR_VERSION; +- data->dir.files = files; +- data->dir.nr = nr; +- + for (i = 0; i < nr; i++) { + struct perf_data_file *file = &files[i]; + +@@ -62,6 +58,9 @@ int perf_data__create_dir(struct perf_data *data, int nr) + file->fd = ret; + } + ++ data->dir.version = PERF_DIR_VERSION; ++ data->dir.files = files; ++ data->dir.nr = nr; + return 0; + + out_err: diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.182-183.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.182-183.patch new file mode 100644 index 0000000000..e90cad92ed --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.182-183.patch @@ -0,0 +1,1981 @@ +diff --git a/Makefile b/Makefile +index 8750309fc42ac..a94b5ea499e13 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 182 ++SUBLEVEL = 183 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c +index 6a95b92966406..183a6f2f165ad 100644 +--- a/arch/arm/kernel/kgdb.c ++++ b/arch/arm/kernel/kgdb.c +@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr) + return 0; + } + +-static struct undef_hook kgdb_brkpt_hook = { ++static struct undef_hook kgdb_brkpt_arm_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_BREAKINST, +- .cpsr_mask = MODE_MASK, ++ .cpsr_mask = PSR_T_BIT | MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = kgdb_brk_fn + }; + +-static struct undef_hook kgdb_compiled_brkpt_hook = { ++static struct undef_hook kgdb_brkpt_thumb_hook = { ++ .instr_mask = 0xffff, ++ .instr_val = KGDB_BREAKINST & 0xffff, ++ .cpsr_mask = PSR_T_BIT | MODE_MASK, ++ .cpsr_val = PSR_T_BIT | SVC_MODE, ++ .fn = kgdb_brk_fn ++}; ++ ++static struct undef_hook kgdb_compiled_brkpt_arm_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_COMPILED_BREAK, +- .cpsr_mask = MODE_MASK, ++ .cpsr_mask = PSR_T_BIT | MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = kgdb_compiled_brk_fn + }; + ++static struct undef_hook kgdb_compiled_brkpt_thumb_hook = { ++ .instr_mask = 0xffff, ++ .instr_val = KGDB_COMPILED_BREAK & 0xffff, ++ .cpsr_mask = PSR_T_BIT | MODE_MASK, ++ .cpsr_val = PSR_T_BIT | SVC_MODE, ++ .fn = kgdb_compiled_brk_fn ++}; ++ + static int __kgdb_notify(struct die_args *args, unsigned long cmd) + { + struct pt_regs *regs = args->regs; +@@ -210,8 +226,10 @@ int kgdb_arch_init(void) + if (ret != 0) + return ret; + +- register_undef_hook(&kgdb_brkpt_hook); +- register_undef_hook(&kgdb_compiled_brkpt_hook); ++ register_undef_hook(&kgdb_brkpt_arm_hook); ++ register_undef_hook(&kgdb_brkpt_thumb_hook); ++ register_undef_hook(&kgdb_compiled_brkpt_arm_hook); ++ register_undef_hook(&kgdb_compiled_brkpt_thumb_hook); + + return 0; + } +@@ -224,8 +242,10 @@ int kgdb_arch_init(void) + */ + void kgdb_arch_exit(void) + { +- unregister_undef_hook(&kgdb_brkpt_hook); +- unregister_undef_hook(&kgdb_compiled_brkpt_hook); ++ unregister_undef_hook(&kgdb_brkpt_arm_hook); ++ unregister_undef_hook(&kgdb_brkpt_thumb_hook); ++ unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook); ++ unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook); + unregister_die_notifier(&kgdb_notifier); + } + +diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c +index 538d5da741b09..6e7f841f67ff1 100644 +--- a/arch/arm/mm/mmu.c ++++ b/arch/arm/mm/mmu.c +@@ -229,12 +229,14 @@ early_param("ecc", early_ecc); + static int __init early_cachepolicy(char *p) + { + pr_warn("cachepolicy kernel parameter not supported without cp15\n"); ++ return 0; + } + early_param("cachepolicy", early_cachepolicy); + + static int __init noalign_setup(char *__unused) + { + pr_warn("noalign kernel parameter not supported without cp15\n"); ++ return 1; + } + __setup("noalign", noalign_setup); + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +index dd5624975c9b4..b7e7bb3517c03 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +@@ -281,7 +281,7 @@ + + sound: sound { + compatible = "rockchip,rk3399-gru-sound"; +- rockchip,cpu = <&i2s0 &i2s2>; ++ rockchip,cpu = <&i2s0 &spdif>; + }; + }; + +@@ -432,10 +432,6 @@ ap_i2c_audio: &i2c8 { + status = "okay"; + }; + +-&i2s2 { +- status = "okay"; +-}; +- + &io_domains { + status = "okay"; + +@@ -532,6 +528,17 @@ ap_i2c_audio: &i2c8 { + vqmmc-supply = <&ppvar_sd_card_io>; + }; + ++&spdif { ++ status = "okay"; ++ ++ /* ++ * SPDIF is routed internally to DP; we either don't use these pins, or ++ * mux them to something else. ++ */ ++ /delete-property/ pinctrl-0; ++ /delete-property/ pinctrl-names; ++}; ++ + &spi1 { + status = "okay"; + +diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c +index 70d1587ddcd46..361b109933725 100644 +--- a/arch/ia64/kernel/acpi.c ++++ b/arch/ia64/kernel/acpi.c +@@ -448,7 +448,8 @@ void __init acpi_numa_fixup(void) + if (srat_num_cpus == 0) { + node_set_online(0); + node_cpuid[0].phys_id = hard_smp_processor_id(); +- return; ++ slit_distance(0, 0) = LOCAL_DISTANCE; ++ goto out; + } + + /* +@@ -491,7 +492,7 @@ void __init acpi_numa_fixup(void) + for (j = 0; j < MAX_NUMNODES; j++) + slit_distance(i, j) = i == j ? + LOCAL_DISTANCE : REMOTE_DISTANCE; +- return; ++ goto out; + } + + memset(numa_slit, -1, sizeof(numa_slit)); +@@ -516,6 +517,8 @@ void __init acpi_numa_fixup(void) + printk("\n"); + } + #endif ++out: ++ node_possible_map = node_online_map; + } + #endif /* CONFIG_ACPI_NUMA */ + +diff --git a/block/blk-flush.c b/block/blk-flush.c +index 5aa6fada22598..f66ff16855310 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -222,8 +222,10 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) + return; + } + +- if (fq->rq_status != BLK_STS_OK) ++ if (fq->rq_status != BLK_STS_OK) { + error = fq->rq_status; ++ fq->rq_status = BLK_STS_OK; ++ } + + hctx = flush_rq->mq_hctx; + if (!q->elevator) { +diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c +index 499a947d56ddb..fef46de2f6b23 100644 +--- a/drivers/ata/pata_hpt37x.c ++++ b/drivers/ata/pata_hpt37x.c +@@ -962,14 +962,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) + + if ((freq >> 12) != 0xABCDE) { + int i; +- u8 sr; ++ u16 sr; + u32 total = 0; + + pr_warn("BIOS has not set timing clocks\n"); + + /* This is the process the HPT371 BIOS is reported to use */ + for (i = 0; i < 128; i++) { +- pci_read_config_byte(dev, 0x78, &sr); ++ pci_read_config_word(dev, 0x78, &sr); + total += sr & 0x1FF; + udelay(15); + } +diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c +index c51de498b5b4b..19eee3d0900b0 100644 +--- a/drivers/dma/sh/shdma-base.c ++++ b/drivers/dma/sh/shdma-base.c +@@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) + ret = pm_runtime_get(schan->dev); + + spin_unlock_irq(&schan->chan_lock); +- if (ret < 0) ++ if (ret < 0) { + dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret); ++ pm_runtime_put(schan->dev); ++ } + + pm_runtime_barrier(schan->dev); + +diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c +index 4e43bdfa041f5..f0b055bc027c4 100644 +--- a/drivers/firmware/arm_scmi/driver.c ++++ b/drivers/firmware/arm_scmi/driver.c +@@ -983,7 +983,7 @@ static struct platform_driver scmi_driver = { + + module_platform_driver(scmi_driver); + +-MODULE_ALIAS("platform: arm-scmi"); ++MODULE_ALIAS("platform:arm-scmi"); + MODULE_AUTHOR("Sudeep Holla "); + MODULE_DESCRIPTION("ARM SCMI protocol driver"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c +index 436d1776bc7be..a32d15b2928f7 100644 +--- a/drivers/firmware/efi/vars.c ++++ b/drivers/firmware/efi/vars.c +@@ -750,6 +750,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, + { + const struct efivar_operations *ops; + efi_status_t status; ++ unsigned long varsize; + + if (!__efivars) + return -EINVAL; +@@ -772,15 +773,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, + return efivar_entry_set_nonblocking(name, vendor, attributes, + size, data); + ++ varsize = size + ucs2_strsize(name, 1024); + if (!block) { + if (down_trylock(&efivars_lock)) + return -EBUSY; ++ status = check_var_size_nonblocking(attributes, varsize); + } else { + if (down_interruptible(&efivars_lock)) + return -EINTR; ++ status = check_var_size(attributes, varsize); + } + +- status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); + if (status != EFI_SUCCESS) { + up(&efivars_lock); + return -ENOSPC; +diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c +index 01135713e8f9b..419d8dec7e498 100644 +--- a/drivers/hid/hid-debug.c ++++ b/drivers/hid/hid-debug.c +@@ -823,7 +823,9 @@ static const char *keys[KEY_MAX + 1] = { + [KEY_F22] = "F22", [KEY_F23] = "F23", + [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD", + [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", +- [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", ++ [KEY_PROG4] = "Prog4", ++ [KEY_ALL_APPLICATIONS] = "AllApplications", ++ [KEY_SUSPEND] = "Suspend", + [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", + [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost", + [KEY_PRINT] = "Print", [KEY_HP] = "HP", +@@ -930,6 +932,7 @@ static const char *keys[KEY_MAX + 1] = { + [KEY_SCREENSAVER] = "ScreenSaver", + [KEY_VOICECOMMAND] = "VoiceCommand", + [KEY_EMOJI_PICKER] = "EmojiPicker", ++ [KEY_DICTATE] = "Dictate", + [KEY_BRIGHTNESS_MIN] = "BrightnessMin", + [KEY_BRIGHTNESS_MAX] = "BrightnessMax", + [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index 749558aa27e78..d1ba6fafe960f 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -956,6 +956,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; + case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break; + ++ case 0x0d8: map_key_clear(KEY_DICTATE); break; + case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break; + + case 0x0e0: map_abs_clear(ABS_VOLUME); break; +@@ -1047,6 +1048,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + + case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break; + ++ case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS); break; ++ + case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break; + case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break; + case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break; +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 2d08a8719506c..854f1b2658b82 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -483,7 +483,7 @@ config I2C_BRCMSTB + + config I2C_CADENCE + tristate "Cadence I2C Controller" +- depends on ARCH_ZYNQ || ARM64 || XTENSA ++ depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST + help + Say yes here to select Cadence I2C Host Controller. This controller is + e.g. used by Xilinx Zynq. +@@ -894,7 +894,7 @@ config I2C_QCOM_GENI + + config I2C_QUP + tristate "Qualcomm QUP based I2C controller" +- depends on ARCH_QCOM ++ depends on ARCH_QCOM || COMPILE_TEST + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Qualcomm SoCs. +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index 5ab901ad615dd..c265fe4621621 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -23,6 +23,11 @@ + #define BCM2835_I2C_FIFO 0x10 + #define BCM2835_I2C_DIV 0x14 + #define BCM2835_I2C_DEL 0x18 ++/* ++ * 16-bit field for the number of SCL cycles to wait after rising SCL ++ * before deciding the slave is not responding. 0 disables the ++ * timeout detection. ++ */ + #define BCM2835_I2C_CLKT 0x1c + + #define BCM2835_I2C_C_READ BIT(0) +@@ -479,6 +484,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) + adap->dev.of_node = pdev->dev.of_node; + adap->quirks = of_device_get_match_data(&pdev->dev); + ++ /* ++ * Disable the hardware clock stretching timeout. SMBUS ++ * specifies a limit for how long the device can stretch the ++ * clock, but core I2C doesn't. ++ */ ++ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); + + ret = i2c_add_adapter(adap); +diff --git a/drivers/input/input.c b/drivers/input/input.c +index e2eb9b9b8363d..f7398b996bacf 100644 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -2181,6 +2181,12 @@ int input_register_device(struct input_dev *dev) + /* KEY_RESERVED is not supposed to be transmitted to userspace. */ + __clear_bit(KEY_RESERVED, dev->keybit); + ++ /* Buttonpads should not map BTN_RIGHT and/or BTN_MIDDLE. */ ++ if (test_bit(INPUT_PROP_BUTTONPAD, dev->propbit)) { ++ __clear_bit(BTN_RIGHT, dev->keybit); ++ __clear_bit(BTN_MIDDLE, dev->keybit); ++ } ++ + /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ + input_cleanse_bitmasks(dev); + +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 196e8505dd8d7..aaef8847f8862 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -139,55 +139,21 @@ static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count, + return 0; + } + +-static int elan_enable_power(struct elan_tp_data *data) ++static int elan_set_power(struct elan_tp_data *data, bool on) + { + int repeat = ETP_RETRY_COUNT; + int error; + +- error = regulator_enable(data->vcc); +- if (error) { +- dev_err(&data->client->dev, +- "failed to enable regulator: %d\n", error); +- return error; +- } +- + do { +- error = data->ops->power_control(data->client, true); ++ error = data->ops->power_control(data->client, on); + if (error >= 0) + return 0; + + msleep(30); + } while (--repeat > 0); + +- dev_err(&data->client->dev, "failed to enable power: %d\n", error); +- return error; +-} +- +-static int elan_disable_power(struct elan_tp_data *data) +-{ +- int repeat = ETP_RETRY_COUNT; +- int error; +- +- do { +- error = data->ops->power_control(data->client, false); +- if (!error) { +- error = regulator_disable(data->vcc); +- if (error) { +- dev_err(&data->client->dev, +- "failed to disable regulator: %d\n", +- error); +- /* Attempt to power the chip back up */ +- data->ops->power_control(data->client, true); +- break; +- } +- +- return 0; +- } +- +- msleep(30); +- } while (--repeat > 0); +- +- dev_err(&data->client->dev, "failed to disable power: %d\n", error); ++ dev_err(&data->client->dev, "failed to set power %s: %d\n", ++ on ? "on" : "off", error); + return error; + } + +@@ -1316,9 +1282,19 @@ static int __maybe_unused elan_suspend(struct device *dev) + /* Enable wake from IRQ */ + data->irq_wake = (enable_irq_wake(client->irq) == 0); + } else { +- ret = elan_disable_power(data); ++ ret = elan_set_power(data, false); ++ if (ret) ++ goto err; ++ ++ ret = regulator_disable(data->vcc); ++ if (ret) { ++ dev_err(dev, "error %d disabling regulator\n", ret); ++ /* Attempt to power the chip back up */ ++ elan_set_power(data, true); ++ } + } + ++err: + mutex_unlock(&data->sysfs_mutex); + return ret; + } +@@ -1329,12 +1305,18 @@ static int __maybe_unused elan_resume(struct device *dev) + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + +- if (device_may_wakeup(dev) && data->irq_wake) { ++ if (!device_may_wakeup(dev)) { ++ error = regulator_enable(data->vcc); ++ if (error) { ++ dev_err(dev, "error %d enabling regulator\n", error); ++ goto err; ++ } ++ } else if (data->irq_wake) { + disable_irq_wake(client->irq); + data->irq_wake = false; + } + +- error = elan_enable_power(data); ++ error = elan_set_power(data, true); + if (error) { + dev_err(dev, "power up when resuming failed: %d\n", error); + goto err; +diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c +index eb7f76753c9c0..9f44e2e458df1 100644 +--- a/drivers/net/arcnet/com20020-pci.c ++++ b/drivers/net/arcnet/com20020-pci.c +@@ -136,6 +136,9 @@ static int com20020pci_probe(struct pci_dev *pdev, + return -ENOMEM; + + ci = (struct com20020_pci_card_info *)id->driver_data; ++ if (!ci) ++ return -EINVAL; ++ + priv->ci = ci; + mm = &ci->misc_map; + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index 8b4c1bb77c334..76747d94c7602 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -190,8 +190,8 @@ struct gs_can { + struct gs_usb { + struct gs_can *canch[GS_MAX_INTF]; + struct usb_anchor rx_submitted; +- atomic_t active_channels; + struct usb_device *udev; ++ u8 active_channels; + }; + + /* 'allocate' a tx context. +@@ -588,7 +588,7 @@ static int gs_can_open(struct net_device *netdev) + if (rc) + return rc; + +- if (atomic_add_return(1, &parent->active_channels) == 1) { ++ if (!parent->active_channels) { + for (i = 0; i < GS_MAX_RX_URBS; i++) { + struct urb *urb; + u8 *buf; +@@ -689,6 +689,7 @@ static int gs_can_open(struct net_device *netdev) + + dev->can.state = CAN_STATE_ERROR_ACTIVE; + ++ parent->active_channels++; + if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) + netif_start_queue(netdev); + +@@ -704,7 +705,8 @@ static int gs_can_close(struct net_device *netdev) + netif_stop_queue(netdev); + + /* Stop polling */ +- if (atomic_dec_and_test(&parent->active_channels)) ++ parent->active_channels--; ++ if (!parent->active_channels) + usb_kill_anchored_urbs(&parent->rx_submitted); + + /* Stop sending URBs */ +@@ -983,8 +985,6 @@ static int gs_usb_probe(struct usb_interface *intf, + + init_usb_anchor(&dev->rx_submitted); + +- atomic_set(&dev->active_channels, 0); +- + usb_set_intfdata(intf, dev); + dev->udev = interface_to_usbdev(intf); + +diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +index 0a9f2c5966242..d3e11fe1eabcc 100644 +--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +@@ -3677,6 +3677,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, + MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10); + adapter->params.pci.vpd_cap_addr = + pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD); ++ if (!adapter->params.pci.vpd_cap_addr) ++ return -ENODEV; + ret = get_vpd_params(adapter, &adapter->params.vpd); + if (ret < 0) + return ret; +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 26d49dcdbeb3e..34bf6f4eef4ab 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -2248,8 +2248,10 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, + * flush reset queue and process this reset + */ + if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) { +- list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) ++ list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) { + list_del(entry); ++ kfree(list_entry(entry, struct ibmvnic_rwi, list)); ++ } + } + rwi->reset_reason = reason; + list_add_tail(&rwi->list, &adapter->rwi_list); +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index 309e953ed1e44..e8850ba5604c4 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -3323,8 +3323,11 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) + iavf_notify_client_l2_params(&adapter->vsi); + adapter->flags |= IAVF_FLAG_SERVICE_CLIENT_REQUESTED; + } +- adapter->flags |= IAVF_FLAG_RESET_NEEDED; +- queue_work(iavf_wq, &adapter->reset_task); ++ ++ if (netif_running(netdev)) { ++ adapter->flags |= IAVF_FLAG_RESET_NEEDED; ++ queue_work(iavf_wq, &adapter->reset_task); ++ } + + return 0; + } +diff --git a/drivers/net/ethernet/intel/igc/igc_phy.c b/drivers/net/ethernet/intel/igc/igc_phy.c +index f4b05af0dd2f6..1a4947e6933c3 100644 +--- a/drivers/net/ethernet/intel/igc/igc_phy.c ++++ b/drivers/net/ethernet/intel/igc/igc_phy.c +@@ -734,8 +734,6 @@ s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data) + if (ret_val) + return ret_val; + ret_val = igc_write_phy_reg_mdic(hw, offset, data); +- if (ret_val) +- return ret_val; + hw->phy.ops.release(hw); + } else { + ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr, +@@ -767,8 +765,6 @@ s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data) + if (ret_val) + return ret_val; + ret_val = igc_read_phy_reg_mdic(hw, offset, data); +- if (ret_val) +- return ret_val; + hw->phy.ops.release(hw); + } else { + ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr, +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +index b43be9f141053..921a2ddb497e1 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +@@ -583,12 +583,14 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget) + u32 cmd_type; + + while (budget-- > 0) { +- if (unlikely(!ixgbe_desc_unused(xdp_ring)) || +- !netif_carrier_ok(xdp_ring->netdev)) { ++ if (unlikely(!ixgbe_desc_unused(xdp_ring))) { + work_done = false; + break; + } + ++ if (!netif_carrier_ok(xdp_ring->netdev)) ++ break; ++ + if (!xsk_umem_consume_tx(xdp_ring->xsk_umem, &desc)) + break; + +diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +index 38767d7979147..431146b391d0c 100644 +--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c ++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +@@ -2277,18 +2277,18 @@ static int __init sxgbe_cmdline_opt(char *str) + char *opt; + + if (!str || !*str) +- return -EINVAL; ++ return 1; + while ((opt = strsep(&str, ",")) != NULL) { + if (!strncmp(opt, "eee_timer:", 10)) { + if (kstrtoint(opt + 10, 0, &eee_timer)) + goto err; + } + } +- return 0; ++ return 1; + + err: + pr_err("%s: ERROR broken module parameter conversion\n", __func__); +- return -EINVAL; ++ return 1; + } + + __setup("sxgbeeth=", sxgbe_cmdline_opt); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 94c652b9a0a8b..9cbc0179d24ec 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4890,7 +4890,7 @@ static int __init stmmac_cmdline_opt(char *str) + char *opt; + + if (!str || !*str) +- return -EINVAL; ++ return 1; + while ((opt = strsep(&str, ",")) != NULL) { + if (!strncmp(opt, "debug:", 6)) { + if (kstrtoint(opt + 6, 0, &debug)) +@@ -4921,11 +4921,11 @@ static int __init stmmac_cmdline_opt(char *str) + goto err; + } + } +- return 0; ++ return 1; + + err: + pr_err("%s: ERROR broken module parameter conversion", __func__); +- return -EINVAL; ++ return 1; + } + + __setup("stmmaceth=", stmmac_cmdline_opt); +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c +index d2eb33f53993b..43aab2835f8ff 100644 +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -31,6 +31,8 @@ + + #define AX_MTU 236 + ++/* some arch define END as assembly function ending, just undef it */ ++#undef END + /* SLIP/KISS protocol characters. */ + #define END 0300 /* indicates end of frame */ + #define ESC 0333 /* indicates byte stuffing */ +diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c +index 77ac5a721e7b6..414341c9cf5ae 100644 +--- a/drivers/net/usb/cdc_mbim.c ++++ b/drivers/net/usb/cdc_mbim.c +@@ -658,6 +658,11 @@ static const struct usb_device_id mbim_devs[] = { + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, + }, + ++ /* Telit FN990 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1071, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, ++ }, ++ + /* default entry */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_zlp, +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index 07b070b14d75d..6e1721d533846 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2062,6 +2062,15 @@ static void hw_scan_work(struct work_struct *work) + if (req->ie_len) + skb_put_data(probe, req->ie, req->ie_len); + ++ if (!ieee80211_tx_prepare_skb(hwsim->hw, ++ hwsim->hw_scan_vif, ++ probe, ++ hwsim->tmp_chan->band, ++ NULL)) { ++ kfree_skb(probe); ++ continue; ++ } ++ + local_bh_disable(); + mac80211_hwsim_tx_frame(hwsim->hw, probe, + hwsim->tmp_chan); +@@ -3316,6 +3325,10 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, + } + txi->flags |= IEEE80211_TX_STAT_ACK; + } ++ ++ if (hwsim_flags & HWSIM_TX_CTL_NO_ACK) ++ txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; ++ + ieee80211_tx_status_irqsafe(data2->hw, skb); + return 0; + out: +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index d2b3381f71825..d45d83968e769 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -761,6 +761,28 @@ static int xennet_close(struct net_device *dev) + return 0; + } + ++static void xennet_destroy_queues(struct netfront_info *info) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < info->netdev->real_num_tx_queues; i++) { ++ struct netfront_queue *queue = &info->queues[i]; ++ ++ if (netif_running(info->netdev)) ++ napi_disable(&queue->napi); ++ netif_napi_del(&queue->napi); ++ } ++ ++ kfree(info->queues); ++ info->queues = NULL; ++} ++ ++static void xennet_uninit(struct net_device *dev) ++{ ++ struct netfront_info *np = netdev_priv(dev); ++ xennet_destroy_queues(np); ++} ++ + static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val) + { + unsigned long flags; +@@ -1373,6 +1395,7 @@ static void xennet_poll_controller(struct net_device *dev) + #endif + + static const struct net_device_ops xennet_netdev_ops = { ++ .ndo_uninit = xennet_uninit, + .ndo_open = xennet_open, + .ndo_stop = xennet_close, + .ndo_start_xmit = xennet_start_xmit, +@@ -1860,22 +1883,6 @@ error: + return err; + } + +-static void xennet_destroy_queues(struct netfront_info *info) +-{ +- unsigned int i; +- +- for (i = 0; i < info->netdev->real_num_tx_queues; i++) { +- struct netfront_queue *queue = &info->queues[i]; +- +- if (netif_running(info->netdev)) +- napi_disable(&queue->napi); +- netif_napi_del(&queue->napi); +- } +- +- kfree(info->queues); +- info->queues = NULL; +-} +- + static int xennet_create_queues(struct netfront_info *info, + unsigned int *num_queues) + { +diff --git a/drivers/soc/fsl/qe/qe_io.c b/drivers/soc/fsl/qe/qe_io.c +index 3657e296a8a27..058c2fec9a4b4 100644 +--- a/drivers/soc/fsl/qe/qe_io.c ++++ b/drivers/soc/fsl/qe/qe_io.c +@@ -37,6 +37,8 @@ int par_io_init(struct device_node *np) + if (ret) + return ret; + par_io = ioremap(res.start, resource_size(&res)); ++ if (!par_io) ++ return -ENOMEM; + + num_ports = of_get_property(np, "num-ports", NULL); + if (num_ports) +diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c +index 5f1e15172403e..9cd80ad075bd2 100644 +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1829,8 +1829,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + spin_lock_irq (&dev->lock); + value = -EINVAL; + if (dev->buf) { ++ spin_unlock_irq(&dev->lock); + kfree(kbuf); +- goto fail; ++ return value; + } + dev->buf = kbuf; + +@@ -1877,8 +1878,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + + value = usb_gadget_probe_driver(&gadgetfs_driver); + if (value != 0) { +- kfree (dev->buf); +- dev->buf = NULL; ++ spin_lock_irq(&dev->lock); ++ goto fail; + } else { + /* at this point "good" hardware has for the first time + * let the USB the host see us. alternatively, if users +@@ -1895,6 +1896,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + return value; + + fail: ++ dev->config = NULL; ++ dev->hs_config = NULL; ++ dev->dev = NULL; + spin_unlock_irq (&dev->lock); + pr_debug ("%s: %s fail %zd, %p\n", shortname, __func__, value, dev); + kfree (dev->buf); +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index a5041bf0d5db1..5a3006c75d63f 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1116,6 +1116,14 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) + if (!fs_info->quota_root) + goto out; + ++ /* ++ * Unlock the qgroup_ioctl_lock mutex before waiting for the rescan worker to ++ * complete. Otherwise we can deadlock because btrfs_remove_qgroup() needs ++ * to lock that mutex while holding a transaction handle and the rescan ++ * worker needs to commit a transaction. ++ */ ++ mutex_unlock(&fs_info->qgroup_ioctl_lock); ++ + /* + * Request qgroup rescan worker to complete and wait for it. This wait + * must be done before transaction start for quota disable since it may +@@ -1123,7 +1131,6 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) + */ + clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); + btrfs_qgroup_wait_for_completion(fs_info, false); +- mutex_unlock(&fs_info->qgroup_ioctl_lock); + + /* + * 1 For the root item +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 7bc4477d7ee7d..9b703c0db9796 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1308,6 +1308,15 @@ again: + inode, name, namelen); + kfree(name); + iput(dir); ++ /* ++ * Whenever we need to check if a name exists or not, we ++ * check the subvolume tree. So after an unlink we must ++ * run delayed items, so that future checks for a name ++ * during log replay see that the name does not exists ++ * anymore. ++ */ ++ if (!ret) ++ ret = btrfs_run_delayed_items(trans); + if (ret) + goto out; + goto again; +@@ -1559,6 +1568,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, + */ + if (!ret && inode->i_nlink == 0) + inc_nlink(inode); ++ /* ++ * Whenever we need to check if a name exists or ++ * not, we check the subvolume tree. So after an ++ * unlink we must run delayed items, so that future ++ * checks for a name during log replay see that the ++ * name does not exists anymore. ++ */ ++ if (!ret) ++ ret = btrfs_run_delayed_items(trans); + } + if (ret < 0) + goto out; +@@ -4249,7 +4267,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, + + /* + * Log all prealloc extents beyond the inode's i_size to make sure we do not +- * lose them after doing a fast fsync and replaying the log. We scan the ++ * lose them after doing a full/fast fsync and replaying the log. We scan the + * subvolume's root instead of iterating the inode's extent map tree because + * otherwise we can log incorrect extent items based on extent map conversion. + * That can happen due to the fact that extent maps are merged when they +@@ -5042,6 +5060,7 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans, + struct btrfs_log_ctx *ctx, + bool *need_log_inode_item) + { ++ const u64 i_size = i_size_read(&inode->vfs_inode); + struct btrfs_root *root = inode->root; + int ins_start_slot = 0; + int ins_nr = 0; +@@ -5062,13 +5081,21 @@ again: + if (min_key->type > max_key->type) + break; + +- if (min_key->type == BTRFS_INODE_ITEM_KEY) ++ if (min_key->type == BTRFS_INODE_ITEM_KEY) { + *need_log_inode_item = false; +- +- if ((min_key->type == BTRFS_INODE_REF_KEY || +- min_key->type == BTRFS_INODE_EXTREF_KEY) && +- inode->generation == trans->transid && +- !recursive_logging) { ++ } else if (min_key->type == BTRFS_EXTENT_DATA_KEY && ++ min_key->offset >= i_size) { ++ /* ++ * Extents at and beyond eof are logged with ++ * btrfs_log_prealloc_extents(). ++ * Only regular files have BTRFS_EXTENT_DATA_KEY keys, ++ * and no keys greater than that, so bail out. ++ */ ++ break; ++ } else if ((min_key->type == BTRFS_INODE_REF_KEY || ++ min_key->type == BTRFS_INODE_EXTREF_KEY) && ++ inode->generation == trans->transid && ++ !recursive_logging) { + u64 other_ino = 0; + u64 other_parent = 0; + +@@ -5099,10 +5126,8 @@ again: + btrfs_release_path(path); + goto next_key; + } +- } +- +- /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */ +- if (min_key->type == BTRFS_XATTR_ITEM_KEY) { ++ } else if (min_key->type == BTRFS_XATTR_ITEM_KEY) { ++ /* Skip xattrs, logged later with btrfs_log_all_xattrs() */ + if (ins_nr == 0) + goto next_slot; + ret = copy_items(trans, inode, dst_path, path, +@@ -5155,9 +5180,21 @@ next_key: + break; + } + } +- if (ins_nr) ++ if (ins_nr) { + ret = copy_items(trans, inode, dst_path, path, ins_start_slot, + ins_nr, inode_only, logged_isize); ++ if (ret) ++ return ret; ++ } ++ ++ if (inode_only == LOG_INODE_ALL && S_ISREG(inode->vfs_inode.i_mode)) { ++ /* ++ * Release the path because otherwise we might attempt to double ++ * lock the same leaf with btrfs_log_prealloc_extents() below. ++ */ ++ btrfs_release_path(path); ++ ret = btrfs_log_prealloc_extents(trans, inode, dst_path); ++ } + + return ret; + } +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 41b3c5fc958c7..f44b6f9d07776 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -855,6 +855,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, + + out_super: + deactivate_locked_super(sb); ++ return root; + out: + cifs_cleanup_volume_info(volume_info); + return root; +diff --git a/include/linux/topology.h b/include/linux/topology.h +index eb2fe6edd73c8..64e7ee0abe71c 100644 +--- a/include/linux/topology.h ++++ b/include/linux/topology.h +@@ -48,6 +48,7 @@ int arch_update_cpu_topology(void); + /* Conform to ACPI 2.0 SLIT distance definitions */ + #define LOCAL_DISTANCE 10 + #define REMOTE_DISTANCE 20 ++#define DISTANCE_BITS 8 + #ifndef node_distance + #define node_distance(from,to) ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE) + #endif +diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h +index 47088083667b2..c204af20c27e4 100644 +--- a/include/net/netfilter/nf_queue.h ++++ b/include/net/netfilter/nf_queue.h +@@ -34,7 +34,7 @@ void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *q + void nf_unregister_queue_handler(struct net *net); + void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); + +-void nf_queue_entry_get_refs(struct nf_queue_entry *entry); ++bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); + void nf_queue_entry_release_refs(struct nf_queue_entry *entry); + + static inline void init_hashrandom(u32 *jhash_initval) +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index 8ce63850d6d01..614f19bbad74f 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -1543,7 +1543,6 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); + void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); + u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); + int xfrm_init_replay(struct xfrm_state *x); +-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu); + u32 xfrm_state_mtu(struct xfrm_state *x, int mtu); + int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload); + int xfrm_init_state(struct xfrm_state *x); +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index 311a57f3e01a2..7f0ae1f411e3a 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -278,7 +278,8 @@ + #define KEY_PAUSECD 201 + #define KEY_PROG3 202 + #define KEY_PROG4 203 +-#define KEY_DASHBOARD 204 /* AL Dashboard */ ++#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */ ++#define KEY_DASHBOARD KEY_ALL_APPLICATIONS + #define KEY_SUSPEND 205 + #define KEY_CLOSE 206 /* AC Close */ + #define KEY_PLAY 207 +@@ -608,6 +609,7 @@ + #define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ + #define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */ + #define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */ ++#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */ + + #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ + #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ +diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h +index ff7cfdc6cb44d..90a8f968af2f9 100644 +--- a/include/uapi/linux/xfrm.h ++++ b/include/uapi/linux/xfrm.h +@@ -504,6 +504,12 @@ struct xfrm_user_offload { + int ifindex; + __u8 flags; + }; ++/* This flag was exposed without any kernel code that supporting it. ++ * Unfortunately, strongswan has the code that uses sets this flag, ++ * which makes impossible to reuse this bit. ++ * ++ * So leave it here to make sure that it won't be reused by mistake. ++ */ + #define XFRM_OFFLOAD_IPV6 1 + #define XFRM_OFFLOAD_INBOUND 2 + +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index ffaa97a8d4051..e5ebaffc4fef5 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -1552,66 +1552,58 @@ static void init_numa_topology_type(void) + } + } + ++ ++#define NR_DISTANCE_VALUES (1 << DISTANCE_BITS) ++ + void sched_init_numa(void) + { +- int next_distance, curr_distance = node_distance(0, 0); + struct sched_domain_topology_level *tl; +- int level = 0; +- int i, j, k; +- +- sched_domains_numa_distance = kzalloc(sizeof(int) * (nr_node_ids + 1), GFP_KERNEL); +- if (!sched_domains_numa_distance) +- return; +- +- /* Includes NUMA identity node at level 0. */ +- sched_domains_numa_distance[level++] = curr_distance; +- sched_domains_numa_levels = level; ++ unsigned long *distance_map; ++ int nr_levels = 0; ++ int i, j; + + /* + * O(nr_nodes^2) deduplicating selection sort -- in order to find the + * unique distances in the node_distance() table. +- * +- * Assumes node_distance(0,j) includes all distances in +- * node_distance(i,j) in order to avoid cubic time. + */ +- next_distance = curr_distance; ++ distance_map = bitmap_alloc(NR_DISTANCE_VALUES, GFP_KERNEL); ++ if (!distance_map) ++ return; ++ ++ bitmap_zero(distance_map, NR_DISTANCE_VALUES); + for (i = 0; i < nr_node_ids; i++) { + for (j = 0; j < nr_node_ids; j++) { +- for (k = 0; k < nr_node_ids; k++) { +- int distance = node_distance(i, k); +- +- if (distance > curr_distance && +- (distance < next_distance || +- next_distance == curr_distance)) +- next_distance = distance; +- +- /* +- * While not a strong assumption it would be nice to know +- * about cases where if node A is connected to B, B is not +- * equally connected to A. +- */ +- if (sched_debug() && node_distance(k, i) != distance) +- sched_numa_warn("Node-distance not symmetric"); ++ int distance = node_distance(i, j); + +- if (sched_debug() && i && !find_numa_distance(distance)) +- sched_numa_warn("Node-0 not representative"); ++ if (distance < LOCAL_DISTANCE || distance >= NR_DISTANCE_VALUES) { ++ sched_numa_warn("Invalid distance value range"); ++ return; + } +- if (next_distance != curr_distance) { +- sched_domains_numa_distance[level++] = next_distance; +- sched_domains_numa_levels = level; +- curr_distance = next_distance; +- } else break; ++ ++ bitmap_set(distance_map, distance, 1); + } ++ } ++ /* ++ * We can now figure out how many unique distance values there are and ++ * allocate memory accordingly. ++ */ ++ nr_levels = bitmap_weight(distance_map, NR_DISTANCE_VALUES); + +- /* +- * In case of sched_debug() we verify the above assumption. +- */ +- if (!sched_debug()) +- break; ++ sched_domains_numa_distance = kcalloc(nr_levels, sizeof(int), GFP_KERNEL); ++ if (!sched_domains_numa_distance) { ++ bitmap_free(distance_map); ++ return; ++ } ++ ++ for (i = 0, j = 0; i < nr_levels; i++, j++) { ++ j = find_next_bit(distance_map, NR_DISTANCE_VALUES, j); ++ sched_domains_numa_distance[i] = j; + } + ++ bitmap_free(distance_map); ++ + /* +- * 'level' contains the number of unique distances ++ * 'nr_levels' contains the number of unique distances + * + * The sched_domains_numa_distance[] array includes the actual distance + * numbers. +@@ -1620,15 +1612,15 @@ void sched_init_numa(void) + /* + * Here, we should temporarily reset sched_domains_numa_levels to 0. + * If it fails to allocate memory for array sched_domains_numa_masks[][], +- * the array will contain less then 'level' members. This could be ++ * the array will contain less then 'nr_levels' members. This could be + * dangerous when we use it to iterate array sched_domains_numa_masks[][] + * in other functions. + * +- * We reset it to 'level' at the end of this function. ++ * We reset it to 'nr_levels' at the end of this function. + */ + sched_domains_numa_levels = 0; + +- sched_domains_numa_masks = kzalloc(sizeof(void *) * level, GFP_KERNEL); ++ sched_domains_numa_masks = kzalloc(sizeof(void *) * nr_levels, GFP_KERNEL); + if (!sched_domains_numa_masks) + return; + +@@ -1636,7 +1628,7 @@ void sched_init_numa(void) + * Now for each level, construct a mask per node which contains all + * CPUs of nodes that are that many hops away from us. + */ +- for (i = 0; i < level; i++) { ++ for (i = 0; i < nr_levels; i++) { + sched_domains_numa_masks[i] = + kzalloc(nr_node_ids * sizeof(void *), GFP_KERNEL); + if (!sched_domains_numa_masks[i]) +@@ -1644,12 +1636,17 @@ void sched_init_numa(void) + + for (j = 0; j < nr_node_ids; j++) { + struct cpumask *mask = kzalloc(cpumask_size(), GFP_KERNEL); ++ int k; ++ + if (!mask) + return; + + sched_domains_numa_masks[i][j] = mask; + + for_each_node(k) { ++ if (sched_debug() && (node_distance(j, k) != node_distance(k, j))) ++ sched_numa_warn("Node-distance not symmetric"); ++ + if (node_distance(j, k) > sched_domains_numa_distance[i]) + continue; + +@@ -1661,7 +1658,7 @@ void sched_init_numa(void) + /* Compute default topology size */ + for (i = 0; sched_domain_topology[i].mask; i++); + +- tl = kzalloc((i + level + 1) * ++ tl = kzalloc((i + nr_levels + 1) * + sizeof(struct sched_domain_topology_level), GFP_KERNEL); + if (!tl) + return; +@@ -1684,7 +1681,7 @@ void sched_init_numa(void) + /* + * .. and append 'j' levels of NUMA goodness. + */ +- for (j = 1; j < level; i++, j++) { ++ for (j = 1; j < nr_levels; i++, j++) { + tl[i] = (struct sched_domain_topology_level){ + .mask = sd_numa_mask, + .sd_flags = cpu_numa_flags, +@@ -1696,8 +1693,8 @@ void sched_init_numa(void) + + sched_domain_topology = tl; + +- sched_domains_numa_levels = level; +- sched_max_numa_distance = sched_domains_numa_distance[level - 1]; ++ sched_domains_numa_levels = nr_levels; ++ sched_max_numa_distance = sched_domains_numa_distance[nr_levels - 1]; + + init_numa_topology_type(); + } +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 615259d8fa9ad..1a89b2bf626a5 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -219,7 +219,7 @@ static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; + static int __init set_trace_boot_options(char *str) + { + strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); +- return 0; ++ return 1; + } + __setup("trace_options=", set_trace_boot_options); + +@@ -230,7 +230,7 @@ static int __init set_trace_boot_clock(char *str) + { + strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE); + trace_boot_clock = trace_boot_clock_buf; +- return 0; ++ return 1; + } + __setup("trace_clock=", set_trace_boot_clock); + +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index 3cef24c6391a5..413da11260f89 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -2891,9 +2891,9 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, + /* + * For backward compatibility, if field_name + * was "cpu", then we treat this the same as +- * common_cpu. ++ * common_cpu. This also works for "CPU". + */ +- if (strcmp(field_name, "cpu") == 0) { ++ if (field && field->filter_type == FILTER_CPU) { + *flags |= HIST_FIELD_FL_CPU; + } else { + hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, +@@ -5247,7 +5247,7 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) + + if (hist_field->flags & HIST_FIELD_FL_STACKTRACE) + cmp_fn = tracing_map_cmp_none; +- else if (!field) ++ else if (!field || hist_field->flags & HIST_FIELD_FL_CPU) + cmp_fn = tracing_map_cmp_num(hist_field->size, + hist_field->is_signed); + else if (is_string_field(field)) +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 13ccf2f28987e..a422cf6a0358b 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -430,7 +430,7 @@ static int disable_trace_kprobe(struct trace_event_call *call, + */ + trace_probe_remove_file(tp, file); + +- return 0; ++ return 1; + } + + #if defined(CONFIG_DYNAMIC_FTRACE) && \ +diff --git a/mm/memfd.c b/mm/memfd.c +index 2647c898990c8..fae4142f7d254 100644 +--- a/mm/memfd.c ++++ b/mm/memfd.c +@@ -31,20 +31,28 @@ + static void memfd_tag_pins(struct xa_state *xas) + { + struct page *page; +- unsigned int tagged = 0; ++ int latency = 0; ++ int cache_count; + + lru_add_drain(); + + xas_lock_irq(xas); + xas_for_each(xas, page, ULONG_MAX) { +- if (xa_is_value(page)) +- continue; +- page = find_subpage(page, xas->xa_index); +- if (page_count(page) - page_mapcount(page) > 1) ++ cache_count = 1; ++ if (!xa_is_value(page) && ++ PageTransHuge(page) && !PageHuge(page)) ++ cache_count = HPAGE_PMD_NR; ++ ++ if (!xa_is_value(page) && ++ page_count(page) - total_mapcount(page) != cache_count) + xas_set_mark(xas, MEMFD_TAG_PINNED); ++ if (cache_count != 1) ++ xas_set(xas, page->index + cache_count); + +- if (++tagged % XA_CHECK_SCHED) ++ latency += cache_count; ++ if (latency < XA_CHECK_SCHED) + continue; ++ latency = 0; + + xas_pause(xas); + xas_unlock_irq(xas); +@@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct address_space *mapping) + + error = 0; + for (scan = 0; scan <= LAST_SCAN; scan++) { +- unsigned int tagged = 0; ++ int latency = 0; ++ int cache_count; + + if (!xas_marked(&xas, MEMFD_TAG_PINNED)) + break; +@@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct address_space *mapping) + xas_lock_irq(&xas); + xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) { + bool clear = true; +- if (xa_is_value(page)) +- continue; +- page = find_subpage(page, xas.xa_index); +- if (page_count(page) - page_mapcount(page) != 1) { ++ ++ cache_count = 1; ++ if (!xa_is_value(page) && ++ PageTransHuge(page) && !PageHuge(page)) ++ cache_count = HPAGE_PMD_NR; ++ ++ if (!xa_is_value(page) && cache_count != ++ page_count(page) - total_mapcount(page)) { + /* + * On the last scan, we clean up all those tags + * we inserted; but make a note that we still +@@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct address_space *mapping) + } + if (clear) + xas_clear_mark(&xas, MEMFD_TAG_PINNED); +- if (++tagged % XA_CHECK_SCHED) ++ ++ latency += cache_count; ++ if (latency < XA_CHECK_SCHED) + continue; ++ latency = 0; + + xas_pause(&xas); + xas_unlock_irq(&xas); +diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c +index 18e644f3cb309..5f44c94ad707b 100644 +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -151,22 +151,25 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) + struct net *net = dev_net(net_dev); + struct net_device *parent_dev; + struct net *parent_net; ++ int iflink; + bool ret; + + /* check if this is a batman-adv mesh interface */ + if (batadv_softif_is_valid(net_dev)) + return true; + +- /* no more parents..stop recursion */ +- if (dev_get_iflink(net_dev) == 0 || +- dev_get_iflink(net_dev) == net_dev->ifindex) ++ iflink = dev_get_iflink(net_dev); ++ if (iflink == 0) + return false; + + parent_net = batadv_getlink_net(net_dev, net); + ++ /* iflink to itself, most likely physical device */ ++ if (net == parent_net && iflink == net_dev->ifindex) ++ return false; ++ + /* recurse over the parent device */ +- parent_dev = __dev_get_by_index((struct net *)parent_net, +- dev_get_iflink(net_dev)); ++ parent_dev = __dev_get_by_index((struct net *)parent_net, iflink); + /* if we got a NULL parent_dev there is something broken.. */ + if (!parent_dev) { + pr_err("Cannot find parent device\n"); +@@ -216,14 +219,15 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev) + struct net_device *real_netdev = NULL; + struct net *real_net; + struct net *net; +- int ifindex; ++ int iflink; + + ASSERT_RTNL(); + + if (!netdev) + return NULL; + +- if (netdev->ifindex == dev_get_iflink(netdev)) { ++ iflink = dev_get_iflink(netdev); ++ if (iflink == 0) { + dev_hold(netdev); + return netdev; + } +@@ -233,9 +237,16 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev) + goto out; + + net = dev_net(hard_iface->soft_iface); +- ifindex = dev_get_iflink(netdev); + real_net = batadv_getlink_net(netdev, net); +- real_netdev = dev_get_by_index(real_net, ifindex); ++ ++ /* iflink to itself, most likely physical device */ ++ if (net == real_net && netdev->ifindex == iflink) { ++ real_netdev = netdev; ++ dev_hold(real_netdev); ++ goto out; ++ } ++ ++ real_netdev = dev_get_by_index(real_net, iflink); + + out: + if (hard_iface) +diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c +index e9ecbb57df455..b53d5e1d026fe 100644 +--- a/net/dcb/dcbnl.c ++++ b/net/dcb/dcbnl.c +@@ -2063,10 +2063,54 @@ u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev) + } + EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask); + ++static void dcbnl_flush_dev(struct net_device *dev) ++{ ++ struct dcb_app_type *itr, *tmp; ++ ++ spin_lock_bh(&dcb_lock); ++ ++ list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) { ++ if (itr->ifindex == dev->ifindex) { ++ list_del(&itr->list); ++ kfree(itr); ++ } ++ } ++ ++ spin_unlock_bh(&dcb_lock); ++} ++ ++static int dcbnl_netdevice_event(struct notifier_block *nb, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ ++ switch (event) { ++ case NETDEV_UNREGISTER: ++ if (!dev->dcbnl_ops) ++ return NOTIFY_DONE; ++ ++ dcbnl_flush_dev(dev); ++ ++ return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ ++static struct notifier_block dcbnl_nb __read_mostly = { ++ .notifier_call = dcbnl_netdevice_event, ++}; ++ + static int __init dcbnl_init(void) + { ++ int err; ++ + INIT_LIST_HEAD(&dcb_app_list); + ++ err = register_netdevice_notifier(&dcbnl_nb); ++ if (err) ++ return err; ++ + rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0); + +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index 86c836fa21459..00210e55b4cd1 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -499,7 +499,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); + u32 padto; + +- padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached)); ++ padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached)); + if (skb->len < padto) + esp.tfclen = padto - skb->len; + } +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index 12570a73def80..7a739f16d82b2 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -440,7 +440,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); + u32 padto; + +- padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached)); ++ padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached)); + if (skb->len < padto) + esp.tfclen = padto - skb->len; + } +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index d847aa32628da..918a9520d1f17 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1361,8 +1361,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, + if (np->frag_size) + mtu = np->frag_size; + } +- if (mtu < IPV6_MIN_MTU) +- return -EINVAL; + cork->base.fragsize = mtu; + cork->base.gso_size = ipc6->gso_size; + cork->base.tx_flags = 0; +@@ -1424,8 +1422,6 @@ static int __ip6_append_data(struct sock *sk, + + fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + + (opt ? opt->opt_nflen : 0); +- maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - +- sizeof(struct frag_hdr); + + headersize = sizeof(struct ipv6hdr) + + (opt ? opt->opt_flen + opt->opt_nflen : 0) + +@@ -1433,6 +1429,13 @@ static int __ip6_append_data(struct sock *sk, + sizeof(struct frag_hdr) : 0) + + rt->rt6i_nfheader_len; + ++ if (mtu < fragheaderlen || ++ ((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr)) ++ goto emsgsize; ++ ++ maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - ++ sizeof(struct frag_hdr); ++ + /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit + * the first fragment + */ +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 464029892478f..ab91683d94596 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2852,13 +2852,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + ether_addr_equal(sdata->vif.addr, hdr->addr3)) + return RX_CONTINUE; + +- ac = ieee80211_select_queue_80211(sdata, skb, hdr); ++ ac = ieee802_1d_to_ac[skb->priority]; + q = sdata->vif.hw_queue[ac]; + if (ieee80211_queue_stopped(&local->hw, q)) { + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); + return RX_DROP_MONITOR; + } +- skb_set_queue_mapping(skb, q); ++ skb_set_queue_mapping(skb, ac); + + if (!--mesh_hdr->ttl) { + if (!is_multicast_ether_addr(hdr->addr1)) +diff --git a/net/netfilter/core.c b/net/netfilter/core.c +index 5d5bdf4500916..451b2df998ea7 100644 +--- a/net/netfilter/core.c ++++ b/net/netfilter/core.c +@@ -336,14 +336,15 @@ static int __nf_register_net_hook(struct net *net, int pf, + p = nf_entry_dereference(*pp); + new_hooks = nf_hook_entries_grow(p, reg); + +- if (!IS_ERR(new_hooks)) ++ if (!IS_ERR(new_hooks)) { ++ hooks_validate(new_hooks); + rcu_assign_pointer(*pp, new_hooks); ++ } + + mutex_unlock(&nf_hook_mutex); + if (IS_ERR(new_hooks)) + return PTR_ERR(new_hooks); + +- hooks_validate(new_hooks); + #ifdef CONFIG_NETFILTER_INGRESS + if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) + net_inc_ingress_queue(); +diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c +index f8f52ff99cfb0..643dbfe7c5815 100644 +--- a/net/netfilter/nf_queue.c ++++ b/net/netfilter/nf_queue.c +@@ -64,6 +64,15 @@ static void nf_queue_entry_release_br_nf_refs(struct sk_buff *skb) + #endif + } + ++static void nf_queue_sock_put(struct sock *sk) ++{ ++#ifdef CONFIG_INET ++ sock_gen_put(sk); ++#else ++ sock_put(sk); ++#endif ++} ++ + void nf_queue_entry_release_refs(struct nf_queue_entry *entry) + { + struct nf_hook_state *state = &entry->state; +@@ -74,7 +83,7 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry) + if (state->out) + dev_put(state->out); + if (state->sk) +- sock_put(state->sk); ++ nf_queue_sock_put(state->sk); + + nf_queue_entry_release_br_nf_refs(entry->skb); + } +@@ -99,18 +108,20 @@ static void nf_queue_entry_get_br_nf_refs(struct sk_buff *skb) + } + + /* Bump dev refs so they don't vanish while packet is out */ +-void nf_queue_entry_get_refs(struct nf_queue_entry *entry) ++bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) + { + struct nf_hook_state *state = &entry->state; + ++ if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt)) ++ return false; ++ + if (state->in) + dev_hold(state->in); + if (state->out) + dev_hold(state->out); +- if (state->sk) +- sock_hold(state->sk); + + nf_queue_entry_get_br_nf_refs(entry->skb); ++ return true; + } + EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs); + +@@ -201,7 +212,10 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, + .size = sizeof(*entry) + route_key_size, + }; + +- nf_queue_entry_get_refs(entry); ++ if (!nf_queue_entry_get_refs(entry)) { ++ kfree(entry); ++ return -ENOTCONN; ++ } + + switch (entry->state.pf) { + case AF_INET: +diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c +index ca21f8f4a47c1..7d3ab08a5a2d0 100644 +--- a/net/netfilter/nfnetlink_queue.c ++++ b/net/netfilter/nfnetlink_queue.c +@@ -712,9 +712,15 @@ static struct nf_queue_entry * + nf_queue_entry_dup(struct nf_queue_entry *e) + { + struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC); +- if (entry) +- nf_queue_entry_get_refs(entry); +- return entry; ++ ++ if (!entry) ++ return NULL; ++ ++ if (nf_queue_entry_get_refs(entry)) ++ return entry; ++ ++ kfree(entry); ++ return NULL; + } + + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c +index aeea67f908415..12672019f76c5 100644 +--- a/net/smc/smc_core.c ++++ b/net/smc/smc_core.c +@@ -342,8 +342,8 @@ void smc_conn_free(struct smc_connection *conn) + } else { + smc_cdc_tx_dismiss_slots(conn); + } +- smc_lgr_unregister_conn(conn); + smc_buf_unuse(conn, lgr); /* allow buffer reuse */ ++ smc_lgr_unregister_conn(conn); + conn->lgr = NULL; + + if (!lgr->conns_num) +@@ -632,7 +632,8 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini) + !lgr->sync_err && + lgr->vlan_id == ini->vlan_id && + (role == SMC_CLNT || +- lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) { ++ (lgr->conns_num < SMC_RMBS_PER_LGR_MAX && ++ !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) { + /* link group found */ + ini->cln_first_contact = SMC_REUSE_CONTACT; + conn->lgr = lgr; +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 7633d6a74bc2b..f2bc465de2845 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -12320,6 +12320,9 @@ static int handle_nan_filter(struct nlattr *attr_filter, + i = 0; + nla_for_each_nested(attr, attr_filter, rem) { + filter[i].filter = nla_memdup(attr, GFP_KERNEL); ++ if (!filter[i].filter) ++ goto err; ++ + filter[i].len = nla_len(attr); + i++; + } +@@ -12332,6 +12335,15 @@ static int handle_nan_filter(struct nlattr *attr_filter, + } + + return 0; ++ ++err: ++ i = 0; ++ nla_for_each_nested(attr, attr_filter, rem) { ++ kfree(filter[i].filter); ++ i++; ++ } ++ kfree(filter); ++ return -ENOMEM; + } + + static int nl80211_nan_add_func(struct sk_buff *skb, +diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c +index bb2292b5260c2..d758e9ec3d008 100644 +--- a/net/xfrm/xfrm_device.c ++++ b/net/xfrm/xfrm_device.c +@@ -206,6 +206,9 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, + if (x->encap || x->tfcpad) + return -EINVAL; + ++ if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND)) ++ return -EINVAL; ++ + dev = dev_get_by_index(net, xuo->ifindex); + if (!dev) { + if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) { +@@ -243,7 +246,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, + + xso->dev = dev; + xso->num_exthdrs = 1; +- xso->flags = xuo->flags; ++ /* Don't forward bit that is not implemented */ ++ xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6; + + err = dev->xfrmdev_ops->xdo_dev_state_add(x); + if (err) { +diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c +index 08343201513a9..3932d3aaff270 100644 +--- a/net/xfrm/xfrm_interface.c ++++ b/net/xfrm/xfrm_interface.c +@@ -695,12 +695,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], + struct net *net = xi->net; + struct xfrm_if_parms p = {}; + ++ xfrmi_netlink_parms(data, &p); + if (!p.if_id) { + NL_SET_ERR_MSG(extack, "if_id must be non zero"); + return -EINVAL; + } + +- xfrmi_netlink_parms(data, &p); + xi = xfrmi_locate(net, &p); + if (!xi) { + xi = netdev_priv(dev); +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index c6b2c99b501b9..1423e2b7cb42a 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -2440,7 +2440,7 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x) + } + EXPORT_SYMBOL(xfrm_state_delete_tunnel); + +-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu) ++u32 xfrm_state_mtu(struct xfrm_state *x, int mtu) + { + const struct xfrm_type *type = READ_ONCE(x->type); + struct crypto_aead *aead; +@@ -2471,17 +2471,7 @@ u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu) + return ((mtu - x->props.header_len - crypto_aead_authsize(aead) - + net_adj) & ~(blksize - 1)) + net_adj - 2; + } +-EXPORT_SYMBOL_GPL(__xfrm_state_mtu); +- +-u32 xfrm_state_mtu(struct xfrm_state *x, int mtu) +-{ +- mtu = __xfrm_state_mtu(x, mtu); +- +- if (x->props.family == AF_INET6 && mtu < IPV6_MIN_MTU) +- return IPV6_MIN_MTU; +- +- return mtu; +-} ++EXPORT_SYMBOL_GPL(xfrm_state_mtu); + + int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) + { +diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c +index 2fb65f246b0cf..77af5b67b9bb4 100644 +--- a/sound/soc/codecs/cs4265.c ++++ b/sound/soc/codecs/cs4265.c +@@ -150,7 +150,6 @@ static const struct snd_kcontrol_new cs4265_snd_controls[] = { + SOC_SINGLE("E to F Buffer Disable Switch", CS4265_SPDIF_CTL1, + 6, 1, 0), + SOC_ENUM("C Data Access", cam_mode_enum), +- SOC_SINGLE("SPDIF Switch", CS4265_SPDIF_CTL2, 5, 1, 1), + SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2, + 3, 1, 0), + SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum), +@@ -186,7 +185,7 @@ static const struct snd_soc_dapm_widget cs4265_dapm_widgets[] = { + + SND_SOC_DAPM_SWITCH("Loopback", SND_SOC_NOPM, 0, 0, + &loopback_ctl), +- SND_SOC_DAPM_SWITCH("SPDIF", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_SWITCH("SPDIF", CS4265_SPDIF_CTL2, 5, 1, + &spdif_switch), + SND_SOC_DAPM_SWITCH("DAC", CS4265_PWRCTL, 1, 1, + &dac_switch), +diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c +index 5716cede99cb4..acc2b34ca334a 100644 +--- a/sound/soc/codecs/rt5668.c ++++ b/sound/soc/codecs/rt5668.c +@@ -1022,11 +1022,13 @@ static void rt5668_jack_detect_handler(struct work_struct *work) + container_of(work, struct rt5668_priv, jack_detect_work.work); + int val, btn_type; + +- while (!rt5668->component) +- usleep_range(10000, 15000); +- +- while (!rt5668->component->card->instantiated) +- usleep_range(10000, 15000); ++ if (!rt5668->component || !rt5668->component->card || ++ !rt5668->component->card->instantiated) { ++ /* card not yet ready, try later */ ++ mod_delayed_work(system_power_efficient_wq, ++ &rt5668->jack_detect_work, msecs_to_jiffies(15)); ++ return; ++ } + + mutex_lock(&rt5668->calibrate_mutex); + +diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c +index 05e883a65d7a7..a8cf4c7451304 100644 +--- a/sound/soc/codecs/rt5682.c ++++ b/sound/soc/codecs/rt5682.c +@@ -1052,11 +1052,13 @@ static void rt5682_jack_detect_handler(struct work_struct *work) + container_of(work, struct rt5682_priv, jack_detect_work.work); + int val, btn_type; + +- while (!rt5682->component) +- usleep_range(10000, 15000); +- +- while (!rt5682->component->card->instantiated) +- usleep_range(10000, 15000); ++ if (!rt5682->component || !rt5682->component->card || ++ !rt5682->component->card->instantiated) { ++ /* card not yet ready, try later */ ++ mod_delayed_work(system_power_efficient_wq, ++ &rt5682->jack_detect_work, msecs_to_jiffies(15)); ++ return; ++ } + + mutex_lock(&rt5682->calibrate_mutex); + +diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c +index f5dcd625e4355..c88bc6bb41cfe 100644 +--- a/sound/soc/soc-ops.c ++++ b/sound/soc/soc-ops.c +@@ -323,7 +323,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, + mask = BIT(sign_bit + 1) - 1; + + val = ucontrol->value.integer.value[0]; +- if (mc->platform_max && val > mc->platform_max) ++ if (mc->platform_max && ((int)val + min) > mc->platform_max) + return -EINVAL; + if (val > max - min) + return -EINVAL; +@@ -336,7 +336,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, + val = val << shift; + if (snd_soc_volsw_is_stereo(mc)) { + val2 = ucontrol->value.integer.value[1]; +- if (mc->platform_max && val2 > mc->platform_max) ++ if (mc->platform_max && ((int)val2 + min) > mc->platform_max) + return -EINVAL; + if (val2 > max - min) + return -EINVAL; +diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c +index 5fd4e32247a6d..a314f13e3292e 100644 +--- a/sound/x86/intel_hdmi_audio.c ++++ b/sound/x86/intel_hdmi_audio.c +@@ -1279,7 +1279,7 @@ static int had_pcm_mmap(struct snd_pcm_substream *substream, + { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, +- substream->dma_buffer.addr >> PAGE_SHIFT, ++ substream->runtime->dma_addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); + } + diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.183-184.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.183-184.patch new file mode 100644 index 0000000000..d528501777 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.183-184.patch @@ -0,0 +1,2222 @@ +diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst +index 985181dba0bac..6bd97cd50d625 100644 +--- a/Documentation/admin-guide/hw-vuln/spectre.rst ++++ b/Documentation/admin-guide/hw-vuln/spectre.rst +@@ -60,8 +60,8 @@ privileged data touched during the speculative execution. + Spectre variant 1 attacks take advantage of speculative execution of + conditional branches, while Spectre variant 2 attacks use speculative + execution of indirect branches to leak privileged memory. +-See :ref:`[1] ` :ref:`[5] ` :ref:`[7] ` +-:ref:`[10] ` :ref:`[11] `. ++See :ref:`[1] ` :ref:`[5] ` :ref:`[6] ` ++:ref:`[7] ` :ref:`[10] ` :ref:`[11] `. + + Spectre variant 1 (Bounds Check Bypass) + --------------------------------------- +@@ -131,6 +131,19 @@ steer its indirect branch speculations to gadget code, and measure the + speculative execution's side effects left in level 1 cache to infer the + victim's data. + ++Yet another variant 2 attack vector is for the attacker to poison the ++Branch History Buffer (BHB) to speculatively steer an indirect branch ++to a specific Branch Target Buffer (BTB) entry, even if the entry isn't ++associated with the source address of the indirect branch. Specifically, ++the BHB might be shared across privilege levels even in the presence of ++Enhanced IBRS. ++ ++Currently the only known real-world BHB attack vector is via ++unprivileged eBPF. Therefore, it's highly recommended to not enable ++unprivileged eBPF, especially when eIBRS is used (without retpolines). ++For a full mitigation against BHB attacks, it's recommended to use ++retpolines (or eIBRS combined with retpolines). ++ + Attack scenarios + ---------------- + +@@ -364,13 +377,15 @@ The possible values in this file are: + + - Kernel status: + +- ==================================== ================================= +- 'Not affected' The processor is not vulnerable +- 'Vulnerable' Vulnerable, no mitigation +- 'Mitigation: Full generic retpoline' Software-focused mitigation +- 'Mitigation: Full AMD retpoline' AMD-specific software mitigation +- 'Mitigation: Enhanced IBRS' Hardware-focused mitigation +- ==================================== ================================= ++ ======================================== ================================= ++ 'Not affected' The processor is not vulnerable ++ 'Mitigation: None' Vulnerable, no mitigation ++ 'Mitigation: Retpolines' Use Retpoline thunks ++ 'Mitigation: LFENCE' Use LFENCE instructions ++ 'Mitigation: Enhanced IBRS' Hardware-focused mitigation ++ 'Mitigation: Enhanced IBRS + Retpolines' Hardware-focused + Retpolines ++ 'Mitigation: Enhanced IBRS + LFENCE' Hardware-focused + LFENCE ++ ======================================== ================================= + + - Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is + used to protect against Spectre variant 2 attacks when calling firmware (x86 only). +@@ -584,12 +599,13 @@ kernel command line. + + Specific mitigations can also be selected manually: + +- retpoline +- replace indirect branches +- retpoline,generic +- google's original retpoline +- retpoline,amd +- AMD-specific minimal thunk ++ retpoline auto pick between generic,lfence ++ retpoline,generic Retpolines ++ retpoline,lfence LFENCE; indirect branch ++ retpoline,amd alias for retpoline,lfence ++ eibrs enhanced IBRS ++ eibrs,retpoline enhanced IBRS + Retpolines ++ eibrs,lfence enhanced IBRS + LFENCE + + Not specifying this option is equivalent to + spectre_v2=auto. +@@ -730,7 +746,7 @@ AMD white papers: + + .. _spec_ref6: + +-[6] `Software techniques for managing speculation on AMD processors `_. ++[6] `Software techniques for managing speculation on AMD processors `_. + + ARM white papers: + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 165abcb656c5b..979423e1b639f 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4493,8 +4493,12 @@ + Specific mitigations can also be selected manually: + + retpoline - replace indirect branches +- retpoline,generic - google's original retpoline +- retpoline,amd - AMD-specific minimal thunk ++ retpoline,generic - Retpolines ++ retpoline,lfence - LFENCE; indirect branch ++ retpoline,amd - alias for retpoline,lfence ++ eibrs - enhanced IBRS ++ eibrs,retpoline - enhanced IBRS + Retpolines ++ eibrs,lfence - enhanced IBRS + LFENCE + + Not specifying this option is equivalent to + spectre_v2=auto. +diff --git a/Makefile b/Makefile +index a94b5ea499e13..e914e1a8a7d2c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 183 ++SUBLEVEL = 184 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h +index 3546d294d55fa..6b3e64e19fb6f 100644 +--- a/arch/arm/include/asm/assembler.h ++++ b/arch/arm/include/asm/assembler.h +@@ -107,6 +107,16 @@ + .endm + #endif + ++#if __LINUX_ARM_ARCH__ < 7 ++ .macro dsb, args ++ mcr p15, 0, r0, c7, c10, 4 ++ .endm ++ ++ .macro isb, args ++ mcr p15, 0, r0, c7, c5, 4 ++ .endm ++#endif ++ + .macro asm_trace_hardirqs_off, save=1 + #if defined(CONFIG_TRACE_IRQFLAGS) + .if \save +diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h +new file mode 100644 +index 0000000000000..d1fa5607d3aa3 +--- /dev/null ++++ b/arch/arm/include/asm/spectre.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef __ASM_SPECTRE_H ++#define __ASM_SPECTRE_H ++ ++enum { ++ SPECTRE_UNAFFECTED, ++ SPECTRE_MITIGATED, ++ SPECTRE_VULNERABLE, ++}; ++ ++enum { ++ __SPECTRE_V2_METHOD_BPIALL, ++ __SPECTRE_V2_METHOD_ICIALLU, ++ __SPECTRE_V2_METHOD_SMC, ++ __SPECTRE_V2_METHOD_HVC, ++ __SPECTRE_V2_METHOD_LOOP8, ++}; ++ ++enum { ++ SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL), ++ SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU), ++ SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC), ++ SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC), ++ SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8), ++}; ++ ++void spectre_v2_update_state(unsigned int state, unsigned int methods); ++ ++int spectre_bhb_update_vectors(unsigned int method); ++ ++#endif +diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile +index 8b679e2ca3c3d..dc31426cae6d8 100644 +--- a/arch/arm/kernel/Makefile ++++ b/arch/arm/kernel/Makefile +@@ -106,4 +106,6 @@ endif + + obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o + ++obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o ++ + extra-y := $(head-y) vmlinux.lds +diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S +index 4937d514318ec..94d25425b7bce 100644 +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -1005,12 +1005,11 @@ vector_\name: + sub lr, lr, #\correction + .endif + +- @ +- @ Save r0, lr_ (parent PC) and spsr_ +- @ (parent CPSR) +- @ ++ @ Save r0, lr_ (parent PC) + stmia sp, {r0, lr} @ save r0, lr +- mrs lr, spsr ++ ++ @ Save spsr_ (parent CPSR) ++2: mrs lr, spsr + str lr, [sp, #8] @ save spsr + + @ +@@ -1031,6 +1030,44 @@ vector_\name: + movs pc, lr @ branch to handler in SVC mode + ENDPROC(vector_\name) + ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++ .subsection 1 ++ .align 5 ++vector_bhb_loop8_\name: ++ .if \correction ++ sub lr, lr, #\correction ++ .endif ++ ++ @ Save r0, lr_ (parent PC) ++ stmia sp, {r0, lr} ++ ++ @ bhb workaround ++ mov r0, #8 ++1: b . + 4 ++ subs r0, r0, #1 ++ bne 1b ++ dsb ++ isb ++ b 2b ++ENDPROC(vector_bhb_loop8_\name) ++ ++vector_bhb_bpiall_\name: ++ .if \correction ++ sub lr, lr, #\correction ++ .endif ++ ++ @ Save r0, lr_ (parent PC) ++ stmia sp, {r0, lr} ++ ++ @ bhb workaround ++ mcr p15, 0, r0, c7, c5, 6 @ BPIALL ++ @ isb not needed due to "movs pc, lr" in the vector stub ++ @ which gives a "context synchronisation". ++ b 2b ++ENDPROC(vector_bhb_bpiall_\name) ++ .previous ++#endif ++ + .align 2 + @ handler addresses follow this label + 1: +@@ -1039,6 +1076,10 @@ ENDPROC(vector_\name) + .section .stubs, "ax", %progbits + @ This must be the first word + .word vector_swi ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++ .word vector_bhb_loop8_swi ++ .word vector_bhb_bpiall_swi ++#endif + + vector_rst: + ARM( swi SYS_ERROR0 ) +@@ -1153,8 +1194,10 @@ vector_addrexcptn: + * FIQ "NMI" handler + *----------------------------------------------------------------------------- + * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86 +- * systems. ++ * systems. This must be the last vector stub, so lets place it in its own ++ * subsection. + */ ++ .subsection 2 + vector_stub fiq, FIQ_MODE, 4 + + .long __fiq_usr @ 0 (USR_26 / USR_32) +@@ -1187,6 +1230,30 @@ vector_addrexcptn: + W(b) vector_irq + W(b) vector_fiq + ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++ .section .vectors.bhb.loop8, "ax", %progbits ++.L__vectors_bhb_loop8_start: ++ W(b) vector_rst ++ W(b) vector_bhb_loop8_und ++ W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004 ++ W(b) vector_bhb_loop8_pabt ++ W(b) vector_bhb_loop8_dabt ++ W(b) vector_addrexcptn ++ W(b) vector_bhb_loop8_irq ++ W(b) vector_bhb_loop8_fiq ++ ++ .section .vectors.bhb.bpiall, "ax", %progbits ++.L__vectors_bhb_bpiall_start: ++ W(b) vector_rst ++ W(b) vector_bhb_bpiall_und ++ W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008 ++ W(b) vector_bhb_bpiall_pabt ++ W(b) vector_bhb_bpiall_dabt ++ W(b) vector_addrexcptn ++ W(b) vector_bhb_bpiall_irq ++ W(b) vector_bhb_bpiall_fiq ++#endif ++ + .data + .align 2 + +diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S +index 271cb8a1eba1e..bd619da73c84e 100644 +--- a/arch/arm/kernel/entry-common.S ++++ b/arch/arm/kernel/entry-common.S +@@ -162,6 +162,29 @@ ENDPROC(ret_from_fork) + *----------------------------------------------------------------------------- + */ + ++ .align 5 ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++ENTRY(vector_bhb_loop8_swi) ++ sub sp, sp, #PT_REGS_SIZE ++ stmia sp, {r0 - r12} ++ mov r8, #8 ++1: b 2f ++2: subs r8, r8, #1 ++ bne 1b ++ dsb ++ isb ++ b 3f ++ENDPROC(vector_bhb_loop8_swi) ++ ++ .align 5 ++ENTRY(vector_bhb_bpiall_swi) ++ sub sp, sp, #PT_REGS_SIZE ++ stmia sp, {r0 - r12} ++ mcr p15, 0, r8, c7, c5, 6 @ BPIALL ++ isb ++ b 3f ++ENDPROC(vector_bhb_bpiall_swi) ++#endif + .align 5 + ENTRY(vector_swi) + #ifdef CONFIG_CPU_V7M +@@ -169,6 +192,7 @@ ENTRY(vector_swi) + #else + sub sp, sp, #PT_REGS_SIZE + stmia sp, {r0 - r12} @ Calling r0 - r12 ++3: + ARM( add r8, sp, #S_PC ) + ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr + THUMB( mov r8, sp ) +diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c +new file mode 100644 +index 0000000000000..0dcefc36fb7a0 +--- /dev/null ++++ b/arch/arm/kernel/spectre.c +@@ -0,0 +1,71 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++#include ++#include ++#include ++ ++#include ++ ++static bool _unprivileged_ebpf_enabled(void) ++{ ++#ifdef CONFIG_BPF_SYSCALL ++ return !sysctl_unprivileged_bpf_disabled; ++#else ++ return false; ++#endif ++} ++ ++ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "Mitigation: __user pointer sanitization\n"); ++} ++ ++static unsigned int spectre_v2_state; ++static unsigned int spectre_v2_methods; ++ ++void spectre_v2_update_state(unsigned int state, unsigned int method) ++{ ++ if (state > spectre_v2_state) ++ spectre_v2_state = state; ++ spectre_v2_methods |= method; ++} ++ ++ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ const char *method; ++ ++ if (spectre_v2_state == SPECTRE_UNAFFECTED) ++ return sprintf(buf, "%s\n", "Not affected"); ++ ++ if (spectre_v2_state != SPECTRE_MITIGATED) ++ return sprintf(buf, "%s\n", "Vulnerable"); ++ ++ if (_unprivileged_ebpf_enabled()) ++ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); ++ ++ switch (spectre_v2_methods) { ++ case SPECTRE_V2_METHOD_BPIALL: ++ method = "Branch predictor hardening"; ++ break; ++ ++ case SPECTRE_V2_METHOD_ICIALLU: ++ method = "I-cache invalidation"; ++ break; ++ ++ case SPECTRE_V2_METHOD_SMC: ++ case SPECTRE_V2_METHOD_HVC: ++ method = "Firmware call"; ++ break; ++ ++ case SPECTRE_V2_METHOD_LOOP8: ++ method = "History overwrite"; ++ break; ++ ++ default: ++ method = "Multiple mitigations"; ++ break; ++ } ++ ++ return sprintf(buf, "Mitigation: %s\n", method); ++} +diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c +index 97a512551b217..207ef9a797bd4 100644 +--- a/arch/arm/kernel/traps.c ++++ b/arch/arm/kernel/traps.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -799,10 +800,59 @@ static inline void __init kuser_init(void *vectors) + } + #endif + ++#ifndef CONFIG_CPU_V7M ++static void copy_from_lma(void *vma, void *lma_start, void *lma_end) ++{ ++ memcpy(vma, lma_start, lma_end - lma_start); ++} ++ ++static void flush_vectors(void *vma, size_t offset, size_t size) ++{ ++ unsigned long start = (unsigned long)vma + offset; ++ unsigned long end = start + size; ++ ++ flush_icache_range(start, end); ++} ++ ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++int spectre_bhb_update_vectors(unsigned int method) ++{ ++ extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[]; ++ extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[]; ++ void *vec_start, *vec_end; ++ ++ if (system_state > SYSTEM_SCHEDULING) { ++ pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n", ++ smp_processor_id()); ++ return SPECTRE_VULNERABLE; ++ } ++ ++ switch (method) { ++ case SPECTRE_V2_METHOD_LOOP8: ++ vec_start = __vectors_bhb_loop8_start; ++ vec_end = __vectors_bhb_loop8_end; ++ break; ++ ++ case SPECTRE_V2_METHOD_BPIALL: ++ vec_start = __vectors_bhb_bpiall_start; ++ vec_end = __vectors_bhb_bpiall_end; ++ break; ++ ++ default: ++ pr_err("CPU%u: unknown Spectre BHB state %d\n", ++ smp_processor_id(), method); ++ return SPECTRE_VULNERABLE; ++ } ++ ++ copy_from_lma(vectors_page, vec_start, vec_end); ++ flush_vectors(vectors_page, 0, vec_end - vec_start); ++ ++ return SPECTRE_MITIGATED; ++} ++#endif ++ + void __init early_trap_init(void *vectors_base) + { +-#ifndef CONFIG_CPU_V7M +- unsigned long vectors = (unsigned long)vectors_base; + extern char __stubs_start[], __stubs_end[]; + extern char __vectors_start[], __vectors_end[]; + unsigned i; +@@ -823,17 +873,20 @@ void __init early_trap_init(void *vectors_base) + * into the vector page, mapped at 0xffff0000, and ensure these + * are visible to the instruction stream. + */ +- memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); +- memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); ++ copy_from_lma(vectors_base, __vectors_start, __vectors_end); ++ copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end); + + kuser_init(vectors_base); + +- flush_icache_range(vectors, vectors + PAGE_SIZE * 2); ++ flush_vectors(vectors_base, 0, PAGE_SIZE * 2); ++} + #else /* ifndef CONFIG_CPU_V7M */ ++void __init early_trap_init(void *vectors_base) ++{ + /* + * on V7-M there is no need to copy the vector table to a dedicated + * memory area. The address is configurable and so a table in the kernel + * image can be used. + */ +-#endif + } ++#endif +diff --git a/arch/arm/kernel/vmlinux.lds.h b/arch/arm/kernel/vmlinux.lds.h +index 8247bc15addc4..78d156e4f0088 100644 +--- a/arch/arm/kernel/vmlinux.lds.h ++++ b/arch/arm/kernel/vmlinux.lds.h +@@ -25,6 +25,19 @@ + #define ARM_MMU_DISCARD(x) x + #endif + ++/* ++ * ld.lld does not support NOCROSSREFS: ++ * https://github.com/ClangBuiltLinux/linux/issues/1609 ++ */ ++#ifdef CONFIG_LD_IS_LLD ++#define NOCROSSREFS ++#endif ++ ++/* Set start/end symbol names to the LMA for the section */ ++#define ARM_LMA(sym, section) \ ++ sym##_start = LOADADDR(section); \ ++ sym##_end = LOADADDR(section) + SIZEOF(section) ++ + #define PROC_INFO \ + . = ALIGN(4); \ + __proc_info_begin = .; \ +@@ -100,19 +113,31 @@ + * only thing that matters is their relative offsets + */ + #define ARM_VECTORS \ +- __vectors_start = .; \ +- .vectors 0xffff0000 : AT(__vectors_start) { \ +- *(.vectors) \ ++ __vectors_lma = .; \ ++ OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ ++ .vectors { \ ++ *(.vectors) \ ++ } \ ++ .vectors.bhb.loop8 { \ ++ *(.vectors.bhb.loop8) \ ++ } \ ++ .vectors.bhb.bpiall { \ ++ *(.vectors.bhb.bpiall) \ ++ } \ + } \ +- . = __vectors_start + SIZEOF(.vectors); \ +- __vectors_end = .; \ ++ ARM_LMA(__vectors, .vectors); \ ++ ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \ ++ ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \ ++ . = __vectors_lma + SIZEOF(.vectors) + \ ++ SIZEOF(.vectors.bhb.loop8) + \ ++ SIZEOF(.vectors.bhb.bpiall); \ + \ +- __stubs_start = .; \ +- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \ ++ __stubs_lma = .; \ ++ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ + *(.stubs) \ + } \ +- . = __stubs_start + SIZEOF(.stubs); \ +- __stubs_end = .; \ ++ ARM_LMA(__stubs, .stubs); \ ++ . = __stubs_lma + SIZEOF(.stubs); \ + \ + PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); + +diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig +index 64cce0c8560ab..00ffee644372e 100644 +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -833,6 +833,7 @@ config CPU_BPREDICT_DISABLE + + config CPU_SPECTRE + bool ++ select GENERIC_CPU_VULNERABILITIES + + config HARDEN_BRANCH_PREDICTOR + bool "Harden the branch predictor against aliasing attacks" if EXPERT +@@ -853,6 +854,16 @@ config HARDEN_BRANCH_PREDICTOR + + If unsure, say Y. + ++config HARDEN_BRANCH_HISTORY ++ bool "Harden Spectre style attacks against branch history" if EXPERT ++ depends on CPU_SPECTRE ++ default y ++ help ++ Speculation attacks against some high-performance processors can ++ make use of branch history to influence future speculation. When ++ taking an exception, a sequence of branches overwrites the branch ++ history, or branch history is invalidated. ++ + config TLS_REG_EMUL + bool + select NEED_KUSER_HELPERS +diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c +index a6554fdb56c54..097ef85bb7f21 100644 +--- a/arch/arm/mm/proc-v7-bugs.c ++++ b/arch/arm/mm/proc-v7-bugs.c +@@ -7,8 +7,35 @@ + #include + #include + #include ++#include + #include + ++#ifdef CONFIG_ARM_PSCI ++static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ++ ARM_SMCCC_ARCH_WORKAROUND_1, &res); ++ ++ switch ((int)res.a0) { ++ case SMCCC_RET_SUCCESS: ++ return SPECTRE_MITIGATED; ++ ++ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: ++ return SPECTRE_UNAFFECTED; ++ ++ default: ++ return SPECTRE_VULNERABLE; ++ } ++} ++#else ++static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) ++{ ++ return SPECTRE_VULNERABLE; ++} ++#endif ++ + #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR + DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn); + +@@ -37,13 +64,61 @@ static void __maybe_unused call_hvc_arch_workaround_1(void) + arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); + } + +-static void cpu_v7_spectre_init(void) ++static unsigned int spectre_v2_install_workaround(unsigned int method) + { + const char *spectre_v2_method = NULL; + int cpu = smp_processor_id(); + + if (per_cpu(harden_branch_predictor_fn, cpu)) +- return; ++ return SPECTRE_MITIGATED; ++ ++ switch (method) { ++ case SPECTRE_V2_METHOD_BPIALL: ++ per_cpu(harden_branch_predictor_fn, cpu) = ++ harden_branch_predictor_bpiall; ++ spectre_v2_method = "BPIALL"; ++ break; ++ ++ case SPECTRE_V2_METHOD_ICIALLU: ++ per_cpu(harden_branch_predictor_fn, cpu) = ++ harden_branch_predictor_iciallu; ++ spectre_v2_method = "ICIALLU"; ++ break; ++ ++ case SPECTRE_V2_METHOD_HVC: ++ per_cpu(harden_branch_predictor_fn, cpu) = ++ call_hvc_arch_workaround_1; ++ cpu_do_switch_mm = cpu_v7_hvc_switch_mm; ++ spectre_v2_method = "hypervisor"; ++ break; ++ ++ case SPECTRE_V2_METHOD_SMC: ++ per_cpu(harden_branch_predictor_fn, cpu) = ++ call_smc_arch_workaround_1; ++ cpu_do_switch_mm = cpu_v7_smc_switch_mm; ++ spectre_v2_method = "firmware"; ++ break; ++ } ++ ++ if (spectre_v2_method) ++ pr_info("CPU%u: Spectre v2: using %s workaround\n", ++ smp_processor_id(), spectre_v2_method); ++ ++ return SPECTRE_MITIGATED; ++} ++#else ++static unsigned int spectre_v2_install_workaround(unsigned int method) ++{ ++ pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n", ++ smp_processor_id()); ++ ++ return SPECTRE_VULNERABLE; ++} ++#endif ++ ++static void cpu_v7_spectre_v2_init(void) ++{ ++ unsigned int state, method = 0; + + switch (read_cpuid_part()) { + case ARM_CPU_PART_CORTEX_A8: +@@ -52,32 +127,37 @@ static void cpu_v7_spectre_init(void) + case ARM_CPU_PART_CORTEX_A17: + case ARM_CPU_PART_CORTEX_A73: + case ARM_CPU_PART_CORTEX_A75: +- per_cpu(harden_branch_predictor_fn, cpu) = +- harden_branch_predictor_bpiall; +- spectre_v2_method = "BPIALL"; ++ state = SPECTRE_MITIGATED; ++ method = SPECTRE_V2_METHOD_BPIALL; + break; + + case ARM_CPU_PART_CORTEX_A15: + case ARM_CPU_PART_BRAHMA_B15: +- per_cpu(harden_branch_predictor_fn, cpu) = +- harden_branch_predictor_iciallu; +- spectre_v2_method = "ICIALLU"; ++ state = SPECTRE_MITIGATED; ++ method = SPECTRE_V2_METHOD_ICIALLU; + break; + +-#ifdef CONFIG_ARM_PSCI + case ARM_CPU_PART_BRAHMA_B53: + /* Requires no workaround */ ++ state = SPECTRE_UNAFFECTED; + break; ++ + default: + /* Other ARM CPUs require no workaround */ +- if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) ++ if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) { ++ state = SPECTRE_UNAFFECTED; + break; ++ } + /* fallthrough */ +- /* Cortex A57/A72 require firmware workaround */ ++ /* Cortex A57/A72 require firmware workaround */ + case ARM_CPU_PART_CORTEX_A57: + case ARM_CPU_PART_CORTEX_A72: { + struct arm_smccc_res res; + ++ state = spectre_v2_get_cpu_fw_mitigation_state(); ++ if (state != SPECTRE_MITIGATED) ++ break; ++ + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) + break; + +@@ -87,10 +167,7 @@ static void cpu_v7_spectre_init(void) + ARM_SMCCC_ARCH_WORKAROUND_1, &res); + if ((int)res.a0 != 0) + break; +- per_cpu(harden_branch_predictor_fn, cpu) = +- call_hvc_arch_workaround_1; +- cpu_do_switch_mm = cpu_v7_hvc_switch_mm; +- spectre_v2_method = "hypervisor"; ++ method = SPECTRE_V2_METHOD_HVC; + break; + + case PSCI_CONDUIT_SMC: +@@ -98,29 +175,97 @@ static void cpu_v7_spectre_init(void) + ARM_SMCCC_ARCH_WORKAROUND_1, &res); + if ((int)res.a0 != 0) + break; +- per_cpu(harden_branch_predictor_fn, cpu) = +- call_smc_arch_workaround_1; +- cpu_do_switch_mm = cpu_v7_smc_switch_mm; +- spectre_v2_method = "firmware"; ++ method = SPECTRE_V2_METHOD_SMC; + break; + + default: ++ state = SPECTRE_VULNERABLE; + break; + } + } +-#endif + } + +- if (spectre_v2_method) +- pr_info("CPU%u: Spectre v2: using %s workaround\n", +- smp_processor_id(), spectre_v2_method); ++ if (state == SPECTRE_MITIGATED) ++ state = spectre_v2_install_workaround(method); ++ ++ spectre_v2_update_state(state, method); ++} ++ ++#ifdef CONFIG_HARDEN_BRANCH_HISTORY ++static int spectre_bhb_method; ++ ++static const char *spectre_bhb_method_name(int method) ++{ ++ switch (method) { ++ case SPECTRE_V2_METHOD_LOOP8: ++ return "loop"; ++ ++ case SPECTRE_V2_METHOD_BPIALL: ++ return "BPIALL"; ++ ++ default: ++ return "unknown"; ++ } ++} ++ ++static int spectre_bhb_install_workaround(int method) ++{ ++ if (spectre_bhb_method != method) { ++ if (spectre_bhb_method) { ++ pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n", ++ smp_processor_id()); ++ ++ return SPECTRE_VULNERABLE; ++ } ++ ++ if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE) ++ return SPECTRE_VULNERABLE; ++ ++ spectre_bhb_method = method; ++ } ++ ++ pr_info("CPU%u: Spectre BHB: using %s workaround\n", ++ smp_processor_id(), spectre_bhb_method_name(method)); ++ ++ return SPECTRE_MITIGATED; + } + #else +-static void cpu_v7_spectre_init(void) ++static int spectre_bhb_install_workaround(int method) + { ++ return SPECTRE_VULNERABLE; + } + #endif + ++static void cpu_v7_spectre_bhb_init(void) ++{ ++ unsigned int state, method = 0; ++ ++ switch (read_cpuid_part()) { ++ case ARM_CPU_PART_CORTEX_A15: ++ case ARM_CPU_PART_BRAHMA_B15: ++ case ARM_CPU_PART_CORTEX_A57: ++ case ARM_CPU_PART_CORTEX_A72: ++ state = SPECTRE_MITIGATED; ++ method = SPECTRE_V2_METHOD_LOOP8; ++ break; ++ ++ case ARM_CPU_PART_CORTEX_A73: ++ case ARM_CPU_PART_CORTEX_A75: ++ state = SPECTRE_MITIGATED; ++ method = SPECTRE_V2_METHOD_BPIALL; ++ break; ++ ++ default: ++ state = SPECTRE_UNAFFECTED; ++ break; ++ } ++ ++ if (state == SPECTRE_MITIGATED) ++ state = spectre_bhb_install_workaround(method); ++ ++ spectre_v2_update_state(state, method); ++} ++ + static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned, + u32 mask, const char *msg) + { +@@ -149,16 +294,17 @@ static bool check_spectre_auxcr(bool *warned, u32 bit) + void cpu_v7_ca8_ibe(void) + { + if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6))) +- cpu_v7_spectre_init(); ++ cpu_v7_spectre_v2_init(); + } + + void cpu_v7_ca15_ibe(void) + { + if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0))) +- cpu_v7_spectre_init(); ++ cpu_v7_spectre_v2_init(); + } + + void cpu_v7_bugs_init(void) + { +- cpu_v7_spectre_init(); ++ cpu_v7_spectre_v2_init(); ++ cpu_v7_spectre_bhb_init(); + } +diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h +index d912457f56a79..f48905f796e9d 100644 +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -202,7 +202,7 @@ + #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ + #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +-#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ ++#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */ + #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ + #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ + #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ +diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h +index b222a35959467..956df82bbc2bc 100644 +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -115,7 +115,7 @@ + ANNOTATE_NOSPEC_ALTERNATIVE + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg), \ + __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ +- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD ++ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_LFENCE + #else + jmp *\reg + #endif +@@ -126,7 +126,7 @@ + ANNOTATE_NOSPEC_ALTERNATIVE + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg), \ + __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ +- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD ++ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_LFENCE + #else + call *\reg + #endif +@@ -171,7 +171,7 @@ + "lfence;\n" \ + ANNOTATE_RETPOLINE_SAFE \ + "call *%[thunk_target]\n", \ +- X86_FEATURE_RETPOLINE_AMD) ++ X86_FEATURE_RETPOLINE_LFENCE) + # define THUNK_TARGET(addr) [thunk_target] "r" (addr) + + #else /* CONFIG_X86_32 */ +@@ -201,7 +201,7 @@ + "lfence;\n" \ + ANNOTATE_RETPOLINE_SAFE \ + "call *%[thunk_target]\n", \ +- X86_FEATURE_RETPOLINE_AMD) ++ X86_FEATURE_RETPOLINE_LFENCE) + + # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) + #endif +@@ -213,9 +213,11 @@ + /* The Spectre V2 mitigation variants */ + enum spectre_v2_mitigation { + SPECTRE_V2_NONE, +- SPECTRE_V2_RETPOLINE_GENERIC, +- SPECTRE_V2_RETPOLINE_AMD, +- SPECTRE_V2_IBRS_ENHANCED, ++ SPECTRE_V2_RETPOLINE, ++ SPECTRE_V2_LFENCE, ++ SPECTRE_V2_EIBRS, ++ SPECTRE_V2_EIBRS_RETPOLINE, ++ SPECTRE_V2_EIBRS_LFENCE, + }; + + /* The indirect branch speculation control variants */ +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index fcc4238ee95f8..e817aaeef254c 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "cpu.h" + +@@ -607,6 +608,32 @@ static inline const char *spectre_v2_module_string(void) + static inline const char *spectre_v2_module_string(void) { return ""; } + #endif + ++#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n" ++#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" ++#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n" ++ ++#ifdef CONFIG_BPF_SYSCALL ++void unpriv_ebpf_notify(int new_state) ++{ ++ if (new_state) ++ return; ++ ++ /* Unprivileged eBPF is enabled */ ++ ++ switch (spectre_v2_enabled) { ++ case SPECTRE_V2_EIBRS: ++ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); ++ break; ++ case SPECTRE_V2_EIBRS_LFENCE: ++ if (sched_smt_active()) ++ pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); ++ break; ++ default: ++ break; ++ } ++} ++#endif ++ + static inline bool match_option(const char *arg, int arglen, const char *opt) + { + int len = strlen(opt); +@@ -621,7 +648,10 @@ enum spectre_v2_mitigation_cmd { + SPECTRE_V2_CMD_FORCE, + SPECTRE_V2_CMD_RETPOLINE, + SPECTRE_V2_CMD_RETPOLINE_GENERIC, +- SPECTRE_V2_CMD_RETPOLINE_AMD, ++ SPECTRE_V2_CMD_RETPOLINE_LFENCE, ++ SPECTRE_V2_CMD_EIBRS, ++ SPECTRE_V2_CMD_EIBRS_RETPOLINE, ++ SPECTRE_V2_CMD_EIBRS_LFENCE, + }; + + enum spectre_v2_user_cmd { +@@ -694,6 +724,13 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd) + return SPECTRE_V2_USER_CMD_AUTO; + } + ++static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) ++{ ++ return (mode == SPECTRE_V2_EIBRS || ++ mode == SPECTRE_V2_EIBRS_RETPOLINE || ++ mode == SPECTRE_V2_EIBRS_LFENCE); ++} ++ + static void __init + spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) + { +@@ -756,10 +793,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) + } + + /* +- * If enhanced IBRS is enabled or SMT impossible, STIBP is not ++ * If no STIBP, enhanced IBRS is enabled or SMT impossible, STIBP is not + * required. + */ +- if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) ++ if (!boot_cpu_has(X86_FEATURE_STIBP) || ++ !smt_possible || ++ spectre_v2_in_eibrs_mode(spectre_v2_enabled)) + return; + + /* +@@ -771,12 +810,6 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + +- /* +- * If STIBP is not available, clear the STIBP mode. +- */ +- if (!boot_cpu_has(X86_FEATURE_STIBP)) +- mode = SPECTRE_V2_USER_NONE; +- + spectre_v2_user_stibp = mode; + + set_mode: +@@ -785,9 +818,11 @@ set_mode: + + static const char * const spectre_v2_strings[] = { + [SPECTRE_V2_NONE] = "Vulnerable", +- [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline", +- [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline", +- [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS", ++ [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", ++ [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE", ++ [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS", ++ [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE", ++ [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines", + }; + + static const struct { +@@ -798,8 +833,12 @@ static const struct { + { "off", SPECTRE_V2_CMD_NONE, false }, + { "on", SPECTRE_V2_CMD_FORCE, true }, + { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, +- { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false }, ++ { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, ++ { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, + { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, ++ { "eibrs", SPECTRE_V2_CMD_EIBRS, false }, ++ { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, ++ { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, + { "auto", SPECTRE_V2_CMD_AUTO, false }, + }; + +@@ -836,17 +875,30 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) + } + + if ((cmd == SPECTRE_V2_CMD_RETPOLINE || +- cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || +- cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && ++ cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || ++ cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && + !IS_ENABLED(CONFIG_RETPOLINE)) { +- pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); ++ pr_err("%s selected but not compiled in. Switching to AUTO select\n", ++ mitigation_options[i].option); ++ return SPECTRE_V2_CMD_AUTO; ++ } ++ ++ if ((cmd == SPECTRE_V2_CMD_EIBRS || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && ++ !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { ++ pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n", ++ mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + +- if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD && +- boot_cpu_data.x86_vendor != X86_VENDOR_HYGON && +- boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { +- pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); ++ if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && ++ !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { ++ pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", ++ mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + +@@ -855,6 +907,16 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) + return cmd; + } + ++static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void) ++{ ++ if (!IS_ENABLED(CONFIG_RETPOLINE)) { ++ pr_err("Kernel not compiled with retpoline; no mitigation available!"); ++ return SPECTRE_V2_NONE; ++ } ++ ++ return SPECTRE_V2_RETPOLINE; ++} ++ + static void __init spectre_v2_select_mitigation(void) + { + enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); +@@ -875,49 +937,64 @@ static void __init spectre_v2_select_mitigation(void) + case SPECTRE_V2_CMD_FORCE: + case SPECTRE_V2_CMD_AUTO: + if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { +- mode = SPECTRE_V2_IBRS_ENHANCED; +- /* Force it so VMEXIT will restore correctly */ +- x86_spec_ctrl_base |= SPEC_CTRL_IBRS; +- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); +- goto specv2_set_mode; ++ mode = SPECTRE_V2_EIBRS; ++ break; + } +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_auto; ++ ++ mode = spectre_v2_select_retpoline(); + break; +- case SPECTRE_V2_CMD_RETPOLINE_AMD: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_amd; ++ ++ case SPECTRE_V2_CMD_RETPOLINE_LFENCE: ++ pr_err(SPECTRE_V2_LFENCE_MSG); ++ mode = SPECTRE_V2_LFENCE; + break; ++ + case SPECTRE_V2_CMD_RETPOLINE_GENERIC: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_generic; ++ mode = SPECTRE_V2_RETPOLINE; + break; ++ + case SPECTRE_V2_CMD_RETPOLINE: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_auto; ++ mode = spectre_v2_select_retpoline(); ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS: ++ mode = SPECTRE_V2_EIBRS; ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS_LFENCE: ++ mode = SPECTRE_V2_EIBRS_LFENCE; ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS_RETPOLINE: ++ mode = SPECTRE_V2_EIBRS_RETPOLINE; + break; + } +- pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); +- return; + +-retpoline_auto: +- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || +- boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { +- retpoline_amd: +- if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { +- pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); +- goto retpoline_generic; +- } +- mode = SPECTRE_V2_RETPOLINE_AMD; +- setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); +- setup_force_cpu_cap(X86_FEATURE_RETPOLINE); +- } else { +- retpoline_generic: +- mode = SPECTRE_V2_RETPOLINE_GENERIC; ++ if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) ++ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); ++ ++ if (spectre_v2_in_eibrs_mode(mode)) { ++ /* Force it so VMEXIT will restore correctly */ ++ x86_spec_ctrl_base |= SPEC_CTRL_IBRS; ++ wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); ++ } ++ ++ switch (mode) { ++ case SPECTRE_V2_NONE: ++ case SPECTRE_V2_EIBRS: ++ break; ++ ++ case SPECTRE_V2_LFENCE: ++ case SPECTRE_V2_EIBRS_LFENCE: ++ setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); ++ fallthrough; ++ ++ case SPECTRE_V2_RETPOLINE: ++ case SPECTRE_V2_EIBRS_RETPOLINE: + setup_force_cpu_cap(X86_FEATURE_RETPOLINE); ++ break; + } + +-specv2_set_mode: + spectre_v2_enabled = mode; + pr_info("%s\n", spectre_v2_strings[mode]); + +@@ -943,7 +1020,7 @@ specv2_set_mode: + * the CPU supports Enhanced IBRS, kernel might un-intentionally not + * enable IBRS around firmware calls. + */ +- if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) { ++ if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) { + setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); + pr_info("Enabling Restricted Speculation for firmware calls\n"); + } +@@ -1013,6 +1090,10 @@ void cpu_bugs_smt_update(void) + { + mutex_lock(&spec_ctrl_mutex); + ++ if (sched_smt_active() && unprivileged_ebpf_enabled() && ++ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) ++ pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); ++ + switch (spectre_v2_user_stibp) { + case SPECTRE_V2_USER_NONE: + break; +@@ -1267,7 +1348,6 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) + return 0; +- + /* + * With strict mode for both IBPB and STIBP, the instruction + * code paths avoid checking this task flag and instead, +@@ -1614,7 +1694,7 @@ static ssize_t tsx_async_abort_show_state(char *buf) + + static char *stibp_state(void) + { +- if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) ++ if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) + return ""; + + switch (spectre_v2_user_stibp) { +@@ -1644,6 +1724,27 @@ static char *ibpb_state(void) + return ""; + } + ++static ssize_t spectre_v2_show_state(char *buf) ++{ ++ if (spectre_v2_enabled == SPECTRE_V2_LFENCE) ++ return sprintf(buf, "Vulnerable: LFENCE\n"); ++ ++ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) ++ return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n"); ++ ++ if (sched_smt_active() && unprivileged_ebpf_enabled() && ++ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) ++ return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); ++ ++ return sprintf(buf, "%s%s%s%s%s%s\n", ++ spectre_v2_strings[spectre_v2_enabled], ++ ibpb_state(), ++ boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", ++ stibp_state(), ++ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", ++ spectre_v2_module_string()); ++} ++ + static ssize_t srbds_show_state(char *buf) + { + return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]); +@@ -1669,12 +1770,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr + return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); + + case X86_BUG_SPECTRE_V2: +- return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], +- ibpb_state(), +- boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", +- stibp_state(), +- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", +- spectre_v2_module_string()); ++ return spectre_v2_show_state(buf); + + case X86_BUG_SPEC_STORE_BYPASS: + return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index ce9a570f217ad..e5b92958c299e 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -2002,16 +2002,6 @@ bool acpi_ec_dispatch_gpe(void) + if (acpi_any_gpe_status_set(first_ec->gpe)) + return true; + +- /* +- * Cancel the SCI wakeup and process all pending events in case there +- * are any wakeup ones in there. +- * +- * Note that if any non-EC GPEs are active at this point, the SCI will +- * retrigger after the rearming in acpi_s2idle_wake(), so no events +- * should be missed by canceling the wakeup here. +- */ +- pm_system_cancel_wakeup(); +- + /* + * Dispatch the EC GPE in-band, but do not report wakeup in any case + * to allow the caller to process events properly after that. +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index cd590b4793e09..b0e23e3fe0d56 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -1003,13 +1003,19 @@ static bool acpi_s2idle_wake(void) + if (acpi_check_wakeup_handlers()) + return true; + +- /* +- * Check non-EC GPE wakeups and if there are none, cancel the +- * SCI-related wakeup and dispatch the EC GPE. +- */ ++ /* Check non-EC GPE wakeups and dispatch the EC GPE. */ + if (acpi_ec_dispatch_gpe()) + return true; + ++ /* ++ * Cancel the SCI wakeup and process all pending events in case ++ * there are any wakeup ones in there. ++ * ++ * Note that if any non-EC GPEs are active at this point, the ++ * SCI will retrigger after the rearming below, so no events ++ * should be missed by canceling the wakeup here. ++ */ ++ pm_system_cancel_wakeup(); + acpi_os_wait_events_complete(); + + /* +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 774af5ce70dad..3731066f2c1ca 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -1344,7 +1344,8 @@ free_shadow: + rinfo->ring_ref[i] = GRANT_INVALID_REF; + } + } +- free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE)); ++ free_pages_exact(rinfo->ring.sring, ++ info->nr_ring_pages * XEN_PAGE_SIZE); + rinfo->ring.sring = NULL; + + if (rinfo->irq) +@@ -1428,9 +1429,15 @@ static int blkif_get_final_status(enum blk_req_status s1, + return BLKIF_RSP_OKAY; + } + +-static bool blkif_completion(unsigned long *id, +- struct blkfront_ring_info *rinfo, +- struct blkif_response *bret) ++/* ++ * Return values: ++ * 1 response processed. ++ * 0 missing further responses. ++ * -1 error while processing. ++ */ ++static int blkif_completion(unsigned long *id, ++ struct blkfront_ring_info *rinfo, ++ struct blkif_response *bret) + { + int i = 0; + struct scatterlist *sg; +@@ -1453,7 +1460,7 @@ static bool blkif_completion(unsigned long *id, + + /* Wait the second response if not yet here. */ + if (s2->status < REQ_DONE) +- return false; ++ return 0; + + bret->status = blkif_get_final_status(s->status, + s2->status); +@@ -1504,42 +1511,43 @@ static bool blkif_completion(unsigned long *id, + } + /* Add the persistent grant into the list of free grants */ + for (i = 0; i < num_grant; i++) { +- if (gnttab_query_foreign_access(s->grants_used[i]->gref)) { ++ if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) { + /* + * If the grant is still mapped by the backend (the + * backend has chosen to make this grant persistent) + * we add it at the head of the list, so it will be + * reused first. + */ +- if (!info->feature_persistent) +- pr_alert_ratelimited("backed has not unmapped grant: %u\n", +- s->grants_used[i]->gref); ++ if (!info->feature_persistent) { ++ pr_alert("backed has not unmapped grant: %u\n", ++ s->grants_used[i]->gref); ++ return -1; ++ } + list_add(&s->grants_used[i]->node, &rinfo->grants); + rinfo->persistent_gnts_c++; + } else { + /* +- * If the grant is not mapped by the backend we end the +- * foreign access and add it to the tail of the list, +- * so it will not be picked again unless we run out of +- * persistent grants. ++ * If the grant is not mapped by the backend we add it ++ * to the tail of the list, so it will not be picked ++ * again unless we run out of persistent grants. + */ +- gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL); + s->grants_used[i]->gref = GRANT_INVALID_REF; + list_add_tail(&s->grants_used[i]->node, &rinfo->grants); + } + } + if (s->req.operation == BLKIF_OP_INDIRECT) { + for (i = 0; i < INDIRECT_GREFS(num_grant); i++) { +- if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) { +- if (!info->feature_persistent) +- pr_alert_ratelimited("backed has not unmapped grant: %u\n", +- s->indirect_grants[i]->gref); ++ if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) { ++ if (!info->feature_persistent) { ++ pr_alert("backed has not unmapped grant: %u\n", ++ s->indirect_grants[i]->gref); ++ return -1; ++ } + list_add(&s->indirect_grants[i]->node, &rinfo->grants); + rinfo->persistent_gnts_c++; + } else { + struct page *indirect_page; + +- gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL); + /* + * Add the used indirect page back to the list of + * available pages for indirect grefs. +@@ -1554,7 +1562,7 @@ static bool blkif_completion(unsigned long *id, + } + } + +- return true; ++ return 1; + } + + static irqreturn_t blkif_interrupt(int irq, void *dev_id) +@@ -1620,12 +1628,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) + } + + if (bret.operation != BLKIF_OP_DISCARD) { ++ int ret; ++ + /* + * We may need to wait for an extra response if the + * I/O request is split in 2 + */ +- if (!blkif_completion(&id, rinfo, &bret)) ++ ret = blkif_completion(&id, rinfo, &bret); ++ if (!ret) + continue; ++ if (unlikely(ret < 0)) ++ goto err; + } + + if (add_id_to_freelist(rinfo, id)) { +@@ -1731,8 +1744,7 @@ static int setup_blkring(struct xenbus_device *dev, + for (i = 0; i < info->nr_ring_pages; i++) + rinfo->ring_ref[i] = GRANT_INVALID_REF; + +- sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH, +- get_order(ring_size)); ++ sring = alloc_pages_exact(ring_size, GFP_NOIO); + if (!sring) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); + return -ENOMEM; +@@ -1742,7 +1754,7 @@ static int setup_blkring(struct xenbus_device *dev, + + err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref); + if (err < 0) { +- free_pages((unsigned long)sring, get_order(ring_size)); ++ free_pages_exact(sring, ring_size); + rinfo->ring.sring = NULL; + goto fail; + } +@@ -2720,11 +2732,10 @@ static void purge_persistent_grants(struct blkfront_info *info) + list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants, + node) { + if (gnt_list_entry->gref == GRANT_INVALID_REF || +- gnttab_query_foreign_access(gnt_list_entry->gref)) ++ !gnttab_try_end_foreign_access(gnt_list_entry->gref)) + continue; + + list_del(&gnt_list_entry->node); +- gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL); + rinfo->persistent_gnts_c--; + gnt_list_entry->gref = GRANT_INVALID_REF; + list_add_tail(&gnt_list_entry->node, &rinfo->grants); +diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c +index 84f4ff351c629..eb797081d1596 100644 +--- a/drivers/firmware/psci/psci.c ++++ b/drivers/firmware/psci/psci.c +@@ -57,6 +57,21 @@ struct psci_operations psci_ops = { + .smccc_version = SMCCC_VERSION_1_0, + }; + ++enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) ++{ ++ if (psci_ops.smccc_version < SMCCC_VERSION_1_1) ++ return SMCCC_CONDUIT_NONE; ++ ++ switch (psci_ops.conduit) { ++ case PSCI_CONDUIT_SMC: ++ return SMCCC_CONDUIT_SMC; ++ case PSCI_CONDUIT_HVC: ++ return SMCCC_CONDUIT_HVC; ++ default: ++ return SMCCC_CONDUIT_NONE; ++ } ++} ++ + typedef unsigned long (psci_fn)(unsigned long, unsigned long, + unsigned long, unsigned long); + static psci_fn *invoke_psci_fn; +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index d45d83968e769..94dd6edd18006 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -412,14 +412,12 @@ static bool xennet_tx_buf_gc(struct netfront_queue *queue) + queue->tx_link[id] = TX_LINK_NONE; + skb = queue->tx_skbs[id]; + queue->tx_skbs[id] = NULL; +- if (unlikely(gnttab_query_foreign_access( +- queue->grant_tx_ref[id]) != 0)) { ++ if (unlikely(!gnttab_end_foreign_access_ref( ++ queue->grant_tx_ref[id], GNTMAP_readonly))) { + dev_alert(dev, + "Grant still in use by backend domain\n"); + goto err; + } +- gnttab_end_foreign_access_ref( +- queue->grant_tx_ref[id], GNTMAP_readonly); + gnttab_release_grant_reference( + &queue->gref_tx_head, queue->grant_tx_ref[id]); + queue->grant_tx_ref[id] = GRANT_INVALID_REF; +@@ -861,7 +859,6 @@ static int xennet_get_responses(struct netfront_queue *queue, + int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD); + int slots = 1; + int err = 0; +- unsigned long ret; + + if (rx->flags & XEN_NETRXF_extra_info) { + err = xennet_get_extras(queue, extras, rp); +@@ -892,8 +889,13 @@ static int xennet_get_responses(struct netfront_queue *queue, + goto next; + } + +- ret = gnttab_end_foreign_access_ref(ref, 0); +- BUG_ON(!ret); ++ if (!gnttab_end_foreign_access_ref(ref, 0)) { ++ dev_alert(dev, ++ "Grant still in use by backend domain\n"); ++ queue->info->broken = true; ++ dev_alert(dev, "Disabled for further use\n"); ++ return -EINVAL; ++ } + + gnttab_release_grant_reference(&queue->gref_rx_head, ref); + +@@ -1097,6 +1099,10 @@ static int xennet_poll(struct napi_struct *napi, int budget) + err = xennet_get_responses(queue, &rinfo, rp, &tmpq); + + if (unlikely(err)) { ++ if (queue->info->broken) { ++ spin_unlock(&queue->rx_lock); ++ return 0; ++ } + err: + while ((skb = __skb_dequeue(&tmpq))) + __skb_queue_tail(&errq, skb); +@@ -1675,7 +1681,7 @@ static int setup_netfront(struct xenbus_device *dev, + struct netfront_queue *queue, unsigned int feature_split_evtchn) + { + struct xen_netif_tx_sring *txs; +- struct xen_netif_rx_sring *rxs; ++ struct xen_netif_rx_sring *rxs = NULL; + grant_ref_t gref; + int err; + +@@ -1695,21 +1701,21 @@ static int setup_netfront(struct xenbus_device *dev, + + err = xenbus_grant_ring(dev, txs, 1, &gref); + if (err < 0) +- goto grant_tx_ring_fail; ++ goto fail; + queue->tx_ring_ref = gref; + + rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); + if (!rxs) { + err = -ENOMEM; + xenbus_dev_fatal(dev, err, "allocating rx ring page"); +- goto alloc_rx_ring_fail; ++ goto fail; + } + SHARED_RING_INIT(rxs); + FRONT_RING_INIT(&queue->rx, rxs, XEN_PAGE_SIZE); + + err = xenbus_grant_ring(dev, rxs, 1, &gref); + if (err < 0) +- goto grant_rx_ring_fail; ++ goto fail; + queue->rx_ring_ref = gref; + + if (feature_split_evtchn) +@@ -1722,22 +1728,28 @@ static int setup_netfront(struct xenbus_device *dev, + err = setup_netfront_single(queue); + + if (err) +- goto alloc_evtchn_fail; ++ goto fail; + + return 0; + + /* If we fail to setup netfront, it is safe to just revoke access to + * granted pages because backend is not accessing it at this point. + */ +-alloc_evtchn_fail: +- gnttab_end_foreign_access_ref(queue->rx_ring_ref, 0); +-grant_rx_ring_fail: +- free_page((unsigned long)rxs); +-alloc_rx_ring_fail: +- gnttab_end_foreign_access_ref(queue->tx_ring_ref, 0); +-grant_tx_ring_fail: +- free_page((unsigned long)txs); +-fail: ++ fail: ++ if (queue->rx_ring_ref != GRANT_INVALID_REF) { ++ gnttab_end_foreign_access(queue->rx_ring_ref, 0, ++ (unsigned long)rxs); ++ queue->rx_ring_ref = GRANT_INVALID_REF; ++ } else { ++ free_page((unsigned long)rxs); ++ } ++ if (queue->tx_ring_ref != GRANT_INVALID_REF) { ++ gnttab_end_foreign_access(queue->tx_ring_ref, 0, ++ (unsigned long)txs); ++ queue->tx_ring_ref = GRANT_INVALID_REF; ++ } else { ++ free_page((unsigned long)txs); ++ } + return err; + } + +diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c +index f0068e96a177f..39e39869a1ad9 100644 +--- a/drivers/scsi/xen-scsifront.c ++++ b/drivers/scsi/xen-scsifront.c +@@ -233,12 +233,11 @@ static void scsifront_gnttab_done(struct vscsifrnt_info *info, + return; + + for (i = 0; i < shadow->nr_grants; i++) { +- if (unlikely(gnttab_query_foreign_access(shadow->gref[i]))) { ++ if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) { + shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME + "grant still in use by backend\n"); + BUG(); + } +- gnttab_end_foreign_access(shadow->gref[i], 0, 0UL); + } + + kfree(shadow->sg); +diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c +index 3fa40c723e8e9..edb0acd0b8323 100644 +--- a/drivers/xen/gntalloc.c ++++ b/drivers/xen/gntalloc.c +@@ -169,20 +169,14 @@ undo: + __del_gref(gref); + } + +- /* It's possible for the target domain to map the just-allocated grant +- * references by blindly guessing their IDs; if this is done, then +- * __del_gref will leave them in the queue_gref list. They need to be +- * added to the global list so that we can free them when they are no +- * longer referenced. +- */ +- if (unlikely(!list_empty(&queue_gref))) +- list_splice_tail(&queue_gref, &gref_list); + mutex_unlock(&gref_mutex); + return rc; + } + + static void __del_gref(struct gntalloc_gref *gref) + { ++ unsigned long addr; ++ + if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { + uint8_t *tmp = kmap(gref->page); + tmp[gref->notify.pgoff] = 0; +@@ -196,21 +190,16 @@ static void __del_gref(struct gntalloc_gref *gref) + gref->notify.flags = 0; + + if (gref->gref_id) { +- if (gnttab_query_foreign_access(gref->gref_id)) +- return; +- +- if (!gnttab_end_foreign_access_ref(gref->gref_id, 0)) +- return; +- +- gnttab_free_grant_reference(gref->gref_id); ++ if (gref->page) { ++ addr = (unsigned long)page_to_virt(gref->page); ++ gnttab_end_foreign_access(gref->gref_id, 0, addr); ++ } else ++ gnttab_free_grant_reference(gref->gref_id); + } + + gref_size--; + list_del(&gref->next_gref); + +- if (gref->page) +- __free_page(gref->page); +- + kfree(gref); + } + +diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c +index 49b381e104efa..c75dc17d1a617 100644 +--- a/drivers/xen/grant-table.c ++++ b/drivers/xen/grant-table.c +@@ -135,12 +135,9 @@ struct gnttab_ops { + */ + unsigned long (*end_foreign_transfer_ref)(grant_ref_t ref); + /* +- * Query the status of a grant entry. Ref parameter is reference of +- * queried grant entry, return value is the status of queried entry. +- * Detailed status(writing/reading) can be gotten from the return value +- * by bit operations. ++ * Read the frame number related to a given grant reference. + */ +- int (*query_foreign_access)(grant_ref_t ref); ++ unsigned long (*read_frame)(grant_ref_t ref); + }; + + struct unmap_refs_callback_data { +@@ -285,22 +282,6 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, + } + EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); + +-static int gnttab_query_foreign_access_v1(grant_ref_t ref) +-{ +- return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); +-} +- +-static int gnttab_query_foreign_access_v2(grant_ref_t ref) +-{ +- return grstatus[ref] & (GTF_reading|GTF_writing); +-} +- +-int gnttab_query_foreign_access(grant_ref_t ref) +-{ +- return gnttab_interface->query_foreign_access(ref); +-} +-EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); +- + static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) + { + u16 flags, nflags; +@@ -354,6 +335,16 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) + } + EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); + ++static unsigned long gnttab_read_frame_v1(grant_ref_t ref) ++{ ++ return gnttab_shared.v1[ref].frame; ++} ++ ++static unsigned long gnttab_read_frame_v2(grant_ref_t ref) ++{ ++ return gnttab_shared.v2[ref].full_page.frame; ++} ++ + struct deferred_entry { + struct list_head list; + grant_ref_t ref; +@@ -383,12 +374,9 @@ static void gnttab_handle_deferred(struct timer_list *unused) + spin_unlock_irqrestore(&gnttab_list_lock, flags); + if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) { + put_free_entry(entry->ref); +- if (entry->page) { +- pr_debug("freeing g.e. %#x (pfn %#lx)\n", +- entry->ref, page_to_pfn(entry->page)); +- put_page(entry->page); +- } else +- pr_info("freeing g.e. %#x\n", entry->ref); ++ pr_debug("freeing g.e. %#x (pfn %#lx)\n", ++ entry->ref, page_to_pfn(entry->page)); ++ put_page(entry->page); + kfree(entry); + entry = NULL; + } else { +@@ -413,9 +401,18 @@ static void gnttab_handle_deferred(struct timer_list *unused) + static void gnttab_add_deferred(grant_ref_t ref, bool readonly, + struct page *page) + { +- struct deferred_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC); ++ struct deferred_entry *entry; ++ gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; + const char *what = KERN_WARNING "leaking"; + ++ entry = kmalloc(sizeof(*entry), gfp); ++ if (!page) { ++ unsigned long gfn = gnttab_interface->read_frame(ref); ++ ++ page = pfn_to_page(gfn_to_pfn(gfn)); ++ get_page(page); ++ } ++ + if (entry) { + unsigned long flags; + +@@ -436,11 +433,21 @@ static void gnttab_add_deferred(grant_ref_t ref, bool readonly, + what, ref, page ? page_to_pfn(page) : -1); + } + ++int gnttab_try_end_foreign_access(grant_ref_t ref) ++{ ++ int ret = _gnttab_end_foreign_access_ref(ref, 0); ++ ++ if (ret) ++ put_free_entry(ref); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(gnttab_try_end_foreign_access); ++ + void gnttab_end_foreign_access(grant_ref_t ref, int readonly, + unsigned long page) + { +- if (gnttab_end_foreign_access_ref(ref, readonly)) { +- put_free_entry(ref); ++ if (gnttab_try_end_foreign_access(ref)) { + if (page != 0) + put_page(virt_to_page(page)); + } else +@@ -1297,7 +1304,7 @@ static const struct gnttab_ops gnttab_v1_ops = { + .update_entry = gnttab_update_entry_v1, + .end_foreign_access_ref = gnttab_end_foreign_access_ref_v1, + .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v1, +- .query_foreign_access = gnttab_query_foreign_access_v1, ++ .read_frame = gnttab_read_frame_v1, + }; + + static const struct gnttab_ops gnttab_v2_ops = { +@@ -1309,7 +1316,7 @@ static const struct gnttab_ops gnttab_v2_ops = { + .update_entry = gnttab_update_entry_v2, + .end_foreign_access_ref = gnttab_end_foreign_access_ref_v2, + .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v2, +- .query_foreign_access = gnttab_query_foreign_access_v2, ++ .read_frame = gnttab_read_frame_v2, + }; + + static bool gnttab_need_v2(void) +diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c +index 57592a6b5c9e3..91e52e05555eb 100644 +--- a/drivers/xen/pvcalls-front.c ++++ b/drivers/xen/pvcalls-front.c +@@ -337,8 +337,8 @@ static void free_active_ring(struct sock_mapping *map) + if (!map->active.ring) + return; + +- free_pages((unsigned long)map->active.data.in, +- map->active.ring->ring_order); ++ free_pages_exact(map->active.data.in, ++ PAGE_SIZE << map->active.ring->ring_order); + free_page((unsigned long)map->active.ring); + } + +@@ -352,8 +352,8 @@ static int alloc_active_ring(struct sock_mapping *map) + goto out; + + map->active.ring->ring_order = PVCALLS_RING_ORDER; +- bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, +- PVCALLS_RING_ORDER); ++ bytes = alloc_pages_exact(PAGE_SIZE << PVCALLS_RING_ORDER, ++ GFP_KERNEL | __GFP_ZERO); + if (!bytes) + goto out; + +diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c +index 81eddb8529ffc..8739dd0ee870d 100644 +--- a/drivers/xen/xenbus/xenbus_client.c ++++ b/drivers/xen/xenbus/xenbus_client.c +@@ -366,7 +366,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, + unsigned int nr_pages, grant_ref_t *grefs) + { + int err; +- int i, j; ++ unsigned int i; ++ grant_ref_t gref_head; ++ ++ err = gnttab_alloc_grant_references(nr_pages, &gref_head); ++ if (err) { ++ xenbus_dev_fatal(dev, err, "granting access to ring page"); ++ return err; ++ } + + for (i = 0; i < nr_pages; i++) { + unsigned long gfn; +@@ -376,23 +383,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, + else + gfn = virt_to_gfn(vaddr); + +- err = gnttab_grant_foreign_access(dev->otherend_id, gfn, 0); +- if (err < 0) { +- xenbus_dev_fatal(dev, err, +- "granting access to ring page"); +- goto fail; +- } +- grefs[i] = err; ++ grefs[i] = gnttab_claim_grant_reference(&gref_head); ++ gnttab_grant_foreign_access_ref(grefs[i], dev->otherend_id, ++ gfn, 0); + + vaddr = vaddr + XEN_PAGE_SIZE; + } + + return 0; +- +-fail: +- for (j = 0; j < i; j++) +- gnttab_end_foreign_access_ref(grefs[j], 0); +- return err; + } + EXPORT_SYMBOL_GPL(xenbus_grant_ring); + +diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h +index 157e4a6a83f6d..4e97ba64dbb42 100644 +--- a/include/linux/arm-smccc.h ++++ b/include/linux/arm-smccc.h +@@ -82,6 +82,22 @@ + + #include + #include ++ ++enum arm_smccc_conduit { ++ SMCCC_CONDUIT_NONE, ++ SMCCC_CONDUIT_SMC, ++ SMCCC_CONDUIT_HVC, ++}; ++ ++/** ++ * arm_smccc_1_1_get_conduit() ++ * ++ * Returns the conduit to be used for SMCCCv1.1 or later. ++ * ++ * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE. ++ */ ++enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void); ++ + /** + * struct arm_smccc_res - Result from SMC/HVC call + * @a0-a3 result values from registers 0 to 3 +@@ -304,5 +320,63 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, + #define SMCCC_RET_NOT_SUPPORTED -1 + #define SMCCC_RET_NOT_REQUIRED -2 + ++/* ++ * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED. ++ * Used when the SMCCC conduit is not defined. The empty asm statement ++ * avoids compiler warnings about unused variables. ++ */ ++#define __fail_smccc_1_1(...) \ ++ do { \ ++ __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ ++ asm ("" __constraints(__count_args(__VA_ARGS__))); \ ++ if (___res) \ ++ ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \ ++ } while (0) ++ ++/* ++ * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call ++ * ++ * This is a variadic macro taking one to eight source arguments, and ++ * an optional return structure. ++ * ++ * @a0-a7: arguments passed in registers 0 to 7 ++ * @res: result values from registers 0 to 3 ++ * ++ * This macro will make either an HVC call or an SMC call depending on the ++ * current SMCCC conduit. If no valid conduit is available then -1 ++ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied). ++ * ++ * The return value also provides the conduit that was used. ++ */ ++#define arm_smccc_1_1_invoke(...) ({ \ ++ int method = arm_smccc_1_1_get_conduit(); \ ++ switch (method) { \ ++ case SMCCC_CONDUIT_HVC: \ ++ arm_smccc_1_1_hvc(__VA_ARGS__); \ ++ break; \ ++ case SMCCC_CONDUIT_SMC: \ ++ arm_smccc_1_1_smc(__VA_ARGS__); \ ++ break; \ ++ default: \ ++ __fail_smccc_1_1(__VA_ARGS__); \ ++ method = SMCCC_CONDUIT_NONE; \ ++ break; \ ++ } \ ++ method; \ ++ }) ++ ++/* Paravirtualised time calls (defined by ARM DEN0057A) */ ++#define ARM_SMCCC_HV_PV_TIME_FEATURES \ ++ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ++ ARM_SMCCC_SMC_64, \ ++ ARM_SMCCC_OWNER_STANDARD_HYP, \ ++ 0x20) ++ ++#define ARM_SMCCC_HV_PV_TIME_ST \ ++ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ++ ARM_SMCCC_SMC_64, \ ++ ARM_SMCCC_OWNER_STANDARD_HYP, \ ++ 0x21) ++ + #endif /*__ASSEMBLY__*/ + #endif /*__LINUX_ARM_SMCCC_H*/ +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 66590ae89c97c..a73ca7c9c7d0e 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -751,6 +751,12 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, + int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, + const union bpf_attr *kattr, + union bpf_attr __user *uattr); ++ ++static inline bool unprivileged_ebpf_enabled(void) ++{ ++ return !sysctl_unprivileged_bpf_disabled; ++} ++ + #else /* !CONFIG_BPF_SYSCALL */ + static inline struct bpf_prog *bpf_prog_get(u32 ufd) + { +@@ -881,6 +887,12 @@ static inline int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, + { + return -ENOTSUPP; + } ++ ++static inline bool unprivileged_ebpf_enabled(void) ++{ ++ return false; ++} ++ + #endif /* CONFIG_BPF_SYSCALL */ + + static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, +diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h +index a9978350b45b0..a58a89cc0e97d 100644 +--- a/include/xen/grant_table.h ++++ b/include/xen/grant_table.h +@@ -97,17 +97,32 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); + * access has been ended, free the given page too. Access will be ended + * immediately iff the grant entry is not in use, otherwise it will happen + * some time later. page may be 0, in which case no freeing will occur. ++ * Note that the granted page might still be accessed (read or write) by the ++ * other side after gnttab_end_foreign_access() returns, so even if page was ++ * specified as 0 it is not allowed to just reuse the page for other ++ * purposes immediately. gnttab_end_foreign_access() will take an additional ++ * reference to the granted page in this case, which is dropped only after ++ * the grant is no longer in use. ++ * This requires that multi page allocations for areas subject to ++ * gnttab_end_foreign_access() are done via alloc_pages_exact() (and freeing ++ * via free_pages_exact()) in order to avoid high order pages. + */ + void gnttab_end_foreign_access(grant_ref_t ref, int readonly, + unsigned long page); + ++/* ++ * End access through the given grant reference, iff the grant entry is ++ * no longer in use. In case of success ending foreign access, the ++ * grant reference is deallocated. ++ * Return 1 if the grant entry was freed, 0 if it is still in use. ++ */ ++int gnttab_try_end_foreign_access(grant_ref_t ref); ++ + int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn); + + unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref); + unsigned long gnttab_end_foreign_transfer(grant_ref_t ref); + +-int gnttab_query_foreign_access(grant_ref_t ref); +- + /* + * operations on reserved batches of grant references + */ +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 8494d5a706bb5..0457d36540e38 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -251,6 +251,11 @@ static int sysrq_sysctl_handler(struct ctl_table *table, int write, + #endif + + #ifdef CONFIG_BPF_SYSCALL ++ ++void __weak unpriv_ebpf_notify(int new_state) ++{ ++} ++ + static int bpf_unpriv_handler(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +@@ -268,6 +273,9 @@ static int bpf_unpriv_handler(struct ctl_table *table, int write, + return -EPERM; + *(int *)table->data = unpriv_enable; + } ++ ++ unpriv_ebpf_notify(unpriv_enable); ++ + return ret; + } + #endif +diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c +index 44e6c74ed4288..2779ec1053a02 100644 +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -301,9 +301,9 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv) + ref = priv->rings[i].intf->ref[j]; + gnttab_end_foreign_access(ref, 0, 0); + } +- free_pages((unsigned long)priv->rings[i].data.in, +- XEN_9PFS_RING_ORDER - +- (PAGE_SHIFT - XEN_PAGE_SHIFT)); ++ free_pages_exact(priv->rings[i].data.in, ++ 1UL << (XEN_9PFS_RING_ORDER + ++ XEN_PAGE_SHIFT)); + } + gnttab_end_foreign_access(priv->rings[i].ref, 0, 0); + free_page((unsigned long)priv->rings[i].intf); +@@ -341,8 +341,8 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev, + if (ret < 0) + goto out; + ring->ref = ret; +- bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, +- XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT)); ++ bytes = alloc_pages_exact(1UL << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT), ++ GFP_KERNEL | __GFP_ZERO); + if (!bytes) { + ret = -ENOMEM; + goto out; +@@ -373,9 +373,7 @@ out: + if (bytes) { + for (i--; i >= 0; i--) + gnttab_end_foreign_access(ring->intf->ref[i], 0, 0); +- free_pages((unsigned long)bytes, +- XEN_9PFS_RING_ORDER - +- (PAGE_SHIFT - XEN_PAGE_SHIFT)); ++ free_pages_exact(bytes, 1UL << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT)); + } + gnttab_end_foreign_access(ring->ref, 0, 0); + free_page((unsigned long)ring->intf); +diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h +index 0652d3eed9bda..4133c721af6ed 100644 +--- a/tools/arch/x86/include/asm/cpufeatures.h ++++ b/tools/arch/x86/include/asm/cpufeatures.h +@@ -202,7 +202,7 @@ + #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ + #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +-#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ ++#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCEs for Spectre variant 2 */ + #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ + #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ + #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */