[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2026021126-overkill-audacity-ad7f@gregkh>
Date: Wed, 11 Feb 2026 15:21:27 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org,
akpm@...ux-foundation.org,
torvalds@...ux-foundation.org,
stable@...r.kernel.org
Cc: lwn@....net,
jslaby@...e.cz,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: Re: Linux 6.1.163
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);
Powered by blists - more mailing lists