From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
torvalds@linux-foundation.org, stable@vger.kernel.org
Cc: lwn@lwn.net, jslaby@suse.cz,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: Linux 6.1.163
Date: Wed, 11 Feb 2026 15:21:27 +0100 [thread overview]
Message-ID: <2026021126-overkill-audacity-ad7f@gregkh> (raw)
In-Reply-To: <2026021126-squeezing-primate-f2f0@gregkh>
diff --git a/Makefile b/Makefile
index 7ae0fee5b79d..f52d3b8656d4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 1
-SUBLEVEL = 162
+SUBLEVEL = 163
EXTRAVERSION =
NAME = Curry Ramen
diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index 6c607c68f3ad..c35250c4991b 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -42,7 +42,10 @@ static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n)
extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi);
static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n)
{
- return __memset64(p, v, n * 8, v >> 32);
+ if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
+ return __memset64(p, v, n * 8, v >> 32);
+ else
+ return __memset64(p, v >> 32, n * 8, v);
}
/*
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index 12c726482d15..cad1e08ca3fb 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -361,10 +361,15 @@ asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr)
asmlinkage void noinstr do_ade(struct pt_regs *regs)
{
irqentry_state_t state = irqentry_enter(regs);
+ unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat);
+
+ if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs))
+ goto out;
die_if_kernel("Kernel ade access", regs);
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)regs->csr_badvaddr);
+out:
irqentry_exit(regs, state);
}
diff --git a/arch/loongarch/mm/cache.c b/arch/loongarch/mm/cache.c
index 72685a48eaf0..09a9209f2139 100644
--- a/arch/loongarch/mm/cache.c
+++ b/arch/loongarch/mm/cache.c
@@ -161,8 +161,8 @@ void cpu_cache_init(void)
static const pgprot_t protection_map[16] = {
[VM_NONE] = __pgprot(_CACHE_CC | _PAGE_USER |
- _PAGE_PROTNONE | _PAGE_NO_EXEC |
- _PAGE_NO_READ),
+ _PAGE_NO_EXEC | _PAGE_NO_READ |
+ (_PAGE_PROTNONE ? : _PAGE_PRESENT)),
[VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID |
_PAGE_USER | _PAGE_PRESENT |
_PAGE_NO_EXEC),
@@ -181,8 +181,8 @@ static const pgprot_t protection_map[16] = {
[VM_EXEC | VM_WRITE | VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID |
_PAGE_USER | _PAGE_PRESENT),
[VM_SHARED] = __pgprot(_CACHE_CC | _PAGE_USER |
- _PAGE_PROTNONE | _PAGE_NO_EXEC |
- _PAGE_NO_READ),
+ _PAGE_NO_EXEC | _PAGE_NO_READ |
+ (_PAGE_PROTNONE ? : _PAGE_PRESENT)),
[VM_SHARED | VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID |
_PAGE_USER | _PAGE_PRESENT |
_PAGE_NO_EXEC),
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index f6fbe7042f1c..fc65afc132ef 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -22,11 +22,6 @@ static inline void flush_dcache_page(struct page *page)
}
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
-/*
- * RISC-V doesn't have an instruction to flush parts of the instruction cache,
- * so instead we just flush the whole thing.
- */
-#define flush_icache_range(start, end) flush_icache_all()
#define flush_icache_user_page(vma, pg, addr, len) \
flush_icache_mm(vma->vm_mm, 0)
@@ -42,6 +37,16 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
#endif /* CONFIG_SMP */
+/*
+ * RISC-V doesn't have an instruction to flush parts of the instruction cache,
+ * so instead we just flush the whole thing.
+ */
+#define flush_icache_range flush_icache_range
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+ flush_icache_all();
+}
+
extern unsigned int riscv_cbom_block_size;
void riscv_init_cbom_blocksize(void);
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c
index 194f166b2cc4..0d18ee53fd64 100644
--- a/arch/riscv/kernel/probes/uprobes.c
+++ b/arch/riscv/kernel/probes/uprobes.c
@@ -161,6 +161,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
/* Initialize the slot */
void *kaddr = kmap_atomic(page);
void *dst = kaddr + (vaddr & ~PAGE_MASK);
+ unsigned long start = (unsigned long)dst;
memcpy(dst, src, len);
@@ -170,13 +171,6 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
*(uprobe_opcode_t *)dst = __BUG_INSN_32;
}
+ flush_icache_range(start, start + len);
kunmap_atomic(kaddr);
-
- /*
- * We probably need flush_icache_user_page() but it needs vma.
- * This should work on most of architectures by default. If
- * architecture needs to do something different it can define
- * its own version of the function.
- */
- flush_dcache_page(page);
}
diff --git a/arch/x86/include/asm/kfence.h b/arch/x86/include/asm/kfence.h
index acf9ffa1a171..dfd5c74ba41a 100644
--- a/arch/x86/include/asm/kfence.h
+++ b/arch/x86/include/asm/kfence.h
@@ -42,7 +42,7 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
unsigned int level;
pte_t *pte = lookup_address(addr, &level);
- pteval_t val;
+ pteval_t val, new;
if (WARN_ON(!pte || level != PG_LEVEL_4K))
return false;
@@ -57,11 +57,12 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
return true;
/*
- * Otherwise, invert the entire PTE. This avoids writing out an
+ * Otherwise, flip the Present bit, taking care to avoid writing an
* L1TF-vulnerable PTE (not present, without the high address bits
* set).
*/
- set_pte(pte, __pte(~val));
+ new = val ^ _PAGE_PRESENT;
+ set_pte(pte, __pte(flip_protnone_guard(val, new, PTE_PFN_MASK)));
/*
* If the page was protected (non-present) and we're making it
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
index c202e2527d05..8e2478efd669 100644
--- a/block/bfq-cgroup.c
+++ b/block/bfq-cgroup.c
@@ -382,7 +382,7 @@ static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from)
blkg_rwstat_add_aux(&to->merged, &from->merged);
blkg_rwstat_add_aux(&to->service_time, &from->service_time);
blkg_rwstat_add_aux(&to->wait_time, &from->wait_time);
- bfq_stat_add_aux(&from->time, &from->time);
+ bfq_stat_add_aux(&to->time, &from->time);
bfq_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum);
bfq_stat_add_aux(&to->avg_queue_size_samples,
&from->avg_queue_size_samples);
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index a109dec62a99..07ff4c1477f8 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3642,8 +3642,9 @@ static void binder_transaction(struct binder_proc *proc,
return;
err_dead_proc_or_thread:
- binder_txn_error("%d:%d dead process or thread\n",
- thread->pid, proc->pid);
+ binder_txn_error("%d:%d %s process or thread\n",
+ proc->pid, thread->pid,
+ return_error == BR_FROZEN_REPLY ? "frozen" : "dead");
return_error_line = __LINE__;
binder_dequeue_work(proc, tcomplete);
err_translate_failed:
diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c
index 09b2ce7e4c34..9d7f0b1969bc 100644
--- a/drivers/android/binderfs.c
+++ b/drivers/android/binderfs.c
@@ -131,8 +131,8 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
mutex_lock(&binderfs_minors_mutex);
if (++info->device_count <= info->mount_opts.max)
minor = ida_alloc_max(&binderfs_minors,
- use_reserve ? BINDERFS_MAX_MINOR :
- BINDERFS_MAX_MINOR_CAPPED,
+ use_reserve ? BINDERFS_MAX_MINOR - 1 :
+ BINDERFS_MAX_MINOR_CAPPED - 1,
GFP_KERNEL);
else
minor = -ENOSPC;
@@ -422,8 +422,8 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
/* Reserve a new minor number for the new device. */
mutex_lock(&binderfs_minors_mutex);
minor = ida_alloc_max(&binderfs_minors,
- use_reserve ? BINDERFS_MAX_MINOR :
- BINDERFS_MAX_MINOR_CAPPED,
+ use_reserve ? BINDERFS_MAX_MINOR - 1 :
+ BINDERFS_MAX_MINOR_CAPPED - 1,
GFP_KERNEL);
mutex_unlock(&binderfs_minors_mutex);
if (minor < 0) {
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4f8efc829a59..f18dcdab95bb 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3496,11 +3496,29 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req)
rbd_assert(!need_exclusive_lock(img_req) ||
__rbd_is_lock_owner(rbd_dev));
- if (rbd_img_is_write(img_req)) {
- rbd_assert(!img_req->snapc);
+ if (test_bit(IMG_REQ_CHILD, &img_req->flags)) {
+ rbd_assert(!rbd_img_is_write(img_req));
+ } else {
+ struct request *rq = blk_mq_rq_from_pdu(img_req);
+ u64 off = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;
+ u64 len = blk_rq_bytes(rq);
+ u64 mapping_size;
+
down_read(&rbd_dev->header_rwsem);
- img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc);
+ mapping_size = rbd_dev->mapping.size;
+ if (rbd_img_is_write(img_req)) {
+ rbd_assert(!img_req->snapc);
+ img_req->snapc =
+ ceph_get_snap_context(rbd_dev->header.snapc);
+ }
up_read(&rbd_dev->header_rwsem);
+
+ if (unlikely(off + len > mapping_size)) {
+ rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)",
+ off, len, mapping_size);
+ img_req->pending.result = -EIO;
+ return;
+ }
}
for_each_obj_request(img_req, obj_req) {
@@ -4726,7 +4744,6 @@ static void rbd_queue_workfn(struct work_struct *work)
struct request *rq = blk_mq_rq_from_pdu(img_request);
u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;
u64 length = blk_rq_bytes(rq);
- u64 mapping_size;
int result;
/* Ignore/skip any zero-length requests */
@@ -4739,17 +4756,9 @@ static void rbd_queue_workfn(struct work_struct *work)
blk_mq_start_request(rq);
down_read(&rbd_dev->header_rwsem);
- mapping_size = rbd_dev->mapping.size;
rbd_img_capture_header(img_request);
up_read(&rbd_dev->header_rwsem);
- if (offset + length > mapping_size) {
- rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset,
- length, mapping_size);
- result = -EIO;
- goto err_img_request;
- }
-
dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev,
img_request, obj_op_name(op_type), offset, length);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 6104353e4c2f..055e05b2cb22 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2067,9 +2067,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
return -ENODEV;
}
- if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev))
- amdgpu_aspm = 0;
-
if (amdgpu_virtual_display ||
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
supports_atomic = true;
diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c b/drivers/gpu/drm/mgag200/mgag200_bmc.c
index 2ba2e3c5086a..852a82f6309b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_bmc.c
+++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/delay.h>
+#include <linux/iopoll.h>
#include "mgag200_drv.h"
void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
{
u8 tmp;
- int iter_max;
+ int ret;
/*
* 1 - The first step is to inform the BMC of an upcoming mode
@@ -37,30 +38,22 @@ void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
/*
* 3a- The third step is to verify if there is an active scan.
- * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>).
+ * We are waiting for a 0 on remhsyncsts (<XSPAREREG<0>).
*/
- iter_max = 300;
- while (!(tmp & 0x1) && iter_max) {
- WREG8(DAC_INDEX, MGA1064_SPAREREG);
- tmp = RREG8(DAC_DATA);
- udelay(1000);
- iter_max--;
- }
+ ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1),
+ 1000, 300000, false,
+ MGA1064_SPAREREG);
+ if (ret == -ETIMEDOUT)
+ return;
/*
- * 3b- This step occurs only if the remove is actually
+ * 3b- This step occurs only if the remote BMC is actually
* scanning. We are waiting for the end of the frame which is
* a 1 on remvsyncsts (XSPAREREG<1>)
*/
- if (iter_max) {
- iter_max = 300;
- while ((tmp & 0x2) && iter_max) {
- WREG8(DAC_INDEX, MGA1064_SPAREREG);
- tmp = RREG8(DAC_DATA);
- udelay(1000);
- iter_max--;
- }
- }
+ (void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2),
+ 1000, 300000, false,
+ MGA1064_SPAREREG);
}
void mgag200_bmc_enable_vidrst(struct mga_device *mdev)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index aebd09e2d408..c84c3d086534 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -116,6 +116,12 @@
#define DAC_INDEX 0x3c00
#define DAC_DATA 0x3c0a
+#define RREG_DAC(reg) \
+ ({ \
+ WREG8(DAC_INDEX, reg); \
+ RREG8(DAC_DATA); \
+ }) \
+
#define WREG_DAC(reg, v) \
do { \
WREG8(DAC_INDEX, reg); \
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 524edddd8489..bac298a4930a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -299,6 +299,7 @@
#define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421
#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA 0xb824
#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2 0xb82c
+#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA3 0xb882
#define USB_VENDOR_ID_CHUNGHWAT 0x2247
#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
@@ -417,6 +418,9 @@
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002
+#define USB_VENDOR_ID_EDIFIER 0x2d99
+#define USB_DEVICE_ID_EDIFIER_QR30 0xa101 /* EDIFIER Hal0 2.0 SE */
+
#define USB_VENDOR_ID_ELAN 0x04f3
#define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401
#define USB_DEVICE_ID_HP_X2 0x074d
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index b9e67b408a4b..6d9a85c5fc40 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -379,6 +379,7 @@ static const struct mt_class mt_classes[] = {
{ .name = MT_CLS_VTL,
.quirks = MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_CONTACT_CNT_ACCURATE |
+ MT_QUIRK_STICKY_FINGERS |
MT_QUIRK_FORCE_GET_FEATURE,
},
{ .name = MT_CLS_GOOGLE,
diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index 2228f6e4ba23..38d5171dd25b 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -487,11 +487,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
if (IS_ERR(gamepad))
return ERR_CAST(gamepad);
+ /* Set initial resting state for joysticks to 128 (center) */
input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
+ gamepad->absinfo[ABS_X].value = 128;
input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0);
+ gamepad->absinfo[ABS_Y].value = 128;
input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0);
input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0);
+ gamepad->absinfo[ABS_RX].value = 128;
input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0);
+ gamepad->absinfo[ABS_RY].value = 128;
input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0);
input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0);
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index b6bec3614cfe..457a52cfa17c 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -81,6 +81,7 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_EDIFIER, USB_DEVICE_ID_EDIFIER_QR30), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II), HID_QUIRK_MULTI_INPUT },
@@ -751,6 +752,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI4713) },
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 8a7ac016b1ab..624d542df3a7 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -257,6 +257,7 @@ static int i2c_hid_get_report(struct i2c_hid *ihid,
* In addition to report data device will supply data length
* in the first 2 bytes of the response, so adjust .
*/
+ recv_len = min(recv_len, ihid->bufsize - sizeof(__le16));
error = i2c_hid_xfer(ihid, ihid->cmdbuf, length,
ihid->rawbuf, recv_len + sizeof(__le16));
if (error) {
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
index e3d70c5460e9..a0c1dc094149 100644
--- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c
+++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
@@ -496,6 +496,7 @@ static int ishtp_enum_enum_devices(struct ishtp_cl *hid_ishtp_cl)
int rv;
/* Send HOSTIF_DM_ENUM_DEVICES */
+ client_data->enum_devices_done = false;
memset(&msg, 0, sizeof(struct hostif_msg));
msg.hdr.command = HOSTIF_DM_ENUM_DEVICES;
rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *)&msg,
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index d4296681cf72..67e3215a332e 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -240,9 +240,17 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
{
struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
+ struct ishtp_fw_client *client = device->fw_client;
+ const struct ishtp_device_id *id;
- return(device->fw_client ? guid_equal(&driver->id[0].guid,
- &device->fw_client->props.protocol_name) : 0);
+ if (client) {
+ for (id = driver->id; !guid_is_null(&id->guid); id++) {
+ if (guid_equal(&id->guid, &client->props.protocol_name))
+ return 1;
+ }
+ }
+
+ return 0;
}
/**
diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c
index 483f79b39429..755926fa0bf7 100644
--- a/drivers/hwmon/occ/common.c
+++ b/drivers/hwmon/occ/common.c
@@ -749,6 +749,7 @@ static ssize_t occ_show_extended(struct device *dev,
* are dynamically allocated, we cannot use the existing kernel macros which
* stringify the name argument.
*/
+__printf(7, 8)
static void occ_init_attribute(struct occ_attribute *attr, int mode,
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf),
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ae9ca0700ad2..73c15b4a308b 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2799,6 +2799,9 @@ iommu_sva_bind_device(struct device *dev, struct mm_struct *mm, void *drvdata)
if (!group)
return ERR_PTR(-ENODEV);
+ if (IS_ENABLED(CONFIG_X86))
+ return ERR_PTR(-EOPNOTSUPP);
+
/* Ensure device count and domain don't change while we're binding */
mutex_lock(&group->mutex);
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index fd7c80edb6e8..131996fd5406 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3525,6 +3525,23 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
*/
netdev->netdev_ops = &lionetdevops;
+ lio = GET_LIO(netdev);
+
+ memset(lio, 0, sizeof(struct lio));
+
+ lio->ifidx = ifidx_or_pfnum;
+
+ props = &octeon_dev->props[i];
+ props->gmxport = resp->cfg_info.linfo.gmxport;
+ props->netdev = netdev;
+
+ /* Point to the properties for octeon device to which this
+ * interface belongs.
+ */
+ lio->oct_dev = octeon_dev;
+ lio->octprops = props;
+ lio->netdev = netdev;
+
retval = netif_set_real_num_rx_queues(netdev, num_oqueues);
if (retval) {
dev_err(&octeon_dev->pci_dev->dev,
@@ -3541,16 +3558,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
goto setup_nic_dev_free;
}
- lio = GET_LIO(netdev);
-
- memset(lio, 0, sizeof(struct lio));
-
- lio->ifidx = ifidx_or_pfnum;
-
- props = &octeon_dev->props[i];
- props->gmxport = resp->cfg_info.linfo.gmxport;
- props->netdev = netdev;
-
lio->linfo.num_rxpciq = num_oqueues;
lio->linfo.num_txpciq = num_iqueues;
for (j = 0; j < num_oqueues; j++) {
@@ -3616,13 +3623,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
netdev->min_mtu = LIO_MIN_MTU_SIZE;
netdev->max_mtu = LIO_MAX_MTU_SIZE;
- /* Point to the properties for octeon device to which this
- * interface belongs.
- */
- lio->oct_dev = octeon_dev;
- lio->octprops = props;
- lio->netdev = netdev;
-
dev_dbg(&octeon_dev->pci_dev->dev,
"if%d gmx: %d hw_addr: 0x%llx\n", i,
lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr));
@@ -3770,6 +3770,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
if (!devlink) {
device_unlock(&octeon_dev->pci_dev->dev);
dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n");
+ i--;
goto setup_nic_dev_free;
}
@@ -3785,11 +3786,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
setup_nic_dev_free:
- while (i--) {
+ do {
dev_err(&octeon_dev->pci_dev->dev,
"NIC ifidx:%d Setup failed\n", i);
liquidio_destroy_nic_device(octeon_dev, i);
- }
+ } while (i--);
setup_nic_dev_done:
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index ac196883f07e..225ed333f484 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -2227,11 +2227,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
setup_nic_dev_free:
- while (i--) {
+ do {
dev_err(&octeon_dev->pci_dev->dev,
"NIC ifidx:%d Setup failed\n", i);
liquidio_destroy_nic_device(octeon_dev, i);
- }
+ } while (i--);
setup_nic_dev_done:
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index e928fea16e84..c08d8d5e47e1 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -1513,6 +1513,10 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
}
if_id = (status & 0xFFFF0000) >> 16;
+ if (if_id >= ethsw->sw_attr.num_ifs) {
+ dev_err(dev, "Invalid if_id %d in IRQ status\n", if_id);
+ goto out;
+ }
port_priv = ethsw->ports[if_id];
if (status & DPSW_IRQ_EVENT_LINK_CHANGED) {
@@ -2970,6 +2974,12 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
goto err_close;
}
+ if (!ethsw->sw_attr.num_ifs) {
+ dev_err(dev, "DPSW device has no interfaces\n");
+ err = -ENODEV;
+ goto err_close;
+ }
+
err = dpsw_get_api_version(ethsw->mc_io, 0,
ðsw->major,
ðsw->minor);
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index 7e60139f8ac5..6ca38d726953 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -145,7 +145,8 @@ gve_get_ethtool_stats(struct net_device *netdev,
tmp_tx_pkts, tmp_tx_bytes;
u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_pkts,
rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, tx_dropped;
- int stats_idx, base_stats_idx, max_stats_idx;
+ int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx;
+ int stats_idx, stats_region_len, nic_stats_len;
struct stats *report_stats;
int *rx_qid_to_stats_idx;
int *tx_qid_to_stats_idx;
@@ -215,8 +216,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = rx_bytes;
data[i++] = tx_bytes;
/* total rx dropped packets */
- data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail +
- rx_desc_err_dropped_pkt;
+ data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt;
data[i++] = tx_dropped;
data[i++] = priv->tx_timeo_cnt;
data[i++] = rx_skb_alloc_fail;
@@ -230,14 +230,33 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = priv->stats_report_trigger_cnt;
i = GVE_MAIN_STATS_LEN;
- /* For rx cross-reporting stats, start from nic rx stats in report */
- base_stats_idx = GVE_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
- GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues;
- max_stats_idx = NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues +
- base_stats_idx;
+ rx_base_stats_idx = 0;
+ max_rx_stats_idx = 0;
+ max_tx_stats_idx = 0;
+ stats_region_len = priv->stats_report_len -
+ sizeof(struct gve_stats_report);
+ nic_stats_len = (NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues +
+ NIC_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues) *
+ sizeof(struct stats);
+ if (unlikely((stats_region_len -
+ nic_stats_len) % sizeof(struct stats))) {
+ net_err_ratelimited("Starting index of NIC stats should be multiple of stats size");
+ } else {
+ /* For rx cross-reporting stats,
+ * start from nic rx stats in report
+ */
+ rx_base_stats_idx = (stats_region_len - nic_stats_len) /
+ sizeof(struct stats);
+ max_rx_stats_idx = NIC_RX_STATS_REPORT_NUM *
+ priv->rx_cfg.num_queues +
+ rx_base_stats_idx;
+ max_tx_stats_idx = NIC_TX_STATS_REPORT_NUM *
+ priv->tx_cfg.num_queues +
+ max_rx_stats_idx;
+ }
/* Preprocess the stats report for rx, map queue id to start index */
skip_nic_stats = false;
- for (stats_idx = base_stats_idx; stats_idx < max_stats_idx;
+ for (stats_idx = rx_base_stats_idx; stats_idx < max_rx_stats_idx;
stats_idx += NIC_RX_STATS_REPORT_NUM) {
u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name);
u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id);
@@ -273,7 +292,6 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = rx->rx_frag_copy_cnt;
/* rx dropped packets */
data[i++] = tmp_rx_skb_alloc_fail +
- tmp_rx_buf_alloc_fail +
tmp_rx_desc_err_dropped_pkt;
data[i++] = rx->rx_copybreak_pkt;
data[i++] = rx->rx_copied_pkt;
@@ -294,13 +312,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS;
}
- /* For tx cross-reporting stats, start from nic tx stats in report */
- base_stats_idx = max_stats_idx;
- max_stats_idx = NIC_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
- max_stats_idx;
- /* Preprocess the stats report for tx, map queue id to start index */
skip_nic_stats = false;
- for (stats_idx = base_stats_idx; stats_idx < max_stats_idx;
+ /* NIC TX stats start right after NIC RX stats */
+ for (stats_idx = max_rx_stats_idx; stats_idx < max_tx_stats_idx;
stats_idx += NIC_TX_STATS_REPORT_NUM) {
u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name);
u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id);
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 2e8b01b3ee44..963c76e4aa5d 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -135,9 +135,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
int tx_stats_num, rx_stats_num;
tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
- priv->tx_cfg.num_queues;
+ priv->tx_cfg.max_queues;
rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
- priv->rx_cfg.num_queues;
+ priv->rx_cfg.max_queues;
priv->stats_report_len = struct_size(priv->stats_report, stats,
size_add(tx_stats_num, rx_stats_num));
priv->stats_report =
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 428b139822cf..5fb956adc426 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1539,9 +1539,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
/* the macvlan port may be freed by macvlan_uninit when fail to register.
* so we destroy the macvlan port only when it's valid.
*/
- if (create && macvlan_port_get_rtnl(lowerdev)) {
+ if (macvlan_port_get_rtnl(lowerdev)) {
macvlan_flush_sources(port, vlan);
- macvlan_port_destroy(port->dev);
+ if (create)
+ macvlan_port_destroy(port->dev);
}
return err;
}
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index 9587eb98cdb3..213b4817cfdf 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -539,6 +539,11 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
.driver_info = (unsigned long)&sr9700_driver_info,
},
+ {
+ /* SR9700 with virtual driver CD-ROM - interface 0 is the CD-ROM device */
+ USB_DEVICE_INTERFACE_NUMBER(0x0fe6, 0x9702, 1),
+ .driver_info = (unsigned long)&sr9700_driver_info,
+ },
{}, /* END */
};
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 7bd3ce2f0804..75ad09667656 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -210,6 +210,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
if (total_blocks <= wl->tx_blocks_available) {
+ if (skb_headroom(skb) < (total_len - skb->len) &&
+ pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) {
+ wl1271_free_tx_id(wl, id);
+ return -EAGAIN;
+ }
desc = skb_push(skb, total_len - skb->len);
wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index dc84cade703d..63bef22095b4 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -3563,6 +3563,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
ctrl->ctrl.opts = NULL;
+ if (ctrl->ctrl.admin_tagset)
+ nvme_remove_admin_tag_set(&ctrl->ctrl);
/* initiate nvme ctrl ref counting teardown */
nvme_uninit_ctrl(&ctrl->ctrl);
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 7fae0103a515..a46c9f511083 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -306,11 +306,14 @@ static void nvmet_tcp_free_cmd_buffers(struct nvmet_tcp_cmd *cmd)
cmd->req.sg = NULL;
}
+static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue);
+
static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
{
struct bio_vec *iov = cmd->iov;
struct scatterlist *sg;
u32 length, offset, sg_offset;
+ unsigned int sg_remaining;
int nr_pages;
length = cmd->pdu_len;
@@ -318,9 +321,22 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
offset = cmd->rbytes_done;
cmd->sg_idx = offset / PAGE_SIZE;
sg_offset = offset % PAGE_SIZE;
+ if (!cmd->req.sg_cnt || cmd->sg_idx >= cmd->req.sg_cnt) {
+ nvmet_tcp_fatal_error(cmd->queue);
+ return;
+ }
sg = &cmd->req.sg[cmd->sg_idx];
+ sg_remaining = cmd->req.sg_cnt - cmd->sg_idx;
while (length) {
+ if (!sg_remaining) {
+ nvmet_tcp_fatal_error(cmd->queue);
+ return;
+ }
+ if (!sg->length || sg->length <= sg_offset) {
+ nvmet_tcp_fatal_error(cmd->queue);
+ return;
+ }
u32 iov_len = min_t(u32, length, sg->length - sg_offset);
bvec_set_page(iov, sg_page(sg), iov_len,
@@ -328,6 +344,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
length -= iov_len;
sg = sg_next(sg);
+ sg_remaining--;
iov++;
sg_offset = 0;
}
diff --git a/drivers/platform/x86/intel/telemetry/debugfs.c b/drivers/platform/x86/intel/telemetry/debugfs.c
index 1d4d0fbfd63c..e533de621ac4 100644
--- a/drivers/platform/x86/intel/telemetry/debugfs.c
+++ b/drivers/platform/x86/intel/telemetry/debugfs.c
@@ -449,7 +449,7 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
seq_printf(s, "%-32s\t%u\n",
debugfs_conf->pss_ltr_data[index].name,
- pss_s0ix_wakeup[index]);
+ pss_ltr_blkd[index]);
}
seq_puts(s, "\n--------------------------------------\n");
@@ -459,7 +459,7 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
seq_printf(s, "%-32s\t%u\n",
debugfs_conf->pss_wakeup[index].name,
- pss_ltr_blkd[index]);
+ pss_s0ix_wakeup[index]);
}
return 0;
diff --git a/drivers/platform/x86/intel/telemetry/pltdrv.c b/drivers/platform/x86/intel/telemetry/pltdrv.c
index 405dea87de6b..dd1ee2730b6a 100644
--- a/drivers/platform/x86/intel/telemetry/pltdrv.c
+++ b/drivers/platform/x86/intel/telemetry/pltdrv.c
@@ -610,7 +610,7 @@ static int telemetry_setup(struct platform_device *pdev)
/* Get telemetry Info */
events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
TELEM_INFO_SRAMEVTS_SHIFT;
- event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
+ event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
if ((events < TELEM_MAX_EVENTS_SRAM) ||
(event_regs < TELEM_MAX_EVENTS_SRAM)) {
dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
diff --git a/drivers/platform/x86/toshiba_haps.c b/drivers/platform/x86/toshiba_haps.c
index 49e84095bb01..8a53f6119fed 100644
--- a/drivers/platform/x86/toshiba_haps.c
+++ b/drivers/platform/x86/toshiba_haps.c
@@ -185,7 +185,7 @@ static int toshiba_haps_add(struct acpi_device *acpi_dev)
pr_info("Toshiba HDD Active Protection Sensor device\n");
- haps = kzalloc(sizeof(struct toshiba_haps_dev), GFP_KERNEL);
+ haps = devm_kzalloc(&acpi_dev->dev, sizeof(*haps), GFP_KERNEL);
if (!haps)
return -ENOMEM;
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index a430c14ce16d..29f00ff82c52 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -326,7 +326,7 @@ static int imx8m_blk_ctrl_remove(struct platform_device *pdev)
of_genpd_del_provider(pdev->dev.of_node);
- for (i = 0; bc->onecell_data.num_domains; i++) {
+ for (i = 0; i < bc->onecell_data.num_domains; i++) {
struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd);
diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c
index 9bc536ee1395..575ed8e3a520 100644
--- a/drivers/soc/imx/imx8mp-blk-ctrl.c
+++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
@@ -42,6 +42,7 @@ struct imx8mp_blk_ctrl_domain_data {
const char * const *path_names;
int num_paths;
const char *gpc_name;
+ const unsigned int flags;
};
#define DOMAIN_MAX_CLKS 2
@@ -54,6 +55,7 @@ struct imx8mp_blk_ctrl_domain {
struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
struct device *power_dev;
struct imx8mp_blk_ctrl *bc;
+ struct notifier_block power_nb;
int num_paths;
int id;
};
@@ -166,10 +168,12 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
[IMX8MP_HSIOBLK_PD_USB_PHY1] = {
.name = "hsioblk-usb-phy1",
.gpc_name = "usb-phy1",
+ .flags = GENPD_FLAG_ACTIVE_WAKEUP,
},
[IMX8MP_HSIOBLK_PD_USB_PHY2] = {
.name = "hsioblk-usb-phy2",
.gpc_name = "usb-phy2",
+ .flags = GENPD_FLAG_ACTIVE_WAKEUP,
},
[IMX8MP_HSIOBLK_PD_PCIE] = {
.name = "hsioblk-pcie",
@@ -492,6 +496,20 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd)
return 0;
}
+static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct imx8mp_blk_ctrl_domain *domain =
+ container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb);
+
+ if (action == GENPD_NOTIFY_PRE_OFF) {
+ if (domain->genpd.status == GENPD_STATE_ON)
+ return NOTIFY_BAD;
+ }
+
+ return NOTIFY_OK;
+}
+
static struct lock_class_key blk_ctrl_genpd_lock_class;
static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
@@ -593,15 +611,25 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
goto cleanup_pds;
}
+ domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier;
+ ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to add power notifier\n");
+ dev_pm_domain_detach(domain->power_dev, true);
+ goto cleanup_pds;
+ }
+
domain->genpd.name = data->name;
domain->genpd.power_on = imx8mp_blk_ctrl_power_on;
domain->genpd.power_off = imx8mp_blk_ctrl_power_off;
+ domain->genpd.flags = data->flags;
domain->bc = bc;
domain->id = i;
ret = pm_genpd_init(&domain->genpd, NULL, true);
if (ret) {
dev_err_probe(dev, ret, "failed to init power domain\n");
+ dev_pm_genpd_remove_notifier(domain->power_dev);
dev_pm_domain_detach(domain->power_dev, true);
goto cleanup_pds;
}
@@ -644,6 +672,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
cleanup_pds:
for (i--; i >= 0; i--) {
pm_genpd_remove(&bc->domains[i].genpd);
+ dev_pm_genpd_remove_notifier(bc->domains[i].power_dev);
dev_pm_domain_detach(bc->domains[i].power_dev, true);
}
@@ -663,6 +692,7 @@ static int imx8mp_blk_ctrl_remove(struct platform_device *pdev)
struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd);
+ dev_pm_genpd_remove_notifier(domain->power_dev);
dev_pm_domain_detach(domain->power_dev, true);
}
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index 24cab56ecb7f..5002c9f897c7 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -1093,8 +1093,10 @@ static int tegra_slink_probe(struct platform_device *pdev)
reset_control_deassert(tspi->rst);
spi_irq = platform_get_irq(pdev, 0);
- if (spi_irq < 0)
- return spi_irq;
+ if (spi_irq < 0) {
+ ret = spi_irq;
+ goto exit_pm_put;
+ }
tspi->irq = spi_irq;
ret = request_threaded_irq(tspi->irq, tegra_slink_isr,
tegra_slink_isr_thread, IRQF_ONESHOT,
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index 2e4d1b2f2a27..022cc0ebee77 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -813,6 +813,7 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran
u32 command1, command2, speed = t->speed_hz;
u8 bits_per_word = t->bits_per_word;
u32 tx_tap = 0, rx_tap = 0;
+ unsigned long flags;
int req_mode;
if (!has_acpi_companion(tqspi->dev) && speed != tqspi->cur_speed) {
@@ -820,10 +821,12 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran
tqspi->cur_speed = speed;
}
+ spin_lock_irqsave(&tqspi->lock, flags);
tqspi->cur_pos = 0;
tqspi->cur_rx_pos = 0;
tqspi->cur_tx_pos = 0;
tqspi->curr_xfer = t;
+ spin_unlock_irqrestore(&tqspi->lock, flags);
if (is_first_of_msg) {
tegra_qspi_mask_clear_irq(tqspi);
@@ -1060,6 +1063,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
u32 address_value = 0;
u32 cmd_config = 0, addr_config = 0;
u8 cmd_value = 0, val = 0;
+ unsigned long flags;
/* Enable Combined sequence mode */
val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG);
@@ -1166,13 +1170,17 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
tegra_qspi_transfer_end(spi);
spi_transfer_delay_exec(xfer);
}
+ spin_lock_irqsave(&tqspi->lock, flags);
tqspi->curr_xfer = NULL;
+ spin_unlock_irqrestore(&tqspi->lock, flags);
transfer_phase++;
}
ret = 0;
exit:
+ spin_lock_irqsave(&tqspi->lock, flags);
tqspi->curr_xfer = NULL;
+ spin_unlock_irqrestore(&tqspi->lock, flags);
msg->status = ret;
return ret;
@@ -1185,6 +1193,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
struct spi_transfer *transfer;
bool is_first_msg = true;
int ret = 0, val = 0;
+ unsigned long flags;
msg->status = 0;
msg->actual_length = 0;
@@ -1254,7 +1263,9 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
msg->actual_length += xfer->len + dummy_bytes;
complete_xfer:
+ spin_lock_irqsave(&tqspi->lock, flags);
tqspi->curr_xfer = NULL;
+ spin_unlock_irqrestore(&tqspi->lock, flags);
if (ret < 0) {
tegra_qspi_transfer_end(spi);
@@ -1325,10 +1336,11 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master,
static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi)
{
- struct spi_transfer *t = tqspi->curr_xfer;
+ struct spi_transfer *t;
unsigned long flags;
spin_lock_irqsave(&tqspi->lock, flags);
+ t = tqspi->curr_xfer;
if (tqspi->tx_status || tqspi->rx_status) {
tegra_qspi_handle_error(tqspi);
@@ -1359,7 +1371,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi)
static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
{
- struct spi_transfer *t = tqspi->curr_xfer;
+ struct spi_transfer *t;
unsigned int total_fifo_words;
unsigned long flags;
long wait_status;
@@ -1396,6 +1408,7 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
}
spin_lock_irqsave(&tqspi->lock, flags);
+ t = tqspi->curr_xfer;
if (err) {
tegra_qspi_dma_unmap_xfer(tqspi, t);
@@ -1435,15 +1448,30 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
{
struct tegra_qspi *tqspi = context_data;
+ u32 status;
+
+ /*
+ * Read transfer status to check if interrupt was triggered by transfer
+ * completion
+ */
+ status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS);
/*
* Occasionally the IRQ thread takes a long time to wake up (usually
* when the CPU that it's running on is excessively busy) and we have
* already reached the timeout before and cleaned up the timed out
* transfer. Avoid any processing in that case and bail out early.
+ *
+ * If no transfer is in progress, check if this was a real interrupt
+ * that the timeout handler already processed, or a spurious one.
*/
- if (!tqspi->curr_xfer)
- return IRQ_NONE;
+ if (!tqspi->curr_xfer) {
+ /* Spurious interrupt - transfer not ready */
+ if (!(status & QSPI_RDY))
+ return IRQ_NONE;
+ /* Real interrupt, already handled by timeout path */
+ return IRQ_HANDLED;
+ }
tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 26dc8ed3045b..438f6448cd67 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -785,8 +785,11 @@ void iscsit_dec_session_usage_count(struct iscsit_session *sess)
spin_lock_bh(&sess->session_usage_lock);
sess->session_usage_count--;
- if (!sess->session_usage_count && sess->session_waiting_on_uc)
+ if (!sess->session_usage_count && sess->session_waiting_on_uc) {
+ spin_unlock_bh(&sess->session_usage_lock);
complete(&sess->session_waiting_on_uc_comp);
+ return;
+ }
spin_unlock_bh(&sess->session_usage_lock);
}
@@ -854,8 +857,11 @@ void iscsit_dec_conn_usage_count(struct iscsit_conn *conn)
spin_lock_bh(&conn->conn_usage_lock);
conn->conn_usage_count--;
- if (!conn->conn_usage_count && conn->conn_waiting_on_uc)
+ if (!conn->conn_usage_count && conn->conn_waiting_on_uc) {
+ spin_unlock_bh(&conn->conn_usage_lock);
complete(&conn->conn_waiting_on_uc_comp);
+ return;
+ }
spin_unlock_bh(&conn->conn_usage_lock);
}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 78cd7b8ccfc8..c409fb3e55bf 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -397,7 +397,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
struct btrfs_drop_extents_args drop_args = { 0 };
struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info;
- struct btrfs_trans_handle *trans;
+ struct btrfs_trans_handle *trans = NULL;
u64 data_len = (compressed_size ?: size);
int ret;
struct btrfs_path *path;
@@ -415,13 +415,16 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
return 1;
path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
+ if (!path) {
+ ret = -ENOMEM;
+ goto out;
+ }
trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
- btrfs_free_path(path);
- return PTR_ERR(trans);
+ ret = PTR_ERR(trans);
+ trans = NULL;
+ goto out;
}
trans->block_rsv = &inode->block_rsv;
@@ -468,7 +471,8 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
*/
btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL);
btrfs_free_path(path);
- btrfs_end_transaction(trans);
+ if (trans)
+ btrfs_end_transaction(trans);
return ret;
}
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 98a30ca6354c..17e651bd04ad 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -204,7 +204,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
fd.entrylength);
type = be16_to_cpu(entry.type);
len = NLS_MAX_CHARSET_SIZE * HFSPLUS_MAX_STRLEN;
- err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len);
+ err = hfsplus_uni2asc_str(sb, &fd.key->cat.name, strbuf, &len);
if (err)
goto out;
if (type == HFSPLUS_FOLDER) {
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index e13da1fe2c2a..3d324e4465d0 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -518,8 +518,12 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *s1,
const struct hfsplus_unistr *s2);
int hfsplus_strcmp(const struct hfsplus_unistr *s1,
const struct hfsplus_unistr *s2);
-int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr,
- char *astr, int *len_p);
+int hfsplus_uni2asc_str(struct super_block *sb,
+ const struct hfsplus_unistr *ustr, char *astr,
+ int *len_p);
+int hfsplus_uni2asc_xattr_str(struct super_block *sb,
+ const struct hfsplus_attr_unistr *ustr,
+ char *astr, int *len_p);
int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
int max_unistr_len, const char *astr, int len);
int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str);
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index ebd326799f35..11e08a4a18b2 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -143,9 +143,8 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc)
return NULL;
}
-int hfsplus_uni2asc(struct super_block *sb,
- const struct hfsplus_unistr *ustr,
- char *astr, int *len_p)
+static int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr,
+ int max_len, char *astr, int *len_p)
{
const hfsplus_unichr *ip;
struct nls_table *nls = HFSPLUS_SB(sb)->nls;
@@ -158,8 +157,8 @@ int hfsplus_uni2asc(struct super_block *sb,
ip = ustr->unicode;
ustrlen = be16_to_cpu(ustr->length);
- if (ustrlen > HFSPLUS_MAX_STRLEN) {
- ustrlen = HFSPLUS_MAX_STRLEN;
+ if (ustrlen > max_len) {
+ ustrlen = max_len;
pr_err("invalid length %u has been corrected to %d\n",
be16_to_cpu(ustr->length), ustrlen);
}
@@ -280,6 +279,21 @@ int hfsplus_uni2asc(struct super_block *sb,
return res;
}
+inline int hfsplus_uni2asc_str(struct super_block *sb,
+ const struct hfsplus_unistr *ustr, char *astr,
+ int *len_p)
+{
+ return hfsplus_uni2asc(sb, ustr, HFSPLUS_MAX_STRLEN, astr, len_p);
+}
+
+inline int hfsplus_uni2asc_xattr_str(struct super_block *sb,
+ const struct hfsplus_attr_unistr *ustr,
+ char *astr, int *len_p)
+{
+ return hfsplus_uni2asc(sb, (const struct hfsplus_unistr *)ustr,
+ HFSPLUS_ATTR_MAX_STRLEN, astr, len_p);
+}
+
/*
* Convert one or more ASCII characters into a single unicode character.
* Returns the number of ASCII characters corresponding to the unicode char.
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index beedc1a2237a..5af9992a2e57 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -737,9 +737,9 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
goto end_listxattr;
xattr_name_len = NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN;
- if (hfsplus_uni2asc(inode->i_sb,
- (const struct hfsplus_unistr *)&fd.key->attr.key_name,
- strbuf, &xattr_name_len)) {
+ if (hfsplus_uni2asc_xattr_str(inode->i_sb,
+ &fd.key->attr.key_name, strbuf,
+ &xattr_name_len)) {
pr_err("unicode conversion failed\n");
res = -EIO;
goto end_listxattr;
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
index afdc78e92ee9..7fc7fcabce80 100644
--- a/fs/smb/client/smb2file.c
+++ b/fs/smb/client/smb2file.c
@@ -123,6 +123,7 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
&err_buftype);
if (rc == -EACCES && retry_without_read_attributes) {
+ free_rsp_buf(err_buftype, err_iov.iov_base);
oparms->desired_access &= ~FILE_READ_ATTRIBUTES;
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
&err_buftype);
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 100016298f87..14d46c52ee74 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2272,7 +2272,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
{
struct smb2_create_rsp *rsp;
struct smb2_create_req *req;
- int id;
+ int id = -1;
int err;
char *name;
@@ -2329,6 +2329,9 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
break;
}
+ if (id >= 0)
+ ksmbd_session_rpc_close(work->sess, id);
+
if (!IS_ERR(name))
kfree(name);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 21b7d044797e..b141486801b1 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -2356,6 +2356,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
list) {
list_del_init(&bpage->list);
free_buffer_page(bpage);
+
+ cond_resched();
}
}
out_err_unlock:
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 9a6568217fc9..494207311934 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -65,14 +65,17 @@ enum trace_type {
#undef __field_fn
#define __field_fn(type, item) type item;
+#undef __field_packed
+#define __field_packed(type, item) type item;
+
#undef __field_struct
#define __field_struct(type, item) __field(type, item)
#undef __field_desc
#define __field_desc(type, container, item)
-#undef __field_packed
-#define __field_packed(type, container, item)
+#undef __field_desc_packed
+#define __field_desc_packed(type, container, item)
#undef __array
#define __array(type, item, size) type item[size];
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index cd41e863b51c..f7ea8b4afd47 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -78,8 +78,8 @@ FTRACE_ENTRY_PACKED(funcgraph_entry, ftrace_graph_ent_entry,
F_STRUCT(
__field_struct( struct ftrace_graph_ent, graph_ent )
- __field_packed( unsigned long, graph_ent, func )
- __field_packed( int, graph_ent, depth )
+ __field_desc_packed( unsigned long, graph_ent, func )
+ __field_desc_packed( int, graph_ent, depth )
),
F_printk("--> %ps (%d)", (void *)__entry->func, __entry->depth)
@@ -92,11 +92,11 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_entry,
F_STRUCT(
__field_struct( struct ftrace_graph_ret, ret )
- __field_packed( unsigned long, ret, func )
- __field_packed( int, ret, depth )
- __field_packed( unsigned int, ret, overrun )
- __field_packed( unsigned long long, ret, calltime)
- __field_packed( unsigned long long, ret, rettime )
+ __field_desc_packed( unsigned long, ret, func )
+ __field_desc_packed( int, ret, depth )
+ __field_desc_packed( unsigned int, ret, overrun )
+ __field_desc_packed( unsigned long long, ret, calltime)
+ __field_desc_packed( unsigned long long, ret, rettime )
),
F_printk("<-- %ps (%d) (start: %llx end: %llx) over: %d",
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 58f3946081e2..b58d0349ff79 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -42,11 +42,14 @@ static int ftrace_event_register(struct trace_event_call *call,
#undef __field_fn
#define __field_fn(type, item) type item;
+#undef __field_packed
+#define __field_packed(type, item) type item;
+
#undef __field_desc
#define __field_desc(type, container, item) type item;
-#undef __field_packed
-#define __field_packed(type, container, item) type item;
+#undef __field_desc_packed
+#define __field_desc_packed(type, container, item) type item;
#undef __array
#define __array(type, item, size) type item[size];
@@ -101,11 +104,14 @@ static void __always_unused ____ftrace_check_##name(void) \
#undef __field_fn
#define __field_fn(_type, _item) __field_ext(_type, _item, FILTER_TRACE_FN)
+#undef __field_packed
+#define __field_packed(_type, _item) __field_ext_packed(_type, _item, FILTER_OTHER)
+
#undef __field_desc
#define __field_desc(_type, _container, _item) __field_ext(_type, _item, FILTER_OTHER)
-#undef __field_packed
-#define __field_packed(_type, _container, _item) __field_ext_packed(_type, _item, FILTER_OTHER)
+#undef __field_desc_packed
+#define __field_desc_packed(_type, _container, _item) __field_ext_packed(_type, _item, FILTER_OTHER)
#undef __array
#define __array(_type, _item, _len) { \
@@ -140,11 +146,14 @@ static struct trace_event_fields ftrace_event_fields_##name[] = { \
#undef __field_fn
#define __field_fn(type, item)
+#undef __field_packed
+#define __field_packed(type, item)
+
#undef __field_desc
#define __field_desc(type, container, item)
-#undef __field_packed
-#define __field_packed(type, container, item)
+#undef __field_desc_packed
+#define __field_desc_packed(type, container, item)
#undef __array
#define __array(type, item, len)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index ed62c1026fe9..f99e348c8f37 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1299,7 +1299,7 @@ int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct ne
list_for_each_entry(tmpl, &template_tables, list) {
if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) {
mutex_unlock(&ebt_mutex);
- return -EEXIST;
+ return -EBUSY;
}
}
diff --git a/net/core/filter.c b/net/core/filter.c
index 305c38636b32..e19bf63ad9a4 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2274,12 +2274,12 @@ static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev,
err = bpf_out_neigh_v6(net, skb, dev, nh);
if (unlikely(net_xmit_eval(err)))
- DEV_STATS_INC(dev, tx_errors);
+ dev_core_stats_tx_dropped_inc(dev);
else
ret = NET_XMIT_SUCCESS;
goto out_xmit;
out_drop:
- DEV_STATS_INC(dev, tx_errors);
+ dev_core_stats_tx_dropped_inc(dev);
kfree_skb(skb);
out_xmit:
return ret;
@@ -2382,12 +2382,12 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev,
err = bpf_out_neigh_v4(net, skb, dev, nh);
if (unlikely(net_xmit_eval(err)))
- DEV_STATS_INC(dev, tx_errors);
+ dev_core_stats_tx_dropped_inc(dev);
else
ret = NET_XMIT_SUCCESS;
goto out_xmit;
out_drop:
- DEV_STATS_INC(dev, tx_errors);
+ dev_core_stats_tx_dropped_inc(dev);
kfree_skb(skb);
out_xmit:
return ret;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 585de86fce84..eb1512f1b007 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -968,7 +968,8 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
if (ieee80211_sdata_running(sdata)) {
list_for_each_entry(key, &sdata->key_list, list) {
- increment_tailroom_need_count(sdata);
+ if (!(key->flags & KEY_FLAG_TAINTED))
+ increment_tailroom_need_count(sdata);
ieee80211_key_enable_hw_accel(key);
}
}
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
index fcc326913391..1e1bfaf12b1a 100644
--- a/net/mac80211/ocb.c
+++ b/net/mac80211/ocb.c
@@ -48,6 +48,9 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
int band;
+ if (!ifocb->joined)
+ return;
+
/* XXX: Consider removing the least recently used entry and
* allow new one to be added.
*/
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index e9ae92094794..8a92077da153 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1314,6 +1314,10 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
}
}
+ sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
+ if (sinfo)
+ sta_set_sinfo(sta, sinfo, true);
+
if (sta->uploaded) {
ret = drv_sta_state(local, sdata, sta, IEEE80211_STA_NONE,
IEEE80211_STA_NOTEXIST);
@@ -1322,9 +1326,6 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr);
- sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
- if (sinfo)
- sta_set_sinfo(sta, sinfo, true);
cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
kfree(sinfo);
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index be93a02497d6..016e31452cbc 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -89,7 +89,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
if (pf == NFPROTO_UNSPEC) {
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
if (rcu_access_pointer(loggers[i][logger->type])) {
- ret = -EEXIST;
+ ret = -EBUSY;
goto unlock;
}
}
@@ -97,7 +97,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
rcu_assign_pointer(loggers[i][logger->type], logger);
} else {
if (rcu_access_pointer(loggers[pf][logger->type])) {
- ret = -EEXIST;
+ ret = -EBUSY;
goto unlock;
}
rcu_assign_pointer(loggers[pf][logger->type], logger);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d154e3e0c980..67729d7c913a 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5211,7 +5211,7 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx,
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
- if (!nft_set_elem_active(ext, genmask))
+ if (nft_set_elem_active(ext, genmask))
continue;
elem.priv = catchall->elem;
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index 8336f2052f22..863162c82330 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -667,6 +667,11 @@ static int pipapo_resize(struct nft_pipapo_field *f, int old_rules, int rules)
}
mt:
+ if (rules > (INT_MAX / sizeof(*new_mt))) {
+ kvfree(new_lt);
+ return -ENOMEM;
+ }
+
new_mt = kvmalloc(rules * sizeof(*new_mt), GFP_KERNEL);
if (!new_mt) {
kvfree(new_lt);
@@ -1360,6 +1365,9 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old)
src->bsize * sizeof(*dst->lt) *
src->groups * NFT_PIPAPO_BUCKETS(src->bb));
+ if (src->rules > (INT_MAX / sizeof(*src->mt)))
+ goto out_mt;
+
dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL);
if (!dst->mt)
goto out_mt;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index e8cc8eef0ab6..c842ec693dad 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1761,7 +1761,7 @@ EXPORT_SYMBOL_GPL(xt_hook_ops_alloc);
int xt_register_template(const struct xt_table *table,
int (*table_init)(struct net *net))
{
- int ret = -EEXIST, af = table->af;
+ int ret = -EBUSY, af = table->af;
struct xt_template *t;
mutex_lock(&xt[af].mutex);
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
index d52829c6aa47..0e84d86f75fe 100644
--- a/net/tipc/crypto.c
+++ b/net/tipc/crypto.c
@@ -1219,7 +1219,7 @@ void tipc_crypto_key_flush(struct tipc_crypto *c)
rx = c;
tx = tipc_net(rx->net)->crypto_tx;
if (cancel_delayed_work(&rx->work)) {
- kfree(rx->skey);
+ kfree_sensitive(rx->skey);
rx->skey = NULL;
atomic_xchg(&rx->key_distr, 0);
tipc_node_put(rx->node);
@@ -2394,7 +2394,7 @@ static void tipc_crypto_work_rx(struct work_struct *work)
break;
default:
synchronize_rcu();
- kfree(rx->skey);
+ kfree_sensitive(rx->skey);
rx->skey = NULL;
break;
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index b513e24572a3..f59985e80e20 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1553,12 +1553,14 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
tmp = result;
tmp *= SCALE;
do_div(tmp, mcs_divisors[rate->mcs]);
- result = tmp;
/* and take NSS, DCM into account */
- result = (result * rate->nss) / 8;
+ tmp *= rate->nss;
+ do_div(tmp, 8);
if (rate->he_dcm)
- result /= 2;
+ do_div(tmp, 2);
+
+ result = tmp;
return result / 10000;
}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ccbdb01ab6ec..b45e5b268a65 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9929,6 +9929,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x863e, "HP Spectre x360 15-df1xxx", ALC285_FIXUP_HP_SPECTRE_X360_DF1),
SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
SND_PCI_QUIRK(0x103c, 0x86f9, "HP Spectre x360 13-aw0xxx", ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x8706, "HP Laptop 15s-eq1xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
@@ -10443,6 +10444,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1d05, 0x1409, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1d05, 0x300f, "TongFang X6AR5xxY", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1d05, 0x3019, "TongFang X6FR5xxY", ALC2XX_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d05, 0x3031, "TongFang X6AR55xU", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1d17, 0x3288, "Haier Boyue G42", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 7203c6488df0..643deed487ab 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -295,9 +295,11 @@ static int acp_pdm_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+ struct pdm_stream_instance *rtd = substream->runtime->private_data;
disable_pdm_interrupts(adata->acp_base);
adata->capture_stream = NULL;
+ kfree(rtd);
return 0;
}
diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c
index 67eef894d0c2..0323d6341c9a 100644
--- a/sound/soc/codecs/tlv320adcx140.c
+++ b/sound/soc/codecs/tlv320adcx140.c
@@ -1157,6 +1157,9 @@ static int adcx140_i2c_probe(struct i2c_client *i2c)
adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev,
"reset", GPIOD_OUT_LOW);
if (IS_ERR(adcx140->gpio_reset))
+ return dev_err_probe(&i2c->dev, PTR_ERR(adcx140->gpio_reset),
+ "Failed to get Reset GPIO\n");
+ if (!adcx140->gpio_reset)
dev_info(&i2c->dev, "Reset GPIO not defined\n");
adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev,
diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c
index 68d69e32681a..c5ff68ee3e12 100644
--- a/sound/soc/ti/davinci-evm.c
+++ b/sound/soc/ti/davinci-evm.c
@@ -404,27 +404,32 @@ static int davinci_evm_probe(struct platform_device *pdev)
return -EINVAL;
dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
- if (!dai->cpus->of_node)
- return -EINVAL;
+ if (!dai->cpus->of_node) {
+ ret = -EINVAL;
+ goto err_put;
+ }
dai->platforms->of_node = dai->cpus->of_node;
evm_soc_card.dev = &pdev->dev;
ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
if (ret)
- return ret;
+ goto err_put;
mclk = devm_clk_get(&pdev->dev, "mclk");
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
- return -EPROBE_DEFER;
+ ret = -EPROBE_DEFER;
+ goto err_put;
} else if (IS_ERR(mclk)) {
dev_dbg(&pdev->dev, "mclk not found.\n");
mclk = NULL;
}
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
+ if (!drvdata) {
+ ret = -ENOMEM;
+ goto err_put;
+ }
drvdata->mclk = mclk;
@@ -434,7 +439,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
if (!drvdata->mclk) {
dev_err(&pdev->dev,
"No clock or clock rate defined.\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_put;
}
drvdata->sysclk = clk_get_rate(drvdata->mclk);
} else if (drvdata->mclk) {
@@ -450,8 +456,25 @@ static int davinci_evm_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
- if (ret)
+ if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto err_put;
+ }
+
+ return ret;
+
+err_put:
+ dai->platforms->of_node = NULL;
+
+ if (dai->cpus->of_node) {
+ of_node_put(dai->cpus->of_node);
+ dai->cpus->of_node = NULL;
+ }
+
+ if (dai->codecs->of_node) {
+ of_node_put(dai->codecs->of_node);
+ dai->codecs->of_node = NULL;
+ }
return ret;
}
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 4a2caef2c939..9b9250b95337 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -202,6 +202,7 @@ else
LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
endif
CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
+ -U_FORTIFY_SOURCE \
-fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \
-I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \
-I$(<D) -Iinclude/$(UNAME_M) -I ../rseq -I.. $(EXTRA_CFLAGS) \
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 2a3ed401ce46..c3340bdc754a 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -148,21 +148,28 @@ irqfd_shutdown(struct work_struct *work)
}
-/* assumes kvm->irqfds.lock is held */
-static bool
-irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
+static bool irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
{
+ /*
+ * Assert that either irqfds.lock or SRCU is held, as irqfds.lock must
+ * be held to prevent false positives (on the irqfd being active), and
+ * while false negatives are impossible as irqfds are never added back
+ * to the list once they're deactivated, the caller must at least hold
+ * SRCU to guard against routing changes if the irqfd is deactivated.
+ */
+ lockdep_assert_once(lockdep_is_held(&irqfd->kvm->irqfds.lock) ||
+ srcu_read_lock_held(&irqfd->kvm->irq_srcu));
+
return list_empty(&irqfd->list) ? false : true;
}
/*
* Mark the irqfd as inactive and schedule it for removal
- *
- * assumes kvm->irqfds.lock is held
*/
-static void
-irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
+static void irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
{
+ lockdep_assert_held(&irqfd->kvm->irqfds.lock);
+
BUG_ON(!irqfd_is_active(irqfd));
list_del_init(&irqfd->list);
@@ -203,8 +210,15 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
seq = read_seqcount_begin(&irqfd->irq_entry_sc);
irq = irqfd->irq_entry;
} while (read_seqcount_retry(&irqfd->irq_entry_sc, seq));
- /* An event has been signaled, inject an interrupt */
- if (kvm_arch_set_irq_inatomic(&irq, kvm,
+
+ /*
+ * An event has been signaled, inject an interrupt unless the
+ * irqfd is being deassigned (isn't active), in which case the
+ * routing information may be stale (once the irqfd is removed
+ * from the list, it will stop receiving routing updates).
+ */
+ if (unlikely(!irqfd_is_active(irqfd)) ||
+ kvm_arch_set_irq_inatomic(&irq, kvm,
KVM_USERSPACE_IRQ_SOURCE_ID, 1,
false) == -EWOULDBLOCK)
schedule_work(&irqfd->inject);
@@ -549,18 +563,8 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
spin_lock_irq(&kvm->irqfds.lock);
list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
- if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) {
- /*
- * This clearing of irq_entry.type is needed for when
- * another thread calls kvm_irq_routing_update before
- * we flush workqueue below (we synchronize with
- * kvm_irq_routing_update using irqfds.lock).
- */
- write_seqcount_begin(&irqfd->irq_entry_sc);
- irqfd->irq_entry.type = 0;
- write_seqcount_end(&irqfd->irq_entry_sc);
+ if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi)
irqfd_deactivate(irqfd);
- }
}
spin_unlock_irq(&kvm->irqfds.lock);
prev parent reply other threads:[~2026-02-11 14:21 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-11 14:21 Linux 6.1.163 Greg Kroah-Hartman
2026-02-11 14:21 ` Greg Kroah-Hartman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2026021126-overkill-audacity-ad7f@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=akpm@linux-foundation.org \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=lwn@lwn.net \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.