Bit 7 of the 'Device Type 2' (0Bh) register is reserved in the FSA9480
device, but is used by the FSA880 and TSU6111 devices.
From FSA9480 datasheet, Table 18. Device Type 2:
Reset Value: x0000000
===========================================================================
Bit # | Name | Size (Bits) | Description
---------------------------------------------------------------------------
7 | Reserved | 1 | NA
From FSA880 datasheet, Table 13. Device Type 2:
Reset Value: 0xxx0000
===========================================================================
Bit # | Name | Size (Bits) | Description
---------------------------------------------------------------------------
7 | Unknown | 1 | 1: Any accessory detected as unknown
| Accessory | | or an accessory that cannot be
| | | detected as being valid even
| | | though ID_CON is not floating
| | | 0: Unknown accessory not detected
From TSU6111 datasheet, Device Type 2:
Reset Value:x0000000
===========================================================================
Bit # | Name | Size (Bits) | Description
---------------------------------------------------------------------------
7 | Audio Type 3 | 1 | Audio device type 3
So the value obtained from the FSA9480_REG_DEV_T2 register in the
fsa9480_detect_dev() function may have the 7th bit set.
In this case, the 'dev' parameter in the fsa9480_handle_change() function
will be 15. And this will cause the 'cable_types' array to overflow when
accessed at this index.
Extend the 'cable_types' array with a new value 'DEV_RESERVED' as
specified in the FSA9480 datasheet. Do not use it as it serves for
various purposes in the listed devices.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: bad5b5e707a5 ("extcon: Add fsa9480 extcon driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Vladimir Moskovkin <Vladimir.Moskovkin(a)kaspersky.com>
---
drivers/extcon/extcon-fsa9480.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/extcon/extcon-fsa9480.c b/drivers/extcon/extcon-fsa9480.c
index b11b43171063..30972a7214f7 100644
--- a/drivers/extcon/extcon-fsa9480.c
+++ b/drivers/extcon/extcon-fsa9480.c
@@ -68,6 +68,7 @@
#define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG)
/* Device Type 2 */
+#define DEV_RESERVED 15
#define DEV_AV 14
#define DEV_TTY 13
#define DEV_PPD 12
@@ -133,6 +134,7 @@ static const u64 cable_types[] = {
[DEV_USB] = BIT_ULL(EXTCON_USB) | BIT_ULL(EXTCON_CHG_USB_SDP),
[DEV_AUDIO_2] = BIT_ULL(EXTCON_JACK_LINE_OUT),
[DEV_AUDIO_1] = BIT_ULL(EXTCON_JACK_LINE_OUT),
+ [DEV_RESERVED] = 0,
[DEV_AV] = BIT_ULL(EXTCON_JACK_LINE_OUT)
| BIT_ULL(EXTCON_JACK_VIDEO_OUT),
[DEV_TTY] = BIT_ULL(EXTCON_JIG),
@@ -228,7 +230,7 @@ static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
dev_err(usbsw->dev, "%s: failed to read registers", __func__);
return;
}
- val = val2 << 8 | val1;
+ val = val2 << 8 | (val1 & 0xFF);
dev_info(usbsw->dev, "dev1: 0x%x, dev2: 0x%x\n", val1, val2);
--
2.25.1
In the max3420_set_clear_feature() function, the endpoint index `id` can have a value from 0 to 15.
However, the udc->ep array is initialized with a maximum of 4 endpoints in max3420_eps_init().
If host sends a request with a wIndex greater than 3, the access to `udc->ep[id]` will go out-of-bounds,
leading to memory corruption or a potential kernel crash.
This bug was found by code inspection and has not been tested on hardware.
Fixes: 48ba02b2e2b1a ("usb: gadget: add udc driver for max3420")
Cc: stable(a)vger.kernel.org
Signed-off-by: Seungjin Bae <eeodqql09(a)gmail.com>
---
drivers/usb/gadget/udc/max3420_udc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/gadget/udc/max3420_udc.c b/drivers/usb/gadget/udc/max3420_udc.c
index 7349ea774adf..e4ecc7f7f3be 100644
--- a/drivers/usb/gadget/udc/max3420_udc.c
+++ b/drivers/usb/gadget/udc/max3420_udc.c
@@ -596,6 +596,8 @@ static void max3420_set_clear_feature(struct max3420_udc *udc)
break;
id = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
+ if (id >= MAX3420_MAX_EPS)
+ break;
ep = &udc->ep[id];
spin_lock_irqsave(&ep->lock, flags);
--
2.43.0
Hi stable maintainers,
Please apply commit d1e420772cd1 ("x86/pkeys: Simplify PKRU update in
signal frame") to the stable branches for 6.12 and later.
This fixes a regression introduced in 6.13 by commit ae6012d72fa6
("x86/pkeys: Ensure updated PKRU value is XRSTOR'd"), which was also
backported in 6.12.5.
Ben.
--
Ben Hutchings
73.46% of all statistics are made up.
inline data handling has a race between writing and writing to a memory
map.
When ext4_page_mkwrite is called, it calls ext4_convert_inline_data, which
destroys the inline data, but if block allocation fails, restores the
inline data. In that process, we could have:
CPU1 CPU2
destroy_inline_data
write_begin (does not see inline data)
restory_inline_data
write_end (sees inline data)
This leads to bugs like the one below, as write_begin did not prepare for
the case of inline data, which is expected by the write_end side of it.
------------[ cut here ]------------
kernel BUG at fs/ext4/inline.c:235!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 5838 Comm: syz-executor110 Not tainted 6.13.0-rc3-syzkaller-00209-g499551201b5f #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
RIP: 0010:ext4_write_inline_data fs/ext4/inline.c:235 [inline]
RIP: 0010:ext4_write_inline_data_end+0xdc7/0xdd0 fs/ext4/inline.c:774
Code: 47 1d 8c e8 4b 3a 91 ff 90 0f 0b e8 63 7a 47 ff 48 8b 7c 24 10 48 c7 c6 e0 47 1d 8c e8 32 3a 91 ff 90 0f 0b e8 4a 7a 47 ff 90 <0f> 0b 0f 1f 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90
RSP: 0018:ffffc900031c7320 EFLAGS: 00010293
RAX: ffffffff8257f9a6 RBX: 000000000000005a RCX: ffff888012968000
RDX: 0000000000000000 RSI: 000000000000005a RDI: 000000000000005b
RBP: ffffc900031c7448 R08: ffffffff8257ef87 R09: 1ffff11006806070
R10: dffffc0000000000 R11: ffffed1006806071 R12: 000000000000005a
R13: dffffc0000000000 R14: ffff888076b65bd8 R15: 000000000000005b
FS: 00007f5c6bacf6c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000a00 CR3: 0000000073fb6000 CR4: 0000000000350ef0
Call Trace:
<TASK>
generic_perform_write+0x6f8/0x990 mm/filemap.c:4070
ext4_buffered_write_iter+0xc5/0x350 fs/ext4/file.c:299
ext4_file_write_iter+0x892/0x1c50
iter_file_splice_write+0xbfc/0x1510 fs/splice.c:743
do_splice_from fs/splice.c:941 [inline]
direct_splice_actor+0x11d/0x220 fs/splice.c:1164
splice_direct_to_actor+0x588/0xc80 fs/splice.c:1108
do_splice_direct_actor fs/splice.c:1207 [inline]
do_splice_direct+0x289/0x3e0 fs/splice.c:1233
do_sendfile+0x564/0x8a0 fs/read_write.c:1363
__do_sys_sendfile64 fs/read_write.c:1424 [inline]
__se_sys_sendfile64+0x17c/0x1e0 fs/read_write.c:1410
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f5c6bb18d09
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 b1 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f5c6bacf218 EFLAGS: 00000246 ORIG_RAX: 0000000000000028
RAX: ffffffffffffffda RBX: 00007f5c6bba0708 RCX: 00007f5c6bb18d09
RDX: 0000000000000000 RSI: 0000000000000005 RDI: 0000000000000004
RBP: 00007f5c6bba0700 R08: 0000000000000000 R09: 0000000000000000
R10: 000080001d00c0d0 R11: 0000000000000246 R12: 00007f5c6bb6d620
R13: 00007f5c6bb6d0c0 R14: 0031656c69662f2e R15: 8088e3ad122bc192
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
This happens because ext4_page_mkwrite is not protected by the inode_lock.
The xattr semaphore is not sufficient to protect inline data handling in a
sane way, so we need to rely on the inode_lock. Adding the inode_lock to
ext4_page_mkwrite is not an option, otherwise lock-ordering problems with
mmap_lock may arise.
The conversion inside ext4_page_mkwrite was introduced at commit
7b4cc9787fe3 ("ext4: evict inline data when writing to memory map"). This
fixes a documented bug in the commit message, which suggests some
alternative fixes.
Convert inline data when mmap is called, instead of doing it only when the
mmapped page is written to. Using the inode_lock there does not lead to
lock-ordering issues.
The drawback is that inline conversion will happen when the file is
mmapped, even though the page will not be written to.
Fixes: 7b4cc9787fe3 ("ext4: evict inline data when writing to memory map")
Reported-by: syzbot+0c89d865531d053abb2d(a)syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0c89d865531d053abb2d
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo(a)igalia.com>
Cc: stable(a)vger.kernel.org
---
Changes in v2:
- Convert inline data at mmap time, avoiding data loss.
- Link to v1: https://lore.kernel.org/r/20250519-ext4_inline_page_mkwrite-v1-1-865d9a62b5…
---
fs/ext4/file.c | 6 ++++++
fs/ext4/inode.c | 4 ----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index beb078ee4811d6092e362e37307e7d87e5276cbc..f2380471df5d99500e49fdc639fa3e56143c328f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -819,6 +819,12 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
if (!daxdev_mapping_supported(vma, dax_dev))
return -EOPNOTSUPP;
+ inode_lock(inode);
+ ret = ext4_convert_inline_data(inode);
+ inode_unlock(inode);
+ if (ret)
+ return ret;
+
file_accessed(file);
if (IS_DAX(file_inode(file))) {
vma->vm_ops = &ext4_dax_vm_ops;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 94c7d2d828a64e42ded09c82497ed7617071aa19..895ecda786194b29d32c9c49785d56a1a84e2096 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -6222,10 +6222,6 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf)
filemap_invalidate_lock_shared(mapping);
- err = ext4_convert_inline_data(inode);
- if (err)
- goto out_ret;
-
/*
* On data journalling we skip straight to the transaction handle:
* there's no delalloc; page truncated will be checked later; the
---
base-commit: 4a95bc121ccdaee04c4d72f84dbfa6b880a514b6
change-id: 20250519-ext4_inline_page_mkwrite-c42ca1f02295
Best regards,
--
Thadeu Lima de Souza Cascardo <cascardo(a)igalia.com>
The SD spec says: "In UHS-I mode, after selecting one of SDR50, SDR104,
or DDR50 mode by Function Group 1, host needs to change the Power Limit
to enable the card to operate in higher performance".
The driver previously determined SD card current limits incorrectly by
checking capability bits before bus speed was established, and by using
support bits in function group 4 (bytes 6 & 7) rather than the actual
current requirement (bytes 0 & 1). This is wrong because the card
responds for a given bus speed.
This patch queries the card's current requirement after setting the bus
speed, and uses the reported value to select the appropriate current
limit.
while at it, remove some unused constants and the misleading comment in
the code.
Fixes: d9812780a020 ("mmc: sd: limit SD card power limit according to cards capabilities")
Signed-off-by: Avri Altman <avri.altman(a)sandisk.com>
Cc: stable(a)vger.kernel.org
---
drivers/mmc/core/sd.c | 36 +++++++++++++-----------------------
include/linux/mmc/card.h | 6 ------
2 files changed, 13 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index cf92c5b2059a..357edfb910df 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -365,7 +365,6 @@ static int mmc_read_switch(struct mmc_card *card)
card->sw_caps.sd3_bus_mode = status[13];
/* Driver Strengths supported by the card */
card->sw_caps.sd3_drv_type = status[9];
- card->sw_caps.sd3_curr_limit = status[7] | status[6] << 8;
}
out:
@@ -556,7 +555,7 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
{
int current_limit = SD_SET_CURRENT_LIMIT_200;
int err;
- u32 max_current;
+ u32 max_current, card_needs;
/*
* Current limit switch is only defined for SDR50, SDR104, and DDR50
@@ -575,33 +574,24 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
max_current = sd_get_host_max_current(card->host);
/*
- * We only check host's capability here, if we set a limit that is
- * higher than the card's maximum current, the card will be using its
- * maximum current, e.g. if the card's maximum current is 300ma, and
- * when we set current limit to 200ma, the card will draw 200ma, and
- * when we set current limit to 400/600/800ma, the card will draw its
- * maximum 300ma from the host.
- *
- * The above is incorrect: if we try to set a current limit that is
- * not supported by the card, the card can rightfully error out the
- * attempt, and remain at the default current limit. This results
- * in a 300mA card being limited to 200mA even though the host
- * supports 800mA. Failures seen with SanDisk 8GB UHS cards with
- * an iMX6 host. --rmk
+ * query the card of its maximun current/power consumption given the
+ * bus speed mode
*/
- if (max_current >= 800 &&
- card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
+ err = mmc_sd_switch(card, 0, 0, card->sd_bus_speed, status);
+ if (err)
+ return err;
+
+ card_needs = status[1] | status[0] << 8;
+
+ if (max_current >= 800 && card_needs > 600)
current_limit = SD_SET_CURRENT_LIMIT_800;
- else if (max_current >= 600 &&
- card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
+ else if (max_current >= 600 && card_needs > 400)
current_limit = SD_SET_CURRENT_LIMIT_600;
- else if (max_current >= 400 &&
- card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
+ else if (max_current >= 400 && card_needs > 200)
current_limit = SD_SET_CURRENT_LIMIT_400;
if (current_limit != SD_SET_CURRENT_LIMIT_200) {
- err = mmc_sd_switch(card, SD_SWITCH_SET, 3,
- current_limit, status);
+ err = mmc_sd_switch(card, SD_SWITCH_SET, 3, current_limit, status);
if (err)
return err;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index e9e964c20e53..67c1386ca574 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -177,17 +177,11 @@ struct sd_switch_caps {
#define SD_DRIVER_TYPE_A 0x02
#define SD_DRIVER_TYPE_C 0x04
#define SD_DRIVER_TYPE_D 0x08
- unsigned int sd3_curr_limit;
#define SD_SET_CURRENT_LIMIT_200 0
#define SD_SET_CURRENT_LIMIT_400 1
#define SD_SET_CURRENT_LIMIT_600 2
#define SD_SET_CURRENT_LIMIT_800 3
-#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200)
-#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400)
-#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600)
-#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
-
#define SD4_SET_POWER_LIMIT_0_72W 0
#define SD4_SET_POWER_LIMIT_1_44W 1
#define SD4_SET_POWER_LIMIT_2_16W 2
--
2.25.1
Use common wrappers operating directly on the struct sg_table objects to
fix incorrect use of statterlists related calls. dma_unmap_sg() function
has to be called with the number of elements originally passed to the
dma_map_sg() function, not the one returned in sgtable's nents.
CC: stable(a)vger.kernel.org
Fixes: 425902f5c8e3 ("fpga zynq: Use the scatterlist interface")
Signed-off-by: Marek Szyprowski <m.szyprowski(a)samsung.com>
---
v2:
- fixed build break (missing flags parameter)
---
drivers/fpga/zynq-fpga.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git drivers/fpga/zynq-fpga.c drivers/fpga/zynq-fpga.c
index f7e08f7ea9ef..0be0d569589d 100644
--- drivers/fpga/zynq-fpga.c
+++ drivers/fpga/zynq-fpga.c
@@ -406,7 +406,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
}
priv->dma_nelms =
- dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
+ dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
if (priv->dma_nelms == 0) {
dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n");
return -ENOMEM;
@@ -478,7 +478,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
clk_disable(priv->clk);
out_free:
- dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
+ dma_unmap_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
return err;
}
--
2.34.1