6.1.159-rc1 review
Greg Kroah-Hartman
maintainerPATCH 281/568 fs/hpfs: Fix error code for new_inode() failure in mkdir/create/mknod/symlink
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yikang Yue <[email protected]>
[ Upstream commit 32058c38d3b79a28963a59ac0353644dc24775cd ]
The function call new_inode() is a primitive for allocating an inode in memory, rather than planning disk space for it. Therefore, -ENOMEM should be returned as the error code rather than -ENOSPC.
To be specific, new_inode()'s call path looks like this:new_inode
new_inode_pseudo
alloc_inode
ops->alloc_inode (hpfs_alloc_inode)
alloc_inode_sb
kmem_cache_alloc_lruTherefore, the failure of new_inode() indicates a memory presure issue (-ENOMEM), not a lack of disk space. However, the current implementation of hpfs_mkdir/create/mknod/symlink incorrectly returns -ENOSPC when new_inode() fails. This patch fix this by set err to -ENOMEM before the goto statement.
BTW, we also noticed that other nested calls within these four functions, like hpfs_alloc_f/dnode and hpfs_add_dirent, might also fail due to memory presure. But similarly, only -ENOSPC is returned. Addressing these will involve code modifications in other functions, and we plan to submit dedicated patches for these issues in the future. For this patch, we focus on new_inode().
--- fs/hpfs/namei.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
fs/hpfs/namei.c +12 -6
@@ -53,8 +53,10 @@ static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, dee.fnode =cpu_to_le32 (fno); dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail2; + }hpfs_init_inode (result); result->i_ino = fno;hpfs_i (result)->i_parent_dir = dir->i_ino;
@@ -156,9 +158,10 @@ static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; - + }hpfs_init_inode (result); result->i_ino = fno; result->i_mode |=S_IFREG ;
@@ -244,9 +247,10 @@ static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; - + }hpfs_init_inode (result); result->i_ino = fno;hpfs_i (result)->i_parent_dir = dir->i_ino;
@@ -321,8 +325,10 @@ static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; + } result->i_ino = fno;hpfs_init_inode (result);hpfs_i (result)->i_parent_dir = dir->i_ino;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 282/568 um: Fix help message for ssl-non-raw
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 725e9d81868fcedaeef775948e699955b01631ae ]
Add the missing option name in the help message. Additionally, switch to __uml_help(), because this is a global option rather than a per-channel option.
--- arch/um/drivers/ssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/um/drivers/ssl.c +4 -1
@@ -199,4 +199,7 @@ static int ssl_non_raw_setup(char *str)return 1 ; }__setup ("ssl-non-raw" , ssl_non_raw_setup); -__channel_help (ssl_non_raw_setup,"set serial lines to non-raw mode" ); +__uml_help (ssl_non_raw_setup, +"ssl-non-raw\n" +" Set serial lines to non-raw mode.\n\n" +);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 283/568 clk: sunxi-ng: sun6i-rtc: Add A523 specifics
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 7aa8781f379c32c31bd78f1408a31765b2297c43 ]
The A523's RTC block is backward compatible with the R329's, but it also has a calibration function for its internal oscillator, which would allow it to provide a clock rate closer to the desired 32.768 KHz. This is useful on the Radxa Cubie A5E, which does not have an external 32.768 KHz crystal.
Add new compatible-specific data for it.
--- drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +11 -0
@@ -323,6 +323,13 @@ static const struct sun6i_rtc_match_data sun50i_r329_rtc_ccu_data = { .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), }; +static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { + .have_ext_osc32k = true, + .have_iosc_calibration = true, + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, + .osc32k_fanout_nparents =ARRAY_SIZE (sun50i_r329_osc32k_fanout_parents), +}; +static const struct of_device_id sun6i_rtc_ccu_match[] = { { .compatible ="allwinner,sun50i-h616-rtc" ,
@@ -332,6 +339,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { .compatible = "allwinner,sun50i-r329-rtc", .data = &sun50i_r329_rtc_ccu_data, }, + { + .compatible = "allwinner,sun55i-a523-rtc", + .data = &sun55i_a523_rtc_ccu_data, + }, {}, };
Signature · 1 line
2.51.0
Re: [PATCH 6.1 283/568] clk: sunxi-ng: sun6i-rtc: Add A523 specifics
Quoted 9 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit
7aa8781f379c32c31bd78f1408a31765b2297c43]
Quoted 7 lines
The A523's RTC block is backward compatible with the R329's, but it also has a calibration function for its internal oscillator, which would allow it to provide a clock rate closer to the desired 32.768 KHz. This is useful on the Radxa Cubie A5E, which does not have an external 32.768 KHz crystal.
Add new compatible-specific data for it.
Support for the A523 SoC was added in v6.16. I don't think we need to backport A523 specific stuff any further back.
ChenYu
Quoted 42 lines
Acked-by Jernej Skrabec <[email protected]>Signed-off-by Chen-Yu Tsai <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 11 +++++++++++ 1 file changed, 11 insertions(+)drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +11
-1@@ -323,6 +323,13 @@ static const struct sun6i_rtc_match_data sun50i_r329_rtc_ccu_data = { .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), }; +static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { + .have_ext_osc32k = true, + .have_iosc_calibration = true, + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, + .osc32k_fanout_nparents =ARRAY_SIZE (sun50i_r329_osc32k_fanout_parents), +}; +static const struct of_device_id sun6i_rtc_ccu_match[] = { { .compatible ="allwinner,sun50i-h616-rtc" ,@@ -332,6 +339,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { .compatible = "allwinner,sun50i-r329-rtc", .data = &sun50i_r329_rtc_ccu_data, }, + { + .compatible = "allwinner,sun55i-a523-rtc", + .data = &sun55i_a523_rtc_ccu_data, + }, {}, }; --2.51.0
Greg Kroah-Hartman
maintainerRe: [PATCH 6.1 283/568] clk: sunxi-ng: sun6i-rtc: Add A523 specifics
Quoted 17 lines · Chen-Yu Tsai
Quoted 15 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit
7aa8781f379c32c31bd78f1408a31765b2297c43]The A523's RTC block is backward compatible with the R329's, but it also has a calibration function for its internal oscillator, which would allow it to provide a clock rate closer to the desired 32.768 KHz. This is useful on the Radxa Cubie A5E, which does not have an external 32.768 KHz crystal.
Quoted 4 lines
Quoted 1 line
Add new compatible-specific data for it.
Support for the A523 SoC was added in v6.16. I don't think we need to backport A523 specific stuff any further back.
Now dropped, thanks!
greg k-h
Greg Kroah-Hartman
maintainerPATCH 284/568 rtc: pcf2127: clear minute/second interrupt
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josua Mayer <[email protected]>
[ Upstream commit a6f1a4f05970664004a9370459c6799c1b2f2dcf ]
PCF2127 can generate interrupt every full second or minute configured from control and status register 1, bits MI (1) and SI (0).
On interrupt control register 2 bit MSF (7) is set and must be cleared to continue normal operation.
While the driver never enables this interrupt on its own, users or firmware may do so - e.g. as an easy way to test the interrupt.
Add preprocessor definition for MSF bit and include it in the irq bitmask to ensure minute and second interrupts are cleared when fired.
This fixes an issue where the rtc enters a test mode and becomes unresponsive after a second interrupt has fired and is not cleared in time. In this state register writes to control registers have no effect and the interrupt line is kept asserted [1]:
[1] userspace commands to put rtc into unresponsive state:
$ i2cget -f -y 2 0x51 0x00 0x04 $ i2cset -f -y 2 0x51 0x00 0x05 # set bit 0 SI $ i2cget -f -y 2 0x51 0x00 0x84 # bit 8 EXT_TEST set $ i2cset -f -y 2 0x51 0x00 0x05 # try overwrite control register $ i2cget -f -y 2 0x51 0x00 0x84 # no change
--- drivers/rtc/rtc-pcf2127.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/rtc/rtc-pcf2127.c +3 -1
@@ -35,6 +35,7 @@#define PCF2127_BIT_CTRL2_AF BIT(4)#define PCF2127_BIT_CTRL2_TSF2 BIT(5)#define PCF2127_BIT_CTRL2_WDTF BIT(6) +#define PCF2127_BIT_CTRL2_MSF BIT(7)/* Control register 3 */ #define PCF2127_REG_CTRL3 0x02#define PCF2127_BIT_CTRL3_BLIE BIT(0)
@@ -99,7 +100,8 @@#define PCF2127_CTRL2_IRQ_MASK ( \ PCF2127_BIT_CTRL2_AF | \ PCF2127_BIT_CTRL2_WDTF | \ - PCF2127_BIT_CTRL2_TSF2) + PCF2127_BIT_CTRL2_TSF2 | \ + PCF2127_BIT_CTRL2_MSF)struct pcf2127 {struct rtc_device *rtc;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 285/568 ARM: at91: pm: save and restore ACR during PLL disable/enable
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Ferre <[email protected]>
[ Upstream commit 0c01fe49651d387776abed6a28541e80c8a93319 ]
Add a new word in assembly to store ACR value during the calls to at91_plla_disable/at91_plla_enable macros and use it.
--- arch/arm/mach-at91/pm_suspend.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/mach-at91/pm_suspend.S +7 -1
@@ -685,6 +685,10 @@ sr_dis_exit: bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID str tmp2, [pmc, #AT91_PMC_PLL_UPDT] + /* save acr */ + ldr tmp2, [pmc, #AT91_PMC_PLL_ACR] + str tmp2, .saved_acr + /* save div. */ mov tmp1, #0 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
@@ -754,7 +758,7 @@ sr_dis_exit: str tmp1, [pmc, #AT91_PMC_PLL_UPDT] /* step 2. */ - ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA + ldr tmp1, .saved_acr str tmp1, [pmc, #AT91_PMC_PLL_ACR] /* step 3. */
@@ -1130,6 +1134,8 @@ ENDPROC(at91_pm_suspend_in_sram) .word 0 .saved_mckr: .word 0 +.saved_acr: + .word 0 .saved_pllar: .word 0 .saved_sam9_lpr:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 286/568 clk: at91: clk-master: Add check for divide by 3
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Wanner <[email protected]>
[ Upstream commit e0237f5635727d64635ec6665e1de9f4cacce35c ]
A potential divider for the master clock is div/3. The register configuration for div/3 is MASTER_PRES_MAX. The current bit shifting method does not work for this case. Checking for MASTER_PRES_MAX will ensure the correct decimal value is stored in the system.
--- drivers/clk/at91/clk-master.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/at91/clk-master.c +3 -0
@@ -574,6 +574,9 @@ clk_sama7g5_master_recalc_rate(struct clk_hw *hw, {struct clk_master *master =to_clk_master (hw); +if (master->div ==MASTER_PRES_MAX ) +return DIV_ROUND_CLOSEST_ULL (parent_rate,3 ); +return DIV_ROUND_CLOSEST_ULL (parent_rate, (1 << master->div)); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 287/568 clk: at91: clk-sam9x60-pll: force write to PLL_UPDT register
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Ferre <[email protected]>
[ Upstream commit af98caeaa7b6ad11eb7b7c8bfaddc769df2889f3 ]
This register is important for sequencing the commands to PLLs, so actually write the update bits with regmap_write_bits() instead of relying on a read/modify/write regmap command that could skip the actual hardware write if the value is identical to the one read.
It's changed when modification is needed to the PLL, when read-only operation is done, we could keep the call to regmap_update_bits().
Add a comment to the sam9x60_div_pll_set_div() function that uses this PLL_UPDT register so that it's used consistently, according to the product's datasheet.
[claudiu.beznea: fix "Alignment should match open parenthesis"
checkpatch.pl check]
--- drivers/clk/at91/clk-sam9x60-pll.c | 75 ++++++++++++++++-------------- 1 file changed, 39 insertions(+), 36 deletions(-)
drivers/clk/at91/clk-sam9x60-pll.c +39 -36
@@ -90,8 +90,8 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL1 , &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -125,17 +125,17 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)udelay (10 ); } -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -161,8 +161,8 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENPLL ,0 );
@@ -170,9 +170,9 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)regmap_update_bits (regmap,AT91_PMC_PLL_ACR ,AT91_PMC_PLL_ACR_UTMIBG |AT91_PMC_PLL_ACR_UTMIVR ,0 ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);spin_unlock_irqrestore (core->lock, flags); }
@@ -257,8 +257,8 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,spin_lock_irqsave (core->lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL1 , &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -270,18 +270,18 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, (frac->mul << core->layout->mul_shift) | (frac->frac << core->layout->frac_shift)); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -333,7 +333,10 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { .restore_context = sam9x60_frac_pll_restore_context, }; -/* This function should be called with spinlock acquired. */ +/* This function should be called with spinlock acquired. +* Warning: this function must be called only if the same PLL ID was set in +* PLL_UPDT register previously. +*/ static void sam9x60_div_pll_set_div (struct sam9x60_pll_core *core,u32 div,bool enable) {
@@ -345,9 +348,9 @@ static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, core->layout->div_mask | ena_msk, (div << core->layout->div_shift) | ena_val); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -361,8 +364,8 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core)unsigned int val, cdiv;spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
@@ -393,15 +396,15 @@ static void sam9x60_div_pll_unprepare(struct clk_hw *hw)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 , core->layout->endiv_mask,0 ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);spin_unlock_irqrestore (core->lock, flags); }
@@ -507,8 +510,8 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, div->div =DIV_ROUND_CLOSEST (parent_rate, rate) -1 ;spin_lock_irqsave (core->lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
@@ -563,8 +566,8 @@ static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier, div->div = div->safe_div;spin_lock_irqsave (core.lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core.id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core.id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core.layout->div_mask) >> core.layout->div_shift;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 288/568 clk: ti: am33xx: keep WKUP_DEBUGSS_CLKCTRL enabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Schiffer <[email protected]>
[ Upstream commit 1e0d75258bd09323cb452655549e03975992b29e ]
As described in AM335x Errata Advisory 1.0.42, WKUP_DEBUGSS_CLKCTRL can't be disabled - the clock module will just be stuck in transitioning state forever, resulting in the following warning message after the wait loop times out:
l3-aon-clkctrl:0000:0: failed to disable
Just add the clock to enable_init_clks, so no attempt is made to disable it.
--- drivers/clk/ti/clk-33xx.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/ti/clk-33xx.c +2 -0
@@ -258,6 +258,8 @@ static const char *enable_init_clks[] = {"dpll_ddr_m2_ck" ,"dpll_mpu_m2_ck" ,"l3_gclk" , +/* WKUP_DEBUGSS_CLKCTRL - disable fails, AM335x Errata Advisory 1.0.42 */ +"l3-aon-clkctrl:0000:0" ,/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */ "l3-clkctrl:00bc:0" , "l4hs_gclk",
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 289/568 NTB: epf: Allow arbitrary BAR mapping
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 5ad865862a0fd349163243e1834ed98ba9b81905 ]
The NTB epf host driver assumes the BAR number associated with a memory window is just incremented from the BAR number associated with MW1. This seems to have been enough so far but this is not really how the endpoint side work and the two could easily become mis-aligned.
ntb_epf_mw_to_bar() even assumes that the BAR number is the memory window index + 2, which means the function only returns a proper result if BAR_2 is associated with MW1.
Instead, fully describe and allow arbitrary NTB BAR mapping.
--- drivers/ntb/hw/epf/ntb_hw_epf.c | 103 ++++++++++++++++---------------- 1 file changed, 53 insertions(+), 50 deletions(-)
drivers/ntb/hw/epf/ntb_hw_epf.c +53 -50
@@ -49,6 +49,7 @@#define NTB_EPF_COMMAND_TIMEOUT 1000/* 1 Sec */ enum pci_barno { +NO_BAR =-1 ,BAR_0 ,BAR_1 ,BAR_2 ,
@@ -57,16 +58,26 @@ enum pci_barno { BAR_5, }; +enum epf_ntb_bar { +BAR_CONFIG , +BAR_PEER_SPAD , +BAR_DB , +BAR_MW1 , +BAR_MW2 , +BAR_MW3 , +BAR_MW4 , +NTB_BAR_NUM , +}; + +#define NTB_EPF_MAX_MW_COUNT (NTB_BAR_NUM - BAR_MW1) +struct ntb_epf_dev {struct ntb_dev ntb;struct device *dev;/* Mutex to protect providing commands to NTB EPF */ struct mutex cmd_lock; -enum pci_barno ctrl_reg_bar; -enum pci_barno peer_spad_reg_bar; -enum pci_barno db_reg_bar; -enum pci_barno mw_bar; +const enum pci_barno *barno_map;unsigned int mw_count;unsigned int spad_count;
@@ -85,17 +96,6 @@ struct ntb_epf_dev {#define ntb_ndev (__ntb) container_of(__ntb, struct ntb_epf_dev, ntb) -struct ntb_epf_data { -/* BAR that contains both control region and self spad region */ -enum pci_barno ctrl_reg_bar; -/* BAR that contains peer spad region */ -enum pci_barno peer_spad_reg_bar; -/* BAR that contains Doorbell region and Memory window '1' */ -enum pci_barno db_reg_bar; -/* BAR that contains memory windows*/ -enum pci_barno mw_bar; -}; -static int ntb_epf_send_command (struct ntb_epf_dev *ndev,u32 command,u32 argument) {
@@ -144,7 +144,7 @@ static int ntb_epf_mw_to_bar(struct ntb_epf_dev *ndev, int idx)return -EINVAL ; } -return idx +2 ; +return ndev->barno_map[BAR_MW1 + idx]; }static int ntb_epf_mw_count (struct ntb_dev *ntb,int pidx)
@@ -413,7 +413,9 @@ static int ntb_epf_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,return -EINVAL ; } - bar = idx + ndev->mw_bar; + bar =ntb_epf_mw_to_bar (ndev, idx); +if (bar <0 ) +return bar; mw_size =pci_resource_len (ntb->pdev, bar);
@@ -455,7 +457,9 @@ static int ntb_epf_peer_mw_get_addr(struct ntb_dev *ntb, int idx,if (idx ==0 ) offset =readl (ndev->ctrl_reg +NTB_EPF_MW1_OFFSET ); - bar = idx + ndev->mw_bar; + bar =ntb_epf_mw_to_bar (ndev, idx); +if (bar <0 ) +return bar;if (base) *base =pci_resource_start (ndev->ntb.pdev, bar) + offset;
@@ -560,6 +564,11 @@ static int ntb_epf_init_dev(struct ntb_epf_dev *ndev) ndev->mw_count =readl (ndev->ctrl_reg +NTB_EPF_MW_COUNT ); ndev->spad_count =readl (ndev->ctrl_reg +NTB_EPF_SPAD_COUNT ); +if (ndev->mw_count >NTB_EPF_MAX_MW_COUNT ) { +dev_err (dev,"Unsupported MW count: %u\n" , ndev->mw_count); +return -EINVAL ; + } +return 0 ; }
@@ -596,14 +605,15 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev,dev_warn (&pdev->dev,"Cannot DMA highmem\n" ); } - ndev->ctrl_reg =pci_iomap (pdev, ndev->ctrl_reg_bar,0 ); + ndev->ctrl_reg =pci_iomap (pdev, ndev->barno_map[BAR_CONFIG ],0 );if (!ndev->ctrl_reg) { ret = -EIO ; goto err_dma_mask; } -if (ndev->peer_spad_reg_bar) { - ndev->peer_spad_reg =pci_iomap (pdev, ndev->peer_spad_reg_bar,0 ); +if (ndev->barno_map[BAR_PEER_SPAD ] != ndev->barno_map[BAR_CONFIG ]) { + ndev->peer_spad_reg =pci_iomap (pdev, + ndev->barno_map[BAR_PEER_SPAD ],0 );if (!ndev->peer_spad_reg) { ret = -EIO ; goto err_dma_mask;
@@ -614,7 +624,7 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev, ndev->peer_spad_reg = ndev->ctrl_reg + spad_off + spad_sz; } - ndev->db_reg =pci_iomap (pdev, ndev->db_reg_bar,0 ); + ndev->db_reg =pci_iomap (pdev, ndev->barno_map[BAR_DB ],0 );if (!ndev->db_reg) { ret = -EIO ; goto err_dma_mask;
@@ -663,12 +673,7 @@ static void ntb_epf_cleanup_isr(struct ntb_epf_dev *ndev)static int ntb_epf_pci_probe (struct pci_dev *pdev,const struct pci_device_id *id) { -enum pci_barno peer_spad_reg_bar =BAR_1 ; -enum pci_barno ctrl_reg_bar =BAR_0 ; -enum pci_barno db_reg_bar =BAR_2 ; -enum pci_barno mw_bar =BAR_2 ;struct device *dev = &pdev->dev; -struct ntb_epf_data *data;struct ntb_epf_dev *ndev;int ret;
@@ -679,18 +684,10 @@ static int ntb_epf_pci_probe(struct pci_dev *pdev,if (!ndev)return -ENOMEM ; - data = (struct ntb_epf_data *)id->driver_data; -if (data) { - peer_spad_reg_bar = data->peer_spad_reg_bar; - ctrl_reg_bar = data->ctrl_reg_bar; - db_reg_bar = data->db_reg_bar; - mw_bar = data->mw_bar; - } + ndev->barno_map = (const enum pci_barno *)id->driver_data; +if (!ndev->barno_map) +return -EINVAL ; - ndev->peer_spad_reg_bar = peer_spad_reg_bar; - ndev->ctrl_reg_bar = ctrl_reg_bar; - ndev->db_reg_bar = db_reg_bar; - ndev->mw_bar = mw_bar; ndev->dev = dev;ntb_epf_init_struct (ndev, pdev);
@@ -734,30 +731,36 @@ static void ntb_epf_pci_remove(struct pci_dev *pdev)ntb_epf_deinit_pci (ndev); } -static const struct ntb_epf_data j721e_data = { - .ctrl_reg_bar =BAR_0 , - .peer_spad_reg_bar =BAR_1 , - .db_reg_bar =BAR_2 , - .mw_bar =BAR_2 , +static const enum pci_barno j721e_map[NTB_BAR_NUM ] = { + [BAR_CONFIG ] =BAR_0 , + [BAR_PEER_SPAD ] =BAR_1 , + [BAR_DB ] =BAR_2 , + [BAR_MW1 ] =BAR_2 , + [BAR_MW2 ] =BAR_3 , + [BAR_MW3 ] =BAR_4 , + [BAR_MW4 ] =BAR_5 }; -static const struct ntb_epf_data mx8_data = { - .ctrl_reg_bar =BAR_0 , - .peer_spad_reg_bar =BAR_0 , - .db_reg_bar =BAR_2 , - .mw_bar =BAR_4 , +static const enum pci_barno mx8_map[NTB_BAR_NUM ] = { + [BAR_CONFIG ] =BAR_0 , + [BAR_PEER_SPAD ] =BAR_0 , + [BAR_DB ] =BAR_2 , + [BAR_MW1 ] =BAR_4 , + [BAR_MW2 ] =BAR_5 , + [BAR_MW3 ] =NO_BAR , + [BAR_MW4 ] =NO_BAR };static const struct pci_device_id ntb_epf_pci_tbl[] = { {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCI_DEVICE_ID_TI_J721E ), .class =PCI_CLASS_MEMORY_RAM <<8 , .class_mask =0xffff00 , - .driver_data = (kernel_ulong_t)&j721e_data, + .driver_data = (kernel_ulong_t )j721e_map, }, {PCI_DEVICE (PCI_VENDOR_ID_FREESCALE ,0x0809 ), .class =PCI_CLASS_MEMORY_RAM <<8 , .class_mask =0xffff00 , - .driver_data = (kernel_ulong_t)&mx8_data, + .driver_data = (kernel_ulong_t )mx8_map, }, { }, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 290/568 9p: fix /sys/fs/9p/caches overwriting itself
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randall P. Embry <[email protected]>
[ Upstream commit 86db0c32f16c5538ddb740f54669ace8f3a1f3d7 ]
caches_show() overwrote its buffer on each iteration, so only the last cache tag was visible in sysfs output.
Properly append with snprintf(buf + count, …).
Message-ID: <[email protected]>
--- fs/9p/v9fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/9p/v9fs.c +1 -1
@@ -561,7 +561,7 @@ static ssize_t caches_show(struct kobject *kobj,spin_lock (&v9fs_sessionlist_lock);list_for_each_entry (v9ses, &v9fs_sessionlist, slist) {if (v9ses->cachetag) { - n =snprintf (buf, limit,"%s\n" , v9ses->cachetag); + n =snprintf (buf + count, limit,"%s\n" , v9ses->cachetag);if (n <0 ) { count = n;break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 291/568 cpufreq: tegra186: Initialize all cores to max frequencies
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Kling <[email protected]>
[ Upstream commit ba6018929165fc914c665f071f8e8cdbac844a49 ]
During initialization, the EDVD_COREx_VOLT_FREQ registers for some cores are still at reset values and not reflecting the actual frequency. This causes get calls to fail. Set all cores to their respective max frequency during probe to initialize the registers to working values.
--- drivers/cpufreq/tegra186-cpufreq.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
drivers/cpufreq/tegra186-cpufreq.c +21 -6
@@ -132,13 +132,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {static struct cpufreq_frequency_table *init_vhint_table (struct platform_device *pdev,struct tegra_bpmp *bpmp, -struct tegra186_cpufreq_cluster *cluster,unsigned int cluster_id) +struct tegra186_cpufreq_cluster *cluster,unsigned int cluster_id, +int *num_rates) {struct cpufreq_frequency_table *table;struct mrq_cpu_vhint_request req;struct tegra_bpmp_message msg;struct cpu_vhint_data *data; -int err, i, j, num_rates =0 ; +int err, i, j;dma_addr_t phys;void *virt;
@@ -168,6 +169,7 @@ static struct cpufreq_frequency_table *init_vhint_table( goto free; } + *num_rates =0 ;for (i = data->vfloor; i <= data->vceil; i++) {u16 ndiv = data->ndiv[i];
@@ -178,10 +180,10 @@ static struct cpufreq_frequency_table *init_vhint_table(if (i >0 && ndiv == data->ndiv[i -1 ])continue ; - num_rates++; + (*num_rates)++; } - table =devm_kcalloc (&pdev->dev, num_rates +1 ,sizeof (*table), + table =devm_kcalloc (&pdev->dev, *num_rates +1 ,sizeof (*table),GFP_KERNEL );if (!table) { table =ERR_PTR (-ENOMEM );
@@ -223,7 +225,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev) {struct tegra186_cpufreq_data *data;struct tegra_bpmp *bpmp; -unsigned int i =0 , err; +unsigned int i =0 , err, edvd_offset; +int num_rates =0 ; +u32 edvd_val, cpu; data =devm_kzalloc (&pdev->dev,sizeof (*data),GFP_KERNEL );if (!data)
@@ -249,10 +253,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)for (i =0 ; i <TEGRA186_NUM_CLUSTERS ; i++) {struct tegra186_cpufreq_cluster *cluster = &data->clusters[i]; - cluster->table =init_vhint_table (pdev, bpmp, cluster, i); + cluster->table =init_vhint_table (pdev, bpmp, cluster, i, &num_rates);if (IS_ERR (cluster->table)) { err =PTR_ERR (cluster->table); goto put_bpmp; + }else if (!num_rates) { + err = -EINVAL ; + goto put_bpmp; + } + +for (cpu =0 ; cpu <ARRAY_SIZE (tegra186_cpus); cpu++) { +if (data->cpus[cpu].bpmp_cluster_id == i) { + edvd_val = cluster->table[num_rates -1 ].driver_data; + edvd_offset = data->cpus[cpu].edvd_offset; +writel (edvd_val, data->regs + edvd_offset); + } } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 292/568 9p: sysfs_init: dont hardcode error to ENOMEM
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randall P. Embry <[email protected]>
[ Upstream commit 528f218b31aac4bbfc58914d43766a22ab545d48 ]
v9fs_sysfs_init() always returned -ENOMEM on failure; return the actual sysfs_create_group() error instead.
Message-ID: <[email protected]>
--- fs/9p/v9fs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/9p/v9fs.c +5 -2
@@ -597,13 +597,16 @@ static const struct attribute_group v9fs_attr_group = {static int __init v9fs_sysfs_init (void ) { +int ret; + v9fs_kobj =kobject_create_and_add ("9p" , fs_kobj);if (!v9fs_kobj)return -ENOMEM ; -if (sysfs_create_group (v9fs_kobj, &v9fs_attr_group)) { + ret =sysfs_create_group (v9fs_kobj, &v9fs_attr_group); +if (ret) {kobject_put (v9fs_kobj); -return -ENOMEM ; +return ret; }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 293/568 scsi: ufs: core: Include UTP error in INT_FATAL_ERRORS
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hoyoung Seo <[email protected]>
[ Upstream commit 558ae4579810fa0fef011944230c65a6f3087f85 ]
When a UTP error occurs in isolation, UFS is not currently recoverable. This is because the UTP error is not considered fatal in the error handling code, leading to either an I/O timeout or an OCS error.
Add the UTP error flag to INT_FATAL_ERRORS so the controller will be reset in this situation.
sd 0:0:0:0: [sda] tag#38 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s
sd 0:0:0:0: [sda] tag#38 CDB: opcode=0x28 28 00 00 51 24 e2 00 00 08 00 I/O error, dev sda, sector 42542864 op 0x0:(READ) flags 0x80700 phys_seg 8 prio class 2
OCS error from controller = 9 for tag 39
pa_err[1] = 0x80000010 at 2667224756 us
pa_err: total cnt=2
dl_err[0] = 0x80000002 at 2667148060 us
dl_err[1] = 0x80002000 at 2667282844 us
No record of nl_err
No record of tl_err
No record of dme_err
No record of auto_hibern8_err
fatal_err[0] = 0x804 at 2667282836 us
---------------------------------------------------
REGISTER
---------------------------------------------------
NAME OFFSET VALUE
STD HCI SFR 0xfffffff0 0x0
AHIT 0x18 0x814
INTERRUPT STATUS 0x20 0x1000
INTERRUPT ENABLE 0x24 0x70ef5[mkp: commit desc]
Message-Id: <[email protected]>
--- include/ufs/ufshci.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
include/ufs/ufshci.h +3 -1
@@ -123,6 +123,7 @@ static inline u32 ufshci_version(u32 major, u32 minor)#define UTP_TASK_REQ_COMPL 0x200#define UIC_COMMAND_COMPL 0x400#define DEVICE_FATAL_ERROR 0x800 +#define UTP_ERROR 0x1000#define CONTROLLER_FATAL_ERROR 0x10000#define SYSTEM_BUS_FATAL_ERROR 0x20000#define CRYPTO_ENGINE_FATAL_ERROR 0x40000
@@ -141,7 +142,8 @@ static inline u32 ufshci_version(u32 major, u32 minor) CONTROLLER_FATAL_ERROR |\ SYSTEM_BUS_FATAL_ERROR |\ CRYPTO_ENGINE_FATAL_ERROR |\ - UIC_LINK_LOST) + UIC_LINK_LOST |\ + UTP_ERROR)/* HCS - Host Controller Status 30h */ #define DEVICE_PRESENT 0x1
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 294/568 ACPI: property: Return present device nodes only on fwnode interface
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
[ Upstream commit d9f866b2bb3eec38b3734f1fed325ec7c55ccdfa ]
fwnode_graph_get_next_subnode() may return fwnode backed by ACPI device nodes and there has been no check these devices are present in the system, unlike there has been on fwnode OF backend.
In order to provide consistent behaviour towards callers, add a check for device presence by introducing
a new function acpi_get_next_present_subnode(), used as the get_next_child_node() fwnode operation that also checks device node presence.
--- drivers/acpi/property.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
drivers/acpi/property.c +23 -1
@@ -1298,6 +1298,28 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,return NULL ; } +/* +* acpi_get_next_present_subnode - Return the next present child node handle +* @fwnode: Firmware node to find the next child node for. +* @child: Handle to one of the device's child nodes or a null handle. +* +* Like acpi_get_next_subnode(), but the device nodes returned by +* acpi_get_next_present_subnode() are guaranteed to be present. +* +* Returns: The fwnode handle of the next present sub-node. +*/ +static struct fwnode_handle * +acpi_get_next_present_subnode (const struct fwnode_handle *fwnode, +struct fwnode_handle *child) +{ +do { + child =acpi_get_next_subnode (fwnode, child); + }while (is_acpi_device_node (child) && + !acpi_device_is_present (to_acpi_device_node (child))); + +return child; +} +/** * acpi_node_get_parent - Return parent fwnode of this fwnode * @fwnode: Firmware node whose parent to get
@@ -1641,7 +1663,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode, .property_read_string_array = \ acpi_fwnode_property_read_string_array, \ .get_parent = acpi_node_get_parent, \ - .get_next_child_node = acpi_get_next_subnode, \ + .get_next_child_node = acpi_get_next_present_subnode, \ .get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_name = acpi_fwnode_get_name, \ .get_name_prefix = acpi_fwnode_get_name_prefix, \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 295/568 tools bitmap: Add missing asm-generic/bitsperlong.h include
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit f38ce0209ab4553906b44bd1159e35c740a84161 ]
small_const_nbits is defined in asm-generic/bitsperlong.h which bitmap.h uses but doesn't include causing build failures in some build systems. Add the missing #include.
Note the bitmap.h in tools has diverged from that of the kernel, so no changes are made there.
--- tools/include/linux/bitmap.h | 1 + 1 file changed, 1 insertion(+)
tools/include/linux/bitmap.h +1 -0
@@ -3,6 +3,7 @@#define _TOOLS_LINUX_BITMAP_H#include <string.h> +#include <asm-generic/bitsperlong.h> #include <linux/align.h> #include <linux/bitops.h> #include <linux/find.h>
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 296/568 tools: lib: thermal: dont preserve owner in install
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emil Dahl Juhl <[email protected]>
[ Upstream commit 1375152bb02ab2a8435e87ea27034482dbc95f57 ]
Instead of preserving mode, timestamp, and owner, for the object files during installation, just preserve the mode and timestamp.
When installing as root, the installed files should be owned by root. When installing as user, --preserve=ownership doesn't work anyway. This makes --preserve=ownership rather pointless.
--- tools/lib/thermal/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/thermal/Makefile +1 -1
@@ -147,7 +147,7 @@ endef install_lib: libs $(call QUIET_INSTALL, $(LIBTHERMAL_ALL)) \ $(call do_install_mkdir,$(libdir_SQ)); \ - cp -fpR $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ) + cp -fR --preserve=mode,timestamp $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ) install_headers: $(call QUIET_INSTALL, headers) \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 297/568 tools: lib: thermal: use pkg-config to locate libnl3
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
[ Upstream commit b31f7f725cd932e2c2b41f3e4b66273653953687 ]
To make libthermal more cross compile friendly use pkg-config to locate libnl3. Only if that fails fall back to hardcoded /usr/include/libnl3.
--- tools/lib/thermal/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/lib/thermal/Makefile +6 -1
@@ -59,8 +59,12 @@ else CFLAGS := -g -Wall endif +NL3_CFLAGS = $(shell pkg-config --cflags libnl-3.0 2>/dev/null) +ifeq ($(NL3_CFLAGS),) +NL3_CFLAGS = -I/usr/include/libnl3 +endif + INCLUDES = \ --I/usr/include/libnl3 \ -I$(srctree)/tools/lib/thermal/include \ -I$(srctree)/tools/lib/ \ -I$(srctree)/tools/include \
@@ -72,6 +76,7 @@ INCLUDES = \ override CFLAGS += $(EXTRA_WARNINGS) override CFLAGS += -Werror -Wall override CFLAGS += -fPIC +override CFLAGS += $(NL3_CFLAGS) override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden override CFGLAS += -Wl,-L.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 298/568 fbdev: Add bounds checking in bit_putcs to fix vmalloc-out-of-bounds
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Albin Babu Varghese <[email protected]>
[ Upstream commit 3637d34b35b287ab830e66048841ace404382b67 ]
Add bounds checking to prevent writes past framebuffer boundaries when rendering text near screen edges. Return early if the Y position is off-screen and clip image height to screen boundary. Break from the rendering loop if the X position is off-screen. When clipping image width to fit the screen, update the character count to match the clipped width to prevent buffer size mismatches.
Without the character count update, bit_putcs_aligned and bit_putcs_unaligned receive mismatched parameters where the buffer is allocated for the clipped width but cnt reflects the original larger count, causing out-of-bounds writes.
--- drivers/video/fbdev/core/bitblit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/video/fbdev/core/bitblit.c +17 -0
@@ -168,6 +168,11 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, image.height = vc->vc_font.height; image.depth =1 ; +if (image.dy >= info->var.yres) +return ; + + image.height =min (image.height, info->var.yres - image.dy); +if (attribute) { buf =kmalloc (cellsize,GFP_ATOMIC );if (!buf)
@@ -181,6 +186,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, cnt = count; image.width = vc->vc_font.width * cnt; + +if (image.dx >= info->var.xres) +break ; + +if (image.dx + image.width > info->var.xres) { + image.width = info->var.xres - image.dx; + cnt = image.width / vc->vc_font.width; +if (cnt ==0 ) +break ; + image.width = cnt * vc->vc_font.width; + } + pitch =DIV_ROUND_UP (image.width,8 ) + scan_align; pitch &= ~scan_align; size = pitch * image.height + buf_align;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 299/568 kbuild: uapi: Strip comments before size type check
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 66128f4287b04aef4d4db9bf5035985ab51487d5 ]
On m68k, check_sizetypes in headers_check reports:
./usr/include/asm/bootinfo-amiga.h:17: found __[us]{8,16,32,64} type without #include <linux/types.h>This header file does not use any of the Linux-specific integer types, but merely refers to them from comments, so this is a false positive. As of commit c3a9d74ee413bdb3 ("kbuild: uapi: upgrade check_sizetypes() warning to error"), this check was promoted to an error, breaking m68k all{mod,yes}config builds.
Fix this by stripping simple comments before looking for Linux-specific integer types.
[nathan: Adjust comment and remove unnecessary escaping from slashes in
regex]
--- usr/include/headers_check.pl | 2 ++ 1 file changed, 2 insertions(+)
usr/include/headers_check.pl +2 -0
@@ -160,6 +160,8 @@ sub check_sizetypes if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { check_include_typesh($included); } + # strip single-line comments, as types may be referenced within them + $line =~ s@/\*.*?\*/@@; if ($line =~ m/__[us](8|16|32|64)\b/) { printf STDERR "$filename:$lineno: " . "found __[us]{8,16,32,64} type " .
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 300/568 ASoC: meson: aiu-encoder-i2s: fix bit clock polarity
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valerio Setti <[email protected]>
[ Upstream commit 4c4ed5e073a923fb3323022e1131cb51ad8df7a0 ]
According to I2S specs audio data is sampled on the rising edge of the clock and it can change on the falling one. When operating in normal mode this SoC behaves the opposite so a clock polarity inversion is required in this case.
This was tested on an OdroidC2 (Amlogic S905 SoC) board.
--- sound/soc/meson/aiu-encoder-i2s.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
sound/soc/meson/aiu-encoder-i2s.c +6 -3
@@ -236,8 +236,12 @@ static int aiu_encoder_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) inv == SND_SOC_DAIFMT_IB_IF) val |=AIU_CLK_CTRL_LRCLK_INVERT ; -if (inv ==SND_SOC_DAIFMT_IB_NF || - inv ==SND_SOC_DAIFMT_IB_IF ) +/* +* The SoC changes data on the rising edge of the bitclock +* so an inversion of the bitclock is required in normal mode +*/ +if (inv ==SND_SOC_DAIFMT_NB_NF || + inv ==SND_SOC_DAIFMT_NB_IF ) val |=AIU_CLK_CTRL_AOCLK_INVERT ;/* Signal skew */
@@ -328,4 +332,3 @@ const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = { .startup = aiu_encoder_i2s_startup, .shutdown = aiu_encoder_i2s_shutdown, }; -
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 301/568 ceph: add checking of wait_for_completion_killable() return value
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit b7ed1e29cfe773d648ca09895b92856bd3a2092d ]
The Coverity Scan service has detected the calling of wait_for_completion_killable() without checking the return value in ceph_lock_wait_for_completion() [1]. The CID 1636232 defect contains explanation: "If the function returns an error value, the error value may be mistaken for a normal value. In ceph_lock_wait_for_completion(): Value returned from a function is not checked for errors before being used. (CWE-252)".
The patch adds the checking of wait_for_completion_killable() return value and return the error code from ceph_lock_wait_for_completion().
[1] https://scan5.scan.coverity.com/#/project-view/64304/10063?selectedIssue=1636232
--- fs/ceph/locks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/ceph/locks.c +4 -1
@@ -202,7 +202,10 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,if (err && err != -ERESTARTSYS )return err; -wait_for_completion_killable (&req->r_safe_completion); + err =wait_for_completion_killable (&req->r_safe_completion); +if (err) +return err; +return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 302/568 ALSA: hda/realtek: Audio disappears on HP 15-fc000 after warm boot again
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
[ Upstream commit f4b3cef55f5f96fdb4e7f9ca90b7d6213689faeb ]
There was a similar bug in the past (Bug 217440), which was fixed for this laptop.
The same issue is occurring again as of kernel v.6.12.2. The symptoms are very similar - initially audio works but after a warm reboot, the audio completely disappears until the computer is powered off (there is no audio output at all).
The issue is also related by caused by a different change now. By bisecting different kernel versions, I found that reverting cc3d0b5dd989 in patch_realtek.c[*] restores the sound and it works fine after the reboot.
[ patch description reformatted by tiwai ]
--- sound/pci/hda/patch_realtek.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
sound/pci/hda/patch_realtek.c +9 -8
@@ -3641,6 +3641,15 @@ static void alc256_shutup(struct hda_codec *codec) hp_pin =0x21 ;alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ + +/* 3k pull low control for Headset jack. */ +/* NOTE: call this before clearing the pin, otherwise codec stalls */ +/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly +* when booting with headset plugged. So skip setting it for the codec alc257 +*/ +if (spec->en_3kpull_low) +alc_update_coef_idx (codec,0x46 ,0 ,3 <<12 ); + hp_pin_sense =snd_hda_jack_detect (codec, hp_pin);if (hp_pin_sense) {
@@ -3651,14 +3660,6 @@ static void alc256_shutup(struct hda_codec *codec)msleep (75 ); -/* 3k pull low control for Headset jack. */ -/* NOTE: call this before clearing the pin, otherwise codec stalls */ -/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly -* when booting with headset plugged. So skip setting it for the codec alc257 -*/ -if (spec->en_3kpull_low) -alc_update_coef_idx (codec,0x46 ,0 ,3 <<12 ); -if (!spec->no_shutup_pins)snd_hda_codec_write (codec, hp_pin,0 ,AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 303/568 Revert "wifi: ath10k: avoid unnecessary wait for service ready message"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baochen Qiang <[email protected]>
commit 2469bb6a6af944755a7d7daf66be90f3b8decbf9 upstream.
This reverts commit 51a73f1b2e56b0324b4a3bb8cebc4221b5be4c7a.
Although this commit benefits QCA6174, it breaks QCA988x and QCA9984 [1][2]. Since it is not likely to root cause/fix this issue in a short time, revert it to get those chips back.
Compile tested only.
--- drivers/net/wireless/ath/ath10k/wmi.c | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-)
drivers/net/wireless/ath/ath10k/wmi.c +20 -19
@@ -1762,32 +1762,33 @@ void ath10k_wmi_put_wmi_channel(struct aint ath10k_wmi_wait_for_service_ready (struct ath10k *ar) { -unsigned long timeout = jiffies +WMI_SERVICE_READY_TIMEOUT_HZ ;unsigned long time_left, i; -/* Sometimes the PCI HIF doesn't receive interrupt -* for the service ready message even if the buffer -* was completed. PCIe sniffer shows that it's -* because the corresponding CE ring doesn't fires -* it. Workaround here by polling CE rings. Since -* the message could arrive at any time, continue -* polling until timeout. -*/ -do { + time_left =wait_for_completion_timeout (&ar->wmi.service_ready, +WMI_SERVICE_READY_TIMEOUT_HZ ); +if (!time_left) { +/* Sometimes the PCI HIF doesn't receive interrupt +* for the service ready message even if the buffer +* was completed. PCIe sniffer shows that it's +* because the corresponding CE ring doesn't fires +* it. Workaround here by polling CE rings once. +*/ +ath10k_warn (ar,"failed to receive service ready completion, polling..\n" ); +for (i =0 ; i <CE_COUNT ; i++)ath10k_hif_send_complete_check (ar, i,1 ); -/* The 100 ms granularity is a tradeoff considering scheduler -* overhead and response latency -*/ time_left =wait_for_completion_timeout (&ar->wmi.service_ready, -msecs_to_jiffies (100 )); -if (time_left) -return 0 ; - }while (time_before (jiffies, timeout)); +WMI_SERVICE_READY_TIMEOUT_HZ ); +if (!time_left) { +ath10k_warn (ar,"polling timed out\n" ); +return -ETIMEDOUT ; + } + +ath10k_warn (ar,"service ready completion received, continuing normally\n" ); + } -ath10k_warn (ar,"failed to receive service ready completion\n" ); -return -ETIMEDOUT ; +return 0 ; }int ath10k_wmi_wait_for_unified_ready (struct ath10k *ar)
Greg Kroah-Hartman
maintainerPATCH 304/568 Bluetooth: hci_event: validate skb length for unknown CC opcode
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Pinsonneault-Thibeault <[email protected]>
[ Upstream commit 5c5f1f64681cc889d9b13e4a61285e9e029d6ab5 ]
In hci_cmd_complete_evt(), if the command complete event has an unknown opcode, we assume the first byte of the remaining skb->data contains the return status. However, parameter data has previously been pulled in hci_event_func(), which may leave the skb empty. If so, using skb->data[0] for the return status uses un-init memory.
The fix is to check skb->len before using skb->data.
--- net/bluetooth/hci_event.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/bluetooth/hci_event.c +7 -0
@@ -4224,6 +4224,13 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, }if (i ==ARRAY_SIZE (hci_cc_table)) { +if (!skb->len) { +bt_dev_err (hdev,"Unexpected cc 0x%4.4x with no status" , + *opcode); + *status =HCI_ERROR_UNSPECIFIED ; +return ; + } +/* Unknown opcode, assume byte 0 contains the status, so * that e.g. __hci_cmd_sync() properly returns errors * for vendor specific commands send by HCI drivers.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 305/568 net: dsa: tag_brcm: legacy: fix untagged rx on unbridged ports for bcm63xx
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 3d18a84eddde169d6dbf3c72cc5358b988c347d0 ]
The internal switch on BCM63XX SoCs will unconditionally add 802.1Q VLAN tags on egress to CPU when 802.1Q mode is enabled. We do this unconditionally since commit ed409f3bbaa5 ("net: dsa: b53: Configure VLANs while not filtering").
This is fine for VLAN aware bridges, but for standalone ports and vlan unaware bridges this means all packets are tagged with the default VID, which is 0.
While the kernel will treat that like untagged, this can break userspace applications processing raw packets, expecting untagged traffic, like STP daemons.
This also breaks several bridge tests, where the tcpdump output then does not match the expected output anymore.
Since 0 isn't a valid VID, just strip out the VLAN tag if we encounter it, unless the priority field is set, since that would be a valid tag again.
--- net/dsa/tag_brcm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/dsa/tag_brcm.c +8 -2
@@ -251,12 +251,14 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, {int len =BRCM_LEG_TAG_LEN ;int source_port; +__be16 *proto;u8 *brcm_tag;if (unlikely (!pskb_may_pull (skb,BRCM_LEG_TAG_LEN +VLAN_HLEN )))return NULL ; brcm_tag =dsa_etype_header_pos_rx (skb); + proto = (__be16 *)(brcm_tag +BRCM_LEG_TAG_LEN ); source_port = brcm_tag[5 ] &BRCM_LEG_PORT_ID ;
@@ -264,8 +266,12 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,if (!skb->dev)return NULL ; -/* VLAN tag is added by BCM63xx internal switch */ -if (netdev_uses_dsa (skb->dev)) +/* The internal switch in BCM63XX SoCs always tags on egress on the CPU +* port. We use VID 0 internally for untagged traffic, so strip the tag +* if the TCI field is all 0, and keep it otherwise to also retain +* e.g. 802.1p tagged packets. +*/ +if (proto[0 ] ==htons (ETH_P_8021Q ) && proto[1 ] ==0 ) len +=VLAN_HLEN ;/* Remove Broadcom tag and update checksum */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 306/568 selftests/net: fix out-of-order delivery of FIN in gro:tcp test
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anubhav Singh <[email protected]>
[ Upstream commit 02d064de05b1fcca769391fa82d205bed8bb9bf0 ]
Due to the gro_sender sending data packets and FIN packets in very quick succession, these are received almost simultaneously by the gro_receiver. FIN packets are sometimes processed before the data packets leading to intermittent (~1/100) test failures.
This change adds a delay of 100ms before sending FIN packets in gro:tcp test to avoid the out-of-order delivery. The same mitigation already exists for the gro:ip test.
--- tools/testing/selftests/net/gro.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/testing/selftests/net/gro.c +8 -0
@@ -802,6 +802,7 @@ static void check_recv_pkts(int fd, int *correct_payload,static void gro_sender (void ) { +const int fin_delay_us =100 *1000 ;static char fin_pkt[MAX_HDR_LEN ];struct sockaddr_ll daddr = {};int txfd =-1 ;
@@ -845,15 +846,22 @@ static void gro_sender(void)write_packet (txfd, fin_pkt, total_hdr_len, &daddr); }else if (strcmp (testname,"tcp" ) ==0 ) {send_changed_checksum (txfd, &daddr); +/* Adding sleep before sending FIN so that it is not +* received prior to other packets. +*/ +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_changed_seq (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_changed_ts (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_diff_opt (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr); }else if (strcmp (testname,"ip" ) ==0 ) {send_changed_ECN (txfd, &daddr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 307/568 selftests/net: fix GRO coalesce test and add ext header coalesce tests
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Gobert <[email protected]>
[ Upstream commit 4e321d590cec6053cb3c566413794706035ee638 ]
Currently there is no test which checks that IPv6 extension header packets successfully coalesce. This commit adds a test, which verifies two IPv6 packets with HBH extension headers do coalesce, and another test which checks that packets with different extension header data do not coalesce in GRO.
I changed the receive socket filter to accept a packet with one extension header. This change exposed a bug in the fragment test -- the old BPF did not accept the fragment packet. I updated correct_num_packets in the fragment test accordingly.
Stable-dep-of: f8e8486702ab ("selftests/net: use destination options instead of hop-by-hop")
--- tools/testing/selftests/net/gro.c | 93 +++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 6 deletions(-)
tools/testing/selftests/net/gro.c +87 -6
@@ -71,6 +71,12 @@#define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))#define NUM_LARGE_PKT (MAX_PAYLOAD / MSS)#define MAX_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) +#define MIN_EXTHDR_SIZE 8 +#define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00" +#define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11" + +#define ipv6_optlen (p) (((p)->hdrlen+1) << 3)/* calculate IPv6 extension header len */ +#define BUILD_BUG_ON (condition) ((void)sizeof(char[1 - 2*!!(condition)]))static const char *addr6_src ="fdaa::2" ;static const char *addr6_dst ="fdaa::1" ;
@@ -104,7 +110,7 @@ static void setup_sock_filter(int fd)const int dport_off = tcp_offset + offsetof(struct tcphdr , dest);const int ethproto_off = offsetof(struct ethhdr , h_proto);int optlen =0 ; -int ipproto_off; +int ipproto_off, opt_ipproto_off;int next_off;if (proto ==PF_INET )
@@ -116,14 +122,30 @@ static void setup_sock_filter(int fd)if (strcmp (testname,"ip" ) ==0 ) {if (proto ==PF_INET ) optlen =sizeof (struct ip_timestamp ); -else - optlen =sizeof (struct ip6_frag ); +else { +BUILD_BUG_ON (sizeof (struct ip6_hbh ) >MIN_EXTHDR_SIZE ); +BUILD_BUG_ON (sizeof (struct ip6_dest ) >MIN_EXTHDR_SIZE ); +BUILD_BUG_ON (sizeof (struct ip6_frag ) >MIN_EXTHDR_SIZE ); + +/* same size for HBH and Fragment extension header types */ + optlen =MIN_EXTHDR_SIZE ; + opt_ipproto_off =ETH_HLEN +sizeof (struct ipv6hdr ) + + offsetof(struct ip6_ext , ip6e_nxt); + } } +/* this filter validates the following: +* - packet is IPv4/IPv6 according to the running test. +* - packet is TCP. Also handles the case of one extension header and then TCP. +* - checks the packet tcp dport equals to DPORT. Also handles the case of one +* extension header and then TCP. +*/ struct sock_filter filter[] = {BPF_STMT (BPF_LD +BPF_H +BPF_ABS , ethproto_off), -BPF_JUMP (BPF_JMP +BPF_JEQ +BPF_K ,ntohs (ethhdr_proto),0 ,7 ), +BPF_JUMP (BPF_JMP +BPF_JEQ +BPF_K ,ntohs (ethhdr_proto),0 ,9 ),BPF_STMT (BPF_LD +BPF_B +BPF_ABS , ipproto_off), +BPF_JUMP (BPF_JMP +BPF_JEQ +BPF_K ,IPPROTO_TCP ,2 ,0 ), +BPF_STMT (BPF_LD +BPF_B +BPF_ABS , opt_ipproto_off),BPF_JUMP (BPF_JMP +BPF_JEQ +BPF_K ,IPPROTO_TCP ,0 ,5 ),BPF_STMT (BPF_LD +BPF_H +BPF_ABS , dport_off),BPF_JUMP (BPF_JMP +BPF_JEQ +BPF_K ,DPORT ,2 ,0 ),
@@ -576,6 +598,39 @@ static void add_ipv4_ts_option(void *buf, void *optpkt) iph->check =checksum_fold (iph,sizeof (struct iphdr ) + optlen,0 ); } +static void add_ipv6_exthdr (void *buf,void *optpkt,__u8 exthdr_type,char *ext_payload) +{ +struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr *)(optpkt + tcp_offset); +struct ipv6hdr *iph = (struct ipv6hdr *)(optpkt +ETH_HLEN ); +char *exthdr_payload_start = (char *)(exthdr +1 ); + + exthdr->hdrlen =0 ; + exthdr->nexthdr =IPPROTO_TCP ; + +memcpy (exthdr_payload_start, ext_payload,MIN_EXTHDR_SIZE -sizeof (*exthdr)); + +memcpy (optpkt, buf, tcp_offset); +memcpy (optpkt + tcp_offset +MIN_EXTHDR_SIZE , buf + tcp_offset, +sizeof (struct tcphdr ) +PAYLOAD_LEN ); + + iph->nexthdr = exthdr_type; + iph->payload_len =htons (ntohs (iph->payload_len) +MIN_EXTHDR_SIZE ); +} + +static void send_ipv6_exthdr (int fd,struct sockaddr_ll *daddr,char *ext_data1,char *ext_data2) +{ +static char buf[MAX_HDR_LEN +PAYLOAD_LEN ]; +static char exthdr_pck[sizeof (buf) +MIN_EXTHDR_SIZE ]; + +create_packet (buf,0 ,0 ,PAYLOAD_LEN ,0 ); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data1); +write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr); + +create_packet (buf,PAYLOAD_LEN *1 ,0 ,PAYLOAD_LEN ,0 ); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data2); +write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr); +} +/* IPv4 options shouldn't coalesce */ static void send_ip_options (int fd,struct sockaddr_ll *daddr) {
@@ -697,7 +752,7 @@ static void send_fragment6(int fd, struct sockaddr_ll *daddr)create_packet (buf,PAYLOAD_LEN * i,0 ,PAYLOAD_LEN ,0 );write_packet (fd, buf, bufpkt_len, daddr); } - +sleep (1 );create_packet (buf,PAYLOAD_LEN *2 ,0 ,PAYLOAD_LEN ,0 );memset (extpkt,0 , extpkt_len);
@@ -760,6 +815,7 @@ static void check_recv_pkts(int fd, int *correct_payload,vlog ("}, Total %d packets\nReceived {" , correct_num_pkts);while (1 ) { + ip_ext_len =0 ; pkt_size =recv (fd, buffer,IP_MAXPACKET +ETH_HLEN +1 ,0 );if (pkt_size <0 )error (1 , errno,"could not receive" );
@@ -767,7 +823,7 @@ static void check_recv_pkts(int fd, int *correct_payload,if (iph->version ==4 ) ip_ext_len = (iph->ihl -5 ) *4 ;else if (ip6h->version ==6 && ip6h->nexthdr !=IPPROTO_TCP ) - ip_ext_len =sizeof (struct ip6_frag ); + ip_ext_len =MIN_EXTHDR_SIZE ; tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
@@ -888,7 +944,21 @@ static void gro_sender(void)sleep (1 );write_packet (txfd, fin_pkt, total_hdr_len, &daddr); }else if (proto ==PF_INET6 ) { +sleep (1 );send_fragment6 (txfd, &daddr); +sleep (1 ); +write_packet (txfd, fin_pkt, total_hdr_len, &daddr); + +sleep (1 ); +/* send IPv6 packets with ext header with same payload */ +send_ipv6_exthdr (txfd, &daddr,EXT_PAYLOAD_1 ,EXT_PAYLOAD_1 ); +sleep (1 ); +write_packet (txfd, fin_pkt, total_hdr_len, &daddr); + +sleep (1 ); +/* send IPv6 packets with ext header with different payload */ +send_ipv6_exthdr (txfd, &daddr,EXT_PAYLOAD_1 ,EXT_PAYLOAD_2 ); +sleep (1 );write_packet (txfd, fin_pkt, total_hdr_len, &daddr); } }else if (strcmp (testname,"large" ) ==0 ) {
@@ -1005,6 +1075,17 @@ static void gro_receiver(void)*/ printf ("fragmented ip6 doesn't coalesce: " ); correct_payload[0 ] =PAYLOAD_LEN *2 ; + correct_payload[1 ] =PAYLOAD_LEN ; + correct_payload[2 ] =PAYLOAD_LEN ; +check_recv_pkts (rxfd, correct_payload,3 ); + +printf ("ipv6 with ext header does coalesce: " ); + correct_payload[0 ] =PAYLOAD_LEN *2 ; +check_recv_pkts (rxfd, correct_payload,1 ); + +printf ("ipv6 with ext header with different payloads doesn't coalesce: " ); + correct_payload[0 ] =PAYLOAD_LEN ; + correct_payload[1 ] =PAYLOAD_LEN ;check_recv_pkts (rxfd, correct_payload,2 ); } }else if (strcmp (testname,"large" ) ==0 ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 308/568 selftests/net: use destination options instead of hop-by-hop
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anubhav Singh <[email protected]>
[ Upstream commit f8e8486702abb05b8c734093aab1606af0eac068 ]
The GRO self-test, gro.c, currently constructs IPv6 packets containing a Hop-by-Hop Options header (IPPROTO_HOPOPTS) to ensure the GRO path correctly handles IPv6 extension headers.
However, network elements may be configured to drop packets with the Hop-by-Hop Options header (HBH). This causes the self-test to fail in environments where such network elements are present.
To improve the robustness and reliability of this test in diverse network environments, switch from using IPPROTO_HOPOPTS to IPPROTO_DSTOPTS (Destination Options).
The Destination Options header is less likely to be dropped by intermediate routers and still serves the core purpose of the test:
validating GRO's handling of an IPv6 extension header. This change ensures the test can execute successfully without being incorrectly failed by network policies outside the kernel's control.
--- tools/testing/selftests/net/gro.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/net/gro.c +2 -2
@@ -623,11 +623,11 @@ static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr, char *ext_data1,static char exthdr_pck[sizeof (buf) +MIN_EXTHDR_SIZE ];create_packet (buf,0 ,0 ,PAYLOAD_LEN ,0 ); -add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data1); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_DSTOPTS , ext_data1);write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr);create_packet (buf,PAYLOAD_LEN *1 ,0 ,PAYLOAD_LEN ,0 ); -add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data2); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_DSTOPTS , ext_data2);write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 309/568 netdevsim: add Makefile for selftests
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wei <[email protected]>
[ Upstream commit 8ff25dac88f616ebebb30830e3a20f079d7a30c9 ]
Add a Makefile for netdevsim selftests and add selftests path to MAINTAINERS
Stable-dep-of: d01f8136d46b ("selftests: netdevsim: Fix ethtool-coalesce.sh fail by installing ethtool-common.sh")
--- MAINTAINERS | 1 + .../selftests/drivers/net/netdevsim/Makefile | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tools/testing/selftests/drivers/net/netdevsim/Makefile
MAINTAINERS +1 -0
@@ -14221,6 +14221,7 @@ NETDEVSIM M: Jakub Kicinski <[email protected]> S: Maintained F: drivers/net/netdevsim/* +F: tools/testing/selftests/drivers/net/netdevsim/* NETEM NETWORK EMULATOR M: Stephen Hemminger <[email protected]>
tools/testing/selftests/drivers/net/netdevsim/Makefile new file +17 -0
@@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0+ OR MIT + +TEST_PROGS = devlink.sh \ + devlink_in_netns.sh \ + devlink_trap.sh \ + ethtool-coalesce.sh \ + ethtool-fec.sh \ + ethtool-pause.sh \ + ethtool-ring.sh \ + fib.sh \ + hw_stats_l3.sh \ + nexthop.sh \ + psample.sh \ + tc-mq-visibility.sh \ + udp_tunnel_nic.sh \ + +include ../../../lib.mk
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 310/568 selftests: netdevsim: Fix ethtool-coalesce.sh fail by installing ethtool-common.sh
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit d01f8136d46b925798abcf86b35a4021e4cfb8bb ]
The script "ethtool-common.sh" is not installed in INSTALL_PATH, and triggers some errors when I try to run the test 'drivers/net/netdevsim/ethtool-coalesce.sh':
TAP version 13
1..1
# timeout set to 600 # selftests: drivers/net/netdevsim: ethtool-coalesce.sh # ./ethtool-coalesce.sh: line 4: ethtool-common.sh: No such file or directory # ./ethtool-coalesce.sh: line 25: make_netdev: command not found # ethtool: bad command line argument(s) # ./ethtool-coalesce.sh: line 124: check: command not found # ./ethtool-coalesce.sh: line 126: [: -eq: unary operator expected # FAILED /0 checks not ok 1 selftests: drivers/net/netdevsim: ethtool-coalesce.sh # exit=1
Install this file to avoid this error. After this patch:
TAP version 13
1..1
# timeout set to 600 # selftests: drivers/net/netdevsim: ethtool-coalesce.sh # PASSED all 22 checks ok 1 selftests: drivers/net/netdevsim: ethtool-coalesce.sh
--- tools/testing/selftests/drivers/net/netdevsim/Makefile | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/drivers/net/netdevsim/Makefile +4 -0
@@ -14,4 +14,8 @@ TEST_PROGS = devlink.sh \ tc-mq-visibility.sh \ udp_tunnel_nic.sh \ +TEST_FILES := \ + ethtool-common.sh +# end of TEST_FILES + include ../../../lib.mk
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 311/568 net: vlan: sync VLAN features with lower device
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit c211f5d7cbd5cb34489d526648bb9c8ecc907dee ]
After registering a VLAN device and setting its feature flags, we need to synchronize the VLAN features with the lower device. For example, the VLAN device does not have the NETIF_F_LRO flag, it should be synchronized with the lower device based on the NETIF_F_UPPER_DISABLES definition.
As the dev->vlan_features has changed, we need to call netdev_update_features(). The caller must run after netdev_upper_dev_link() links the lower devices, so this patch adds the netdev_update_features() call in register_vlan_dev().
--- net/8021q/vlan.c | 2 ++ 1 file changed, 2 insertions(+)
net/8021q/vlan.c +2 -0
@@ -194,6 +194,8 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)vlan_group_set_device (grp, vlan->vlan_proto, vlan_id, dev); grp->nr_vlan_devs++; +netdev_update_features (dev); +return 0 ; out_unregister_netdev:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 312/568 net: dsa: b53: fix resetting speed and pause on forced link
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit b6a8a5477fe9bd6be2b594a88f82f8bba41e6d54 ]
There is no guarantee that the port state override registers have their default values, as not all switches support being reset via register or have a reset GPIO.
So when forcing port config, we need to make sure to clear all fields, which we currently do not do for the speed and flow control configuration. This can cause flow control stay enabled, or in the case of speed becoming an illegal value, e.g. configured for 1G (0x2), then setting 100M (0x1), results in 0x3 which is invalid.
For PORT_OVERRIDE_SPEED_2000M we need to make sure to only clear it on supported chips, as the bit can have different meanings on other chips, e.g. for BCM5389 this controls scanning PHYs for link/speed configuration.
--- drivers/net/dsa/b53/b53_common.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/dsa/b53/b53_common.c +9 -0
@@ -1215,6 +1215,10 @@ static void b53_force_port_config(struct b53_device *dev, int port,else reg &= ~PORT_OVERRIDE_FULL_DUPLEX ; + reg &= ~(0x3 <<GMII_PO_SPEED_S ); +if (is5301x (dev) ||is58xx (dev)) + reg &= ~PORT_OVERRIDE_SPEED_2000M ; +switch (speed) {case 2000 : reg |=PORT_OVERRIDE_SPEED_2000M ;
@@ -1233,6 +1237,11 @@ static void b53_force_port_config(struct b53_device *dev, int port,return ; } +if (is5325 (dev)) + reg &= ~PORT_OVERRIDE_LP_FLOW_25 ; +else + reg &= ~(PORT_OVERRIDE_RX_FLOW |PORT_OVERRIDE_TX_FLOW ); +if (rx_pause) {if (is5325 (dev)) reg |=PORT_OVERRIDE_LP_FLOW_25 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 313/568 net: dsa: b53: fix enabling ip multicast
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit c264294624e956a967a9e2e5fa41e3273340b089 ]
In the New Control register bit 1 is either reserved, or has a different function:
Out of Range Error Discard
When enabled, the ingress port discards any frames if the Length field is between 1500 and 1536 (excluding 1500 and 1536) and with good CRC.
The actual bit for enabling IP multicast is bit 0, which was only explicitly enabled for BCM5325 so far.
For older switch chips, this bit defaults to 0, so we want to enable it as well, while newer switch chips default to 1, and their documentation says "It is illegal to set this bit to zero."
So drop the wrong B53_IPMC_FWD_EN define, enable the IP multicast bit also for other switch chips. While at it, rename it to (B53_)IP_MC as that is how it is called in Broadcom code.
--- drivers/net/dsa/b53/b53_common.c | 4 ++-- drivers/net/dsa/b53/b53_regs.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-)
drivers/net/dsa/b53/b53_common.c +2 -2
@@ -349,11 +349,11 @@ static void b53_set_forwarding(struct b53_device *dev, int enable)* frames should be flooded or not. */ b53_read8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , &mgmt); - mgmt |=B53_UC_FWD_EN |B53_MC_FWD_EN |B53_IPMC_FWD_EN ; + mgmt |=B53_UC_FWD_EN |B53_MC_FWD_EN |B53_IP_MC ;b53_write8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , mgmt); }else {b53_read8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , &mgmt); - mgmt |=B53_IP_MCAST_25 ; + mgmt |=B53_IP_MC ;b53_write8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , mgmt); } }
drivers/net/dsa/b53/b53_regs.h +1 -2
@@ -104,8 +104,7 @@/* IP Multicast control (8 bit) */ #define B53_IP_MULTICAST_CTRL 0x21 -#define B53_IP_MCAST_25 BIT(0) -#define B53_IPMC_FWD_EN BIT(1) +#define B53_IP_MC BIT(0)#define B53_UC_FWD_EN BIT(6)#define B53_MC_FWD_EN BIT(7)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 314/568 net: dsa: b53: stop reading ARL entries if search is done
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 0be04b5fa62a82a9929ca261f6c9f64a3d0a28da ]
The switch clears the ARL_SRCH_STDN bit when the search is done, i.e. it finished traversing the ARL table.
This means that there will be no valid result, so we should not attempt to read and process any further entries.
We only ever check the validity of the entries for 4 ARL bin chips, and only after having passed the first entry to the b53_fdb_copy().
This means that we always pass an invalid entry at the end to the b53_fdb_copy(). b53_fdb_copy() does check the validity though before passing on the entry, so it never gets passed on.
On < 4 ARL bin chips, we will even continue reading invalid entries until we reach the result limit.
--- drivers/net/dsa/b53/b53_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +1 -1
@@ -1785,7 +1785,7 @@ static int b53_arl_search_wait(struct b53_device *dev) do { b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, ®); if (!(reg & ARL_SRCH_STDN)) - return 0; + return -ENOENT; if (reg & ARL_SRCH_VLID) return 0;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 315/568 sctp: Hold RCU read lock while iterating over address list
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit 38f50242bf0f237cdc262308d624d333286ec3c5 ]
With CONFIG_PROVE_RCU_LIST=y and by executing
$ netcat -l --sctp & $ netcat --sctp localhost & $ ss --sctp
one can trigger the following Lockdep-RCU splat(s):
WARNING: suspicious RCU usage 6.18.0-rc1-00093-g7f864458e9a6 #5 Not tainted
-----------------------------
net/sctp/diag.c:76 RCU-list traversed in non-reader section!!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
2 locks held by ss/215:
#0: ffff9c740828bec0 (nlk_cb_mutex-SOCK_DIAG){+.+.}-{4:4}, at: __netlink_dump_start+0x84/0x2b0 #1: ffff9c7401d72cd0 (sk_lock-AF_INET6){+.+.}-{0:0}, at: sctp_sock_dump+0x38/0x200
stack backtrace: CPU: 0 UID: 0 PID: 215 Comm: ss Not tainted 6.18.0-rc1-00093-g7f864458e9a6 #5 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x5d/0x90 lockdep_rcu_suspicious.cold+0x4e/0xa3 inet_sctp_diag_fill.isra.0+0x4b1/0x5d0 sctp_sock_dump+0x131/0x200 sctp_transport_traverse_process+0x170/0x1b0 ? __pfx_sctp_sock_filter+0x10/0x10 ? __pfx_sctp_sock_dump+0x10/0x10 sctp_diag_dump+0x103/0x140 __inet_diag_dump+0x70/0xb0 netlink_dump+0x148/0x490 __netlink_dump_start+0x1f3/0x2b0 inet_diag_handler_cmd+0xcd/0x100 ? __pfx_inet_diag_dump_start+0x10/0x10 ? __pfx_inet_diag_dump+0x10/0x10 ? __pfx_inet_diag_dump_done+0x10/0x10 sock_diag_rcv_msg+0x18e/0x320 ? __pfx_sock_diag_rcv_msg+0x10/0x10 netlink_rcv_skb+0x4d/0x100 netlink_unicast+0x1d7/0x2b0 netlink_sendmsg+0x203/0x450 ____sys_sendmsg+0x30c/0x340 ___sys_sendmsg+0x94/0xf0 __sys_sendmsg+0x83/0xf0 do_syscall_64+0xbb/0x390 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... </TASK>
--- net/sctp/diag.c | 4 ++++ 1 file changed, 4 insertions(+)
net/sctp/diag.c +4 -0
@@ -73,19 +73,23 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,struct nlattr *attr;void *info =NULL ; +rcu_read_lock ();list_for_each_entry_rcu (laddr, address_list, list) addrcnt++; +rcu_read_unlock (); attr =nla_reserve (skb,INET_DIAG_LOCALS , addrlen * addrcnt);if (!attr)return -EMSGSIZE ; info =nla_data (attr); +rcu_read_lock ();list_for_each_entry_rcu (laddr, address_list, list) {memcpy (info, &laddr->a,sizeof (laddr->a));memset (info +sizeof (laddr->a),0 , addrlen -sizeof (laddr->a)); info += addrlen; } +rcu_read_unlock ();return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 316/568 sctp: Prevent TOCTOU out-of-bounds write
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit 95aef86ab231f047bb8085c70666059b58f53c09 ]
For the following path not holding the sock lock,
sctp_diag_dump() -> sctp_for_each_endpoint() -> sctp_ep_dump()
make sure not to exceed bounds in case the address list has grown between buffer allocation (time-of-check) and write (time-of-use).
--- net/sctp/diag.c | 3 +++ 1 file changed, 3 insertions(+)
net/sctp/diag.c +3 -0
@@ -88,6 +88,9 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,memcpy (info, &laddr->a,sizeof (laddr->a));memset (info +sizeof (laddr->a),0 , addrlen -sizeof (laddr->a)); info += addrlen; + +if (!--addrcnt) +break ; }rcu_read_unlock ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 317/568 sctp: Hold sock lock while iterating over address list
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit f1fc201148c7e684c10a72b6a3375597f28d1ef6 ]
Move address list traversal in inet_assoc_attr_size() under the sock lock to avoid holding the RCU read lock.
--- net/sctp/diag.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
net/sctp/diag.c +9 -5
@@ -230,14 +230,15 @@ struct sctp_comm_param {bool net_admin; }; -static size_t inet_assoc_attr_size (struct sctp_association *asoc) +static size_t inet_assoc_attr_size (struct sock *sk, +struct sctp_association *asoc) {int addrlen =sizeof (struct sockaddr_storage );int addrcnt =0 ;struct sctp_sockaddr_entry *laddr;list_for_each_entry_rcu (laddr, &asoc->base.bind_addr.address_list, - list) + list,lockdep_sock_is_held (sk)) addrcnt++;return nla_total_size (sizeof (struct sctp_info ))
@@ -263,11 +264,14 @@ static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *tif (err)return err; - rep =nlmsg_new (inet_assoc_attr_size (assoc),GFP_KERNEL ); -if (!rep) +lock_sock (sk); + + rep =nlmsg_new (inet_assoc_attr_size (sk, assoc),GFP_KERNEL ); +if (!rep) { +release_sock (sk);return -ENOMEM ; + } -lock_sock (sk);if (ep != assoc->ep) { err = -EAGAIN ; goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 318/568 net: usb: qmi_wwan: initialize MAC header offset in qmimux_rx_fixup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qendrim Maxhuni <[email protected]>
[ Upstream commit e120f46768d98151ece8756ebd688b0e43dc8b29 ]
Raw IP packets have no MAC header, leaving skb->mac_header uninitialized. This can trigger kernel panics on ARM64 when xfrm or other subsystems access the offset due to strict alignment checks.
Initialize the MAC header to prevent such crashes.
This can trigger kernel panics on ARM when running IPsec over the qmimux0 interface.
Example trace:
Internal error: Oops: 000000009600004f [#1] SMP
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.34-gbe78e49cb433 #1
Hardware name: LS1028A RDB Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : xfrm_input+0xde8/0x1318
lr : xfrm_input+0x61c/0x1318
sp : ffff800080003b20
Call trace:
xfrm_input+0xde8/0x1318
xfrm6_rcv+0x38/0x44
xfrm6_esp_rcv+0x48/0xa8
ip6_protocol_deliver_rcu+0x94/0x4b0
ip6_input_finish+0x44/0x70
ip6_input+0x44/0xc0
ipv6_rcv+0x6c/0x114
__netif_receive_skb_one_core+0x5c/0x8c
__netif_receive_skb+0x18/0x60
process_backlog+0x78/0x17c
__napi_poll+0x38/0x180
net_rx_action+0x168/0x2f0--- drivers/net/usb/qmi_wwan.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/usb/qmi_wwan.c +6 -0
@@ -191,6 +191,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)if (!skbn)return 0 ; +/* Raw IP packets don't have a MAC header, but other subsystems +* (like xfrm) may still access MAC header offsets, so they must +* be initialized. +*/ +skb_reset_mac_header (skbn); +switch (skb->data[offset + qmimux_hdr_sz] &0xf0 ) {case 0x40 : skbn->protocol =htons (ETH_P_IP );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 319/568 bnxt_en: Fix a possible memory leak in bnxt_ptp_init
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh AP <[email protected]>
[ Upstream commit deb8eb39164382f1f67ef8e8af9176baf5e10f2d ]
In bnxt_ptp_init(), when ptp_clock_register() fails, the driver is not freeing the memory allocated for ptp_info->pin_config. Fix it to unconditionally free ptp_info->pin_config in bnxt_ptp_free().
--- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +2 -2
@@ -895,9 +895,9 @@ static void bnxt_ptp_free(struct bnxt *bp)if (ptp->ptp_clock) {ptp_clock_unregister (ptp->ptp_clock); ptp->ptp_clock =NULL ; -kfree (ptp->ptp_info.pin_config); - ptp->ptp_info.pin_config =NULL ; } +kfree (ptp->ptp_info.pin_config); + ptp->ptp_info.pin_config =NULL ; }int bnxt_ptp_init (struct bnxt *bp,bool phc_cfg)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 320/568 net/mlx5e: SHAMPO, Fix skb size check for 64K pages
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <[email protected]>
[ Upstream commit bacd8d80181ebe34b599a39aa26bf73a44c91e55 ]
mlx5e_hw_gro_skb_has_enough_space() uses a formula to check if there is enough space in the skb frags to store more data. This formula is incorrect for 64K page sizes and it triggers early GRO session termination because the first fragment will blow up beyond GRO_LEGACY_MAX_SIZE.
This patch adds a special case for page sizes >= GRO_LEGACY_MAX_SIZE (64K) which uses the skb->len instead. Within this context, the check is safe from fragment overflow because the hardware will continuously fill the data up to the reservation size of 64K and the driver will coalesce all data from the same page to the same fragment. This means that the data will span one fragment or at most two for such a large page size.
It is expected that the if statement will be optimized out as the check is done with constants.
--- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +4 -1
@@ -2056,7 +2056,10 @@ mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt) {int nr_frags =skb_shinfo (skb)->nr_frags; -return PAGE_SIZE * nr_frags + data_bcnt <=GRO_LEGACY_MAX_SIZE ; +if (PAGE_SIZE >=GRO_LEGACY_MAX_SIZE ) +return skb->len + data_bcnt <=GRO_LEGACY_MAX_SIZE ; +else +return PAGE_SIZE * nr_frags + data_bcnt <=GRO_LEGACY_MAX_SIZE ; } static void
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 321/568 net: dsa: microchip: Fix reserved multicast address table programming
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristram Ha <[email protected]>
[ Upstream commit 96baf482ca1f69f0da9d10a5bd8422c87ea9039e ]
KSZ9477/KSZ9897 and LAN937X families of switches use a reserved multicast address table for some specific forwarding with some multicast addresses, like the one used in STP. The hardware assumes the host port is the last port in KSZ9897 family and port 5 in LAN937X family. Most of the time this assumption is correct but not in other cases like KSZ9477. Originally the function just setups the first entry, but the others still need update, especially for one common multicast address that is used by PTP operation.
LAN937x also uses different register bits when accessing the reserved table.
--- drivers/net/dsa/microchip/ksz9477.c | 98 +++++++++++++++++++++---- drivers/net/dsa/microchip/ksz9477_reg.h | 3 +- drivers/net/dsa/microchip/ksz_common.c | 4 + drivers/net/dsa/microchip/ksz_common.h | 2 + 4 files changed, 91 insertions(+), 16 deletions(-)
drivers/net/dsa/microchip/ksz9477.c +84 -14
@@ -1127,9 +1127,15 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) } } +#define RESV_MCAST_CNT 8 + +static u8 reserved_mcast_map[RESV_MCAST_CNT ] = {0 ,1 ,3 ,16 ,32 ,33 ,2 ,17 }; +int ksz9477_enable_stp_addr (struct ksz_device *dev) { +u8 i, ports, update;const u32 *masks; +bool override;u32 data;int ret;
@@ -1138,23 +1144,87 @@ int ksz9477_enable_stp_addr(struct ksz_device *dev)/* Enable Reserved multicast table */ ksz_cfg (dev,REG_SW_LUE_CTRL_0 ,SW_RESV_MCAST_ENABLE , true); -/* Set the Override bit for forwarding BPDU packet to CPU */ - ret =ksz_write32 (dev,REG_SW_ALU_VAL_B , -ALU_V_OVERRIDE |BIT (dev->cpu_port)); -if (ret <0 ) -return ret; +/* The reserved multicast address table has 8 entries. Each entry has +* a default value of which port to forward. It is assumed the host +* port is the last port in most of the switches, but that is not the +* case for KSZ9477 or maybe KSZ9897. For LAN937X family the default +* port is port 5, the first RGMII port. It is okay for LAN9370, a +* 5-port switch, but may not be correct for the other 8-port +* versions. It is necessary to update the whole table to forward to +* the right ports. +* Furthermore PTP messages can use a reserved multicast address and +* the host will not receive them if this table is not correct. +*/ +for (i =0 ; i <RESV_MCAST_CNT ; i++) { + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX ]; + data |=ALU_STAT_START | + masks[ALU_STAT_DIRECT ] | + masks[ALU_RESV_MCAST_ADDR ] | + masks[ALU_STAT_READ ]; + ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); +if (ret <0 ) +return ret; - data =ALU_STAT_START |ALU_RESV_MCAST_ADDR | masks[ALU_STAT_WRITE ]; +/* wait to be finished */ + ret =ksz9477_wait_alu_sta_ready (dev); +if (ret <0 ) +return ret; - ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); -if (ret <0 ) -return ret; + ret =ksz_read32 (dev,REG_SW_ALU_VAL_B , &data); +if (ret <0 ) +return ret; -/* wait to be finished */ - ret =ksz9477_wait_alu_sta_ready (dev); -if (ret <0 ) { -dev_err (dev->dev,"Failed to update Reserved Multicast table\n" ); -return ret; + override = false; + ports = data & dev->port_mask; +switch (i) { +case 0 : +case 6 : +/* Change the host port. */ + update =BIT (dev->cpu_port); + override = true; +break ; +case 2 : +/* Change the host port. */ + update =BIT (dev->cpu_port); +break ; +case 4 : +case 5 : +case 7 : +/* Skip the host port. */ + update = dev->port_mask & ~BIT (dev->cpu_port); +break ; +default : + update = ports; +break ; + } +if (update != ports || override) { + data &= ~dev->port_mask; + data |= update; +/* Set Override bit to receive frame even when port is +* closed. +*/ +if (override) + data |=ALU_V_OVERRIDE ; + ret =ksz_write32 (dev,REG_SW_ALU_VAL_B , data); +if (ret <0 ) +return ret; + + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX ]; + data |=ALU_STAT_START | + masks[ALU_STAT_DIRECT ] | + masks[ALU_RESV_MCAST_ADDR ] | + masks[ALU_STAT_WRITE ]; + ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); +if (ret <0 ) +return ret; + +/* wait to be finished */ + ret =ksz9477_wait_alu_sta_ready (dev); +if (ret <0 ) +return ret; + } }return 0 ;
drivers/net/dsa/microchip/ksz9477_reg.h +1 -2
@@ -2,7 +2,7 @@/* * Microchip KSZ9477 register definitions * -* Copyright (C) 2017-2024 Microchip Technology Inc. +* Copyright (C) 2017-2025 Microchip Technology Inc. */ #ifndef __KSZ9477_REGS_H
@@ -422,7 +422,6 @@#define ALU_RESV_MCAST_INDEX_M (BIT(6) - 1)#define ALU_STAT_START BIT(7) -#define ALU_RESV_MCAST_ADDR BIT(1)#define REG_SW_ALU_VAL_A 0x0420
drivers/net/dsa/microchip/ksz_common.c +4 -0
@@ -392,6 +392,8 @@ static const u16 ksz9477_regs[] = {static const u32 ksz9477_masks[] = { [ALU_STAT_WRITE ] =0 , [ALU_STAT_READ ] =1 , + [ALU_STAT_DIRECT ] =0 , + [ALU_RESV_MCAST_ADDR ] =BIT (1 ), [P_MII_TX_FLOW_CTRL ] =BIT (5 ), [P_MII_RX_FLOW_CTRL ] =BIT (3 ), };
@@ -419,6 +421,8 @@ static const u8 ksz9477_xmii_ctrl1[] = {static const u32 lan937x_masks[] = { [ALU_STAT_WRITE ] =1 , [ALU_STAT_READ ] =2 , + [ALU_STAT_DIRECT ] =BIT (3 ), + [ALU_RESV_MCAST_ADDR ] =BIT (2 ), [P_MII_TX_FLOW_CTRL ] =BIT (5 ), [P_MII_RX_FLOW_CTRL ] =BIT (3 ), };
drivers/net/dsa/microchip/ksz_common.h +2 -0
@@ -225,6 +225,8 @@ enum ksz_masks {DYNAMIC_MAC_TABLE_TIMESTAMP ,ALU_STAT_WRITE ,ALU_STAT_READ , +ALU_STAT_DIRECT , +ALU_RESV_MCAST_ADDR ,P_MII_TX_FLOW_CTRL , P_MII_RX_FLOW_CTRL, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 322/568 net: bridge: fix use-after-free due to MST port state bypass
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 8dca36978aa80bab9d4da130c211db75c9e00048 ]
syzbot reported[1] a use-after-free when deleting an expired fdb. It is due to a race condition between learning still happening and a port being deleted, after all its fdbs have been flushed. The port's state has been toggled to disabled so no learning should happen at that time, but if we have MST enabled, it will bypass the port's state, that together with VLAN filtering disabled can lead to fdb learning at a time when it shouldn't happen while the port is being deleted. VLAN filtering must be disabled because we flush the port VLANs when it's being deleted which will stop learning. This fix adds a check for the port's vlan group which is initialized to NULL when the port is getting deleted, that avoids the port state bypass. When MST is enabled there would be a minimal new overhead in the fast-path because the port's vlan group pointer is cache-hot.
[1] https://syzkaller.appspot.com/bug?extid=dd280197f0f7ab3917be
--- net/bridge/br_forward.c | 2 +- net/bridge/br_input.c | 4 ++-- net/bridge/br_private.h | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-)
net/bridge/br_forward.c +1 -1
@@ -25,7 +25,7 @@ static inline int should_deliver(const struct net_bridge_port *p, vg =nbp_vlan_group_rcu (p);return ((p->flags &BR_HAIRPIN_MODE ) || skb->dev != p->dev) && - (br_mst_is_enabled (p->br) || p->state ==BR_STATE_FORWARDING ) && + (br_mst_is_enabled (p) || p->state ==BR_STATE_FORWARDING ) &&br_allowed_egress (vg, skb) &&nbp_switchdev_allowed_egress (p, skb) && !br_skb_isolated (p, skb); }
net/bridge/br_input.c +2 -2
@@ -93,7 +93,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb br = p->br; -if (br_mst_is_enabled (br)) { +if (br_mst_is_enabled (p)) { state =BR_STATE_FORWARDING ; }else {if (p->state ==BR_STATE_DISABLED )
@@ -393,7 +393,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)return RX_HANDLER_PASS ; forward: -if (br_mst_is_enabled (p->br)) +if (br_mst_is_enabled (p)) goto defer_stp_filtering;switch (p->state) {
net/bridge/br_private.h +5 -3
@@ -1802,10 +1802,12 @@ static inline bool br_vlan_state_allowed(u8 state, bool learn_allow)/* br_mst.c */ #ifdef CONFIG_BRIDGE_VLAN_FILTERING DECLARE_STATIC_KEY_FALSE (br_mst_used); -static inline bool br_mst_is_enabled (struct net_bridge *br) +static inline bool br_mst_is_enabled (const struct net_bridge_port *p) { +/* check the port's vlan group to avoid racing with port deletion */ return static_branch_unlikely (&br_mst_used) && -br_opt_get (br,BROPT_MST_ENABLED ); +br_opt_get (p->br,BROPT_MST_ENABLED ) && +rcu_access_pointer (p->vlgrp); } int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
@@ -1820,7 +1822,7 @@ int br_mst_fill_info(struct sk_buff *skb,int br_mst_process (struct net_bridge_port *p,const struct nlattr *mst_attr,struct netlink_ext_ack *extack);#else -static inline bool br_mst_is_enabled (struct net_bridge *br) +static inline bool br_mst_is_enabled (const struct net_bridge_port *p) {return false; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 323/568 net: bridge: fix MST static key usage
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit ee87c63f9b2a418f698d79c2991347e31a7d2c27 ]
As Ido pointed out, the static key usage in MST is buggy and should use inc/dec instead of enable/disable because we can have multiple bridges with MST enabled which means a single bridge can disable MST for all. Use static_branch_inc/dec to avoid that. When destroying a bridge decrement the key if MST was enabled.
--- net/bridge/br_if.c | 1 + net/bridge/br_mst.c | 10 ++++++++-- net/bridge/br_private.h | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-)
net/bridge/br_if.c +1 -0
@@ -386,6 +386,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)del_nbp (p); } +br_mst_uninit (br);br_recalculate_neigh_suppress_enabled (br);br_fdb_delete_by_port (br,NULL ,0 ,1 );
net/bridge/br_mst.c +8 -2
@@ -22,6 +22,12 @@ bool br_mst_enabled(const struct net_device *dev) }EXPORT_SYMBOL_GPL (br_mst_enabled); +void br_mst_uninit (struct net_bridge *br) +{ +if (br_opt_get (br,BROPT_MST_ENABLED )) +static_branch_dec (&br_mst_used); +} +int br_mst_get_info (const struct net_device *dev,u16 msti,unsigned long *vids) {const struct net_bridge_vlan_group *vg;
@@ -225,9 +231,9 @@ int br_mst_set_enabled(struct net_bridge *br, bool on,return err;if (on) -static_branch_enable (&br_mst_used); +static_branch_inc (&br_mst_used);else -static_branch_disable (&br_mst_used); +static_branch_dec (&br_mst_used);br_opt_toggle (br,BROPT_MST_ENABLED , on);return 0 ;
net/bridge/br_private.h +5 -0
@@ -1821,6 +1821,7 @@ int br_mst_fill_info(struct sk_buff *skb, const struct net_bridge_vlan_group *vg);int br_mst_process (struct net_bridge_port *p,const struct nlattr *mst_attr,struct netlink_ext_ack *extack); +void br_mst_uninit (struct net_bridge *br);#else static inline bool br_mst_is_enabled (const struct net_bridge_port *p) {
@@ -1856,6 +1857,10 @@ static inline int br_mst_process(struct net_bridge_port *p, {return -EOPNOTSUPP ; } + +static inline void br_mst_uninit (struct net_bridge *br) +{ +}#endif struct nf_br_ops {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 324/568 tracing: Fix memory leaks in create_field_var()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 80f0d631dcc76ee1b7755bfca1d8417d91d71414 ]
The function create_field_var() allocates memory for 'val' through create_hist_field() inside parse_atom(), and for 'var' through create_var(), which in turn allocates var->type and var->var.name internally. Simply calling kfree() to release these structures will result in memory leaks.
Use destroy_hist_field() to properly free 'val', and explicitly release the memory of var->type and var->var.name before freeing 'var' itself.
--- kernel/trace/trace_events_hist.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/trace/trace_events_hist.c +4 -2
@@ -3210,14 +3210,16 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, var =create_var (hist_data, file, field_name, val->size, val->type);if (IS_ERR (var)) {hist_err (tr,HIST_ERR_VAR_CREATE_FIND_FAIL ,errpos (field_name)); -kfree (val); +destroy_hist_field (val,0 ); ret =PTR_ERR (var); goto err; } field_var =kzalloc (sizeof (struct field_var ),GFP_KERNEL );if (!field_var) { -kfree (val); +destroy_hist_field (val,0 ); +kfree_const (var->type); +kfree (var->var.name);kfree (var); ret = -ENOMEM ; goto err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 325/568 Bluetooth: MGMT: Fix OOB access in parse_adv_monitor_pattern()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Gavrilov <[email protected]>
commit 8d59fba49362c65332395789fd82771f1028d87e upstream.
In the parse_adv_monitor_pattern() function, the value of
the 'length' variable is currently limited to HCI_MAX_EXT_AD_LENGTH(251). The size of the 'value' array in the mgmt_adv_pattern structure is 31. If the value of 'pattern[i].length' is set in the user space and exceeds 31, the 'patterns[i].value' array can be accessed out of bound when copied.
Increasing the size of the 'value' array in
the 'mgmt_adv_pattern' structure will break the userspace. Considering this, and to avoid OOB access revert the limits for 'offset' and 'length' back to the value of HCI_MAX_AD_LENGTH.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.
--- include/net/bluetooth/mgmt.h | 2 +- net/bluetooth/mgmt.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
include/net/bluetooth/mgmt.h +1 -1
@@ -772,7 +772,7 @@ struct mgmt_adv_pattern {__u8 ad_type;__u8 offset;__u8 length; -__u8 value[31 ]; +__u8 value[HCI_MAX_AD_LENGTH ]; } __packed;#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR 0x0052
net/bluetooth/mgmt.c +3 -3
@@ -5436,9 +5436,9 @@ static u8 parse_adv_monitor_pattern(strufor (i =0 ; i < pattern_count; i++) { offset = patterns[i].offset; length = patterns[i].length; -if (offset >=HCI_MAX_EXT_AD_LENGTH || - length >HCI_MAX_EXT_AD_LENGTH || - (offset + length) >HCI_MAX_EXT_AD_LENGTH ) +if (offset >=HCI_MAX_AD_LENGTH || + length >HCI_MAX_AD_LENGTH || + (offset + length) >HCI_MAX_AD_LENGTH )return MGMT_STATUS_INVALID_PARAMS ; p =kmalloc (sizeof (*p),GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 326/568 rtc: rx8025: fix incorrect register reference
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuta Hayama <[email protected]>
commit 162f24cbb0f6ec596e7e9f3e91610d79dc805229 upstream.
This code is intended to operate on the CTRL1 register, but ctrl[1] is actually CTRL2. Correctly, ctrl[0] is CTRL1.
--- drivers/rtc/rtc-rx8025.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-rx8025.c +1 -1
@@ -315,7 +315,7 @@ static int rx8025_init_client(struct i2creturn hour_reg; rx8025->is_24 = (hour_reg &RX8035_BIT_HOUR_1224 ); }else { - rx8025->is_24 = (ctrl[1 ] &RX8025_BIT_CTRL1_1224 ); + rx8025->is_24 = (ctrl[0 ] &RX8025_BIT_CTRL1_1224 ); } out:return err;
Greg Kroah-Hartman
maintainerPATCH 327/568 smb: client: validate change notify buffer before copy
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <[email protected]>
commit 4012abe8a78fbb8869634130024266eaef7081fe upstream.
SMB2_change_notify called smb2_validate_iov() but ignored the return code, then kmemdup()ed using server provided OutputBufferOffset/Length.
Check the return of smb2_validate_iov() and bail out on error.
Discovered with help from the ZeroPath security tooling.
--- fs/smb/client/smb2pdu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/smb/client/smb2pdu.c +5 -2
@@ -3837,9 +3837,12 @@ SMB2_change_notify(const unsigned int xi smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base; -smb2_validate_iov (le16_to_cpu (smb_rsp->OutputBufferOffset), -le32_to_cpu (smb_rsp->OutputBufferLength), &rsp_iov, + rc =smb2_validate_iov (le16_to_cpu (smb_rsp->OutputBufferOffset), +le32_to_cpu (smb_rsp->OutputBufferLength), + &rsp_iov,sizeof (struct file_notify_information )); +if (rc) + goto cnotify_exit; *out_data =kmemdup ((char *)smb_rsp +le16_to_cpu (smb_rsp->OutputBufferOffset),le32_to_cpu (smb_rsp->OutputBufferLength),GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 328/568 lib/crypto: curve25519-hacl64: Fix older clang KASAN workaround for GCC
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 2b81082ad37cc3f28355fb73a6a69b91ff7dbf20 upstream.
Commit 2f13daee2a72 ("lib/crypto/curve25519-hacl64: Disable KASAN with clang-17 and older") inadvertently disabled KASAN in curve25519-hacl64.o for GCC unconditionally because clang-min-version will always evaluate to nothing for GCC. Add a check for CONFIG_CC_IS_CLANG to avoid applying the workaround for GCC, which is only needed for clang-17 and older.
--- lib/crypto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/crypto/Makefile +1 -1
@@ -26,7 +26,7 @@ libcurve25519-generic-y := curve25519 libcurve25519-generic-$(CONFIG_ARCH_SUPPORTS_INT128) := curve25519-hacl64.o libcurve25519-generic-y += curve25519-generic.o # clang versions prior to 18 may blow out the stack with KASAN -ifeq ($(call clang-min-version, 180000),) +ifeq ($(CONFIG_CC_IS_CLANG)_$(call clang-min-version, 180000),y_) KASAN_SANITIZE_curve25519-hacl64.o := n endif
Greg Kroah-Hartman
maintainerPATCH 329/568 scsi: ufs: ufs-pci: Fix S0ix/S3 for Intel controllers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
commit bb44826c3bdbf1fa3957008a04908f45e5666463 upstream.
Intel platforms with UFS, can support Suspend-to-Idle (S0ix) and Suspend-to-RAM (S3). For S0ix the link state should be HIBERNATE. For S3, state is lost, so the link state must be OFF. Driver policy, expressed by spm_lvl, can be 3 (link HIBERNATE, device SLEEP) for S0ix but must be changed to 5 (link OFF, device POWEROFF) for S3.
Fix support for S0ix/S3 by switching spm_lvl as needed. During suspend ->prepare(), if the suspend target state is not Suspend-to-Idle, ensure the spm_lvl is at least 5 to ensure that resume will be possible from deep sleep states. During suspend ->complete(), restore the spm_lvl to its original value that is suitable for S0ix.
This fix is first needed in Intel Alder Lake based controllers.
--- drivers/ufs/host/ufshcd-pci.c | 67 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-)
drivers/ufs/host/ufshcd-pci.c +65 -2
@@ -15,6 +15,7 @@#include <linux/pci.h> #include <linux/pm_runtime.h> #include <linux/pm_qos.h> +#include <linux/suspend.h> #include <linux/debugfs.h> #include <linux/uuid.h> #include <linux/acpi.h>
@@ -34,6 +35,7 @@ struct intel_host {u32 dsm_fns;u32 active_ltr;u32 idle_ltr; +int saved_spm_lvl;struct dentry *debugfs_root;struct gpio_desc *reset_gpio; };
@@ -375,6 +377,7 @@ static int ufs_intel_common_init(struct host =devm_kzalloc (hba->dev,sizeof (*host),GFP_KERNEL );if (!host)return -ENOMEM ; + host->saved_spm_lvl =-1 ;ufshcd_set_variant (hba, host);intel_dsm_init (host, hba->dev);if (INTEL_DSM_SUPPORTED (host,RESET )) {
@@ -542,6 +545,66 @@ static int ufshcd_pci_restore(struct devreturn ufshcd_system_resume (dev); } + +static int ufs_intel_suspend_prepare (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); +struct intel_host *host =ufshcd_get_variant (hba); +int err; + +/* +* Only s2idle (S0ix) retains link state. Force power-off +* (UFS_PM_LVL_5) for any other case. +*/ +if (pm_suspend_target_state !=PM_SUSPEND_TO_IDLE && hba->spm_lvl <UFS_PM_LVL_5 ) { + host->saved_spm_lvl = hba->spm_lvl; + hba->spm_lvl =UFS_PM_LVL_5 ; + } + + err =ufshcd_suspend_prepare (dev); + +if (err <0 && host->saved_spm_lvl !=-1 ) { + hba->spm_lvl = host->saved_spm_lvl; + host->saved_spm_lvl =-1 ; + } + +return err; +} + +static void ufs_intel_resume_complete (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); +struct intel_host *host =ufshcd_get_variant (hba); + +ufshcd_resume_complete (dev); + +if (host->saved_spm_lvl !=-1 ) { + hba->spm_lvl = host->saved_spm_lvl; + host->saved_spm_lvl =-1 ; + } +} + +static int ufshcd_pci_suspend_prepare (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); + +if (!strcmp (hba->vops->name,"intel-pci" )) +return ufs_intel_suspend_prepare (dev); + +return ufshcd_suspend_prepare (dev); +} + +static void ufshcd_pci_resume_complete (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); + +if (!strcmp (hba->vops->name,"intel-pci" )) { +ufs_intel_resume_complete (dev); +return ; + } + +ufshcd_resume_complete (dev); +}#endif /**
@@ -633,8 +696,8 @@ static const struct dev_pm_ops ufshcd_pc .thaw = ufshcd_system_resume, .poweroff = ufshcd_system_suspend, .restore = ufshcd_pci_restore, - .prepare = ufshcd_suspend_prepare, - .complete = ufshcd_resume_complete, + .prepare = ufshcd_pci_suspend_prepare, + .complete = ufshcd_pci_resume_complete,#endif };
Greg Kroah-Hartman
maintainerPATCH 330/568 extcon: adc-jack: Cleanup wakeup source only if it was enabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 92bac7d4de9c07933f6b76d8f1c7f8240f911f4f upstream.
Driver in the probe enables wakeup source conditionally, so the cleanup path should do the same - do not release the wakeup source memory if it was not allocated.
--- drivers/extcon/extcon-adc-jack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/extcon/extcon-adc-jack.c +2 -1
@@ -162,7 +162,8 @@ static int adc_jack_remove(struct platfo {struct adc_jack_data *data =platform_get_drvdata (pdev); -device_init_wakeup (&pdev->dev, false); +if (data->wakeup_source) +device_init_wakeup (&pdev->dev, false);free_irq (data->irq, data);cancel_work_sync (&data->handler.work);
Greg Kroah-Hartman
maintainerPATCH 331/568 drm/amdgpu: Fix function header names in amdgpu_connectors.c
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
commit 38ab33dbea594700c8d6cc81eec0a54e95d3eb2f upstream.
Align the function headers for amdgpu_max_hdmi_pixel_clock and amdgpu_connector_dvi_mode_valid with the function implementations so they match the expected kdoc style.
Fixes the below:drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c:1199: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Returns the maximum supported HDMI (TMDS) pixel clock in KHz.drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c:1212: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Validates the given display mode on DVI and HDMI connectors.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +12 -3
@@ -1166,7 +1166,10 @@ static void amdgpu_connector_dvi_force(s }/** -* Returns the maximum supported HDMI (TMDS) pixel clock in KHz. +* amdgpu_max_hdmi_pixel_clock - Return max supported HDMI (TMDS) pixel clock +* @adev: pointer to amdgpu_device +* +* Return: maximum supported HDMI (TMDS) pixel clock in KHz. */ static int amdgpu_max_hdmi_pixel_clock (const struct amdgpu_device *adev) {
@@ -1179,8 +1182,14 @@ static int amdgpu_max_hdmi_pixel_clock(c }/** -* Validates the given display mode on DVI and HDMI connectors, -* including analog signals on DVI-I. +* amdgpu_connector_dvi_mode_valid - Validate a mode on DVI/HDMI connectors +* @connector: DRM connector to validate the mode on +* @mode: display mode to validate +* +* Validate the given display mode on DVI and HDMI connectors, including +* analog signals on DVI-I. +* +* Return: drm_mode_status indicating whether the mode is valid. */ static enum drm_mode_status amdgpu_connector_dvi_mode_valid (struct drm_connector *connector,struct drm_display_mode *mode)
Greg Kroah-Hartman
maintainerPATCH 332/568 selftests: netdevsim: set test timeout to 10 minutes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
commit afbf75e8da8ce8a0698212953d350697bb4355a6 upstream.
The longest running netdevsim test, nexthop.sh, currently takes 5 min to finish. Around 260s to be exact, and 310s on a debug kernel. The default timeout in selftest is 45sec, so we need an explicit config. Give ourselves some headroom and use 10min.
Commit under Fixes isn't really to "blame" but prior to that netdevsim tests weren't integrated with kselftest infra so blaming the tests themselves doesn't seem right, either.
--- tools/testing/selftests/drivers/net/netdevsim/settings | 1 + 1 file changed, 1 insertion(+) create mode 100644 tools/testing/selftests/drivers/net/netdevsim/settings
tools/testing/selftests/drivers/net/netdevsim/settings new file +1 -0
@@ -0,0 +1 @@ +timeout=600
Greg Kroah-Hartman
maintainerPATCH 333/568 drm/i915: Avoid lock inversion when pinning to GGTT on CHV/BXT+VTD
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Janusz Krzysztofik <[email protected]>
[ Upstream commit 84bbe327a5cbb060f3321c9d9d4d53936fc1ef9b ]
On completion of i915_vma_pin_ww(), a synchronous variant of dma_fence_work_commit() is called. When pinning a VMA to GGTT address space on a Cherry View family processor, or on a Broxton generation SoC with VTD enabled, i.e., when stop_machine() is then called from intel_ggtt_bind_vma(), that can potentially lead to lock inversion among reservation_ww and cpu_hotplug locks.
[86.861179] ======================================================
[86.861193] WARNING: possible circular locking dependency detected
[86.861209] 6.15.0-rc5-CI_DRM_16515-gca0305cadc2d+ #1 Tainted: G U
[86.861226] ------------------------------------------------------
[86.861238] i915_module_loa/1432 is trying to acquire lock:
[86.861252] ffffffff83489090 (cpu_hotplug_lock){++++}-{0:0}, at: stop_machine+0x1c/0x50
[86.861290]
but task is already holding lock:
[86.861303] ffffc90002e0b4c8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.0+0x39/0x1d0 [i915]
[86.862233]
which lock already depends on the new lock.
[86.862251]
the existing dependency chain (in reverse order) is:
[86.862265]
-> #5 (reservation_ww_class_mutex){+.+.}-{3:3}:
[86.862292] dma_resv_lockdep+0x19a/0x390
[86.862315] do_one_initcall+0x60/0x3f0
[86.862334] kernel_init_freeable+0x3cd/0x680
[86.862353] kernel_init+0x1b/0x200
[86.862369] ret_from_fork+0x47/0x70
[86.862383] ret_from_fork_asm+0x1a/0x30
[86.862399]
-> #4 (reservation_ww_class_acquire){+.+.}-{0:0}:
[86.862425] dma_resv_lockdep+0x178/0x390
[86.862440] do_one_initcall+0x60/0x3f0
[86.862454] kernel_init_freeable+0x3cd/0x680
[86.862470] kernel_init+0x1b/0x200
[86.862482] ret_from_fork+0x47/0x70
[86.862495] ret_from_fork_asm+0x1a/0x30
[86.862509]
-> #3 (&mm->mmap_lock){++++}-{3:3}:
[86.862531] down_read_killable+0x46/0x1e0
[86.862546] lock_mm_and_find_vma+0xa2/0x280
[86.862561] do_user_addr_fault+0x266/0x8e0
[86.862578] exc_page_fault+0x8a/0x2f0
[86.862593] asm_exc_page_fault+0x27/0x30
[86.862607] filldir64+0xeb/0x180
[86.862620] kernfs_fop_readdir+0x118/0x480
[86.862635] iterate_dir+0xcf/0x2b0
[86.862648] __x64_sys_getdents64+0x84/0x140
[86.862661] x64_sys_call+0x1058/0x2660
[86.862675] do_syscall_64+0x91/0xe90
[86.862689] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[86.862703]
-> #2 (&root->kernfs_rwsem){++++}-{3:3}:
[86.862725] down_write+0x3e/0xf0
[86.862738] kernfs_add_one+0x30/0x3c0
[86.862751] kernfs_create_dir_ns+0x53/0xb0
[86.862765] internal_create_group+0x134/0x4c0
[86.862779] sysfs_create_group+0x13/0x20
[86.862792] topology_add_dev+0x1d/0x30
[86.862806] cpuhp_invoke_callback+0x4b5/0x850
[86.862822] cpuhp_issue_call+0xbf/0x1f0
[86.862836] __cpuhp_setup_state_cpuslocked+0x111/0x320
[86.862852] __cpuhp_setup_state+0xb0/0x220
[86.862866] topology_sysfs_init+0x30/0x50
[86.862879] do_one_initcall+0x60/0x3f0
[86.862893] kernel_init_freeable+0x3cd/0x680
[86.862908] kernel_init+0x1b/0x200
[86.862921] ret_from_fork+0x47/0x70
[86.862934] ret_from_fork_asm+0x1a/0x30
[86.862947]
-> #1 (cpuhp_state_mutex){+.+.}-{3:3}:
[86.862969] __mutex_lock+0xaa/0xed0
[86.862982] mutex_lock_nested+0x1b/0x30
[86.862995] __cpuhp_setup_state_cpuslocked+0x67/0x320
[86.863012] __cpuhp_setup_state+0xb0/0x220
[86.863026] page_alloc_init_cpuhp+0x2d/0x60
[86.863041] mm_core_init+0x22/0x2d0
[86.863054] start_kernel+0x576/0xbd0
[86.863068] x86_64_start_reservations+0x18/0x30
[86.863084] x86_64_start_kernel+0xbf/0x110
[86.863098] common_startup_64+0x13e/0x141
[86.863114]
-> #0 (cpu_hotplug_lock){++++}-{0:0}:
[86.863135] __lock_acquire+0x1635/0x2810
[86.863152] lock_acquire+0xc4/0x2f0
[86.863166] cpus_read_lock+0x41/0x100
[86.863180] stop_machine+0x1c/0x50
[86.863194] bxt_vtd_ggtt_insert_entries__BKL+0x3b/0x60 [i915]
[86.863987] intel_ggtt_bind_vma+0x43/0x70 [i915]
[86.864735] __vma_bind+0x55/0x70 [i915]
[86.865510] fence_work+0x26/0xa0 [i915]
[86.866248] fence_notify+0xa1/0x140 [i915]
[86.866983] __i915_sw_fence_complete+0x8f/0x270 [i915]
[86.867719] i915_sw_fence_commit+0x39/0x60 [i915]
[86.868453] i915_vma_pin_ww+0x462/0x1360 [i915]
[86.869228] i915_vma_pin.constprop.0+0x133/0x1d0 [i915]
[86.870001] initial_plane_vma+0x307/0x840 [i915]
[86.870774] intel_initial_plane_config+0x33f/0x670 [i915]
[86.871546] intel_display_driver_probe_nogem+0x1c6/0x260 [i915]
[86.872330] i915_driver_probe+0x7fa/0xe80 [i915]
[86.873057] i915_pci_probe+0xe6/0x220 [i915]
[86.873782] local_pci_probe+0x47/0xb0
[86.873802] pci_device_probe+0xf3/0x260
[86.873817] really_probe+0xf1/0x3c0
[86.873833] __driver_probe_device+0x8c/0x180
[86.873848] driver_probe_device+0x24/0xd0
[86.873862] __driver_attach+0x10f/0x220
[86.873876] bus_for_each_dev+0x7f/0xe0
[86.873892] driver_attach+0x1e/0x30
[86.873904] bus_add_driver+0x151/0x290
[86.873917] driver_register+0x5e/0x130
[86.873931] __pci_register_driver+0x7d/0x90
[86.873945] i915_pci_register_driver+0x23/0x30 [i915]
[86.874678] i915_init+0x37/0x120 [i915]
[86.875347] do_one_initcall+0x60/0x3f0
[86.875369] do_init_module+0x97/0x2a0
[86.875385] load_module+0x2c54/0x2d80
[86.875398] init_module_from_file+0x96/0xe0
[86.875413] idempotent_init_module+0x117/0x330
[86.875426] __x64_sys_finit_module+0x77/0x100
[86.875440] x64_sys_call+0x24de/0x2660
[86.875454] do_syscall_64+0x91/0xe90
[86.875470] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[86.875486]
other info that might help us debug this:
[86.875502] Chain exists of:
cpu_hotplug_lock --> reservation_ww_class_acquire --> reservation_ww_class_mutex
[86.875539] Possible unsafe locking scenario:
[86.875552] CPU0 CPU1
[86.875563] ---- ----
[86.875573] lock(reservation_ww_class_mutex);
[86.875588] lock(reservation_ww_class_acquire);
[86.875606] lock(reservation_ww_class_mutex);
[86.875624] rlock(cpu_hotplug_lock);
[86.875637]
*** DEADLOCK ***
[86.875650] 3 locks held by i915_module_loa/1432:
[86.875663] #0: ffff888101f5c1b0 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x104/0x220
[86.875699] #1: ffffc90002e0b4a0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.0+0x39/0x1d0 [i915]
[86.876512] #2: ffffc90002e0b4c8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.0+0x39/0x1d0 [i915]
[86.877305]
stack backtrace:
[86.877326] CPU: 0 UID: 0 PID: 1432 Comm: i915_module_loa Tainted: G U 6.15.0-rc5-CI_DRM_16515-gca0305cadc2d+ #1 PREEMPT(voluntary)
[86.877334] Tainted: [U]=USER
[86.877336] Hardware name: /NUC5CPYB, BIOS PYBSWCEL.86A.0079.2020.0420.1316 04/20/2020
[86.877339] Call Trace:
[86.877344] <TASK>
[86.877353] dump_stack_lvl+0x91/0xf0
[86.877364] dump_stack+0x10/0x20
[86.877369] print_circular_bug+0x285/0x360
[86.877379] check_noncircular+0x135/0x150
[86.877390] __lock_acquire+0x1635/0x2810
[86.877403] lock_acquire+0xc4/0x2f0
[86.877408] ? stop_machine+0x1c/0x50
[86.877422] ? __pfx_bxt_vtd_ggtt_insert_entries__cb+0x10/0x10 [i915]
[86.878173] cpus_read_lock+0x41/0x100
[86.878182] ? stop_machine+0x1c/0x50
[86.878191] ? __pfx_bxt_vtd_ggtt_insert_entries__cb+0x10/0x10 [i915]
[86.878916] stop_machine+0x1c/0x50
[86.878927] bxt_vtd_ggtt_insert_entries__BKL+0x3b/0x60 [i915]
[86.879652] intel_ggtt_bind_vma+0x43/0x70 [i915]
[86.880375] __vma_bind+0x55/0x70 [i915]
[86.881133] fence_work+0x26/0xa0 [i915]
[86.881851] fence_notify+0xa1/0x140 [i915]
[86.882566] __i915_sw_fence_complete+0x8f/0x270 [i915]
[86.883286] i915_sw_fence_commit+0x39/0x60 [i915]
[86.884003] i915_vma_pin_ww+0x462/0x1360 [i915]
[86.884756] ? i915_vma_pin.constprop.0+0x6c/0x1d0 [i915]
[86.885513] i915_vma_pin.constprop.0+0x133/0x1d0 [i915]
[86.886281] initial_plane_vma+0x307/0x840 [i915]
[86.887049] intel_initial_plane_config+0x33f/0x670 [i915]
[86.887819] intel_display_driver_probe_nogem+0x1c6/0x260 [i915]
[86.888587] i915_driver_probe+0x7fa/0xe80 [i915]
[86.889293] ? mutex_unlock+0x12/0x20
[86.889301] ? drm_privacy_screen_get+0x171/0x190
[86.889308] ? acpi_dev_found+0x66/0x80
[86.889321] i915_pci_probe+0xe6/0x220 [i915]
[86.890038] local_pci_probe+0x47/0xb0
[86.890049] pci_device_probe+0xf3/0x260
[86.890058] really_probe+0xf1/0x3c0
[86.890067] __driver_probe_device+0x8c/0x180
[86.890072] driver_probe_device+0x24/0xd0
[86.890078] __driver_attach+0x10f/0x220
[86.890083] ? __pfx___driver_attach+0x10/0x10
[86.890088] bus_for_each_dev+0x7f/0xe0
[86.890097] driver_attach+0x1e/0x30
[86.890101] bus_add_driver+0x151/0x290
[86.890107] driver_register+0x5e/0x130
[86.890113] __pci_register_driver+0x7d/0x90
[86.890119] i915_pci_register_driver+0x23/0x30 [i915]
[86.890833] i915_init+0x37/0x120 [i915]
[86.891482] ? __pfx_i915_init+0x10/0x10 [i915]
[86.892135] do_one_initcall+0x60/0x3f0
[86.892145] ? __kmalloc_cache_noprof+0x33f/0x470
[86.892157] do_init_module+0x97/0x2a0
[86.892164] load_module+0x2c54/0x2d80
[86.892168] ? __kernel_read+0x15c/0x300
[86.892185] ? kernel_read_file+0x2b1/0x320
[86.892195] init_module_from_file+0x96/0xe0
[86.892199] ? init_module_from_file+0x96/0xe0
[86.892211] idempotent_init_module+0x117/0x330
[86.892224] __x64_sys_finit_module+0x77/0x100
[86.892230] x64_sys_call+0x24de/0x2660
[86.892236] do_syscall_64+0x91/0xe90
[86.892243] ? irqentry_exit+0x77/0xb0
[86.892249] ? sysvec_apic_timer_interrupt+0x57/0xc0
[86.892256] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[86.892261] RIP: 0033:0x7303e1b2725d
[86.892271] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 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 8b 0d 8b bb 0d 00 f7 d8 64 89 01 48
[86.892276] RSP: 002b:00007ffddd1fdb38 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[86.892281] RAX: ffffffffffffffda RBX: 00005d771d88fd90 RCX: 00007303e1b2725d
[86.892285] RDX: 0000000000000000 RSI: 00005d771d893aa0 RDI: 000000000000000c
[86.892287] RBP: 00007ffddd1fdbf0 R08: 0000000000000040 R09: 00007ffddd1fdb80
[86.892289] R10: 00007303e1c03b20 R11: 0000000000000246 R12: 00005d771d893aa0
[86.892292] R13: 0000000000000000 R14: 00005d771d88f0d0 R15: 00005d771d895710
[86.892304] </TASK>Call asynchronous variant of dma_fence_work_commit() in that case.
v3: Provide more verbose in-line comment (Andi),
- mention target environments in commit message.
--- drivers/gpu/drm/i915/i915_vma.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/i915_vma.c +14 -2
@@ -1548,8 +1548,20 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, err_vma_res:i915_vma_resource_free (vma_res); err_fence: -if (work) -dma_fence_work_commit_imm (&work->base); +if (work) { +/* +* When pinning VMA to GGTT on CHV or BXT with VTD enabled, +* commit VMA binding asynchronously to avoid risk of lock +* inversion among reservation_ww locks held here and +* cpu_hotplug_lock acquired from stop_machine(), which we +* wrap around GGTT updates when running in those environments. +*/ +if (i915_vma_is_ggtt (vma) && +intel_vm_no_concurrent_access_wa (vma->vm->i915)) +dma_fence_work_commit (&work->base); +else +dma_fence_work_commit_imm (&work->base); + } err_rpm:intel_runtime_pm_put (&vma->vm->i915->runtime_pm, wakeref);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 334/568 drm/i915: Fix conversion between clock ticks and nanoseconds
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Umesh Nerlige Ramappa <[email protected]>
[ Upstream commit 7d44ad6b43d0be43d080180413a1b6c24cfbd266 ]
When tick values are large, the multiplication by NSEC_PER_SEC is larger than 64 bits and results in bad conversions.
The issue is seen in PMU busyness counters that look like they have wrapped around due to bad conversion. i915 PMU implementation returns monotonically increasing counters. If a count is lesser than previous one, it will only return the larger value until the smaller value catches up. The user will see this as zero delta between two measurements even though the engines are busy.
Fix it by using mul_u64_u32_div()
--- drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c +2 -2
@@ -180,7 +180,7 @@ static u64 div_u64_roundup(u64 nom, u32 den)u64 intel_gt_clock_interval_to_ns (const struct intel_gt *gt,u64 count) { -return div_u64_roundup (count *NSEC_PER_SEC , gt->clock_frequency); +return mul_u64_u32_div (count,NSEC_PER_SEC , gt->clock_frequency); }u64 intel_gt_pm_interval_to_ns (const struct intel_gt *gt,u64 count)
@@ -190,7 +190,7 @@ u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)u64 intel_gt_ns_to_clock_interval (const struct intel_gt *gt,u64 ns) { -return div_u64_roundup (gt->clock_frequency * ns,NSEC_PER_SEC ); +return mul_u64_u32_div (ns, gt->clock_frequency,NSEC_PER_SEC ); }u64 intel_gt_ns_to_pm_interval (const struct intel_gt *gt,u64 ns)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 335/568 smb: client: fix refcount leak in smb2_set_path_attr
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhao Fu <[email protected]>
[ Upstream commit b540de9e3b4fab3b9e10f30714a6f5c1b2a50ec3 ]
Fix refcount leak in smb2_set_path_attr when path conversion fails.
Function cifs_get_writable_path returns cfile with its reference counter cfile->count increased on success. Function smb2_compound_op would decrease the reference counter for cfile, as stated in its comment. By calling smb2_rename_path, the reference counter of cfile would leak if cifs_convert_path_to_utf16 fails in smb2_set_path_attr.
--- fs/smb/client/smb2inode.c | 2 ++ 1 file changed, 2 insertions(+)
fs/smb/client/smb2inode.c +2 -0
@@ -721,6 +721,8 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, smb2_to_name =cifs_convert_path_to_utf16 (to_name, cifs_sb);if (smb2_to_name ==NULL ) { rc = -ENOMEM ; +if (cfile) +cifsFileInfo_put (cfile); goto smb2_rename_path; } rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 336/568 drm/amd: Fix suspend failure with secure display TA
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit b09cb2996cdf50cd1ab4020e002c95d742c81313 ]
commit c760bcda83571 ("drm/amd: Check whether secure display TA loaded successfully") attempted to fix extra messages, but failed to port the cleanup that was in commit 5c6d52ff4b61e ("drm/amd: Don't try to enable secure display TA multiple times") to prevent multiple tries.
Add that to the failure handling path even on a quick failure.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +4 -1
@@ -1962,8 +1962,11 @@ static int psp_securedisplay_initialize(struct psp_context *psp)if (!ret && !psp->securedisplay_context.context.resp_status) { psp->securedisplay_context.context.initialized = true;mutex_init (&psp->securedisplay_context.mutex); - }else + }else { +/* don't try again */ + psp->securedisplay_context.context.bin_desc.size_bytes =0 ;return ret; + }psp_prep_securedisplay_cmd_buf (psp, &securedisplay_cmd,TA_SECUREDISPLAY_COMMAND__QUERY_TA );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 337/568 compiler_types: Move unused static inline functions warning to W=2
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 9818af18db4bfefd320d0fef41390a616365e6f7 ]
Per Nathan, clang catches unused "static inline" functions in C files since commit 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build").
Quoted 8 lines · Linus
So I entirely ignore W=1 issues, because I think so many of the extra warnings are bogus.
But if this one in particular is causing more problems than most - some teams do seem to use W=1 as part of their test builds - it's fine to send me a patch that just moves bad warnings to W=2.
And if anybody uses W=2 for their test builds, that's THEIR problem..
Here is the change to bump the warning from W=1 to W=2.
--- include/linux/compiler_types.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
include/linux/compiler_types.h +2 -3
@@ -175,10 +175,9 @@ struct ftrace_likely_data {/* * GCC does not warn about unused static inline functions for -Wunused-function. * Suppress the warning in clang as well by using __maybe_unused, but enable it -* for W=1 build. This will allow clang to find unused functions. Remove the -* __inline_maybe_unused entirely after fixing most of -Wunused-function warnings. +* for W=2 build. This will allow clang to find unused functions. */ -#ifdef KBUILD_EXTRA_WARN1 +#ifdef KBUILD_EXTRA_WARN2 #define __inline_maybe_unused#else #define __inline_maybe_unused __maybe_unused
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 338/568 RISC-V: clear hot-unplugged cores from all task mm_cpumasks to avoid rfence errors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danil Skrebenkov <[email protected]>
[ Upstream commit ae9e9f3d67dcef7582a4524047b01e33c5185ddb ]
openSBI v1.7 adds harts checks for ipi operations. Especially it adds comparison between hmask passed as an argument from linux and mask of online harts (from openSBI side). If they don't fit each other the error occurs.
When cpu is offline, cpu_online_mask is explicitly cleared in __cpu_disable. However, there is no explicit clearing of mm_cpumask. mm_cpumask is used for rfence operations that call openSBI RFENCE extension which uses ipi to remote harts. If hart is offline there may be error if mask of linux is not as mask of online harts in openSBI.
this patch adds explicit clearing of mm_cpumask for offline hart.
--- arch/riscv/kernel/cpu-hotplug.c | 1 + 1 file changed, 1 insertion(+)
arch/riscv/kernel/cpu-hotplug.c +1 -0
@@ -61,6 +61,7 @@ void __cpu_die(unsigned int cpu) }pr_notice ("CPU%u: off\n" , cpu); +clear_tasks_mm_cpumask (cpu);/* Verify from the firmware if the cpu is really stopped*/ if (cpu_ops[cpu]->cpu_is_stopped) ret = cpu_ops[cpu]->cpu_is_stopped (cpu);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 339/568 drm/amd/pm: Disable MCLK switching on SI at high pixel clocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 5c05bcf6ae7732da1bd4dc1958d527b5f07f216a ]
On various SI GPUs, a flickering can be observed near the bottom edge of the screen when using a single 4K 60Hz monitor over DP. Disabling MCLK switching works around this problem.
--- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +5 -0
@@ -3485,6 +3485,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,* for these GPUs to calculate bandwidth requirements. */ if (high_pixelclock_count) { +/* Work around flickering lines at the bottom edge +* of the screen when using a single 4K 60Hz monitor. +*/ + disable_mclk_switching = true; +/* On Oland, we observe some flickering when two 4K 60Hz * displays are connected, possibly because voltage is too low. * Raise the voltage by requiring a higher SCLK.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 340/568 drm/amdgpu: Fix NULL pointer dereference in VRAM logic for APU devices
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse.Zhang <[email protected]>
[ Upstream commit 883f309add55060233bf11c1ea6947140372920f ]
Previously, APU platforms (and other scenarios with uninitialized VRAM managers) triggered a NULL pointer dereference in ttm_resource_manager_usage(). The root cause is not that the struct ttm_resource_manager *man pointer itself is NULL, but that man->bdev (the backing device pointer within the manager) remains uninitialized (NULL) on APUs—since APUs lack dedicated VRAM and do not fully set up VRAM manager structures. When ttm_resource_manager_usage() attempts to acquire man->bdev->lru_lock, it dereferences the NULL man->bdev, leading to a kernel OOPS.
1. **amdgpu_cs.c**: Extend the existing bandwidth control check in amdgpu_cs_get_threshold_for_moves() to include a check for ttm_resource_manager_used(). If the manager is not used (uninitialized bdev), return 0 for migration thresholds immediately—skipping VRAM-specific logic that would trigger the NULL dereference.
2. **amdgpu_kms.c**: Update the AMDGPU_INFO_VRAM_USAGE ioctl and memory info reporting to use a conditional: if the manager is used, return the real VRAM usage; otherwise, return 0. This avoids accessing man->bdev when it is NULL.
3. **amdgpu_virt.c**: Modify the vf2pf (virtual function to physical function) data write path. Use ttm_resource_manager_used() to check validity: if the manager is usable, calculate fb_usage from VRAM usage; otherwise, set fb_usage to 0 (APUs have no discrete framebuffer to report).
This approach is more robust than APU-specific checks because it:
- Works for all scenarios where the VRAM manager is uninitialized (not just APUs),
- Aligns with TTM's design by using its native helper function,
- Preserves correct behavior for discrete GPUs (which have fully initialized man->bdev and pass the ttm_resource_manager_used() check).
v4: use ttm_resource_manager_used(&adev->mman.vram_mgr.manager) instead of checking the adev->gmc.is_app_apu flag (Christian)
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 7 ++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +1 -1
@@ -663,7 +663,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,*/ const s64 us_upper_bound =200000 ; -if (!adev->mm_stats.log2_max_MBps) { +if ((!adev->mm_stats.log2_max_MBps) || !ttm_resource_manager_used (&adev->mman.vram_mgr.manager)) { *max_bytes =0 ; *max_vis_bytes =0 ;return ;
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +4 -3
@@ -647,7 +647,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ui64 =atomic64_read (&adev->num_vram_cpu_page_faults);return copy_to_user (out, &ui64,min (size,8u )) ? -EFAULT :0 ;case AMDGPU_INFO_VRAM_USAGE : - ui64 =ttm_resource_manager_usage (&adev->mman.vram_mgr.manager); + ui64 =ttm_resource_manager_used (&adev->mman.vram_mgr.manager) ? +ttm_resource_manager_usage (&adev->mman.vram_mgr.manager) :0 ;return copy_to_user (out, &ui64,min (size,8u )) ? -EFAULT :0 ;case AMDGPU_INFO_VIS_VRAM_USAGE : ui64 =amdgpu_vram_mgr_vis_usage (&adev->mman.vram_mgr);
@@ -693,8 +694,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) mem.vram.usable_heap_size = adev->gmc.real_vram_size -atomic64_read (&adev->vram_pin_size) -AMDGPU_VM_RESERVED_VRAM ; - mem.vram.heap_usage = -ttm_resource_manager_usage (vram_man); + mem.vram.heap_usage =ttm_resource_manager_used (&adev->mman.vram_mgr.manager) ? +ttm_resource_manager_usage (vram_man) :0 ; mem.vram.max_allocation = mem.vram.usable_heap_size *3 /4 ; mem.cpu_accessible_vram.total_heap_size =
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +2 -2
@@ -593,8 +593,8 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) vf2pf_info->driver_cert =0 ; vf2pf_info->os_info.all =0 ; - vf2pf_info->fb_usage = -ttm_resource_manager_usage (&adev->mman.vram_mgr.manager) >>20 ; + vf2pf_info->fb_usage =ttm_resource_manager_used (&adev->mman.vram_mgr.manager) ? +ttm_resource_manager_usage (&adev->mman.vram_mgr.manager) >>20 :0 ; vf2pf_info->fb_vis_usage =amdgpu_vram_mgr_vis_usage (&adev->mman.vram_mgr) >>20 ; vf2pf_info->fb_size = adev->gmc.real_vram_size >>20 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 341/568 NFS4: Fix state renewals missing after boot
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Watt <[email protected]>
[ Upstream commit 9bb3baa9d1604cd20f49ae7dac9306b4037a0e7a ]
Since the last renewal time was initialized to 0 and jiffies start counting at -5 minutes, any clients connected in the first 5 minutes after a reboot would have their renewal timer set to a very long interval. If the connection was idle, this would result in the client state timing out on the server and the next call to the server would return NFS4ERR_BADSESSION.
Fix this by initializing the last renewal time to the current jiffies instead of 0.
--- fs/nfs/nfs4client.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs4client.c +1 -0
@@ -221,6 +221,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) clp->cl_state =1 <<NFS4CLNT_LEASE_EXPIRED ; clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; clp->cl_mig_gen =1 ; + clp->cl_last_renewal = jiffies;#if IS_ENABLED (CONFIG_NFS_V4_1 )init_waitqueue_head (&clp->cl_lock_waitq);#endif
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 342/568 HID: quirks: avoid Cooler Master MM712 dongle wakeup bug
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Lobb <[email protected]>
[ Upstream commit 0be4253bf878d9aaa2b96031ac8683fceeb81480 ]
The Cooler Master Mice Dongle includes a vendor defined HID interface alongside its mouse interface. Not polling it will cause the mouse to stop responding to polls on any interface once woken up again after going into power saving mode.
Add the HID_QUIRK_ALWAYS_POLL quirk alongside the Cooler Master VID and the Dongle's PID.
--- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+)
drivers/hid/hid-ids.h +3 -0
@@ -321,6 +321,9 @@#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff +#define USB_VENDOR_ID_COOLER_MASTER 0x2516 +#define USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE 0x01b7 +#define USB_VENDOR_ID_CORSAIR 0x1b1c#define USB_DEVICE_ID_CORSAIR_K90 0x1b02#define USB_DEVICE_ID_CORSAIR_K70R 0x1b09
drivers/hid/hid-quirks.c +1 -0
@@ -57,6 +57,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_COOLER_MASTER, USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 343/568 NFS: check if suid/sgid was cleared after a write as needed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Mayhew <[email protected]>
[ Upstream commit 9ff022f3820a31507cb93be6661bf5f3ca0609a4 ]
I noticed xfstests generic/193 and generic/355 started failing against knfsd after commit e7a8ebc305f2 ("NFSD: Offer write delegation for OPEN with OPEN4_SHARE_ACCESS_WRITE").
I ran those same tests against ONTAP (which has had write delegation support for a lot longer than knfsd) and they fail there too... so while it's a new failure against knfsd, it isn't an entirely new failure.
Add the NFS_INO_REVAL_FORCED flag so that the presence of a delegation doesn't keep the inode from being revalidated to fetch the updated mode.
--- fs/nfs/write.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfs/write.c +2 -1
@@ -1633,7 +1633,8 @@ static int nfs_writeback_done(struct rpc_task *task,/* Deal with the suid/sgid bit corner case */ if (nfs_should_remove_suid (inode)) {spin_lock (&inode->i_lock); -nfs_set_cache_invalid (inode,NFS_INO_INVALID_MODE ); +nfs_set_cache_invalid (inode,NFS_INO_INVALID_MODE + |NFS_INO_REVAL_FORCED );spin_unlock (&inode->i_lock); }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 344/568 smb/server: fix possible memory leak in smb2_read()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZhangGuoDong <[email protected]>
[ Upstream commit 6fced056d2cc8d01b326e6fcfabaacb9850b71a4 ]
Memory leak occurs when ksmbd_vfs_read() fails. Fix this by adding the missing kvfree().
--- fs/smb/server/smb2pdu.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/server/smb2pdu.c +1 -0
@@ -6405,6 +6405,7 @@ int smb2_read(struct ksmbd_work *work) nbytes =ksmbd_vfs_read (work, fp, length, &offset, aux_payload_buf);if (nbytes <0 ) { +kvfree (aux_payload_buf); err = nbytes; goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 345/568 smb/server: fix possible refcount leak in smb2_sess_setup()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZhangGuoDong <[email protected]>
[ Upstream commit 379510a815cb2e64eb0a379cb62295d6ade65df0 ]
Reference count of ksmbd_session will leak when session need reconnect. Fix this by adding the missing ksmbd_user_session_put().
--- fs/smb/server/smb2pdu.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/server/smb2pdu.c +1 -0
@@ -1796,6 +1796,7 @@ int smb2_sess_setup(struct ksmbd_work *work)if (ksmbd_conn_need_reconnect (conn)) { rc = -EFAULT ; +ksmbd_user_session_put (sess); sess =NULL ; goto out_err; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 346/568 ASoC: max98090/91: fixed max98091 ALSA widget powering up/down
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sharique Mohammad <[email protected]>
[ Upstream commit 7a37291ed40a33a5f6c3d370fdde5ee0d8f7d0e4 ]
The widgets DMIC3_ENA and DMIC4_ENA must be defined in the DAPM suppy widget, just like DMICL_ENA and DMICR_ENA. Whenever they are turned on or off, the required startup or shutdown sequences must be taken care by the max98090_shdn_event.
--- sound/soc/codecs/max98090.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
sound/soc/codecs/max98090.c +4 -2
@@ -1235,9 +1235,11 @@ static const struct snd_soc_dapm_widget max98091_dapm_widgets[] = {SND_SOC_DAPM_INPUT ("DMIC4" ),SND_SOC_DAPM_SUPPLY ("DMIC3_ENA" ,M98090_REG_DIGITAL_MIC_ENABLE , -M98090_DIGMIC3_SHIFT ,0 ,NULL ,0 ), +M98090_DIGMIC3_SHIFT ,0 , max98090_shdn_event, +SND_SOC_DAPM_POST_PMU ),SND_SOC_DAPM_SUPPLY ("DMIC4_ENA" ,M98090_REG_DIGITAL_MIC_ENABLE , - M98090_DIGMIC4_SHIFT, 0, NULL, 0), +M98090_DIGMIC4_SHIFT ,0 , max98090_shdn_event, + SND_SOC_DAPM_POST_PMU), }; static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 347/568 wifi: ath11k: Add tx ack signal support for management packets
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abinaya Kalaiselvan <[email protected]>
[ Upstream commit 01c6c9fccbd51c1d9eab0f5794b0271b026178df ]
Add support to notify tx ack signal values for management packets to userspace through nl80211 interface.
Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT flag to enable this feature and it will be used for data packets as well.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
Stable-dep-of: 9065b9687523 ("wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()")
--- drivers/net/wireless/ath/ath11k/hw.c | 1 + drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ drivers/net/wireless/ath/ath11k/wmi.c | 27 ++++++++++++++++----------- drivers/net/wireless/ath/ath11k/wmi.h | 3 +++ 4 files changed, 25 insertions(+), 11 deletions(-)
drivers/net/wireless/ath/ath11k/hw.c +1 -0
@@ -201,6 +201,7 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab, config->twt_ap_pdev_count = ab->num_radios; config->twt_ap_sta_count =1000 ; config->flag1 |=WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 ; + config->flag1 |=WMI_RSRC_CFG_FLAG1_ACK_RSSI ; } static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
drivers/net/wireless/ath/ath11k/mac.c +5 -0
@@ -9045,6 +9045,11 @@ static int __ath11k_mac_register(struct ath11k *ar) goto err_free_if_combs; } +if (test_bit (WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI , + ar->ab->wmi_ab.svc_map)) +wiphy_ext_feature_set (ar->hw->wiphy, +NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT ); + ar->hw->queues =ATH11K_HW_MAX_QUEUES ; ar->hw->wiphy->tx_queue_len =ATH11K_QUEUE_LEN ; ar->hw->offchannel_tx_hw_queue =ATH11K_HW_MAX_QUEUES -1 ;
drivers/net/wireless/ath/ath11k/wmi.c +16 -11
@@ -5221,8 +5221,8 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,return 0 ; } -static int wmi_process_mgmt_tx_comp (struct ath11k *ar,u32 desc_id, -u32 status) +static int wmi_process_mgmt_tx_comp (struct ath11k *ar, +struct wmi_mgmt_tx_compl_event *tx_compl_param) {struct sk_buff *msdu;struct ieee80211_tx_info *info;
@@ -5230,24 +5230,29 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,int num_mgmt;spin_lock_bh (&ar->txmgmt_idr_lock); - msdu =idr_find (&ar->txmgmt_idr, desc_id); + msdu =idr_find (&ar->txmgmt_idr, tx_compl_param->desc_id);if (!msdu) {ath11k_warn (ar->ab,"received mgmt tx compl for invalid msdu_id: %d\n" , - desc_id); + tx_compl_param->desc_id);spin_unlock_bh (&ar->txmgmt_idr_lock);return -ENOENT ; } -idr_remove (&ar->txmgmt_idr, desc_id); +idr_remove (&ar->txmgmt_idr, tx_compl_param->desc_id);spin_unlock_bh (&ar->txmgmt_idr_lock); skb_cb =ATH11K_SKB_CB (msdu);dma_unmap_single (ar->ab->dev, skb_cb->paddr, msdu->len,DMA_TO_DEVICE ); info =IEEE80211_SKB_CB (msdu); -if ((!(info->flags &IEEE80211_TX_CTL_NO_ACK )) && !status) +if ((!(info->flags &IEEE80211_TX_CTL_NO_ACK )) && + !tx_compl_param->status) { info->flags |=IEEE80211_TX_STAT_ACK ; +if (test_bit (WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI , + ar->ab->wmi_ab.svc_map)) + info->status.ack_signal = tx_compl_param->ack_rssi; + }ieee80211_tx_status_irqsafe (ar->hw, msdu);
@@ -5259,7 +5264,7 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,ath11k_dbg (ar->ab,ATH11K_DBG_WMI ,"wmi mgmt tx comp pending %d desc id %d\n" , - num_mgmt, desc_id); + num_mgmt, tx_compl_param->desc_id);if (!num_mgmt)wake_up (&ar->txmgmt_empty_waitq);
@@ -5292,6 +5297,7 @@ static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab, param->pdev_id = ev->pdev_id; param->desc_id = ev->desc_id; param->status = ev->status; + param->ack_rssi = ev->ack_rssi;kfree (tb);return 0 ;
@@ -7062,13 +7068,12 @@ static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *s goto exit; } -wmi_process_mgmt_tx_comp (ar, tx_compl_param.desc_id, - tx_compl_param.status); +wmi_process_mgmt_tx_comp (ar, &tx_compl_param);ath11k_dbg (ab,ATH11K_DBG_MGMT , -"mgmt tx compl ev pdev_id %d, desc_id %d, status %d" , +"mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d" , tx_compl_param.pdev_id, tx_compl_param.desc_id, - tx_compl_param.status); + tx_compl_param.status, tx_compl_param.ack_rssi); exit:rcu_read_unlock ();
drivers/net/wireless/ath/ath11k/wmi.h +3 -0
@@ -2309,6 +2309,7 @@ struct wmi_init_cmd { } __packed;#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) +#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)struct wmi_resource_config {u32 tlv_header;
@@ -4541,6 +4542,8 @@ struct wmi_mgmt_tx_compl_event {u32 desc_id;u32 status;u32 pdev_id; +u32 ppdu_id; +u32 ack_rssi; } __packed;struct wmi_scan_event {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 348/568 wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Escande <[email protected]>
[ Upstream commit 9065b968752334f972e0d48e50c4463a172fc2a7 ]
When reporting tx completion using ieee80211_tx_status_xxx() family of functions, the status part of the struct ieee80211_tx_info nested in the skb is used to report things like transmit rates & retry count to mac80211
On the TX data path, this is correctly memset to 0 before calling ieee80211_tx_status_ext(), but on the tx mgmt path this was not done.
This leads to mac80211 treating garbage values as valid transmit counters (like tx retries for example) and accounting them as real statistics that makes their way to userland via station dump.
The same issue was resolved in ath12k by commit 9903c0986f78 ("wifi:
ath12k: Add memset and update default rate value in wmi tx completion")
Tested-on: QCN9074 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/wmi.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/ath/ath11k/wmi.c +3 -0
@@ -5246,6 +5246,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar,dma_unmap_single (ar->ab->dev, skb_cb->paddr, msdu->len,DMA_TO_DEVICE ); info =IEEE80211_SKB_CB (msdu); +memset (&info->status,0 ,sizeof (info->status)); + info->status.rates[0 ].idx =-1 ; +if ((!(info->flags &IEEE80211_TX_CTL_NO_ACK )) && !tx_compl_param->status) { info->flags |=IEEE80211_TX_STAT_ACK ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 349/568 selftests: net: local_termination: Wait for interfaces to come up
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Sverdlin <[email protected]>
[ Upstream commit 57531b3416448d1ced36a2a974a4085ec43d57b0 ]
It seems that most of the tests prepare the interfaces once before the test run (setup_prepare()), rely on setup_wait() to wait for link and only then run the test(s).
local_termination brings the physical interfaces down and up during test run but never wait for them to come up. If the auto-negotiation takes some seconds, first test packets are being lost, which leads to false-negative test results.
Use setup_wait() in run_test() to make sure auto-negotiation has been completed after all simple_if_init() calls on physical interfaces and test packets will not be lost because of the race against link establishment.
--- tools/testing/selftests/net/forwarding/local_termination.sh | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/selftests/net/forwarding/local_termination.sh +2 -0
@@ -108,6 +108,8 @@ run_test() local smac=$(mac_get $h1) local rcv_dmac=$(mac_get $rcv_if_name) + setup_wait + tcpdump_start $rcv_if_name mc_route_prepare $h1
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 350/568 net: fec: correct rx_bytes statistic for the case SHIFT16 is set
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <[email protected]>
[ Upstream commit ad17e7e92a7c52ce70bb764813fcf99464f96903 ]
Two additional bytes in front of each frame received into the RX FIFO if SHIFT16 is set, so we need to subtract the extra two bytes from pkt_len to correct the statistic of rx_bytes.
--- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/freescale/fec_main.c +2 -0
@@ -1681,6 +1681,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) ndev->stats.rx_packets++; pkt_len =fec16_to_cpu (bdp->cbd_datlen); ndev->stats.rx_bytes += pkt_len; +if (fep->quirks &FEC_QUIRK_HAS_RACC ) + ndev->stats.rx_bytes -=2 ; index =fec_enet_get_bd_index (bdp, &rxq->bd); page = rxq->rx_skb_info[index].page;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 351/568 Bluetooth: MGMT: cancel mesh send timer when hdev removed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit 55fb52ffdd62850d667ebed842815e072d3c9961 ]
mesh_send_done timer is not canceled when hdev is removed, which causes crash if the timer triggers after hdev is gone.
Cancel the timer when MGMT removes the hdev, like other MGMT timers.
Should fix the BUG: sporadically seen by BlueZ test bot (in "Mesh - Send cancel - 1" test).
Log:
------
BUG: KASAN: slab-use-after-free in run_timer_softirq+0x76b/0x7d0 ... Freed by task 36: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 __kasan_save_free_info+0x3a/0x60 __kasan_slab_free+0x43/0x70 kfree+0x103/0x500 device_release+0x9a/0x210 kobject_put+0x100/0x1e0 vhci_release+0x18b/0x240
------
--- net/bluetooth/mgmt.c | 1 + 1 file changed, 1 insertion(+)
net/bluetooth/mgmt.c +1 -0
@@ -9501,6 +9501,7 @@ void mgmt_index_removed(struct hci_dev *hdev)cancel_delayed_work_sync (&hdev->discov_off);cancel_delayed_work_sync (&hdev->service_cache);cancel_delayed_work_sync (&hdev->rpa_expired); +cancel_delayed_work_sync (&hdev->mesh_send_done); }void mgmt_power_on (struct hci_dev *hdev,int err)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 352/568 Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Pinsonneault-Thibeault <[email protected]>
[ Upstream commit 23d22f2f71768034d6ef86168213843fc49bf550 ]
There is a KASAN: slab-use-after-free read in btusb_disconnect(). Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will free the btusb data associated with the interface. The same data is then used later in the function, hence the UAF.
Fix by moving the accesses to btusb data to before the data is free'd.
--- drivers/bluetooth/btusb.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/bluetooth/btusb.c +6 -7
@@ -4204,6 +4204,11 @@ static void btusb_disconnect(struct usb_interface *intf)hci_unregister_dev (hdev); +if (data->oob_wake_irq) +device_init_wakeup (&data->udev->dev, false); +if (data->reset_gpio) +gpiod_put (data->reset_gpio); +if (intf == data->intf) {if (data->isoc)usb_driver_release_interface (&btusb_driver, data->isoc);
@@ -4214,17 +4219,11 @@ static void btusb_disconnect(struct usb_interface *intf)usb_driver_release_interface (&btusb_driver, data->diag);usb_driver_release_interface (&btusb_driver, data->intf); }else if (intf == data->diag) { -usb_driver_release_interface (&btusb_driver, data->intf);if (data->isoc)usb_driver_release_interface (&btusb_driver, data->isoc); +usb_driver_release_interface (&btusb_driver, data->intf); } -if (data->oob_wake_irq) -device_init_wakeup (&data->udev->dev, false); - -if (data->reset_gpio) -gpiod_put (data->reset_gpio); -hci_free_dev (hdev); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 353/568 Bluetooth: 6lowpan: reset link-local header on ipv6 recv path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit 3b78f50918276ab28fb22eac9aa49401ac436a3b ]
Bluetooth 6lowpan.c netdev has header_ops, so it must set link-local header for RX skb, otherwise things crash, eg. with AF_PACKET SOCK_RAW
Add missing skb_reset_mac_header() for uncompressed ipv6 RX path.
For the compressed one, it is done in lowpan_header_decompress().
Log: (BlueZ 6lowpan-tester Client Recv Raw - Success)
------
kernel BUG at net/core/skbuff.c:212!
Call Trace: <IRQ> ... packet_rcv (net/packet/af_packet.c:2152) ... <TASK>
__local_bh_enable_ip (kernel/softirq.c:407)netif_rx (net/core/dev.c:5648)chan_recv_cb (net/bluetooth/6lowpan.c:294 net/bluetooth/6lowpan.c:359)
------
--- net/bluetooth/6lowpan.c | 1 + 1 file changed, 1 insertion(+)
net/bluetooth/6lowpan.c +1 -0
@@ -288,6 +288,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, local_skb->pkt_type =PACKET_HOST ; local_skb->dev = dev; +skb_reset_mac_header (local_skb);skb_set_transport_header (local_skb,sizeof (struct ipv6hdr ));if (give_skb_to_upper (local_skb, dev) !=NET_RX_SUCCESS ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 354/568 Bluetooth: 6lowpan: fix BDADDR_LE vs ADDR_LE_DEV address type confusion
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit b454505bf57a2e4f5d49951d4deb03730a9348d9 ]
Bluetooth 6lowpan.c confuses BDADDR_LE and ADDR_LE_DEV address types, e.g. debugfs "connect" command takes the former, and "disconnect" and "connect" to already connected device take the latter. This is due to using same value both for l2cap_chan_connect and hci_conn_hash_lookup_le which take different dst_type values.
Fix address type passed to hci_conn_hash_lookup_le().
Retain the debugfs API difference between "connect" and "disconnect" commands since it's been like this since 2015 and nobody apparently complained.
--- net/bluetooth/6lowpan.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
net/bluetooth/6lowpan.c +24 -4
@@ -956,10 +956,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void) }static int get_l2cap_conn (char *buf,bdaddr_t *addr,u8 *addr_type, -struct l2cap_conn **conn) +struct l2cap_conn **conn,bool disconnect) {struct hci_conn *hcon;struct hci_dev *hdev; +int le_addr_type;int n; n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
@@ -970,13 +971,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,if (n <7 )return -EINVAL ; +if (disconnect) { +/* The "disconnect" debugfs command has used different address +* type constants than "connect" since 2015. Let's retain that +* for now even though it's obviously buggy... +*/ + *addr_type +=1 ; + } + +switch (*addr_type) { +case BDADDR_LE_PUBLIC : + le_addr_type =ADDR_LE_DEV_PUBLIC ; +break ; +case BDADDR_LE_RANDOM : + le_addr_type =ADDR_LE_DEV_RANDOM ; +break ; +default : +return -EINVAL ; + } +/* The LE_PUBLIC address type is ignored because of BDADDR_ANY */ hdev =hci_get_route (addr,BDADDR_ANY ,BDADDR_LE_PUBLIC );if (!hdev)return -ENOENT ;hci_dev_lock (hdev); - hcon =hci_conn_hash_lookup_le (hdev, addr, *addr_type); + hcon =hci_conn_hash_lookup_le (hdev, addr, le_addr_type);hci_dev_unlock (hdev);hci_dev_put (hdev);
@@ -1103,7 +1123,7 @@ static ssize_t lowpan_control_write(struct file *fp, buf[buf_size] ='\0' ;if (memcmp (buf,"connect " ,8 ) ==0 ) { - ret =get_l2cap_conn (&buf[8 ], &addr, &addr_type, &conn); + ret =get_l2cap_conn (&buf[8 ], &addr, &addr_type, &conn, false);if (ret == -EINVAL )return ret;
@@ -1140,7 +1160,7 @@ static ssize_t lowpan_control_write(struct file *fp, }if (memcmp (buf,"disconnect " ,11 ) ==0 ) { - ret =get_l2cap_conn (&buf[11 ], &addr, &addr_type, &conn); + ret =get_l2cap_conn (&buf[11 ], &addr, &addr_type, &conn, true);if (ret <0 )return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 355/568 Bluetooth: 6lowpan: Dont hold spin lock over sleeping functions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit 98454bc812f3611551e4b1f81732da4aa7b9597e ]
disconnect_all_peers() calls sleeping function (l2cap_chan_close) under spinlock. Holding the lock doesn't actually do any good -- we work on a local copy of the list, and the lock doesn't protect against peer->chan having already been freed.
Fix by taking refcounts of peer->chan instead. Clean up the code and old comments a bit.
Take devices_lock instead of RCU, because the kfree_rcu(); l2cap_chan_put(); construct in chan_close_cb() does not guarantee peer->chan is necessarily valid in RCU.
Also take l2cap_chan_lock() which is required for l2cap_chan_close().
Log: (bluez 6lowpan-tester Client Connect - Disable)
------
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575 ... <TASK>
...l2cap_send_disconn_req (net/bluetooth/l2cap_core.c:938 net/bluetooth/l2cap_core.c:1495)
...
? __pfx_l2cap_chan_close (net/bluetooth/l2cap_core.c:809)do_enable_set (net/bluetooth/6lowpan.c:1048 net/bluetooth/6lowpan.c:1068)
------
--- net/bluetooth/6lowpan.c | 68 ++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 25 deletions(-)
net/bluetooth/6lowpan.c +43 -25
@@ -52,6 +52,11 @@ static bool enable_6lowpan;static struct l2cap_chan *listen_chan;static DEFINE_MUTEX (set_lock); +enum { +LOWPAN_PEER_CLOSING , +LOWPAN_PEER_MAXBITS +}; +struct lowpan_peer {struct list_head list;struct rcu_head rcu;
@@ -60,6 +65,8 @@ struct lowpan_peer {/* peer addresses in various formats */ unsigned char lladdr[ETH_ALEN ];struct in6_addr peer_addr; + +DECLARE_BITMAP (flags,LOWPAN_PEER_MAXBITS ); };struct lowpan_btle_dev {
@@ -1013,41 +1020,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,static void disconnect_all_peers (void ) {struct lowpan_btle_dev *entry; -struct lowpan_peer *peer, *tmp_peer, *new_peer; -struct list_head peers; - -INIT_LIST_HEAD (&peers); +struct lowpan_peer *peer; +int nchans; -/* We make a separate list of peers as the close_cb() will -* modify the device peers list so it is better not to mess -* with the same list at the same time. +/* l2cap_chan_close() cannot be called from RCU, and lock ordering +* chan->lock > devices_lock prevents taking write side lock, so copy +* then close. */ rcu_read_lock (); +list_for_each_entry_rcu (entry, &bt_6lowpan_devices, list) +list_for_each_entry_rcu (peer, &entry->peers, list) +clear_bit (LOWPAN_PEER_CLOSING , peer->flags); +rcu_read_unlock (); -list_for_each_entry_rcu (entry, &bt_6lowpan_devices, list) { -list_for_each_entry_rcu (peer, &entry->peers, list) { - new_peer =kmalloc (sizeof (*new_peer),GFP_ATOMIC ); -if (!new_peer) -break ; +do { +struct l2cap_chan *chans[32 ]; +int i; - new_peer->chan = peer->chan; -INIT_LIST_HEAD (&new_peer->list); + nchans =0 ; -list_add (&new_peer->list, &peers); - } - } +spin_lock (&devices_lock); -rcu_read_unlock (); +list_for_each_entry_rcu (entry, &bt_6lowpan_devices, list) { +list_for_each_entry_rcu (peer, &entry->peers, list) { +if (test_and_set_bit (LOWPAN_PEER_CLOSING , + peer->flags)) +continue ; -spin_lock (&devices_lock); -list_for_each_entry_safe (peer, tmp_peer, &peers, list) { -l2cap_chan_close (peer->chan,ENOENT ); +l2cap_chan_hold (peer->chan); + chans[nchans++] = peer->chan; -list_del_rcu (&peer->list); -kfree_rcu (peer, rcu); - } -spin_unlock (&devices_lock); +if (nchans >=ARRAY_SIZE (chans)) + goto done; + } + } + +done: +spin_unlock (&devices_lock); + +for (i =0 ; i < nchans; ++i) { +l2cap_chan_lock (chans[i]); +l2cap_chan_close (chans[i],ENOENT ); +l2cap_chan_unlock (chans[i]); +l2cap_chan_put (chans[i]); + } + }while (nchans); }struct set_enable {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 356/568 sctp: prevent possible shift-out-of-bounds in sctp_transport_update_rto
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 1534ff77757e44bcc4b98d0196bc5c0052fce5fa ]
syzbot reported a possible shift-out-of-bounds [1]
Blamed commit added rto_alpha_max and rto_beta_max set to 1000.
It is unclear if some sctp users are setting very large rto_alpha and/or rto_beta.
In order to prevent user regression, perform the test at run time.
Also add READ_ONCE() annotations as sysctl values can change under us.
[1]
UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41 shift exponent 64 is too large for 32-bit type 'unsigned int' CPU: 0 UID: 0 PID: 16704 Comm: syz.2.2320 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025 Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:233 [inline] __ubsan_handle_shift_out_of_bounds+0x27f/0x420 lib/ubsan.c:494 sctp_transport_update_rto.cold+0x1c/0x34b net/sctp/transport.c:509 sctp_check_transmitted+0x11c4/0x1c30 net/sctp/outqueue.c:1502 sctp_outq_sack+0x4ef/0x1b20 net/sctp/outqueue.c:1338 sctp_cmd_process_sack net/sctp/sm_sideeffect.c:840 [inline] sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1372 [inline]
--- net/sctp/transport.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/sctp/transport.c +9 -4
@@ -495,6 +495,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)if (tp->rttvar || tp->srtt) {struct net *net = tp->asoc->base.net; +unsigned int rto_beta, rto_alpha;/* 6.3.1 C3) When a new RTT measurement R' is made, set * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R'
@@ -506,10 +507,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)* For example, assuming the default value of RTO.Alpha of * 1/8, rto_alpha would be expressed as 3. */ - tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) - + (((__u32 )abs ((__s64 )tp->srtt - (__s64 )rtt)) >> net->sctp.rto_beta); - tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) - + (rtt >> net->sctp.rto_alpha); + rto_beta =READ_ONCE (net->sctp.rto_beta); +if (rto_beta <32 ) + tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta) + + (((__u32 )abs ((__s64 )tp->srtt - (__s64 )rtt)) >> rto_beta); + rto_alpha =READ_ONCE (net->sctp.rto_alpha); +if (rto_alpha <32 ) + tp->srtt = tp->srtt - (tp->srtt >> rto_alpha) + + (rtt >> rto_alpha); }else {/* 6.3.1 C2) When the first RTT measurement R is made, set * SRTT <- R, RTTVAR <- R/2.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 357/568 net/smc: fix mismatch between CLC header and proposal
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: D. Wythe <[email protected]>
[ Upstream commit ec33f2e5a2d0dbbfd71435209aee812fdc9369b8 ]
The current CLC proposal message construction uses a mix of ini->smc_type_v1/v2 and pclc_base->hdr.typev1/v2 to decide whether to include optional extensions (IPv6 prefix extension for v1, and v2 extension). This leads to a critical inconsistency: when smc_clc_prfx_set() fails - for example, in IPv6-only environments with only link-local addresses, or when the local IP address and the outgoing interface’s network address are not in the same subnet.
As a result, the proposal message is assembled using the stale ini->smc_type_v1 value—causing the IPv6 prefix extension to be included even though the header indicates v1 is not supported. The peer then receives a malformed CLC proposal where the header type does not match the payload, and immediately resets the connection.
The fix ensures consistency between the CLC header flags and the actual payload by synchronizing ini->smc_type_v1 with pclc_base->hdr.typev1 when prefix setup fails.
--- net/smc/smc_clc.c | 1 + 1 file changed, 1 insertion(+)
net/smc/smc_clc.c +1 -0
@@ -862,6 +862,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)return SMC_CLC_DECL_CNFERR ; } pclc_base->hdr.typev1 =SMC_TYPE_N ; + ini->smc_type_v1 =SMC_TYPE_N ; }else { pclc_base->iparea_offset =htons (sizeof (*pclc_smcd)); plen += sizeof(*pclc_prfx) +
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 358/568 tipc: Fix use-after-free in tipc_mon_reinit_self().
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 0725e6afb55128be21a2ca36e9674f573ccec173 ]
syzbot reported use-after-free of tipc_net(net)->monitors[] in tipc_mon_reinit_self(). [0]
The array is protected by RTNL, but tipc_mon_reinit_self() iterates over it without RTNL.
tipc_mon_reinit_self() is called from tipc_net_finalize(), which is always under RTNL except for tipc_net_finalize_work().
Let's hold RTNL in tipc_net_finalize_work().
[0]:
BUG: KASAN: slab-use-after-free in __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
Read of size 1 at addr ffff88805eae1030 by task kworker/0:7/5989
CPU: 0 UID: 0 PID: 5989 Comm: kworker/0:7 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
Workqueue: events tipc_net_finalize_work
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xca/0x240 mm/kasan/report.c:482
kasan_report+0x118/0x150 mm/kasan/report.c:595
__kasan_check_byte+0x2a/0x40 mm/kasan/common.c:568
kasan_check_byte include/linux/kasan.h:399 [inline]
lock_acquire+0x8d/0x360 kernel/locking/lockdep.c:5842
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0xa7/0xf0 kernel/locking/spinlock.c:162
rtlock_slowlock kernel/locking/rtmutex.c:1894 [inline]
rwbase_rtmutex_lock_state kernel/locking/spinlock_rt.c:160 [inline]
rwbase_write_lock+0xd3/0x7e0 kernel/locking/rwbase_rt.c:244
rt_write_lock+0x76/0x110 kernel/locking/spinlock_rt.c:243
write_lock_bh include/linux/rwlock_rt.h:99 [inline]
tipc_mon_reinit_self+0x79/0x430 net/tipc/monitor.c:718
tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
process_one_work kernel/workqueue.c:3236 [inline]
process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3319
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
kthread+0x70e/0x8a0 kernel/kthread.c:463
ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 6089:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
__kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
kasan_kmalloc include/linux/kasan.h:260 [inline]
__kmalloc_cache_noprof+0x1a8/0x320 mm/slub.c:4407
kmalloc_noprof include/linux/slab.h:905 [inline]
kzalloc_noprof include/linux/slab.h:1039 [inline]
tipc_mon_create+0xc3/0x4d0 net/tipc/monitor.c:657
tipc_enable_bearer net/tipc/bearer.c:357 [inline]
__tipc_nl_bearer_enable+0xe16/0x13f0 net/tipc/bearer.c:1047
__tipc_nl_compat_doit net/tipc/netlink_compat.c:371 [inline]
tipc_nl_compat_doit+0x3bc/0x5f0 net/tipc/netlink_compat.c:393
tipc_nl_compat_handle net/tipc/netlink_compat.c:-1 [inline]
tipc_nl_compat_recv+0x83c/0xbe0 net/tipc/netlink_compat.c:1321
genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115
genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210
netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346
netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
sock_sendmsg_nosec net/socket.c:714 [inline]
__sock_sendmsg+0x21c/0x270 net/socket.c:729
____sys_sendmsg+0x508/0x820 net/socket.c:2614
___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
__sys_sendmsg net/socket.c:2700 [inline]
__do_sys_sendmsg net/socket.c:2705 [inline]
__se_sys_sendmsg net/socket.c:2703 [inline]
__x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2703
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 6088:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
poison_slab_object mm/kasan/common.c:243 [inline]
__kasan_slab_free+0x5b/0x80 mm/kasan/common.c:275
kasan_slab_free include/linux/kasan.h:233 [inline]
slab_free_hook mm/slub.c:2422 [inline]
slab_free mm/slub.c:4695 [inline]
kfree+0x195/0x550 mm/slub.c:4894
tipc_l2_device_event+0x380/0x650 net/tipc/bearer.c:-1
notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2267 [inline]
call_netdevice_notifiers net/core/dev.c:2281 [inline]
unregister_netdevice_many_notify+0x14d7/0x1fe0 net/core/dev.c:12166
unregister_netdevice_many net/core/dev.c:12229 [inline]
unregister_netdevice_queue+0x33c/0x380 net/core/dev.c:12073
unregister_netdevice include/linux/netdevice.h:3385 [inline]
__tun_detach+0xe4d/0x1620 drivers/net/tun.c:621
tun_detach drivers/net/tun.c:637 [inline]
tun_chr_close+0x10d/0x1c0 drivers/net/tun.c:3433
__fput+0x458/0xa80 fs/file_table.c:468
task_work_run+0x1d4/0x260 kernel/task_work.c:227
resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:43
exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline]
syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline]
do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100
entry_SYSCALL_64_after_hwframe+0x77/0x7f--- net/tipc/net.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/net.c +2 -0
@@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work) { struct tipc_net *tn = container_of(work, struct tipc_net, work); +rtnl_lock ();tipc_net_finalize (tipc_link_net (tn->bcl), tn->trial_addr); +rtnl_unlock (); }void tipc_net_stop (struct net *net)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 359/568 net: mdio: fix resource leak in mdiobus_register_device()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Buday Csaba <[email protected]>
[ Upstream commit e6ca8f533ed41129fcf052297718f417f021cc7d ]
Fix a possible leak in mdiobus_register_device() when both a reset-gpio and a reset-controller are present.
Clean up the already claimed reset-gpio, when the registration of the reset-controller fails, so when an error code is returned, the device retains its state before the registration attempt.
--- drivers/net/phy/mdio_bus.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/phy/mdio_bus.c +4 -1
@@ -80,8 +80,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev)return err; err =mdiobus_register_reset (mdiodev); -if (err) +if (err) { +gpiod_put (mdiodev->reset_gpio); + mdiodev->reset_gpio =NULL ;return err; + }/* Assert the reset signal */ mdio_device_reset (mdiodev,1 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 360/568 wifi: mac80211: skip rate verification for not captured PSDUs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
[ Upstream commit 7fe0d21f5633af8c3fab9f0ef0706c6156623484 ]
If for example the sniffer did not follow any AIDs in an MU frame, then some of the information may not be filled in or is even expected to be invalid. As an example, in that case it is expected that Nss is zero.
--- net/mac80211/rx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
net/mac80211/rx.c +7 -3
@@ -5228,10 +5228,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,if (WARN_ON (!local->started)) goto drop; -if (likely (!(status->flag &RX_FLAG_FAILED_PLCP_CRC ))) { +if (likely (!(status->flag &RX_FLAG_FAILED_PLCP_CRC ) && + !(status->flag &RX_FLAG_NO_PSDU && + status->zero_length_psdu_type == +IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED ))) {/* -* Validate the rate, unless a PLCP error means that -* we probably can't have a valid rate here anyway. +* Validate the rate, unless there was a PLCP error which may +* have an invalid rate or the PSDU was not capture and may be +* missing rate information. */ switch (status->encoding) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 361/568 af_unix: Initialise scc_index in unix_add_edge().
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 60e6489f8e3b086bd1130ad4450a2c112e863791 ]
Quang Le reported that the AF_UNIX GC could garbage-collect a receive queue of an alive in-flight socket, with a nice repro.
The repro consists of three stages.
1)
1-a. Create a single cyclic reference with many sockets 1-b. close() all sockets
1-c. Trigger GC
2)
2-a. Pass sk-A to an embryo sk-B
2-b. Pass sk-X to sk-X
2-c. Trigger GC
3)
3-a. accept() the embryo sk-B
3-b. Pass sk-B to sk-C
3-c. close() the in-flight sk-A
3-d. Trigger GC
As of 2-c, sk-A and sk-X are linked to unix_unvisited_vertices, and unix_walk_scc() groups them into two different SCCs:
unix_sk(sk-A)->vertex->scc_index = 2 (UNIX_VERTEX_INDEX_START) unix_sk(sk-X)->vertex->scc_index = 3
Once GC completes, unix_graph_grouped is set to true. Also, unix_graph_maybe_cyclic is set to true due to sk-X's cyclic self-reference, which makes close() trigger GC.
At 3-b, unix_add_edge() allocates unix_sk(sk-B)->vertex and links it to unix_unvisited_vertices.
unix_update_graph() is called at 3-a. and 3-b., but neither unix_graph_grouped nor unix_graph_maybe_cyclic is changed because both sk-B's listener and sk-C are not in-flight.
3-c decrements sk-A's file refcnt to 1.
Since unix_graph_grouped is true at 3-d, unix_walk_scc_fast() is finally called and iterates 3 sockets sk-A, sk-B, and sk-X:
sk-A -> sk-B (-> sk-C)
sk-X -> sk-X
This is totally fine. All of them are not yet close()d and should be grouped into different SCCs.
However, unix_vertex_dead() misjudges that sk-A and sk-B are in the same SCC and sk-A is dead.
unix_sk(sk-A)->scc_index == unix_sk(sk-B)->scc_index <-- Wrong! &&
sk-A's file refcnt == unix_sk(sk-A)->vertex->out_degree
^-- 1 in-flight count for sk-B
-> sk-A is dead !?
The problem is that unix_add_edge() does not initialise scc_index.
Stage 1) is used for heap spraying, making a newly allocated vertex have vertex->scc_index == 2 (UNIX_VERTEX_INDEX_START) set by unix_walk_scc() at 1-c.
Let's track the max SCC index from the previous unix_walk_scc() call and assign the max + 1 to a new vertex's scc_index.
This way, we can continue to avoid Tarjan's algorithm while preventing misjudgments.
--- net/unix/garbage.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
net/unix/garbage.c +11 -3
@@ -136,6 +136,7 @@ enum unix_vertex_index { };static unsigned long unix_vertex_unvisited_index =UNIX_VERTEX_INDEX_MARK1 ; +static unsigned long unix_vertex_max_scc_index =UNIX_VERTEX_INDEX_START ;static void unix_add_edge (struct scm_fp_list *fpl,struct unix_edge *edge) {
@@ -144,6 +145,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge)if (!vertex) { vertex =list_first_entry (&fpl->vertices,typeof (*vertex), entry); vertex->index = unix_vertex_unvisited_index; + vertex->scc_index = ++unix_vertex_max_scc_index; vertex->out_degree =0 ;INIT_LIST_HEAD (&vertex->edges);INIT_LIST_HEAD (&vertex->scc_entry);
@@ -480,10 +482,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde scc_dead =unix_vertex_dead (v); } -if (scc_dead) +if (scc_dead) {unix_collect_skb (&scc, hitlist); -else if (!unix_graph_maybe_cyclic) - unix_graph_maybe_cyclic =unix_scc_cyclic (&scc); + }else { +if (unix_vertex_max_scc_index < vertex->scc_index) + unix_vertex_max_scc_index = vertex->scc_index; + +if (!unix_graph_maybe_cyclic) + unix_graph_maybe_cyclic =unix_scc_cyclic (&scc); + }list_del (&scc); }
@@ -498,6 +505,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist)unsigned long last_index =UNIX_VERTEX_INDEX_START ; unix_graph_maybe_cyclic = false; + unix_vertex_max_scc_index =UNIX_VERTEX_INDEX_START ;/* Visit every vertex exactly once. * __unix_walk_scc() moves visited vertices to unix_visited_vertices.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 362/568 net/sched: act_connmark: transition to percpu stats and rcu
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
[ Upstream commit 288864effe33885988d53faf7830b35cb9a84c7a ]
The tc action act_connmark was using shared stats and taking the per action lock in the datapath. Improve it by using percpu stats and rcu.
perf before:
- 13.55% tcf_connmark_act
- 81.18% _raw_spin_lock
80.46% native_queued_spin_lock_slowpath
perf after:
- 2.85% tcf_connmark_act
tdc results:
1..15
ok 1 2002 - Add valid connmark action with defaults
ok 2 56a5 - Add valid connmark action with control pass ok 3 7c66 - Add valid connmark action with control drop ok 4 a913 - Add valid connmark action with control pipe ok 5 bdd8 - Add valid connmark action with control reclassify ok 6 b8be - Add valid connmark action with control continue ok 7 d8a6 - Add valid connmark action with control jump ok 8 aae8 - Add valid connmark action with zone argument ok 9 2f0b - Add valid connmark action with invalid zone argument ok 10 9305 - Add connmark action with unsupported argument ok 11 71ca - Add valid connmark action and replace it ok 12 5f8f - Add valid connmark action with cookie
ok 13 c506 - Replace connmark with invalid goto chain control ok 14 6571 - Delete connmark action with valid index ok 15 3426 - Delete connmark action with invalid index
Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
--- include/net/tc_act/tc_connmark.h | 9 ++- net/sched/act_connmark.c | 107 ++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 41 deletions(-)
include/net/tc_act/tc_connmark.h +7 -2
@@ -4,10 +4,15 @@#include <net/act_api.h> -struct tcf_connmark_info { -struct tc_action common; +struct tcf_connmark_parms {struct net *net;u16 zone; +struct rcu_head rcu; +}; + +struct tcf_connmark_info { +struct tc_action common; +struct tcf_connmark_parms __rcu *parms; };#define to_connmark (a) ((struct tcf_connmark_info *)a)
net/sched/act_connmark.c +68 -39
193 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 363/568 net_sched: act_connmark: use RCU in tcf_connmark_dump()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 0d752877705c0252ef2726e4c63c5573f048951c ]
Also storing tcf_action into struct tcf_connmark_parms makes sure there is no discrepancy in tcf_connmark_act().
Stable-dep-of: 62b656e43eae ("net: sched: act_connmark: initialize struct tc_ife to fix kernel leak")
--- include/net/tc_act/tc_connmark.h | 1 + net/sched/act_connmark.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-)
include/net/tc_act/tc_connmark.h +1 -0
@@ -7,6 +7,7 @@struct tcf_connmark_parms {struct net *net;u16 zone; +int action;struct rcu_head rcu; };
net/sched/act_connmark.c +10 -8
@@ -86,7 +86,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,/* using overlimits stats to count how many packets marked */ tcf_action_inc_overlimit_qstats (&ca->common); out: -return READ_ONCE (ca->tcf_action); +return parms->action; }static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX +1 ] = {
@@ -162,6 +162,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,if (err <0 ) goto release_idr; + nparms->action = parm->action; +spin_lock_bh (&ci->tcf_lock); goto_ch =tcf_action_set_ctrlact (*a, parm->action, goto_ch); oparms =rcu_replace_pointer (ci->parms, nparms,lockdep_is_held (&ci->tcf_lock));
@@ -185,20 +187,20 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,static inline int tcf_connmark_dump (struct sk_buff *skb,struct tc_action *a,int bind,int ref) { +const struct tcf_connmark_info *ci =to_connmark (a);unsigned char *b =skb_tail_pointer (skb); -struct tcf_connmark_info *ci =to_connmark (a); +const struct tcf_connmark_parms *parms;struct tc_connmark opt = { .index = ci->tcf_index, .refcnt =refcount_read (&ci->tcf_refcnt) - ref, .bindcnt =atomic_read (&ci->tcf_bindcnt) - bind, }; -struct tcf_connmark_parms *parms;struct tcf_t t; -spin_lock_bh (&ci->tcf_lock); - parms =rcu_dereference_protected (ci->parms,lockdep_is_held (&ci->tcf_lock)); +rcu_read_lock (); + parms =rcu_dereference (ci->parms); - opt.action = ci->tcf_action; + opt.action = parms->action; opt.zone = parms->zone;if (nla_put (skb,TCA_CONNMARK_PARMS ,sizeof (opt), &opt)) goto nla_put_failure;
@@ -207,12 +209,12 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,if (nla_put_64bit (skb,TCA_CONNMARK_TM ,sizeof (t), &t,TCA_CONNMARK_PAD )) goto nla_put_failure; -spin_unlock_bh (&ci->tcf_lock); +rcu_read_unlock ();return skb->len; nla_put_failure: -spin_unlock_bh (&ci->tcf_lock); +rcu_read_unlock ();nlmsg_trim (skb, b);return -1 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 364/568 net: sched: act_connmark: initialize struct tc_ife to fix kernel leak
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranganath V N <[email protected]>
[ Upstream commit 62b656e43eaeae445a39cd8021a4f47065af4389 ]
In tcf_connmark_dump(), the variable 'opt' was partially initialized using a designatied initializer. While the padding bytes are reamined uninitialized. nla_put() copies the entire structure into a netlink message, these uninitialized bytes leaked to userspace.
Initialize the structure with memset before assigning its fields to ensure all members and padding are cleared prior to beign copied.
--- net/sched/act_connmark.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
net/sched/act_connmark.c +7 -5
@@ -190,13 +190,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,const struct tcf_connmark_info *ci =to_connmark (a);unsigned char *b =skb_tail_pointer (skb);const struct tcf_connmark_parms *parms; -struct tc_connmark opt = { - .index = ci->tcf_index, - .refcnt =refcount_read (&ci->tcf_refcnt) - ref, - .bindcnt =atomic_read (&ci->tcf_bindcnt) - bind, - }; +struct tc_connmark opt;struct tcf_t t; +memset (&opt,0 ,sizeof (opt)); + + opt.index = ci->tcf_index; + opt.refcnt =refcount_read (&ci->tcf_refcnt) - ref; + opt.bindcnt =atomic_read (&ci->tcf_bindcnt) - bind; +rcu_read_lock (); parms =rcu_dereference (ci->parms);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 365/568 net: sched: act_ife: initialize struct tc_ife to fix KMSAN kernel-infoleak
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranganath V N <[email protected]>
[ Upstream commit ce50039be49eea9b4cd8873ca6eccded1b4a130a ]
Fix a KMSAN kernel-infoleak detected by the syzbot .
[net?] KMSAN: kernel-infoleak in __skb_datagram_iter
In tcf_ife_dump(), the variable 'opt' was partially initialized using a designatied initializer. While the padding bytes are reamined uninitialized. nla_put() copies the entire structure into a netlink message, these uninitialized bytes leaked to userspace.
Initialize the structure with memset before assigning its fields to ensure all members and padding are cleared prior to beign copied.
This change silences the KMSAN report and prevents potential information leaks from the kernel memory.
This fix has been tested and validated by syzbot. This patch closes the bug reported at the following syzkaller link and ensures no infoleak.
--- net/sched/act_ife.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
net/sched/act_ife.c +7 -5
@@ -643,13 +643,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,unsigned char *b =skb_tail_pointer (skb);struct tcf_ife_info *ife =to_ife (a);struct tcf_ife_params *p; -struct tc_ife opt = { - .index = ife->tcf_index, - .refcnt =refcount_read (&ife->tcf_refcnt) - ref, - .bindcnt =atomic_read (&ife->tcf_bindcnt) - bind, - }; +struct tc_ife opt;struct tcf_t t; +memset (&opt,0 ,sizeof (opt)); + + opt.index = ife->tcf_index, + opt.refcnt =refcount_read (&ife->tcf_refcnt) - ref, + opt.bindcnt =atomic_read (&ife->tcf_bindcnt) - bind, +spin_lock_bh (&ife->tcf_lock); opt.action = ife->tcf_action; p = rcu_dereference_protected(ife->params,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 366/568 net/mlx5e: Fix maxrate wraparound in threshold between units
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit a7bf4d5063c7837096aab2853224eb23628514d9 ]
The previous calculation used roundup() which caused an overflow for rates between 25.5Gbps and 26Gbps.
For example, a rate of 25.6Gbps would result in using 100Mbps units with value of 256, which would overflow the 8 bits field.
Simplify the upper_limit_mbps calculation by removing the unnecessary roundup, and adjust the comparison to use <= to correctly handle the boundary condition.
--- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +3 -2
@@ -587,18 +587,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,struct mlx5_core_dev *mdev = priv->mdev;u8 max_bw_value[IEEE_8021QAZ_MAX_TCS ];u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS ]; -__u64 upper_limit_mbps =roundup (255 *MLX5E_100MB ,MLX5E_1GB ); +__u64 upper_limit_mbps;int i;memset (max_bw_value,0 ,sizeof (max_bw_value));memset (max_bw_unit,0 ,sizeof (max_bw_unit)); + upper_limit_mbps =255 *MLX5E_100MB ;for (i =0 ; i <=mlx5_max_tc (mdev); i++) {if (!maxrate->tc_maxrate[i]) { max_bw_unit[i] =MLX5_BW_NO_LIMIT ;continue ; } -if (maxrate->tc_maxrate[i] < upper_limit_mbps) { +if (maxrate->tc_maxrate[i] <= upper_limit_mbps) { max_bw_value[i] =div_u64 (maxrate->tc_maxrate[i],MLX5E_100MB ); max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] :1 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 367/568 net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit 43b27d1bd88a4bce34ec2437d103acfae9655f9e ]
Add validation to reject rates exceeding 255 Gbps that would overflow the 8 bits max bandwidth field.
--- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +9 -1
@@ -588,11 +588,13 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,u8 max_bw_value[IEEE_8021QAZ_MAX_TCS ];u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS ];__u64 upper_limit_mbps; +__u64 upper_limit_gbps;int i;memset (max_bw_value,0 ,sizeof (max_bw_value));memset (max_bw_unit,0 ,sizeof (max_bw_unit)); upper_limit_mbps =255 *MLX5E_100MB ; + upper_limit_gbps =255 *MLX5E_1GB ;for (i =0 ; i <=mlx5_max_tc (mdev); i++) {if (!maxrate->tc_maxrate[i]) {
@@ -604,10 +606,16 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, MLX5E_100MB); max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] :1 ; max_bw_unit[i] =MLX5_100_MBPS_UNIT ; - }else { + }else if (max_bw_value[i] <= upper_limit_gbps) { max_bw_value[i] =div_u64 (maxrate->tc_maxrate[i],MLX5E_1GB ); max_bw_unit[i] =MLX5_GBPS_UNIT ; + }else { +netdev_err (netdev, +"tc_%d maxrate %llu Kbps exceeds limit %llu\n" , + i, maxrate->tc_maxrate[i], + upper_limit_gbps); +return -EINVAL ; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 368/568 net/mlx5: Expose shared buffer registers bits and structs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
[ Upstream commit 8d231dbc3b10155727bcfa9e543d397ad357f14f ]
Add the shared receive buffer management and configuration registers:
1. SBPR - Shared Buffer Pools Register
2. SBCM - Shared Buffer Class Management Register
Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
--- include/linux/mlx5/driver.h | 2 ++ include/linux/mlx5/mlx5_ifc.h | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)
include/linux/mlx5/driver.h +2 -0
@@ -100,6 +100,8 @@ enum { };enum { +MLX5_REG_SBPR =0xb001 , +MLX5_REG_SBCM =0xb002 ,MLX5_REG_QPTS =0x4002 ,MLX5_REG_QETCR =0x4005 ,MLX5_REG_QTCT =0x400a ,
include/linux/mlx5/mlx5_ifc.h +61 -0
67 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 369/568 net/mlx5e: Add API to query/modify SBPR and SBCM registers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
[ Upstream commit 11f0996d5c6023f4889882c8d088ec76a050d704 ]
To allow users to configure shared receive buffer parameters through dcbnl callbacks, expose an API to query and modify SBPR and SBCM registers, which will be used in the upcoming patch.
Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
--- .../net/ethernet/mellanox/mlx5/core/en/port.c | 72 +++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/en/port.h | 6 ++ 2 files changed, 78 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en/port.c +72 -0
@@ -287,6 +287,78 @@ int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)return err; } +int mlx5e_port_query_sbpr (struct mlx5_core_dev *mdev,u32 desc,u8 dir, +u8 pool_idx,void *out,int size_out) +{ +u32 in[MLX5_ST_SZ_DW (sbpr_reg)] = {}; + +MLX5_SET (sbpr_reg, in, desc, desc); +MLX5_SET (sbpr_reg, in, dir, dir); +MLX5_SET (sbpr_reg, in, pool, pool_idx); + +return mlx5_core_access_reg (mdev, in,sizeof (in), out, size_out,MLX5_REG_SBPR ,0 ,0 ); +} + +int mlx5e_port_set_sbpr (struct mlx5_core_dev *mdev,u32 desc,u8 dir, +u8 pool_idx,u32 infi_size,u32 size) +{ +u32 out[MLX5_ST_SZ_DW (sbpr_reg)] = {}; +u32 in[MLX5_ST_SZ_DW (sbpr_reg)] = {}; + +MLX5_SET (sbpr_reg, in, desc, desc); +MLX5_SET (sbpr_reg, in, dir, dir); +MLX5_SET (sbpr_reg, in, pool, pool_idx); +MLX5_SET (sbpr_reg, in, infi_size, infi_size); +MLX5_SET (sbpr_reg, in, size, size); +MLX5_SET (sbpr_reg, in, mode,1 ); + +return mlx5_core_access_reg (mdev, in,sizeof (in), out,sizeof (out),MLX5_REG_SBPR ,0 ,1 ); +} + +static int mlx5e_port_query_sbcm (struct mlx5_core_dev *mdev,u32 desc, +u8 pg_buff_idx,u8 dir,void *out, +int size_out) +{ +u32 in[MLX5_ST_SZ_DW (sbcm_reg)] = {}; + +MLX5_SET (sbcm_reg, in, desc, desc); +MLX5_SET (sbcm_reg, in, local_port,1 ); +MLX5_SET (sbcm_reg, in, pg_buff, pg_buff_idx); +MLX5_SET (sbcm_reg, in, dir, dir); + +return mlx5_core_access_reg (mdev, in,sizeof (in), out, size_out,MLX5_REG_SBCM ,0 ,0 ); +} + +int mlx5e_port_set_sbcm (struct mlx5_core_dev *mdev,u32 desc,u8 pg_buff_idx, +u8 dir,u8 infi_size,u32 max_buff,u8 pool_idx) +{ +u32 out[MLX5_ST_SZ_DW (sbcm_reg)] = {}; +u32 in[MLX5_ST_SZ_DW (sbcm_reg)] = {}; +u32 min_buff; +int err; +u8 exc; + + err =mlx5e_port_query_sbcm (mdev, desc, pg_buff_idx, dir, out, +sizeof (out)); +if (err) +return err; + + exc =MLX5_GET (sbcm_reg, out, exc); + min_buff =MLX5_GET (sbcm_reg, out, min_buff); + +MLX5_SET (sbcm_reg, in, desc, desc); +MLX5_SET (sbcm_reg, in, local_port,1 ); +MLX5_SET (sbcm_reg, in, pg_buff, pg_buff_idx); +MLX5_SET (sbcm_reg, in, dir, dir); +MLX5_SET (sbcm_reg, in, exc, exc); +MLX5_SET (sbcm_reg, in, min_buff, min_buff); +MLX5_SET (sbcm_reg, in, infi_max, infi_size); +MLX5_SET (sbcm_reg, in, max_buff, max_buff); +MLX5_SET (sbcm_reg, in, pool, pool_idx); + +return mlx5_core_access_reg (mdev, in,sizeof (in), out,sizeof (out),MLX5_REG_SBCM ,0 ,1 ); +} +/* buffer[i]: buffer that priority i mapped to */ int mlx5e_port_query_priority2buffer (struct mlx5_core_dev *mdev,u8 *buffer) {
drivers/net/ethernet/mellanox/mlx5/core/en/port.h +6 -0
@@ -57,6 +57,12 @@ u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,bool mlx5e_ptys_ext_supported (struct mlx5_core_dev *mdev);int mlx5e_port_query_pbmc (struct mlx5_core_dev *mdev,void *out);int mlx5e_port_set_pbmc (struct mlx5_core_dev *mdev,void *in); +int mlx5e_port_query_sbpr (struct mlx5_core_dev *mdev,u32 desc,u8 dir, +u8 pool_idx,void *out,int size_out); +int mlx5e_port_set_sbpr (struct mlx5_core_dev *mdev,u32 desc,u8 dir, +u8 pool_idx,u32 infi_size,u32 size); +int mlx5e_port_set_sbcm (struct mlx5_core_dev *mdev,u32 desc,u8 pg_buff_idx, +u8 dir,u8 infi_size,u32 max_buff,u8 pool_idx);int mlx5e_port_query_priority2buffer (struct mlx5_core_dev *mdev,u8 *buffer);int mlx5e_port_set_priority2buffer (struct mlx5_core_dev *mdev,u8 *buffer);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 370/568 net/mlx5e: Update shared buffer along with device buffer changes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
[ Upstream commit a440030d8946bfe3fd44b6da685e33ffe0ecd1ff ]
Currently, the user can modify device's receive buffer size, modify the mapping between QoS priority groups to buffers and change the buffer state to become lossy/lossless via pfc command.
However, the shared receive buffer pool alignments, as a result of such commands, is performed only when the shared buffer is in FW ownership. When a user changes the mapping of priority groups or buffer size, the shared buffer is moved to SW ownership.
Therefore, for devices that support shared buffer, handle the shared buffer alignments in accordance to user's desired configurations.
Meaning, the following will be performed:
1. For every change of buffer's headroom, recalculate the size of shared buffer to be equal to "total_buffer_size" - "new_headroom_size". The new shared buffer size will be split in ratio of 3:1 between lossy and lossless pools, respectively.
2. For each port buffer change, count the number of lossless buffers. If there is only one lossless buffer, then set its lossless pool usage threshold to be infinite. Otherwise, if there is more than one lossless buffer, set a usage threshold for each lossless buffer.
While at it, add more verbosity to debug prints when handling user commands, to assist in future debug.
Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
--- .../mellanox/mlx5/core/en/port_buffer.c | 222 +++++++++++++++++- .../mellanox/mlx5/core/en/port_buffer.h | 1 + 2 files changed, 219 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +218 -4
@@ -73,6 +73,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv, port_buffer->buffer[i].lossy); } + port_buffer->headroom_size = total_used; port_buffer->port_buffer_size =MLX5_GET (pbmc_reg, out, port_buffer_size) * port_buff_cell_sz; port_buffer->spare_buffer_size =
@@ -86,16 +87,204 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,return err; } +struct mlx5e_buffer_pool { +u32 infi_size; +u32 size; +u32 buff_occupancy; +}; + +static int mlx5e_port_query_pool (struct mlx5_core_dev *mdev, +struct mlx5e_buffer_pool *buffer_pool, +u32 desc,u8 dir,u8 pool_idx) +{ +u32 out[MLX5_ST_SZ_DW (sbpr_reg)] = {}; +int err; + + err =mlx5e_port_query_sbpr (mdev, desc, dir, pool_idx, out, +sizeof (out)); +if (err) +return err; + + buffer_pool->size =MLX5_GET (sbpr_reg, out, size); + buffer_pool->infi_size =MLX5_GET (sbpr_reg, out, infi_size); + buffer_pool->buff_occupancy =MLX5_GET (sbpr_reg, out, buff_occupancy); + +return err; +} + +enum { +MLX5_INGRESS_DIR =0 , +MLX5_EGRESS_DIR =1 , +}; + +enum { +MLX5_LOSSY_POOL =0 , +MLX5_LOSSLESS_POOL =1 , +}; + +/* No limit on usage of shared buffer pool (max_buff=0) */ +#define MLX5_SB_POOL_NO_THRESHOLD 0 +/* Shared buffer pool usage threshold when calculated +* dynamically in alpha units. alpha=13 is equivalent to +* HW_alpha of [(1/128) * 2 ^ (alpha-1)] = 32, where HW_alpha +* equates to the following portion of the shared buffer pool: +* [32 / (1 + n * 32)] While *n* is the number of buffers +* that are using the shared buffer pool. +*/ +#define MLX5_SB_POOL_THRESHOLD 13 + +/* Shared buffer class management parameters */ +struct mlx5_sbcm_params { +u8 pool_idx; +u8 max_buff; +u8 infi_size; +}; + +static const struct mlx5_sbcm_params sbcm_default = { + .pool_idx =MLX5_LOSSY_POOL , + .max_buff =MLX5_SB_POOL_NO_THRESHOLD , + .infi_size =0 , +}; + +static const struct mlx5_sbcm_params sbcm_lossy = { + .pool_idx =MLX5_LOSSY_POOL , + .max_buff =MLX5_SB_POOL_NO_THRESHOLD , + .infi_size =1 , +}; + +static const struct mlx5_sbcm_params sbcm_lossless = { + .pool_idx =MLX5_LOSSLESS_POOL , + .max_buff =MLX5_SB_POOL_THRESHOLD , + .infi_size =0 , +}; + +static const struct mlx5_sbcm_params sbcm_lossless_no_threshold = { + .pool_idx =MLX5_LOSSLESS_POOL , + .max_buff =MLX5_SB_POOL_NO_THRESHOLD , + .infi_size =1 , +}; + +/** +* select_sbcm_params() - selects the shared buffer pool configuration +* +* @buffer: <input> port buffer to retrieve params of +* @lossless_buff_count: <input> number of lossless buffers in total +* +* The selection is based on the following rules: +* 1. If buffer size is 0, no shared buffer pool is used. +* 2. If buffer is lossy, use lossy shared buffer pool. +* 3. If there are more than 1 lossless buffers, use lossless shared buffer pool +* with threshold. +* 4. If there is only 1 lossless buffer, use lossless shared buffer pool +* without threshold. +* +* @return const struct mlx5_sbcm_params* selected values +*/ +static const struct mlx5_sbcm_params * +select_sbcm_params (struct mlx5e_bufferx_reg *buffer,u8 lossless_buff_count) +{ +if (buffer->size ==0 ) +return &sbcm_default; + +if (buffer->lossy) +return &sbcm_lossy; + +if (lossless_buff_count >1 ) +return &sbcm_lossless; + +return &sbcm_lossless_no_threshold; +} + +static int port_update_pool_cfg (struct mlx5_core_dev *mdev, +struct mlx5e_port_buffer *port_buffer) +{ +const struct mlx5_sbcm_params *p; +u8 lossless_buff_count =0 ; +int err; +int i; + +if (!MLX5_CAP_GEN (mdev, sbcam_reg)) +return 0 ; + +for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) + lossless_buff_count += ((port_buffer->buffer[i].size) && + (!(port_buffer->buffer[i].lossy))); + +for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { + p =select_sbcm_params (&port_buffer->buffer[i], lossless_buff_count); + err =mlx5e_port_set_sbcm (mdev,0 , i, +MLX5_INGRESS_DIR , + p->infi_size, + p->max_buff, + p->pool_idx); +if (err) +return err; + } + +return 0 ; +} + +static int port_update_shared_buffer (struct mlx5_core_dev *mdev, +u32 current_headroom_size, +u32 new_headroom_size) +{ +struct mlx5e_buffer_pool lossless_ipool; +struct mlx5e_buffer_pool lossy_epool; +u32 lossless_ipool_size; +u32 shared_buffer_size; +u32 total_buffer_size; +u32 lossy_epool_size; +int err; + +if (!MLX5_CAP_GEN (mdev, sbcam_reg)) +return 0 ; + + err =mlx5e_port_query_pool (mdev, &lossy_epool,0 ,MLX5_EGRESS_DIR , +MLX5_LOSSY_POOL ); +if (err) +return err; + + err =mlx5e_port_query_pool (mdev, &lossless_ipool,0 ,MLX5_INGRESS_DIR , +MLX5_LOSSLESS_POOL ); +if (err) +return err; + + total_buffer_size = current_headroom_size + lossy_epool.size + + lossless_ipool.size; + shared_buffer_size = total_buffer_size - new_headroom_size; + +if (shared_buffer_size <4 ) { +pr_err ("Requested port buffer is too large, not enough space left for shared buffer\n" ); +return -EINVAL ; + } + +/* Total shared buffer size is split in a ratio of 3:1 between +* lossy and lossless pools respectively. +*/ + lossy_epool_size = (shared_buffer_size /4 ) *3 ; + lossless_ipool_size = shared_buffer_size /4 ; + +mlx5e_port_set_sbpr (mdev,0 ,MLX5_EGRESS_DIR ,MLX5_LOSSY_POOL ,0 , + lossy_epool_size); +mlx5e_port_set_sbpr (mdev,0 ,MLX5_INGRESS_DIR ,MLX5_LOSSLESS_POOL ,0 , + lossless_ipool_size); +return 0 ; +} +static int port_set_buffer (struct mlx5e_priv *priv,struct mlx5e_port_buffer *port_buffer) {u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;struct mlx5_core_dev *mdev = priv->mdev;int sz =MLX5_ST_SZ_BYTES (pbmc_reg); +u32 new_headroom_size =0 ; +u32 current_headroom_size;void *in;int err;int i; + current_headroom_size = port_buffer->headroom_size; + in =kzalloc (sz,GFP_KERNEL );if (!in)return -ENOMEM ;
@@ -110,6 +299,7 @@ static int port_set_buffer(struct mlx5e_priv *priv,u64 xoff = port_buffer->buffer[i].xoff;u64 xon = port_buffer->buffer[i].xon; + new_headroom_size += size;do_div (size, port_buff_cell_sz);do_div (xoff, port_buff_cell_sz);do_div (xon, port_buff_cell_sz);
@@ -119,6 +309,17 @@ static int port_set_buffer(struct mlx5e_priv *priv,MLX5_SET (bufferx_reg, buffer, xon_threshold, xon); } + new_headroom_size /= port_buff_cell_sz; + current_headroom_size /= port_buff_cell_sz; + err =port_update_shared_buffer (priv->mdev, current_headroom_size, + new_headroom_size); +if (err) +return err; + + err =port_update_pool_cfg (priv->mdev, port_buffer); +if (err) +return err; + err =mlx5e_port_set_pbmc (mdev, in); out:kfree (in);
@@ -174,6 +375,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,/** * update_buffer_lossy - Update buffer configuration based on pfc +* @mdev: port function core device * @max_mtu: netdev's max_mtu * @pfc_en: <input> current pfc configuration * @buffer: <input> current prio to buffer mapping
@@ -192,7 +394,8 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,* @return: 0 if no error, * sets change to true if buffer configuration was modified. */ -static int update_buffer_lossy (unsigned int max_mtu, +static int update_buffer_lossy (struct mlx5_core_dev *mdev, +unsigned int max_mtu,u8 pfc_en,u8 *buffer,u32 xoff,u16 port_buff_cell_sz,struct mlx5e_port_buffer *port_buffer,bool *change)
@@ -229,6 +432,10 @@ static int update_buffer_lossy(unsigned int max_mtu, }if (changed) { + err =port_update_pool_cfg (mdev, port_buffer); +if (err) +return err; + err =update_xoff_threshold (port_buffer, xoff, max_mtu, port_buff_cell_sz);if (err)return err;
@@ -293,23 +500,30 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, }if (change &MLX5E_PORT_BUFFER_PFC ) { +mlx5e_dbg (HW , priv,"%s: requested PFC per priority bitmask: 0x%x\n" , + __func__, pfc->pfc_en); err =mlx5e_port_query_priority2buffer (priv->mdev, buffer);if (err)return err; - err =update_buffer_lossy (max_mtu, pfc->pfc_en, buffer, xoff, port_buff_cell_sz, - &port_buffer, &update_buffer); + err =update_buffer_lossy (priv->mdev, max_mtu, pfc->pfc_en, buffer, xoff, + port_buff_cell_sz, &port_buffer, + &update_buffer);if (err)return err; }if (change &MLX5E_PORT_BUFFER_PRIO2BUFFER ) { update_prio2buffer = true; +for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) +mlx5e_dbg (HW , priv,"%s: requested to map prio[%d] to buffer %d\n" , + __func__, i, prio2buffer[i]); + err =fill_pfc_en (priv->mdev, &curr_pfc_en);if (err)return err; - err =update_buffer_lossy (max_mtu, curr_pfc_en, prio2buffer, xoff, + err =update_buffer_lossy (priv->mdev, max_mtu, curr_pfc_en, prio2buffer, xoff, port_buff_cell_sz, &port_buffer, &update_buffer);if (err)return err;
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h +1 -0
@@ -60,6 +60,7 @@ struct mlx5e_bufferx_reg {struct mlx5e_port_buffer {u32 port_buffer_size;u32 spare_buffer_size; +u32 headroom_size;struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER ]; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 371/568 net/mlx5e: Consider internal buffers size in port buffer calculations
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <[email protected]>
[ Upstream commit 81fe2be062915e2a2fdc494c3cd90e946e946c25 ]
Currently, when a user triggers a change in port buffer headroom (buffers 0-7), the driver checks that the requested headroom does not exceed the total port buffer size. However, this check does not take into account the internal buffers (buffers 8-9), which are also part of the total port buffer. This can result in treating invalid port buffer change requests as valid, causing unintended changes to the shared buffer.
To address this, include the internal buffers size in the calculation of available port buffer space which ensures that port buffer requests do not exceed the correct limit.
Furthermore, remove internal buffers (8-9) size from the total_size calculation as these buffers are reserved for internal use and are not exposed to the user.
While at it, add verbosity to the debug prints in mlx5e_port_query_buffer() function to ease future debugging.
Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
--- .../mellanox/mlx5/core/en/port_buffer.c | 42 ++++++++++++------- .../mellanox/mlx5/core/en/port_buffer.h | 8 ++-- .../ethernet/mellanox/mlx5/core/en_dcbnl.c | 7 ++-- 3 files changed, 36 insertions(+), 21 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +27 -15
@@ -51,7 +51,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,if (err) goto out; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) { buffer =MLX5_ADDR_OF (pbmc_reg, out, buffer[i]); port_buffer->buffer[i].lossy =MLX5_GET (bufferx_reg, buffer, lossy);
@@ -73,14 +73,24 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv, port_buffer->buffer[i].lossy); } - port_buffer->headroom_size = total_used; + port_buffer->internal_buffers_size =0 ; +for (i =MLX5E_MAX_NETWORK_BUFFER ; i <MLX5E_TOTAL_BUFFERS ; i++) { + buffer =MLX5_ADDR_OF (pbmc_reg, out, buffer[i]); + port_buffer->internal_buffers_size += +MLX5_GET (bufferx_reg, buffer, size) * port_buff_cell_sz; + } + port_buffer->port_buffer_size =MLX5_GET (pbmc_reg, out, port_buffer_size) * port_buff_cell_sz; - port_buffer->spare_buffer_size = - port_buffer->port_buffer_size - total_used; - -mlx5e_dbg (HW , priv,"total buffer size=%d, spare buffer size=%d\n" , - port_buffer->port_buffer_size, + port_buffer->headroom_size = total_used; + port_buffer->spare_buffer_size = port_buffer->port_buffer_size - + port_buffer->internal_buffers_size - + port_buffer->headroom_size; + +mlx5e_dbg (HW , priv, +"total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n" , + port_buffer->port_buffer_size, port_buffer->headroom_size, + port_buffer->internal_buffers_size, port_buffer->spare_buffer_size); out:kfree (out);
@@ -206,11 +216,11 @@ static int port_update_pool_cfg(struct mlx5_core_dev *mdev,if (!MLX5_CAP_GEN (mdev, sbcam_reg))return 0 ; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) lossless_buff_count += ((port_buffer->buffer[i].size) && (!(port_buffer->buffer[i].lossy))); -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) { p =select_sbcm_params (&port_buffer->buffer[i], lossless_buff_count); err = mlx5e_port_set_sbcm(mdev, 0, i, MLX5_INGRESS_DIR,
@@ -293,7 +303,7 @@ static int port_set_buffer(struct mlx5e_priv *priv,if (err) goto out; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {void *buffer =MLX5_ADDR_OF (pbmc_reg, in, buffer[i]);u64 size = port_buffer->buffer[i].size;u64 xoff = port_buffer->buffer[i].xoff;
@@ -351,7 +361,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, {int i; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {if (port_buffer->buffer[i].lossy) { port_buffer->buffer[i].xoff =0 ; port_buffer->buffer[i].xon =0 ;
@@ -408,7 +418,7 @@ static int update_buffer_lossy(struct mlx5_core_dev *mdev,int err;int i; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) { prio_count =0 ; lossy_count =0 ;
@@ -515,7 +525,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,if (change &MLX5E_PORT_BUFFER_PRIO2BUFFER ) { update_prio2buffer = true; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++)mlx5e_dbg (HW , priv,"%s: requested to map prio[%d] to buffer %d\n" , __func__, i, prio2buffer[i]);
@@ -530,7 +540,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, }if (change &MLX5E_PORT_BUFFER_SIZE ) { -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {mlx5e_dbg (HW , priv,"%s: buffer[%d]=%d\n" , __func__, i, buffer_size[i]);if (!port_buffer.buffer[i].lossy && !buffer_size[i]) { mlx5e_dbg(HW, priv, "%s: lossless buffer[%d] size cannot be zero\n",
@@ -544,7 +554,9 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,mlx5e_dbg (HW , priv,"%s: total buffer requested=%d\n" , __func__, total_used); -if (total_used > port_buffer.port_buffer_size) +if (total_used > port_buffer.headroom_size && + (total_used - port_buffer.headroom_size) > + port_buffer.spare_buffer_size)return -EINVAL ; update_buffer = true;
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h +5 -3
@@ -35,7 +35,8 @@#include "en.h" #include "port.h" -#define MLX5E_MAX_BUFFER 8 +#define MLX5E_MAX_NETWORK_BUFFER 8 +#define MLX5E_TOTAL_BUFFERS 10#define MLX5E_DEFAULT_CABLE_LEN 7/* 7 meters */ #define MLX5_BUFFER_SUPPORTED (mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \
@@ -60,8 +61,9 @@ struct mlx5e_bufferx_reg {struct mlx5e_port_buffer {u32 port_buffer_size;u32 spare_buffer_size; -u32 headroom_size; -struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER ]; +u32 headroom_size;/* Buffers 0-7 */ +u32 internal_buffers_size;/* Buffers 8-9 */ +struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER ]; }; int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +4 -3
@@ -935,9 +935,10 @@ static int mlx5e_dcbnl_getbuffer(struct net_device *dev,if (err)return err; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) dcb_buffer->buffer_size[i] = port_buffer.buffer[i].size; - dcb_buffer->total_size = port_buffer.port_buffer_size; + dcb_buffer->total_size = port_buffer.port_buffer_size - + port_buffer.internal_buffers_size;return 0 ; }
@@ -979,7 +980,7 @@ static int mlx5e_dcbnl_setbuffer(struct net_device *dev,if (err)return err; -for (i =0 ; i <MLX5E_MAX_BUFFER ; i++) { +for (i =0 ; i <MLX5E_MAX_NETWORK_BUFFER ; i++) {if (port_buffer.buffer[i].size != dcb_buffer->buffer_size[i]) { changed |=MLX5E_PORT_BUFFER_SIZE ; buffer_size = dcb_buffer->buffer_size;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 372/568 net/mlx5e: Remove mlx5e_dbg() and msglvl support
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit 559f4c32ebff40a25199b5178d58c9283ac5eb9c ]
The msglvl support was implemented using the mlx5e_dbg() macro which is rarely used in the driver, and is not very useful when you can just use dynamic debug instead.
Remove mlx5e_dbg() and convert its usages to netdev_dbg().
Stable-dep-of: 9fcc2b6c1052 ("net/mlx5e: Fix potentially misleading debug message")
--- drivers/net/ethernet/mellanox/mlx5/core/en.h | 10 ----- .../mellanox/mlx5/core/en/port_buffer.c | 44 ++++++++++--------- .../net/ethernet/mellanox/mlx5/core/en_arfs.c | 8 ++-- .../ethernet/mellanox/mlx5/core/en_dcbnl.c | 26 +++++------ .../ethernet/mellanox/mlx5/core/en_ethtool.c | 18 ++------ .../net/ethernet/mellanox/mlx5/core/en_main.c | 5 +-- 6 files changed, 45 insertions(+), 66 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +0 -10
@@ -165,15 +165,6 @@ struct page_pool;#define MLX5E_MAX_KLM_PER_WQE (mdev) \ MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev)) -#define MLX5E_MSG_LEVEL NETIF_MSG_LINK - -#define mlx5e_dbg (mlevel, priv, format, ...) \ -do { \ - if (NETIF_MSG_##mlevel & (priv)->msglevel) \ - netdev_warn(priv->netdev, format, \ - ##__VA_ARGS__); \ -} while (0) -#define mlx5e_state_dereference (priv, p) \ rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock))
@@ -901,7 +892,6 @@ struct mlx5e_priv {#endif /* priv data path fields - end */ -u32 msglevel;unsigned long state;struct mutex state_lock;/* Protects Interface state */ struct mlx5e_rq drop_rq;
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +23 -21
99 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +4 -4
@@ -595,10 +595,10 @@ static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv,if (IS_ERR (rule)) { err =PTR_ERR (rule); priv->channel_stats[arfs_rule->rxq]->rq.arfs_err++; -mlx5e_dbg (HW , priv, -"%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n" , - __func__, arfs_rule->filter_id, arfs_rule->rxq, - tuple->ip_proto, err); +netdev_dbg (priv->netdev, +"%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n" , + __func__, arfs_rule->filter_id, arfs_rule->rxq, + tuple->ip_proto, err); } out:
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +13 -13
@@ -275,10 +275,10 @@ static int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_etsmemcpy (priv->dcbx.tc_tsa, ets->tc_tsa,sizeof (ets->tc_tsa));for (i =0 ; i <IEEE_8021QAZ_MAX_TCS ; i++) { -mlx5e_dbg (HW , priv,"%s: prio_%d <=> tc_%d\n" , - __func__, i, ets->prio_tc[i]); -mlx5e_dbg (HW , priv,"%s: tc_%d <=> tx_bw_%d%%, group_%d\n" , - __func__, i, tc_tx_bw[i], tc_group[i]); +netdev_dbg (priv->netdev,"%s: prio_%d <=> tc_%d\n" , + __func__, i, ets->prio_tc[i]); +netdev_dbg (priv->netdev,"%s: tc_%d <=> tx_bw_%d%%, group_%d\n" , + __func__, i, tc_tx_bw[i], tc_group[i]); }return err;
@@ -399,9 +399,9 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev, }if (!ret) { -mlx5e_dbg (HW , priv, -"%s: PFC per priority bit mask: 0x%x\n" , - __func__, pfc->pfc_en); +netdev_dbg (dev, +"%s: PFC per priority bit mask: 0x%x\n" , + __func__, pfc->pfc_en); }return ret; }
@@ -620,8 +620,8 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, }for (i =0 ; i <IEEE_8021QAZ_MAX_TCS ; i++) { -mlx5e_dbg (HW , priv,"%s: tc_%d <=> max_bw %d Gbps\n" , - __func__, i, max_bw_value[i]); +netdev_dbg (netdev,"%s: tc_%d <=> max_bw %d Gbps\n" , + __func__, i, max_bw_value[i]); }return mlx5_modify_port_ets_rate_limit (mdev, max_bw_value, max_bw_unit);
@@ -649,10 +649,10 @@ static u8 mlx5e_dcbnl_setall(struct net_device *netdev) ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i]; ets.tc_tsa[i] =IEEE_8021QAZ_TSA_ETS ; ets.prio_tc[i] = cee_cfg->prio_to_pg_map[i]; -mlx5e_dbg (HW , priv, -"%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n" , - __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i], - ets.prio_tc[i]); +netdev_dbg (netdev, +"%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n" , + __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i], + ets.prio_tc[i]); } err =mlx5e_dbcnl_validate_ets (netdev, &ets, true);
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +3 -15
@@ -1703,16 +1703,6 @@ static int mlx5e_set_fecparam(struct net_device *netdev,return 0 ; } -static u32 mlx5e_get_msglevel (struct net_device *dev) -{ -return ((struct mlx5e_priv *)netdev_priv (dev))->msglevel; -} - -static void mlx5e_set_msglevel (struct net_device *dev,u32 val) -{ - ((struct mlx5e_priv *)netdev_priv (dev))->msglevel = val; -} -static int mlx5e_set_phys_id (struct net_device *dev,enum ethtool_phys_id_state state) {
@@ -1966,9 +1956,9 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_valif (err)return err; -mlx5e_dbg (DRV , priv,"MLX5E: RxCqeCmprss was turned %s\n" , -MLX5E_GET_PFLAG (&priv->channels.params, -MLX5E_PFLAG_RX_CQE_COMPRESS ) ?"ON" :"OFF" ); +netdev_dbg (priv->netdev,"MLX5E: RxCqeCmprss was turned %s\n" , +MLX5E_GET_PFLAG (&priv->channels.params, +MLX5E_PFLAG_RX_CQE_COMPRESS ) ?"ON" :"OFF" );return 0 ; }
@@ -2450,8 +2440,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = { .get_priv_flags = mlx5e_get_priv_flags, .set_priv_flags = mlx5e_set_priv_flags, .self_test = mlx5e_self_test, - .get_msglevel = mlx5e_get_msglevel, - .set_msglevel = mlx5e_set_msglevel, .get_fec_stats = mlx5e_get_fec_stats, .get_fecparam = mlx5e_get_fecparam, .set_fecparam = mlx5e_set_fecparam,
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +2 -3
@@ -2339,7 +2339,7 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu)/* Asymmetric dynamic memory allocation. * Freed in mlx5e_priv_arrays_free, not on channel closure. */ -mlx5e_dbg (DRV , priv,"Creating channel stats %d\n" , ix); +netdev_dbg (priv->netdev,"Creating channel stats %d\n" , ix); priv->channel_stats[ix] =kvzalloc_node (sizeof (**priv->channel_stats),GFP_KERNEL ,cpu_to_node (cpu));if (!priv->channel_stats[ix])
@@ -2714,7 +2714,7 @@ int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv)if (MLX5E_GET_PFLAG (&priv->channels.params,MLX5E_PFLAG_TX_PORT_TS )) num_txqs += ntc; -mlx5e_dbg (DRV , priv,"Setting num_txqs %d\n" , num_txqs); +netdev_dbg (priv->netdev,"Setting num_txqs %d\n" , num_txqs); err =netif_set_real_num_tx_queues (priv->netdev, num_txqs);if (err)netdev_warn (priv->netdev,"netif_set_real_num_tx_queues failed, %d\n" , err);
@@ -5515,7 +5515,6 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,/* priv init */ priv->mdev = mdev; priv->netdev = netdev; - priv->msglevel =MLX5E_MSG_LEVEL ; priv->max_nch = nch; priv->max_opened_tc =1 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 373/568 net/mlx5e: Fix potentially misleading debug message
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit 9fcc2b6c10523f7e75db6387946c86fcf19dc97e ]
Change the debug message to print the correct units instead of always assuming Gbps, as the value can be in either 100 Mbps or 1 Gbps units.
--- .../net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +16 -2
@@ -590,6 +590,19 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,__u64 upper_limit_mbps;__u64 upper_limit_gbps;int i; +struct { +int scale; +const char *units_str; + } units[] = { + [MLX5_100_MBPS_UNIT ] = { + .scale =100 , + .units_str ="Mbps" , + }, + [MLX5_GBPS_UNIT ] = { + .scale =1 , + .units_str ="Gbps" , + }, + };memset (max_bw_value,0 ,sizeof (max_bw_value));memset (max_bw_unit,0 ,sizeof (max_bw_unit));
@@ -620,8 +633,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, }for (i =0 ; i <IEEE_8021QAZ_MAX_TCS ; i++) { -netdev_dbg (netdev,"%s: tc_%d <=> max_bw %d Gbps\n" , - __func__, i, max_bw_value[i]); +netdev_dbg (netdev,"%s: tc_%d <=> max_bw %u %s\n" , __func__, i, + max_bw_value[i] * units[max_bw_unit[i]].scale, + units[max_bw_unit[i]].units_str); }return mlx5_modify_port_ets_rate_limit (mdev, max_bw_value, max_bw_unit);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 374/568 net_sched: limit try_bulk_dequeue_skb() batches
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 0345552a653ce5542affeb69ac5aa52177a5199b ]
After commit 100dfa74cad9 ("inet: dev_queue_xmit() llist adoption") I started seeing many qdisc requeues on IDPF under high TX workload.
$ tc -s qd sh dev eth1 handle 1: ; sleep 1; tc -s qd sh dev eth1 handle 1: qdisc mq 1: root Sent 43534617319319 bytes 268186451819 pkt (dropped 0, overlimits 0 requeues 3532840114) backlog 1056Kb 6675p requeues 3532840114 qdisc mq 1: root Sent 43554665866695 bytes 268309964788 pkt (dropped 0, overlimits 0 requeues 3537737653) backlog 781164b 4822p requeues 3537737653
This is caused by try_bulk_dequeue_skb() being only limited by BQL budget.
perf record -C120-239 -e qdisc:qdisc_dequeue sleep 1 ; perf script
...
netperf 75332 [146] 2711.138269: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1292 skbaddr=0xff378005a1e9f200 netperf 75332 [146] 2711.138953: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1213 skbaddr=0xff378004d607a500 netperf 75330 [144] 2711.139631: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1233 skbaddr=0xff3780046be20100 netperf 75333 [147] 2711.140356: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1093 skbaddr=0xff37800514845b00 netperf 75337 [151] 2711.141037: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1353 skbaddr=0xff37800460753300 netperf 75337 [151] 2711.141877: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1367 skbaddr=0xff378004e72c7b00 netperf 75330 [144] 2711.142643: qdisc:qdisc_dequeue: dequeue ifindex=5 qdisc handle=0x80150000 parent=0x10013 txq_state=0x0 packets=1202 skbaddr=0xff3780045bd60000
...
This is bad because :
1) Large batches hold one victim cpu for a very long time.
2) Driver often hit their own TX ring limit (all slots are used).
3) We call dev_requeue_skb()
4) Requeues are using a FIFO (q->gso_skb), breaking qdisc ability to implement FQ or priority scheduling.
5) dequeue_skb() gets packets from q->gso_skb one skb at a time with no xmit_more support. This is causing many spinlock games between the qdisc and the device driver.
Requeues were supposed to be very rare, lets keep them this way.
Limit batch sizes to /proc/sys/net/core/dev_weight (default 64) as __qdisc_run() was designed to use.
--- net/sched/sch_generic.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
net/sched/sch_generic.c +10 -7
@@ -178,9 +178,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)static void try_bulk_dequeue_skb (struct Qdisc *q,struct sk_buff *skb,const struct netdev_queue *txq, -int *packets) +int *packets,int budget) {int bytelimit =qdisc_avail_bulklimit (txq) - skb->len; +int cnt =0 ;while (bytelimit >0 ) {struct sk_buff *nskb = q->dequeue (q);
@@ -191,8 +192,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q, bytelimit -= nskb->len;/* covers GSO len */ skb->next = nskb; skb = nskb; - (*packets)++;/* GSO counts as one pkt */ +if (++cnt >= budget) +break ; } + (*packets) += cnt;skb_mark_not_on_list (skb); }
@@ -226,7 +229,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,* A requeued skb (via q->gso_skb) can also be a SKB list. */ static struct sk_buff *dequeue_skb (struct Qdisc *q,bool *validate, -int *packets) +int *packets,int budget) {const struct netdev_queue *txq = q->dev_queue;struct sk_buff *skb =NULL ;
@@ -293,7 +296,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,if (skb) { bulk:if (qdisc_may_bulk (q)) -try_bulk_dequeue_skb (q, skb, txq, packets); +try_bulk_dequeue_skb (q, skb, txq, packets, budget);else try_bulk_dequeue_skb_slow (q, skb, packets); }
@@ -385,7 +388,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,* >0 - queue is not empty. * */ -static inline bool qdisc_restart (struct Qdisc *q,int *packets) +static inline bool qdisc_restart (struct Qdisc *q,int *packets,int budget) {spinlock_t *root_lock =NULL ;struct netdev_queue *txq;
@@ -394,7 +397,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)bool validate;/* Dequeue packet */ - skb =dequeue_skb (q, &validate, packets); + skb =dequeue_skb (q, &validate, packets, budget);if (unlikely (!skb))return false;
@@ -412,7 +415,7 @@ void __qdisc_run(struct Qdisc *q)int quota =READ_ONCE (dev_tx_weight);int packets; -while (qdisc_restart (q, &packets)) { +while (qdisc_restart (q, &packets, quota)) { quota -= packets;if (quota <=0 ) {if (q->flags &TCQ_F_NOLOCK )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 375/568 hsr: Fix supervision frame sending on HSRv0
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Maurer <[email protected]>
[ Upstream commit 96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f ]
On HSRv0, no supervision frames were sent. The supervison frames were generated successfully, but failed the check for a sufficiently long mac header, i.e., at least sizeof(struct hsr_ethhdr), in hsr_fill_frame_info() because the mac header only contained the ethernet header.
Fix this by including the HSR header in the mac header when generating HSR supervision frames. Note that the mac header now also includes the TLV fields. This matches how we set the headers on rx and also the size of struct hsrv0_ethhdr_sp.
--- net/hsr/hsr_device.c | 3 +++ 1 file changed, 3 insertions(+)
net/hsr/hsr_device.c +3 -0
@@ -313,6 +313,9 @@ static void send_hsr_supervision_frame(struct hsr_port *master, } hsr_stag =skb_put (skb,sizeof (struct hsr_sup_tag )); +skb_set_network_header (skb,ETH_HLEN +HSR_HLEN ); +skb_reset_mac_len (skb); +set_hsr_stag_path (hsr_stag, (hsr->prot_version ?0x0 :0xf ));set_hsr_stag_HSR_ver (hsr_stag, hsr->prot_version);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 376/568 ACPI: CPPC: Check _CPC validity for only the online CPUs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautham R. Shenoy <[email protected]>
[ Upstream commit 6dd3b8a709a130a4d55c866af9804c81b8486d28 ]
per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> acpi_cppc_processor_probe().
However the function acpi_cpc_valid() checks for the validity of the _CPC object for all the present CPUs. This breaks when the kernel is booted with "nosmt=force".
Hence check the validity of the _CPC objects of only the online CPUs.
--- drivers/acpi/cppc_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/cppc_acpi.c +1 -1
@@ -440,7 +440,7 @@ bool acpi_cpc_valid(void)if (acpi_disabled)return false; -for_each_present_cpu (cpu) { +for_each_online_cpu (cpu) { cpc_ptr =per_cpu (cpc_desc_ptr, cpu);if (!cpc_ptr)return false;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 377/568 ACPI: CPPC: Perform fast check switch only for online CPUs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautham R. Shenoy <[email protected]>
[ Upstream commit 8821c8e80a65bc4eb73daf63b34aac6b8ad69461 ]
per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> acpi_cppc_processor_probe().
However the function cppc_allow_fast_switch() checks for the validity of the _CPC object for all the present CPUs. This breaks when the kernel is booted with "nosmt=force".
Check fast_switch capability only on online CPUs
--- drivers/acpi/cppc_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/cppc_acpi.c +1 -1
@@ -456,7 +456,7 @@ bool cppc_allow_fast_switch(void)struct cpc_desc *cpc_ptr;int cpu; -for_each_present_cpu (cpu) { +for_each_online_cpu (cpu) { cpc_ptr =per_cpu (cpc_desc_ptr, cpu); desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF ]; if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 378/568 ACPI: CPPC: Limit perf ctrs in PCC check only to online CPUs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautham R. Shenoy <[email protected]>
[ Upstream commit 0fce75870666b46b700cfbd3216380b422f975da ]
per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online CPU via acpi_soft_cpu_online() --> __acpi_processor_start() --> acpi_cppc_processor_probe().
However the function cppc_perf_ctrs_in_pcc() checks if the CPPC perf-ctrs are in a PCC region for all the present CPUs, which breaks when the kernel is booted with "nosmt=force".
Hence, limit the check only to the online CPUs.
--- drivers/acpi/cppc_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/cppc_acpi.c +1 -1
@@ -1336,7 +1336,7 @@ bool cppc_perf_ctrs_in_pcc(void) {int cpu; -for_each_present_cpu (cpu) { +for_each_online_cpu (cpu) {struct cpc_register_resource *ref_perf_reg;struct cpc_desc *cpc_desc;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 379/568 Bluetooth: L2CAP: export l2cap_chan_hold for modules
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit e060088db0bdf7932e0e3c2d24b7371c4c5b867c ]
l2cap_chan_put() is exported, so export also l2cap_chan_hold() for modules.
l2cap_chan_hold() has use case in net/bluetooth/6lowpan.c
--- net/bluetooth/l2cap_core.c | 1 + 1 file changed, 1 insertion(+)
net/bluetooth/l2cap_core.c +1 -0
@@ -521,6 +521,7 @@ void l2cap_chan_hold(struct l2cap_chan *c)kref_get (&c->kref); } +EXPORT_SYMBOL_GPL (l2cap_chan_hold);struct l2cap_chan *l2cap_chan_hold_unless_zero (struct l2cap_chan *c) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 380/568 acpi,srat: Fix incorrect device handle check for Generic Initiator
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuai Xue <[email protected]>
[ Upstream commit 7c3643f204edf1c5edb12b36b34838683ee5f8dc ]
The Generic Initiator Affinity Structure in SRAT table uses device handle type field to indicate the device type. According to ACPI specification, the device handle type value of 1 represents PCI device, not 0.
--- drivers/acpi/numa/srat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/numa/srat.c +1 -1
@@ -140,7 +140,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)struct acpi_srat_generic_affinity *p = (struct acpi_srat_generic_affinity *)header; -if (p->device_handle_type ==0 ) { +if (p->device_handle_type ==1 ) {/* * For pci devices this may be the only place they * are assigned a proximity domain
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 381/568 regulator: fixed: fix GPIO descriptor leak on register failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 636f4618b1cd96f6b5a2b8c7c4f665c8533ecf13 ]
In the commit referenced by the Fixes tag, devm_gpiod_get_optional() was replaced by manual
GPIO management, relying on the regulator core to release the GPIO descriptor. However, this approach does not account for the error path: when regulator registration fails, the core never takes over the GPIO, resulting in a resource leak.
Add gpiod_put() before returning on regulator registration failure.
--- drivers/regulator/fixed.c | 1 + 1 file changed, 1 insertion(+)
drivers/regulator/fixed.c +1 -0
@@ -287,6 +287,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) ret =dev_err_probe (&pdev->dev,PTR_ERR (drvdata->dev),"Failed to register regulator: %ld\n" ,PTR_ERR (drvdata->dev)); +gpiod_put (cfg.ena_gpiod);return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 382/568 ASoC: cs4271: Fix regulator leak on probe failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 6b6eddc63ce871897d3a5bc4f8f593e698aef104 ]
The probe function enables regulators at the beginning but fails to disable them in its error handling path. If any operation after enabling the regulators fails, the probe will exit with an error, leaving the regulators permanently enabled, which could lead to a resource leak.
Add a proper error handling path to call regulator_bulk_disable() before returning an error.
--- sound/soc/codecs/cs4271.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/soc/codecs/cs4271.c +7 -3
@@ -594,17 +594,17 @@ static int cs4271_component_probe(struct snd_soc_component *component) ret =regcache_sync (cs4271->regmap);if (ret <0 ) -return ret; + goto err_disable_regulator; ret =regmap_update_bits (cs4271->regmap,CS4271_MODE2 ,CS4271_MODE2_PDN |CS4271_MODE2_CPEN ,CS4271_MODE2_PDN |CS4271_MODE2_CPEN );if (ret <0 ) -return ret; + goto err_disable_regulator; ret =regmap_update_bits (cs4271->regmap,CS4271_MODE2 ,CS4271_MODE2_PDN ,0 );if (ret <0 ) -return ret; + goto err_disable_regulator;/* Power-up sequence requires 85 uS */ udelay (85 );
@@ -614,6 +614,10 @@ static int cs4271_component_probe(struct snd_soc_component *component) CS4271_MODE2_MUTECAEQUB);return 0 ; + +err_disable_regulator: +regulator_bulk_disable (ARRAY_SIZE (cs4271->supplies), cs4271->supplies); +return ret; }static void cs4271_component_remove (struct snd_soc_component *component)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 383/568 ASoC: codecs: va-macro: fix resource leak in probe error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 3dc8c73365d3ca25c99e7e1a0f493039d7291df5 ]
In the commit referenced by the Fixes tag, clk_hw_get_clk() was added in va_macro_probe() to get the fsgen clock, but forgot to add the corresponding clk_put() in va_macro_remove(). This leads to a clock reference leak when the driver is unloaded.
Switch to devm_clk_hw_get_clk() to automatically manage the clock resource.
--- sound/soc/codecs/lpass-va-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/lpass-va-macro.c +1 -1
@@ -1554,7 +1554,7 @@ static int va_macro_probe(struct platform_device *pdev)if (ret) goto err_clkout; - va->fsgen =clk_hw_get_clk (&va->hw,"fsgen" ); + va->fsgen =devm_clk_hw_get_clk (dev, &va->hw,"fsgen" );if (IS_ERR (va->fsgen)) { ret =PTR_ERR (va->fsgen); goto err_clkout;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 384/568 drm/vmwgfx: Validate command header size against SVGA_CMD_MAX_DATASIZE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Forbes <[email protected]>
[ Upstream commit 32b415a9dc2c212e809b7ebc2b14bc3fbda2b9af ]
This data originates from userspace and is used in buffer offset calculations which could potentially overflow causing an out-of-bounds access.
--- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +5 -0
@@ -3669,6 +3669,11 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, cmd_id = header->id; +if (header->size >SVGA_CMD_MAX_DATASIZE ) { +VMW_DEBUG_USER ("SVGA3D command: %d is too big.\n" , + cmd_id +SVGA_3D_CMD_BASE ); +return -E2BIG ; + } *size = header->size +sizeof (SVGA3dCmdHeader); cmd_id -=SVGA_3D_CMD_BASE ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 385/568 NFSv4: Fix an incorrect parameter when calling nfs4_call_sync()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 1f214e9c3aef2d0936be971072e991d78a174d71 ]
The Smatch static checker noted that in _nfs4_proc_lookupp(), the flag RPC_TASK_TIMEOUT is being passed as an argument to nfs4_init_sequence(), which is clearly incorrect.
Since LOOKUPP is an idempotent operation, nfs4_init_sequence() should not ask the server to cache the result. The RPC_TASK_TIMEOUT flag needs to be passed down to the RPC layer.
--- fs/nfs/nfs4proc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/nfs/nfs4proc.c +6 -3
@@ -4584,16 +4584,19 @@ static int _nfs4_proc_lookupp(struct inode *inode, };unsigned short task_flags =0 ; -if (NFS_SERVER (inode)->flags &NFS_MOUNT_SOFTREVAL ) +if (server->flags &NFS_MOUNT_SOFTREVAL ) task_flags |=RPC_TASK_TIMEOUT ; +if (server->caps &NFS_CAP_MOVEABLE ) + task_flags |=RPC_TASK_MOVEABLE ; args.bitmask =nfs4_bitmask (server, fattr->label);nfs_fattr_init (fattr); +nfs4_init_sequence (&args.seq_args, &res.seq_res,0 ,0 );dprintk ("NFS call lookupp ino=0x%lx\n" , inode->i_ino); - status =nfs4_call_sync (clnt, server, &msg, &args.seq_args, - &res.seq_res, task_flags); + status =nfs4_do_call_sync (clnt, server, &msg, &args.seq_args, + &res.seq_res, task_flags);dprintk ("NFS reply lookupp: %d\n" , status);return status; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 386/568 ALSA: usb-audio: Fix NULL pointer dereference in snd_usb_mixer_controls_badd
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haein Lee <[email protected]>
[ Upstream commit 632108ec072ad64c8c83db6e16a7efee29ebfb74 ]
In snd_usb_create_streams(), for UAC version 3 devices, the Interface Association Descriptor (IAD) is retrieved via usb_ifnum_to_if(). If this call fails, a fallback routine attempts to obtain the IAD from the next interface and sets a BADD profile. However, snd_usb_mixer_controls_badd() assumes that the IAD retrieved from usb_ifnum_to_if() is always valid, without performing a NULL check. This can lead to a NULL pointer dereference when usb_ifnum_to_if() fails to find the interface descriptor.
This patch adds a NULL pointer check after calling usb_ifnum_to_if() in snd_usb_mixer_controls_badd() to prevent the dereference.
This issue was discovered by syzkaller, which triggered the bug by sending a crafted USB device descriptor.
--- sound/usb/mixer.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/mixer.c +2 -0
@@ -3081,6 +3081,8 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,int i; assoc =usb_ifnum_to_if (dev, ctrlif)->intf_assoc; +if (!assoc) +return -EINVAL ;/* Detect BADD capture/playback channels from AS EP descriptors */ for (i =0 ; i < assoc->bInterfaceCount; i++) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 387/568 bpf: Add bpf_prog_run_data_pointers()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 4ef92743625818932b9c320152b58274c05e5053 ]
syzbot found that cls_bpf_classify() is able to change tc_skb_cb(skb)->drop_reason triggering a warning in sk_skb_reason_drop().
WARNING: CPU: 0 PID: 5965 at net/core/skbuff.c:1192 __sk_skb_reason_drop net/core/skbuff.c:1189 [inline] WARNING: CPU: 0 PID: 5965 at net/core/skbuff.c:1192 sk_skb_reason_drop+0x76/0x170 net/core/skbuff.c:1214
struct tc_skb_cb has been added in commit ec624fe740b4 ("net/sched:
Extend qdisc control block with tc control block"), which added a wrong interaction with db58ba459202 ("bpf: wire in data and data_end for cls_act_bpf").
drop_reason was added later.
Add bpf_prog_run_data_pointers() helper to save/restore the net_sched storage colliding with BPF data_meta/data_end.
--- include/linux/filter.h | 20 ++++++++++++++++++++ net/sched/act_bpf.c | 6 ++---- net/sched/cls_bpf.c | 6 ++---- 3 files changed, 24 insertions(+), 8 deletions(-)
include/linux/filter.h +20 -0
@@ -676,6 +676,26 @@ static inline void bpf_compute_data_pointers(struct sk_buff *skb) cb->data_end = skb->data +skb_headlen (skb); } +static inline int bpf_prog_run_data_pointers ( +const struct bpf_prog *prog, +struct sk_buff *skb) +{ +struct bpf_skb_data_end *cb = (struct bpf_skb_data_end *)skb->cb; +void *save_data_meta, *save_data_end; +int res; + + save_data_meta = cb->data_meta; + save_data_end = cb->data_end; + +bpf_compute_data_pointers (skb); + res =bpf_prog_run (prog, skb); + + cb->data_meta = save_data_meta; + cb->data_end = save_data_end; + +return res; +} +/* Similar to bpf_compute_data_pointers(), except that save orginal * data in cb->data and cb->meta_data for restore. */
net/sched/act_bpf.c +2 -4
@@ -45,12 +45,10 @@ static int tcf_bpf_act(struct sk_buff *skb, const struct tc_action *act, filter =rcu_dereference (prog->filter);if (at_ingress) {__skb_push (skb, skb->mac_len); -bpf_compute_data_pointers (skb); - filter_res =bpf_prog_run (filter, skb); + filter_res =bpf_prog_run_data_pointers (filter, skb);__skb_pull (skb, skb->mac_len); }else { -bpf_compute_data_pointers (skb); - filter_res =bpf_prog_run (filter, skb); + filter_res =bpf_prog_run_data_pointers (filter, skb); }if (unlikely (!skb->tstamp && skb->mono_delivery_time)) skb->mono_delivery_time =0 ;
net/sched/cls_bpf.c +2 -4
@@ -95,12 +95,10 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp, }else if (at_ingress) {/* It is safe to push/pull even if skb_shared() */ __skb_push (skb, skb->mac_len); -bpf_compute_data_pointers (skb); - filter_res =bpf_prog_run (prog->filter, skb); + filter_res =bpf_prog_run_data_pointers (prog->filter, skb);__skb_pull (skb, skb->mac_len); }else { -bpf_compute_data_pointers (skb); - filter_res =bpf_prog_run (prog->filter, skb); + filter_res =bpf_prog_run_data_pointers (prog->filter, skb); }if (unlikely (!skb->tstamp && skb->mono_delivery_time)) skb->mono_delivery_time =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 388/568 softirq: Add trace points for tasklet entry/exit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumanth Gavini <[email protected]>
commit f4bf3ca2e5cba655824b6e0893a98dfb33ed24e5 upstream.
Tasklets are supposed to finish their work quickly and should not block the current running process, but it is not guaranteed that they do so.
Currently softirq_entry/exit can be used to analyse the total tasklets execution time, but that's not helpful to track individual tasklets execution time. That makes it hard to identify tasklet functions, which take more time than expected.
Add tasklet_entry/exit trace point support to track individual tasklet execution.
Trivial usage example:
# echo 1 > /sys/kernel/debug/tracing/events/irq/tasklet_entry/enable
# echo 1 > /sys/kernel/debug/tracing/events/irq/tasklet_exit/enable
# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 4/4 #P:4
#
# _-----=> irqs-off/BH-disabled
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / _-=> migrate-disable
# |||| / delay
# TASK-PID CPU# ||||| TIMESTAMP FUNCTION
# | | | ||||| | |
<idle>-0 [003] ..s1. 314.011428: tasklet_entry: tasklet=0xffffa01ef8db2740 function=tcp_tasklet_func
<idle>-0 [003] ..s1. 314.011432: tasklet_exit: tasklet=0xffffa01ef8db2740 function=tcp_tasklet_func
<idle>-0 [003] ..s1. 314.017369: tasklet_entry: tasklet=0xffffa01ef8db2740 function=tcp_tasklet_func
<idle>-0 [003] ..s1. 314.017371: tasklet_exit: tasklet=0xffffa01ef8db2740 function=tcp_tasklet_func[elavila: Port to android-mainline]
[jstultz: Rebased to upstream, cut unused trace points, added
comments for the tracepoints, reworded commit]
The intention is to keep the stable branch in sync with upstream fixes and improve observability without introducing new functionality.
Changes in V2:
- No code changes
- Link to V1: https://lore.kernel.org/all/[email protected]/
- Updated the comment msg before the signed-off-by
--- include/trace/events/irq.h | 47 ++++++++++++++++++++++++++++++++++++++ kernel/softirq.c | 9 ++++++-- 2 files changed, 54 insertions(+), 2 deletions(-)
include/trace/events/irq.h +47 -0
@@ -160,6 +160,53 @@ DEFINE_EVENT(softirq, softirq_raise,TP_ARGS (vec_nr) ); +DECLARE_EVENT_CLASS (tasklet, + + TP_PROTO(struct tasklet_struct *t, void *func), + +TP_ARGS (t, func), + +TP_STRUCT__entry ( + __field( void *, tasklet) + __field( void *, func) + ), + +TP_fast_assign ( + __entry->tasklet = t; + __entry->func = func; + ), + +TP_printk ("tasklet=%ps function=%ps" , __entry->tasklet, __entry->func) +); + +/** +* tasklet_entry - called immediately before the tasklet is run +* @t: tasklet pointer +* @func: tasklet callback or function being run +* +* Used to find individual tasklet execution time +*/ +DEFINE_EVENT (tasklet, tasklet_entry, + + TP_PROTO(struct tasklet_struct *t, void *func), + +TP_ARGS (t, func) +); + +/** +* tasklet_exit - called immediately after the tasklet is run +* @t: tasklet pointer +* @func: tasklet callback or function being run +* +* Used to find individual tasklet execution time +*/ +DEFINE_EVENT (tasklet, tasklet_exit, + + TP_PROTO(struct tasklet_struct *t, void *func), + +TP_ARGS (t, func) +); +#endif /* _TRACE_IRQ_H */ /* This part must be outside protection */
kernel/softirq.c +7 -2
@@ -822,10 +822,15 @@ static void tasklet_action_common(struct softirq_action *a,if (tasklet_trylock (t)) {if (!atomic_read (&t->count)) {if (tasklet_clear_sched (t)) { -if (t->use_callback) +if (t->use_callback) { +trace_tasklet_entry (t, t->callback); t->callback (t); -else +trace_tasklet_exit (t, t->callback); + }else { +trace_tasklet_entry (t, t->func); t->func (t->data); +trace_tasklet_exit (t, t->func); + } }tasklet_unlock (t);continue ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 389/568 Bluetooth: hci_sync: fix double free in hci_discovery_filter_clear()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arseniy Krasnov <[email protected]>
[ Upstream commit 2935e556850e9c94d7a00adf14d3cd7fe406ac03 ]
Function 'hci_discovery_filter_clear()' frees 'uuids' array and then sets it to NULL. There is a tiny chance of the following race:
'hci_cmd_sync_work()'
'update_passive_scan_sync()'
'hci_update_passive_scan_sync()'
'hci_discovery_filter_clear()'
kfree(uuids);
<-------------------------preempted-------------------------------->
'start_service_discovery()'
'hci_discovery_filter_clear()'
kfree(uuids); // DOUBLE FREE
<-------------------------preempted-------------------------------->
uuids = NULL;To fix it let's add locking around 'kfree()' call and NULL pointer assignment. Otherwise the following backtrace fires:
[ ] ------------[ cut here ]------------
[ ] kernel BUG at mm/slub.c:547!
[ ] Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP [ ] CPU: 3 UID: 0 PID: 246 Comm: bluetoothd Tainted: G O 6.12.19-kernel #1 [ ] Tainted: [O]=OOT_MODULE
[ ] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ ] pc : __slab_free+0xf8/0x348
[ ] lr : __slab_free+0x48/0x348
...
[ ] Call trace:
[ ] __slab_free+0xf8/0x348 [ ] kfree+0x164/0x27c [ ] start_service_discovery+0x1d0/0x2c0 [ ] hci_sock_sendmsg+0x518/0x924 [ ] __sock_sendmsg+0x54/0x60 [ ] sock_write_iter+0x98/0xf8 [ ] do_iter_readv_writev+0xe4/0x1c8 [ ] vfs_writev+0x128/0x2b0 [ ] do_writev+0xfc/0x118 [ ] __arm64_sys_writev+0x20/0x2c [ ] invoke_syscall+0x68/0xf0 [ ] el0_svc_common.constprop.0+0x40/0xe0 [ ] do_el0_svc+0x1c/0x28 [ ] el0_svc+0x30/0xd0 [ ] el0t_64_sync_handler+0x100/0x12c [ ] el0t_64_sync+0x194/0x198
[ ] Code: 8b0002e6 eb17031f 54fffbe1 d503201f (d4210000) [ ] ---[ end trace 0000000000000000 ]---
--- include/net/bluetooth/hci_core.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
include/net/bluetooth/hci_core.h +7 -1
@@ -28,7 +28,7 @@#include <linux/idr.h> #include <linux/leds.h> #include <linux/rculist.h> - +#include <linux/spinlock.h> #include <net/bluetooth/hci.h> #include <net/bluetooth/hci_sync.h> #include <net/bluetooth/hci_sock.h>
@@ -92,6 +92,7 @@ struct discovery_state {unsigned long scan_start;unsigned long scan_duration;unsigned long name_resolve_timeout; +spinlock_t lock; };#define SUSPEND_NOTIFIER_TIMEOUT msecs_to_jiffies(2000)/* 2 seconds */
@@ -881,6 +882,7 @@ static inline void iso_recv(struct hci_conn *hcon, struct sk_buff *skb,static inline void discovery_init (struct hci_dev *hdev) { +spin_lock_init (&hdev->discovery.lock); hdev->discovery.state =DISCOVERY_STOPPED ;INIT_LIST_HEAD (&hdev->discovery.all);INIT_LIST_HEAD (&hdev->discovery.unknown);
@@ -895,8 +897,12 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev) hdev->discovery.report_invalid_rssi = true; hdev->discovery.rssi =HCI_RSSI_INVALID ; hdev->discovery.uuid_count =0 ; + +spin_lock (&hdev->discovery.lock);kfree (hdev->discovery.uuids); hdev->discovery.uuids =NULL ; +spin_unlock (&hdev->discovery.lock); + hdev->discovery.scan_start =0 ; hdev->discovery.scan_duration =0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 390/568 espintcp: fix skb leaks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <[email protected]>
[ Upstream commit 63c1f19a3be3169e51a5812d22a6d0c879414076 ]
A few error paths are missing a kfree_skb.
--- net/ipv4/esp4.c | 4 +++- net/ipv6/esp6.c | 4 +++- net/xfrm/espintcp.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-)
net/ipv4/esp4.c +3 -1
@@ -152,8 +152,10 @@ static int esp_output_tcp_finish(struct xfrm_state *x, struct sk_buff *skb) sk =esp_find_tcp_sk (x); err =PTR_ERR_OR_ZERO (sk); -if (err) +if (err) { +kfree_skb (skb); goto out; + }bh_lock_sock (sk);if (sock_owned_by_user (sk))
net/ipv6/esp6.c +3 -1
@@ -169,8 +169,10 @@ static int esp_output_tcp_finish(struct xfrm_state *x, struct sk_buff *skb) sk =esp6_find_tcp_sk (x); err =PTR_ERR_OR_ZERO (sk); -if (err) +if (err) { +kfree_skb (skb); goto out; + }bh_lock_sock (sk);if (sock_owned_by_user (sk))
net/xfrm/espintcp.c +3 -1
@@ -168,8 +168,10 @@ int espintcp_queue_out(struct sock *sk, struct sk_buff *skb) {struct espintcp_ctx *ctx =espintcp_getctx (sk); -if (skb_queue_len (&ctx->out_queue) >=READ_ONCE (netdev_max_backlog)) +if (skb_queue_len (&ctx->out_queue) >=READ_ONCE (netdev_max_backlog)) { +kfree_skb (skb);return -ENOBUFS ; + }__skb_queue_tail (&ctx->out_queue, skb);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 391/568 lib/crypto: arm/curve25519: Disable on CPU_BIG_ENDIAN
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 44e8241c51f762aafa50ed116da68fd6ecdcc954 upstream.
On big endian arm kernels, the arm optimized Curve25519 code produces incorrect outputs and fails the Curve25519 test. This has been true ever since this code was added.
It seems that hardly anyone (or even no one?) actually uses big endian arm kernels. But as long as they're ostensibly supported, we should disable this code on them so that it's not accidentally used.
Note: for future-proofing, use !CPU_BIG_ENDIAN instead of CPU_LITTLE_ENDIAN. Both of these are arch-specific options that could get removed in the future if big endian support gets dropped.
--- arch/arm/crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/crypto/Kconfig +1 -1
@@ -4,7 +4,7 @@ menu "Accelerated Cryptographic Algorithms for CPU (arm)" config CRYPTO_CURVE25519_NEON tristate "Public key crypto: Curve25519 (NEON)" - depends on KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON && !CPU_BIG_ENDIAN select CRYPTO_LIB_CURVE25519_GENERIC select CRYPTO_ARCH_HAVE_LIB_CURVE25519 help
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 392/568 asm-generic: Unify uapi bitsperlong.h for arm64, riscv and loongarch
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit 8386f58f8deda81110283798a387fb53ec21957c ]
Now we specify the minimal version of GCC as 5.1 and Clang/LLVM as 11.0.0 in Documentation/process/changes.rst, __CHAR_BIT__ and __SIZEOF_LONG__ are usable, it is probably fine to unify the definition of __BITS_PER_LONG as (__CHAR_BIT__ * __SIZEOF_LONG__) in asm-generic uapi bitsperlong.h.
In order to keep safe and avoid regression, only unify uapi bitsperlong.h for some archs such as arm64, riscv and loongarch which are using newer toolchains that have the definitions of __CHAR_BIT__ and __SIZEOF_LONG__.
--- arch/arm64/include/uapi/asm/bitsperlong.h | 24 ------------------- arch/loongarch/include/uapi/asm/bitsperlong.h | 9 ------- arch/riscv/include/uapi/asm/bitsperlong.h | 14 ----------- include/uapi/asm-generic/bitsperlong.h | 13 +++++++++- .../arch/arm64/include/uapi/asm/bitsperlong.h | 24 ------------------- .../arch/riscv/include/uapi/asm/bitsperlong.h | 14 ----------- tools/include/uapi/asm-generic/bitsperlong.h | 14 ++++++++++- tools/include/uapi/asm/bitsperlong.h | 6 ----- 8 files changed, 25 insertions(+), 93 deletions(-) delete mode 100644 arch/arm64/include/uapi/asm/bitsperlong.h delete mode 100644 arch/loongarch/include/uapi/asm/bitsperlong.h delete mode 100644 arch/riscv/include/uapi/asm/bitsperlong.h delete mode 100644 tools/arch/arm64/include/uapi/asm/bitsperlong.h delete mode 100644 tools/arch/riscv/include/uapi/asm/bitsperlong.h
arch/arm64/include/uapi/asm/bitsperlong.h deleted +0 -24
@@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* -* Copyright (C) 2012 ARM Ltd. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef __ASM_BITSPERLONG_H -#define __ASM_BITSPERLONG_H - -#define __BITS_PER_LONG 64 - -#include <asm-generic/bitsperlong.h> - -#endif /* __ASM_BITSPERLONG_H */
arch/loongarch/include/uapi/asm/bitsperlong.h deleted +0 -9
@@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef __ASM_LOONGARCH_BITSPERLONG_H -#define __ASM_LOONGARCH_BITSPERLONG_H - -#define __BITS_PER_LONG (__SIZEOF_LONG__ * 8) - -#include <asm-generic/bitsperlong.h> - -#endif /* __ASM_LOONGARCH_BITSPERLONG_H */
arch/riscv/include/uapi/asm/bitsperlong.h deleted +0 -14
@@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ -/* -* Copyright (C) 2012 ARM Ltd. -* Copyright (C) 2015 Regents of the University of California -*/ - -#ifndef _UAPI_ASM_RISCV_BITSPERLONG_H -#define _UAPI_ASM_RISCV_BITSPERLONG_H - -#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8) - -#include <asm-generic/bitsperlong.h> - -#endif /* _UAPI_ASM_RISCV_BITSPERLONG_H */
include/uapi/asm-generic/bitsperlong.h +12 -1
@@ -2,6 +2,17 @@#ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG#define _UAPI__ASM_GENERIC_BITS_PER_LONG +#ifndef __BITS_PER_LONG +/* +* In order to keep safe and avoid regression, only unify uapi +* bitsperlong.h for some archs which are using newer toolchains +* that have the definitions of __CHAR_BIT__ and __SIZEOF_LONG__. +* See the following link for more info: +* https://lore.kernel.org/linux-arch/[email protected]/ +*/ +#if defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__) +#define __BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__) +#else /* * There seems to be no way of detecting this automatically from user * space, so 64 bit architectures should override this in their
@@ -9,8 +20,8 @@* both 32 and 64 bit user space must not rely on CONFIG_64BIT * to decide it, but rather check a compiler provided macro. */ -#ifndef __BITS_PER_LONG#define __BITS_PER_LONG 32#endif +#endif #endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
tools/arch/arm64/include/uapi/asm/bitsperlong.h deleted +0 -24
@@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* -* Copyright (C) 2012 ARM Ltd. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef __ASM_BITSPERLONG_H -#define __ASM_BITSPERLONG_H - -#define __BITS_PER_LONG 64 - -#include <asm-generic/bitsperlong.h> - -#endif /* __ASM_BITSPERLONG_H */
tools/arch/riscv/include/uapi/asm/bitsperlong.h deleted +0 -14
@@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* -* Copyright (C) 2012 ARM Ltd. -* Copyright (C) 2015 Regents of the University of California -*/ - -#ifndef _UAPI_ASM_RISCV_BITSPERLONG_H -#define _UAPI_ASM_RISCV_BITSPERLONG_H - -#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8) - -#include <asm-generic/bitsperlong.h> - -#endif /* _UAPI_ASM_RISCV_BITSPERLONG_H */
tools/include/uapi/asm-generic/bitsperlong.h +13 -1
@@ -1,6 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG#define _UAPI__ASM_GENERIC_BITS_PER_LONG +#ifndef __BITS_PER_LONG +/* +* In order to keep safe and avoid regression, only unify uapi +* bitsperlong.h for some archs which are using newer toolchains +* that have the definitions of __CHAR_BIT__ and __SIZEOF_LONG__. +* See the following link for more info: +* https://lore.kernel.org/linux-arch/[email protected]/ +*/ +#if defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__) +#define __BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__) +#else /* * There seems to be no way of detecting this automatically from user * space, so 64 bit architectures should override this in their
@@ -8,8 +20,8 @@* both 32 and 64 bit user space must not rely on CONFIG_64BIT * to decide it, but rather check a compiler provided macro. */ -#ifndef __BITS_PER_LONG#define __BITS_PER_LONG 32#endif +#endif #endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
tools/include/uapi/asm/bitsperlong.h +0 -6
@@ -1,8 +1,6 @@/* SPDX-License-Identifier: GPL-2.0 */ #if defined(__i386__) || defined(__x86_64__)#include "../../../arch/x86/include/uapi/asm/bitsperlong.h" -#elif defined(__aarch64__) -#include "../../../arch/arm64/include/uapi/asm/bitsperlong.h" #elif defined(__powerpc__)#include "../../../arch/powerpc/include/uapi/asm/bitsperlong.h" #elif defined(__s390__)
@@ -13,12 +11,8 @@#include "../../../arch/mips/include/uapi/asm/bitsperlong.h" #elif defined(__ia64__)#include "../../../arch/ia64/include/uapi/asm/bitsperlong.h" -#elif defined(__riscv) -#include "../../../arch/riscv/include/uapi/asm/bitsperlong.h" #elif defined(__alpha__)#include "../../../arch/alpha/include/uapi/asm/bitsperlong.h" -#elif defined(__loongarch__) -#include "../../../arch/loongarch/include/uapi/asm/bitsperlong.h" #else #include <asm-generic/bitsperlong.h> #endif
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 393/568 mtd: onenand: Pass correct pointer to IRQ handler
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 97315e7c901a1de60e8ca9b11e0e96d0f9253e18 ]
This was supposed to pass "onenand" instead of "&onenand" with the ampersand. Passing a random stack address which will be gone when the function ends makes no sense. However the good thing is that the pointer is never used, so this doesn't cause a problem at run time.
--- drivers/mtd/nand/onenand/onenand_samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/onenand/onenand_samsung.c +1 -1
@@ -909,7 +909,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) err =devm_request_irq (&pdev->dev, r->start, s5pc110_onenand_irq,IRQF_SHARED ,"onenand" , - &onenand); + onenand);if (err) {dev_err (&pdev->dev,"failed to get irq\n" );return err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 394/568 netfilter: nf_tables: reject duplicate device on updates
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit cf5fb87fcdaaaafec55dcc0dc5a9e15ead343973 upstream.
A chain/flowtable update with duplicated devices in the same batch is possible. Unfortunately, netdev event path only removes the first device that is found, leaving unregistered the hook of the duplicated device.
Check if a duplicated device exists in the transaction batch, bail out with EEXIST in such case.
WARNING is hit when unregistering the hook:
[49042.221275] WARNING: CPU: 4 PID: 8425 at net/netfilter/core.c:340 nf_hook_entry_head+0xaa/0x150 [49042.221375] CPU: 4 UID: 0 PID: 8425 Comm: nft Tainted: G S 6.16.0+ #170 PREEMPT(full) [...] [49042.221382] RIP: 0010:nf_hook_entry_head+0xaa/0x150
--- net/netfilter/nf_tables_api.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
net/netfilter/nf_tables_api.c +15 -0
@@ -8078,6 +8078,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, {const struct nlattr *const *nla = ctx->nla;struct nft_flowtable_hook flowtable_hook; +struct nftables_pernet *nft_net;struct nft_hook *hook, *next;struct nft_trans *trans;bool unregister = false;
@@ -8093,6 +8094,20 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,if (nft_hook_list_find (&flowtable->hook_list, hook)) {list_del (&hook->list);kfree (hook); +continue ; + } + + nft_net =nft_pernet (ctx->net); +list_for_each_entry (trans, &nft_net->commit_list, list) { +if (trans->msg_type !=NFT_MSG_NEWFLOWTABLE || + trans->ctx.table != ctx->table || + !nft_trans_flowtable_update (trans)) +continue ; + +if (nft_hook_list_find (&nft_trans_flowtable_hooks (trans), hook)) { + err = -EEXIST ; + goto err_flowtable_update_hook; + } } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 395/568 HID: hid-ntrig: Prevent memory leak in ntrig_report_version()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Ichikawa <[email protected]>
[ Upstream commit 53f731f5bba0cf03b751ccceb98b82fadc9ccd1e ]
Use a scope-based cleanup helper for the buffer allocated with kmalloc() in ntrig_report_version() to simplify the cleanup logic and prevent memory leaks (specifically the !hid_is_usb()-case one).
--- drivers/hid/hid-ntrig.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/hid/hid-ntrig.c +2 -5
@@ -142,13 +142,13 @@ static void ntrig_report_version(struct hid_device *hdev)int ret;char buf[20 ];struct usb_device *usb_dev =hid_to_usb_dev (hdev); -unsigned char *data =kmalloc (8 ,GFP_KERNEL ); + unsigned char *data __free(kfree) = kmalloc(8, GFP_KERNEL);if (!hid_is_usb (hdev))return ;if (!data) - goto err_free; +return ; ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), USB_REQ_CLEAR_FEATURE,
@@ -163,9 +163,6 @@ static void ntrig_report_version(struct hid_device *hdev)hid_info (hdev,"Firmware version: %s (%02x%02x %02x%02x)\n" , buf, data[2 ], data[3 ], data[4 ], data[5 ]); } - -err_free: -kfree (data); } static ssize_t show_phys_width(struct device *dev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 396/568 NFSD: free copynotify stateid in nfs4_free_ol_stateid()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olga Kornievskaia <[email protected]>
commit 4aa17144d5abc3c756883e3a010246f0dba8b468 upstream.
Typically copynotify stateid is freed either when parent's stateid is being close/freed or in nfsd4_laundromat if the stateid hasn't been used in a lease period.
However, in case when the server got an OPEN (which created a parent stateid), followed by a COPY_NOTIFY using that stateid, followed by a client reboot. New client instance while doing CREATE_SESSION would force expire previous state of this client. It leads to the open state being freed thru release_openowner-> nfs4_free_ol_stateid() and it finds that it still has copynotify stateid associated with it. We currently print a warning and is triggerred
WARNING: CPU: 1 PID: 8858 at fs/nfsd/nfs4state.c:1550 nfs4_free_ol_stateid+0xb0/0x100 [nfsd]
This patch, instead, frees the associated copynotify stateid here.
If the parent stateid is freed (without freeing the copynotify stateids associated with it), it leads to the list corruption when laundromat ends up freeing the copynotify state later.
[ 1626.839430] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP [ 1626.842828] Modules linked in: nfnetlink_queue nfnetlink_log bluetooth cfg80211 rpcrdma rdma_cm iw_cm ib_cm ib_core nfsd nfs_acl lockd grace nfs_localio ext4 crc16 mbcache jbd2 overlay uinput snd_seq_dummy snd_hrtimer qrtr rfkill vfat fat uvcvideo snd_hda_codec_generic videobuf2_vmalloc videobuf2_memops snd_hda_intel uvc snd_intel_dspcfg videobuf2_v4l2 videobuf2_common snd_hda_codec snd_hda_core videodev snd_hwdep snd_seq mc snd_seq_device snd_pcm snd_timer snd soundcore sg loop auth_rpcgss vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vmw_vmci vsock xfs 8021q garp stp llc mrp nvme ghash_ce e1000e nvme_core sr_mod nvme_keyring nvme_auth cdrom vmwgfx drm_ttm_helper ttm sunrpc dm_mirror dm_region_hash dm_log iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi fuse dm_multipath dm_mod nfnetlink [ 1626.855594] CPU: 2 UID: 0 PID: 199 Comm: kworker/u24:33 Kdump: loaded Tainted: G B W 6.17.0-rc7+ #22 PREEMPT(voluntary) [ 1626.857075] Tainted: [B]=BAD_PAGE, [W]=WARN [ 1626.857573] Hardware name: VMware, Inc. VMware20,1/VBSA, BIOS VMW201.00V.24006586.BA64.2406042154 06/04/2024 [ 1626.858724] Workqueue: nfsd4 laundromat_main [nfsd] [ 1626.859304] pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) [ 1626.860010] pc : __list_del_entry_valid_or_report+0x148/0x200 [ 1626.860601] lr : __list_del_entry_valid_or_report+0x148/0x200 [ 1626.861182] sp : ffff8000881d7a40 [ 1626.861521] x29: ffff8000881d7a40 x28: 0000000000000018 x27: ffff0000c2a98200 [ 1626.862260] x26: 0000000000000600 x25: 0000000000000000 x24: ffff8000881d7b20 [ 1626.862986] x23: ffff0000c2a981e8 x22: 1fffe00012410e7d x21: ffff0000920873e8 [ 1626.863701] x20: ffff0000920873e8 x19: ffff000086f22998 x18: 0000000000000000 [ 1626.864421] x17: 20747562202c3839 x16: 3932326636383030 x15: 3030666666662065 [ 1626.865092] x14: 6220646c756f6873 x13: 0000000000000001 x12: ffff60004fd9e4a3 [ 1626.865713] x11: 1fffe0004fd9e4a2 x10: ffff60004fd9e4a2 x9 : dfff800000000000 [ 1626.866320] x8 : 00009fffb0261b5e x7 : ffff00027ecf2513 x6 : 0000000000000001 [ 1626.866938] x5 : ffff00027ecf2510 x4 : ffff60004fd9e4a3 x3 : 0000000000000000 [ 1626.867553] x2 : 0000000000000000 x1 : ffff000096069640 x0 : 000000000000006d [ 1626.868167] Call trace: [ 1626.868382] __list_del_entry_valid_or_report+0x148/0x200 (P) [ 1626.868876] _free_cpntf_state_locked+0xd0/0x268 [nfsd] [ 1626.869368] nfs4_laundromat+0x6f8/0x1058 [nfsd] [ 1626.869813] laundromat_main+0x24/0x60 [nfsd] [ 1626.870231] process_one_work+0x584/0x1050 [ 1626.870595] worker_thread+0x4c4/0xc60 [ 1626.870893] kthread+0x2f8/0x398 [ 1626.871146] ret_from_fork+0x10/0x20 [ 1626.871422] Code: aa1303e1 aa1403e3 910e8000 97bc55d7 (d4210000) [ 1626.871892] SMP: stopping secondary CPUs
--- fs/nfsd/nfs4state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4state.c +2 -1
@@ -1499,7 +1499,8 @@ static void nfs4_free_ol_stateid(structrelease_all_access (stp);if (stp->st_stateowner)nfs4_put_stateowner (stp->st_stateowner); -WARN_ON (!list_empty (&stid->sc_cp_list)); +if (!list_empty (&stid->sc_cp_list)) +nfs4_free_cpntf_statelist (stid->sc_client->net, stid);kmem_cache_free (stateid_slab, stid); }
Greg Kroah-Hartman
maintainerPATCH 397/568 gcov: add support for GCC 15
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
commit ec4d11fc4b2dd4a2fa8c9d801ee9753b74623554 upstream.
Using gcov on kernels compiled with GCC 15 results in truncated 16-byte long .gcda files with no usable data. To fix this, update GCOV_COUNTERS to match the value defined by GCC 15.
Tested with GCC 14.3.0 and GCC 15.2.0.
--- kernel/gcov/gcc_4_7.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/gcov/gcc_4_7.c +3 -1
@@ -18,7 +18,9 @@#include <linux/mm.h> #include "gcov.h" -#if (__GNUC__ >=14 ) +#if (__GNUC__ >=15 ) +#define GCOV_COUNTERS 10 +#elif (__GNUC__ >=14 )#define GCOV_COUNTERS 9#elif (__GNUC__ >=10 )#define GCOV_COUNTERS 8
Greg Kroah-Hartman
maintainerPATCH 398/568 ksmbd: close accepted socket when per-IP limit rejects connection
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <[email protected]>
commit 98a5fd31cbf72d46bf18e50b3ab0ce86d5f319a9 upstream.
When the per-IP connection limit is exceeded in ksmbd_kthread_fn(), the code sets ret = -EAGAIN and continues the accept loop without closing the just-accepted socket. That leaks one socket per rejected attempt from a single IP and enables a trivial remote DoS.
Release client_sk before continuing.
This bug was found with ZeroPath.
--- fs/smb/server/transport_tcp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/smb/server/transport_tcp.c +4 -1
@@ -282,8 +282,11 @@ static int ksmbd_kthread_fn(void *p) } }up_read (&conn_list_lock); -if (ret == -EAGAIN ) +if (ret == -EAGAIN ) { +/* Per-IP limit hit: release the just-accepted socket. */ +sock_release (client_sk);continue ; + } skip_max_ip_conns_limit: if (server_conf.max_connections &&
Greg Kroah-Hartman
maintainerPATCH 399/568 strparser: Fix signed/unsigned mismatch bug
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nate Karstens <[email protected]>
commit 4da4e4bde1c453ac5cc2dce5def81d504ae257ee upstream.
The len member of the sk_buff is an unsigned int. This is cast to ssize_t (a signed type) for the first sk_buff in the comparison, but not the second sk_buff. On 32-bit systems, this can result in an integer underflow for certain values because unsigned arithmetic is being used.
This appears to be an oversight: if the intention was to use unsigned arithmetic, then the first cast would have been omitted. The change ensures both len values are cast to ssize_t.
The underflow causes an issue with ktls when multiple TLS PDUs are included in a single TCP segment. The mainline kernel does not use strparser for ktls anymore, but this is still useful for other features that still use strparser, and for backporting.
--- net/strparser/strparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/strparser/strparser.c +1 -1
@@ -238,7 +238,7 @@ static int __strp_recv(read_descriptor_tstrp_parser_err (strp, -EMSGSIZE , desc);break ; }else if (len <= (ssize_t )head->len - - skb->len - stm->strp.offset) { + (ssize_t )skb->len - stm->strp.offset) {/* Length must be into new skb (and also * greater than zero) */
Greg Kroah-Hartman
maintainerPATCH 400/568 dma-mapping: benchmark: Restore padding to ensure uABI remained consistent
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qinxin Xia <[email protected]>
commit 23ee8a2563a0f24cf4964685ced23c32be444ab8 upstream.
The padding field in the structure was previously reserved to maintain a stable interface for potential new fields, ensuring compatibility with user-space shared data structures. However,it was accidentally removed by tiantao in a prior commit, which may lead to incompatibility between user space and the kernel.
This patch reinstates the padding to restore the original structure layout and preserve compatibility.
--- include/linux/map_benchmark.h | 1 + 1 file changed, 1 insertion(+)
include/linux/map_benchmark.h +1 -0
@@ -27,5 +27,6 @@ struct map_benchmark {__u32 dma_dir;/* DMA data direction */ __u32 dma_trans_ns;/* time for DMA transmission in ns */ __u32 granule;/* how many PAGE_SIZE will do map/unmap once a time */ + __u8 expansion[76]; /* For future use */ };#endif /* _KERNEL_DMA_BENCHMARK_H */
Greg Kroah-Hartman
maintainerPATCH 401/568 LoongArch: Let {pte,pmd}_modify() record the status of _PAGE_DIRTY
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianyang Zhang <[email protected]>
commit a073d637c8cfbfbab39b7272226a3fbf3b887580 upstream.
Now if the PTE/PMD is dirty with _PAGE_DIRTY but without _PAGE_MODIFIED, after {pte,pmd}_modify() we lose _PAGE_DIRTY, then {pte,pmd}_dirty() return false and lead to data loss. This can happen in certain scenarios such as HW PTW doesn't set _PAGE_MODIFIED automatically, so here we need _PAGE_MODIFIED to record the dirty status (_PAGE_DIRTY).
The new modification involves checking whether the original PTE/PMD has the _PAGE_DIRTY flag. If it exists, the _PAGE_MODIFIED bit is also set, ensuring that the {pte,pmd}_dirty() interface can always return accurate information.
--- arch/loongarch/include/asm/pgtable.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/loongarch/include/asm/pgtable.h +8 -3
@@ -403,6 +403,9 @@ static inline unsigned long pte_accessibstatic inline pte_t pte_modify (pte_t pte,pgprot_t newprot) { +if (pte_val (pte) & _PAGE_DIRTY) +pte_val (pte) |= _PAGE_MODIFIED; +return __pte ((pte_val (pte) & _PAGE_CHG_MASK) | (pgprot_val (newprot) & ~_PAGE_CHG_MASK)); }
@@ -516,9 +519,11 @@ static inline struct page *pmd_page(pmd_static inline pmd_t pmd_modify (pmd_t pmd,pgprot_t newprot) { -pmd_val (pmd) = (pmd_val (pmd) & _HPAGE_CHG_MASK) | - (pgprot_val (newprot) & ~_HPAGE_CHG_MASK); -return pmd; +if (pmd_val (pmd) & _PAGE_DIRTY) +pmd_val (pmd) |= _PAGE_MODIFIED; + +return __pmd ((pmd_val (pmd) & _HPAGE_CHG_MASK) | + (pgprot_val (newprot) & ~_HPAGE_CHG_MASK)); }static inline pmd_t pmd_mkinvalid (pmd_t pmd)
Greg Kroah-Hartman
maintainerPATCH 402/568 ipv4: route: Prevent rt_bind_exception() from rebinding stale fnhe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuang Wang <[email protected]>
commit ac1499fcd40fe06479e9b933347b837ccabc2a40 upstream.
The sit driver's packet transmission path calls: sit_tunnel_xmit() -> update_or_create_fnhe(), which lead to fnhe_remove_oldest() being called to delete entries exceeding FNHE_RECLAIM_DEPTH+random.
The race window is between fnhe_remove_oldest() selecting fnheX for deletion and the subsequent kfree_rcu(). During this time, the concurrent path's __mkroute_output() -> find_exception() can fetch the soon-to-be-deleted fnheX, and rt_bind_exception() then binds it with a new dst using a dst_hold(). When the original fnheX is freed via RCU, the dst reference remains permanently leaked.
CPU 0 CPU 1__mkroute_output()
find_exception() [fnheX]
update_or_create_fnhe()
fnhe_remove_oldest() [fnheX]
rt_bind_exception() [bind dst]
RCU callback [fnheX freed, dst leak]
This issue manifests as a device reference count leak and a warning in dmesg when unregistering the net device:
unregister_netdevice: waiting for sitX to become free. Usage count = N
Ido Schimmel provided the simple test validation method [1].
The fix clears 'oldest->fnhe_daddr' before calling fnhe_flush_routes(). Since rt_bind_exception() checks this field, setting it to zero prevents the stale fnhe from being reused and bound to a new dst just before it is freed.
[1]
ip netns add ns1
ip -n ns1 link set dev lo up
ip -n ns1 address add 192.0.2.1/32 dev lo
ip -n ns1 link add name dummy1 up type dummy
ip -n ns1 route add 192.0.2.2/32 dev dummy1
ip -n ns1 link add name gretap1 up arp off type gretap \
local 192.0.2.1 remote 192.0.2.2
ip -n ns1 route add 198.51.0.0/16 dev gretap1
taskset -c 0 ip netns exec ns1 mausezahn gretap1 \
-A 198.51.100.1 -B 198.51.0.0/16 -t udp -p 1000 -c 0 -q &
taskset -c 2 ip netns exec ns1 mausezahn gretap1 \
-A 198.51.100.1 -B 198.51.0.0/16 -t udp -p 1000 -c 0 -q &sleep 10
ip netns pids ns1 | xargs kill
ip netns del ns1
--- net/ipv4/route.c | 5 +++++ 1 file changed, 5 insertions(+)
net/ipv4/route.c +5 -0
@@ -617,6 +617,11 @@ static void fnhe_remove_oldest(struct fn oldest_p = fnhe_p; } } + +/* Clear oldest->fnhe_daddr to prevent this fnhe from being +* rebound with new dsts in rt_bind_exception(). +*/ + oldest->fnhe_daddr =0 ;fnhe_flush_routes (oldest); *oldest_p = oldest->fnhe_next;kfree_rcu (oldest, rcu);
Greg Kroah-Hartman
maintainerPATCH 403/568 wifi: mac80211: reject address change while connecting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit a9da90e618cd0669a22bcc06a96209db5dd96e9b upstream.
While connecting, the MAC address can already no longer be changed. The change is already rejected if netif_carrier_ok(), but of course that's not true yet while connecting. Check for auth_data or assoc_data, so the MAC address cannot be changed.
Also more comprehensively check that there are no stations on the interface being changed - if any peer station is added it will know about our address already, so we cannot change it.
--- net/mac80211/iface.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
net/mac80211/iface.c +11 -3
@@ -216,6 +216,10 @@ static int ieee80211_can_powered_addr_chmutex_lock (&local->mtx); +/* if any stations are set known (so they know this vif too), reject */ +if (sta_info_get_by_idx (sdata,0 )) +return -EBUSY ; +/* First check no ROC work is happening on this iface */ list_for_each_entry (roc, &local->roc_list, list) {if (roc->sdata != sdata)
@@ -235,12 +239,16 @@ static int ieee80211_can_powered_addr_ch ret = -EBUSY ; } +/* +* More interface types could be added here but changing the +* address while powered makes the most sense in client modes. +*/ switch (sdata->vif.type) {case NL80211_IFTYPE_STATION :case NL80211_IFTYPE_P2P_CLIENT : -/* More interface types could be added here but changing the -* address while powered makes the most sense in client modes. -*/ +/* refuse while connecting */ +if (sdata->u.mgd.auth_data || sdata->u.mgd.assoc_data) +return -EBUSY ;break ;default : ret = -EOPNOTSUPP ;
Greg Kroah-Hartman
maintainerPATCH 404/568 fs/proc: fix uaf in proc_readdir_de()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yang <[email protected]>
commit 895b4c0c79b092d732544011c3cecaf7322c36a1 upstream.
Pde is erased from subdir rbtree through rb_erase(), but not set the node to EMPTY, which may result in uaf access. We should use RB_CLEAR_NODE() set the erased node to EMPTY, then pde_subdir_next() will return NULL to avoid uaf access.
We found an uaf issue while using stress-ng testing, need to run testcase getdent and tun in the same time. The steps of the issue is as follows:
1) use getdent to traverse dir /proc/pid/net/dev_snmp6/, and current pde is tun3;
2) in the [time windows] unregister netdevice tun3 and tun2, and erase them from rbtree. erase tun3 first, and then erase tun2. the pde(tun2) will be released to slab;
3) continue to getdent process, then pde_subdir_next() will return pde(tun2) which is released, it will case uaf access.
CPU 0 | CPU 1
-------------------------------------------------------------------------
traverse dir /proc/pid/net/dev_snmp6/ | unregister_netdevice(tun->dev) //tun3 tun2
sys_getdents64() |
iterate_dir() |
proc_readdir() |
proc_readdir_de() | snmp6_unregister_dev()
pde_get(de); | proc_remove()
read_unlock(&proc_subdir_lock); | remove_proc_subtree()
| write_lock(&proc_subdir_lock);
[time window] | rb_erase(&root->subdir_node, &parent->subdir);
| write_unlock(&proc_subdir_lock);
read_lock(&proc_subdir_lock); |
next = pde_subdir_next(de); |
pde_put(de); |
de = next; //UAF |rbtree of dev_snmp6
|
pde(tun3)
/ \
NULL pde(tun2)--- fs/proc/generic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/proc/generic.c +9 -3
@@ -695,6 +695,12 @@ void pde_put(struct proc_dir_entry *pde) } } +static void pde_erase (struct proc_dir_entry *pde,struct proc_dir_entry *parent) +{ +rb_erase (&pde->subdir_node, &parent->subdir); +RB_CLEAR_NODE (&pde->subdir_node); +} +/* * Remove a /proc entry and free it if it's not currently in use. */
@@ -717,7 +723,7 @@ void remove_proc_entry(const char *name,WARN (1 ,"removing permanent /proc entry '%s'" , de->name); de =NULL ; }else { -rb_erase (&de->subdir_node, &parent->subdir); +pde_erase (de, parent);if (S_ISDIR (de->mode)) parent->nlink--; }
@@ -761,7 +767,7 @@ int remove_proc_subtree(const char *name root->parent->name, root->name);return -EINVAL ; } -rb_erase (&root->subdir_node, &parent->subdir); +pde_erase (root, parent); de = root;while (1 ) {
@@ -773,7 +779,7 @@ int remove_proc_subtree(const char *name next->parent->name, next->name);return -EINVAL ; } -rb_erase (&next->subdir_node, &de->subdir); +pde_erase (next, de); de = next;continue ; }
Greg Kroah-Hartman
maintainerPATCH 405/568 mmc: sdhci-of-dwcmshc: Change DLL_STRBIN_TAPNUM_DEFAULT to 0x4
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
commit a28352cf2d2f8380e7aca8cb61682396dca7a991 upstream.
strbin signal delay under 0x8 configuration is not stable after massive test. The recommandation of it should be 0x4.
--- drivers/mmc/host/sdhci-of-dwcmshc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/sdhci-of-dwcmshc.c +1 -1
@@ -52,7 +52,7 @@#define DLL_TXCLK_TAPNUM_DEFAULT 0x10#define DLL_TXCLK_TAPNUM_90_DEGREES 0xA#define DLL_TXCLK_TAPNUM_FROM_SW BIT(24) -#define DLL_STRBIN_TAPNUM_DEFAULT 0x8 +#define DLL_STRBIN_TAPNUM_DEFAULT 0x4#define DLL_STRBIN_TAPNUM_FROM_SW BIT(24)#define DLL_STRBIN_DELAY_NUM_SEL BIT(26)#define DLL_STRBIN_DELAY_NUM_OFFSET 16
Greg Kroah-Hartman
maintainerPATCH 406/568 ALSA: usb-audio: Fix potential overflow of PCM transfer buffer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 05a1fc5efdd8560f34a3af39c9cf1e1526cc3ddf upstream.
The PCM stream data in USB-audio driver is transferred over USB URB packet buffers, and each packet size is determined dynamically. The packet sizes are limited by some factors such as wMaxPacketSize USB descriptor. OTOH, in the current code, the actually used packet sizes are determined only by the rate and the PPS, which may be bigger than the size limit above. This results in a buffer overflow, as reported by syzbot.
Basically when the limit is smaller than the calculated packet size, it implies that something is wrong, most likely a weird USB descriptor. So the best option would be just to return an error at the parameter setup time before doing any further operations.
This patch introduces such a sanity check, and returns -EINVAL when the packet size is greater than maxpacksize. The comparison with ep->packsize[1] alone should suffice since it's always equal or greater than ep->packsize[0].
--- sound/usb/endpoint.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/usb/endpoint.c +5 -0
@@ -1379,6 +1379,11 @@ int snd_usb_endpoint_set_params(struct s ep->sample_rem = ep->cur_rate % ep->pps; ep->packsize[0 ] = ep->cur_rate / ep->pps; ep->packsize[1 ] = (ep->cur_rate + (ep->pps -1 )) / ep->pps; +if (ep->packsize[1 ] > ep->maxpacksize) { +usb_audio_dbg (chip,"Too small maxpacksize %u for rate %u / pps %u\n" , + ep->maxpacksize, ep->cur_rate, ep->pps); +return -EINVAL ; + }/* calculate the frequency in 16.16 format */ ep->freqm = ep->freqn;
Re: [PATCH 6.1 406/568] ALSA: usb-audio: Fix potential overflow of PCM transfer buffer
Quoted 43 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit
05a1fc5efdd8560f34a3af39c9cf1e1526cc3ddfupstream.The PCM stream data in USB-audio driver is transferred over USB URB packet buffers, and each packet size is determined dynamically. The packet sizes are limited by some factors such as wMaxPacketSize USB descriptor. OTOH, in the current code, the actually used packet sizes are determined only by the rate and the PPS, which may be bigger than the size limit above. This results in a buffer overflow, as reported by syzbot.
Basically when the limit is smaller than the calculated packet size, it implies that something is wrong, most likely a weird USB descriptor. So the best option would be just to return an error at the parameter setup time before doing any further operations.
This patch introduces such a sanity check, and returns
-EINVALwhen the packet size is greater than maxpacksize. The comparison with ep->packsize[1] alone should suffice since it's always equal or greater than ep->packsize[0].Reported-by [email protected]Cc Lizhi Xu <[email protected]>Cc <[email protected]>Signed-off-by Takashi Iwai <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- sound/usb/endpoint.c | 5 +++++ 1 file changed, 5 insertions(+)sound/usb/endpoint.c +0
-0@@ -1379,6 +1379,11 @@ int snd_usb_endpoint_set_params(struct s ep->sample_rem = ep->cur_rate % ep->pps;
sound/usb/endpoint.c int snd_usb_endpoint_set_params(struct s · line 1389
Quoted 10 lines
sound/usb/endpoint.c +5
-0ep->packsize[0 ] = ep->cur_rate / ep->pps; ep->packsize[1 ] = (ep->cur_rate + (ep->pps -1 )) / ep->pps; +if (ep->packsize[1 ] > ep->maxpacksize) { +usb_audio_dbg (chip,"Too small maxpacksize %u for rate %u / pps %u\n" , + ep->maxpacksize, ep->cur_rate, ep->pps); +return -EINVAL ; + }/* calculate the frequency in 16.16 format */ ep->freqm = ep->freqn;
This one requires the same workaround again, just as mentioned for 5.15.y:
https://lore.kernel.org/[email protected]
thanks,
Takashi
Greg Kroah-Hartman
maintainerPATCH 407/568 spi: Try to get ACPI GPIO IRQ earlier
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 3cd2018e15b3d66d2187d92867e265f45ad79e6f upstream.
Since commit d24cfee7f63d ("spi: Fix acpi deferred irq probe"), the acpi_dev_gpio_irq_get() call gets delayed till spi_probe() is called on the SPI device.
If there is no driver for the SPI device then the move to spi_probe() results in acpi_dev_gpio_irq_get() never getting called. This may cause problems by leaving the GPIO pin floating because this call is responsible for setting up the GPIO pin direction and/or bias according to the values from the ACPI tables.
Re-add the removed acpi_dev_gpio_irq_get() in acpi_register_spi_device() to ensure the GPIO pin is always correctly setup, while keeping the acpi_dev_gpio_irq_get() call added to spi_probe() to deal with -EPROBE_DEFER returns caused by the GPIO controller not having a driver yet.
--- drivers/spi/spi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/spi/spi.c +10 -0
@@ -2707,6 +2707,16 @@ static acpi_status acpi_register_spi_devacpi_set_modalias (adev,acpi_device_hid (adev), spi->modalias,sizeof (spi->modalias)); +/* +* This gets re-tried in spi_probe() for -EPROBE_DEFER handling in case +* the GPIO controller does not have a driver yet. This needs to be done +* here too, because this call sets the GPIO direction and/or bias. +* Setting these needs to be done even if there is no driver, in which +* case spi_probe() will never get called. +*/ +if (spi->irq <0 ) + spi->irq =acpi_dev_gpio_irq_get (adev,0 ); +acpi_device_set_enumerated (adev); adev->power.flags.ignore_parent = true;
Greg Kroah-Hartman
maintainerPATCH 408/568 LoongArch: Use physical addresses for CSR_MERRENTRY/CSR_TLBRENTRY
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 4e67526840fc55917581b90f6a4b65849a616dd8 upstream.
Now we use virtual addresses to fill CSR_MERRENTRY/CSR_TLBRENTRY, but hardware hope physical addresses. Now it works well because the high bits are ignored above PA_BITS (48 bits), but explicitly use physical addresses can avoid potential bugs. So fix it.
--- arch/loongarch/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/loongarch/kernel/traps.c +2 -2
@@ -657,8 +657,8 @@ static void configure_exception_vector(v tlbrentry = (unsigned long )exception_handlers +80 *VECSIZE ;csr_write64 (eentry,LOONGARCH_CSR_EENTRY ); -csr_write64 (eentry,LOONGARCH_CSR_MERRENTRY ); -csr_write64 (tlbrentry,LOONGARCH_CSR_TLBRENTRY ); +csr_write64 (__pa (eentry),LOONGARCH_CSR_MERRENTRY ); +csr_write64 (__pa (tlbrentry),LOONGARCH_CSR_TLBRENTRY ); }void per_cpu_trap_init (int cpu)
Greg Kroah-Hartman
maintainerPATCH 409/568 EDAC/altera: Handle OCRAM ECC enable after warm reset
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit fd3ecda38fe0cb713d167b5477d25f6b350f0514 upstream.
The OCRAM ECC is always enabled either by the BootROM or by the Secure Device Manager (SDM) during a power-on reset on SoCFPGA.
However, during a warm reset, the OCRAM content is retained to preserve data, while the control and status registers are reset to their default values. As a result, ECC must be explicitly re-enabled after a warm reset.
--- drivers/edac/altera_edac.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/edac/altera_edac.c +15 -3
@@ -1194,10 +1194,22 @@ altr_check_ocram_deps_init(struct altr_eif (ret)return ret; -/* Verify OCRAM has been initialized */ +/* +* Verify that OCRAM has been initialized. +* During a warm reset, OCRAM contents are retained, but the control +* and status registers are reset to their default values. Therefore, +* ECC must be explicitly re-enabled in the control register. +* Error condition: if INITCOMPLETEA is clear and ECC_EN is already set. +*/ if (!ecc_test_bits (ALTR_A10_ECC_INITCOMPLETEA , - (base +ALTR_A10_ECC_INITSTAT_OFST ))) -return -ENODEV ; + (base +ALTR_A10_ECC_INITSTAT_OFST ))) { +if (!ecc_test_bits (ALTR_A10_ECC_EN , + (base +ALTR_A10_ECC_CTRL_OFST ))) +ecc_set_bits (ALTR_A10_ECC_EN , + (base +ALTR_A10_ECC_CTRL_OFST )); +else +return -ENODEV ; + }/* Enable IRQ on Single Bit Error */ writel (ALTR_A10_ECC_SERRINTEN , (base +ALTR_A10_ECC_ERRINTENS_OFST ));
Greg Kroah-Hartman
maintainerPATCH 410/568 EDAC/altera: Use INTTEST register for Ethernet and USB SBE injection
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit 281326be67252ac5794d1383f67526606b1d6b13 upstream.
The current single-bit error injection mechanism flips bits directly in ECC RAM by performing write and read operations. When the ECC RAM is actively used by the Ethernet or USB controller, this approach sometimes trigger a false double-bit error.
Switch both Ethernet and USB EDAC devices to use the INTTEST register (altr_edac_a10_device_inject_fops) for single-bit error injection, similar to the existing double-bit error injection method.
--- drivers/edac/altera_edac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/edac/altera_edac.c +2 -2
@@ -1379,7 +1379,7 @@ static const struct edac_device_prv_data .ue_set_mask = ALTR_A10_ECC_TDERRA, .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, .ecc_irq_handler = altr_edac_a10_ecc_irq, - .inject_fops = &altr_edac_a10_device_inject2_fops, + .inject_fops = &altr_edac_a10_device_inject_fops, };#endif /* CONFIG_EDAC_ALTERA_ETHERNET */
@@ -1469,7 +1469,7 @@ static const struct edac_device_prv_data .ue_set_mask = ALTR_A10_ECC_TDERRA, .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, .ecc_irq_handler = altr_edac_a10_ecc_irq, - .inject_fops = &altr_edac_a10_device_inject2_fops, + .inject_fops = &altr_edac_a10_device_inject_fops, };#endif /* CONFIG_EDAC_ALTERA_USB */
Greg Kroah-Hartman
maintainerPATCH 411/568 btrfs: do not update last_log_commit when logging inode due to a new name
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit bfe3d755ef7cec71aac6ecda34a107624735aac7 upstream.
When logging that a new name exists, we skip updating the inode's last_log_commit field to prevent a later explicit fsync against the inode from doing nothing (as updating last_log_commit makes btrfs_inode_in_log() return true). We are detecting, at btrfs_log_inode(), that logging a new name is happening by checking the logging mode is not LOG_INODE_EXISTS, but that is not enough because we may log parent directories when logging a new name of a file in LOG_INODE_ALL mode - we need to check that the logging_new_name field of the log context too.
An example scenario where this results in an explicit fsync against a directory not persisting changes to the directory is the following:
$ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt
$ touch /mnt/foo
$ sync
$ mkdir /mnt/dir
# Write some data to our file and fsync it.
$ xfs_io -c "pwrite -S 0xab 0 64K" -c "fsync" /mnt/foo
# Add a new link to our file. Since the file was logged before, we
# update it in the log tree by calling btrfs_log_new_name(). $ ln /mnt/foo /mnt/dir/bar
# fsync the root directory - we expect it to persist the dentry for # the new directory "dir". $ xfs_io -c "fsync" /mnt
<power fail>
After mounting the fs the entry for directory "dir" does not exists, despite the explicit fsync on the root directory.
Here's why this happens:
1) When we fsync the file we log the inode, so that it's present in the log tree;
2) When adding the new link we enter btrfs_log_new_name(), and since the inode is in the log tree we proceed to updating the inode in the log tree;
3) We first set the inode's last_unlink_trans to the current transaction (early in btrfs_log_new_name());
4) We then eventually enter btrfs_log_inode_parent(), and after logging the file's inode, we call btrfs_log_all_parents() because the inode's last_unlink_trans matches the current transaction's ID (updated in the previous step);
5) So btrfs_log_all_parents() logs the root directory by calling btrfs_log_inode() for the root's inode with a log mode of LOG_INODE_ALL so that new dentries are logged;
6) At btrfs_log_inode(), because the log mode is LOG_INODE_ALL, we update root inode's last_log_commit to the last transaction that changed the inode (->last_sub_trans field of the inode), which corresponds to the current transaction's ID;
7) Then later when user space explicitly calls fsync against the root directory, we enter btrfs_sync_file(), which calls skip_inode_logging() and that returns true, since its call to btrfs_inode_in_log() returns true and there are no ordered extents (it's a directory, never has ordered extents). This results in btrfs_sync_file() returning without syncing the log or committing the current transaction, so all the updates we did when logging the new name, including logging the root directory, are not persisted.
So fix this by but updating the inode's last_log_commit if we are sure we are not logging a new name (if ctx->logging_new_name is false).
A test case for fstests will follow soon.
--- fs/btrfs/tree-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/tree-log.c +1 -1
@@ -6705,7 +6705,7 @@ log_extents:* a power failure unless the log was synced as part of an fsync * against any other unrelated inode. */ -if (inode_only !=LOG_INODE_EXISTS ) +if (!ctx->logging_new_name && inode_only !=LOG_INODE_EXISTS ) inode->last_log_commit = inode->last_sub_trans;spin_unlock (&inode->lock);
Greg Kroah-Hartman
maintainerPATCH 412/568 selftests: mptcp: connect: trunc: read all recv data
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit ee79980f7a428ec299f6261bea4c1084dcbc9631 upstream.
MPTCP Join "fastclose server" selftest is sometimes failing because the client output file doesn't have the expected size, e.g. 296B instead of 1024B.
When looking at a packet trace when this happens, the server sent the expected 1024B in two parts -- 100B, then 924B -- then the MP_FASTCLOSE. It is then strange to see the client only receiving 296B, which would mean it only got a part of the second packet. The problem is then not on the networking side, but rather on the data reception side.
When mptcp_connect is launched with '-f -1', it means the connection might stop before having sent everything, because a reset has been received. When this happens, the program was directly stopped. But it is also possible there are still some data to read, simply because the previous 'read' step was done with a buffer smaller than the pending data, see do_rnd_read(). In this case, it is important to read what's left in the kernel buffers before stopping without error like before.
SIGPIPE is now ignored, not to quit the app before having read everything.
--- tools/testing/selftests/net/mptcp/mptcp_connect.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_connect.c +13 -5
@@ -655,8 +655,14 @@ static int copyfd_io_poll(int infd, int bw =do_rnd_write (peerfd, wbuf + woff, wlen);if (bw <0 ) { -if (cfg_rcv_trunc) -return 0 ; +/* expected reset, continue to read */ +if (cfg_rcv_trunc && + (errno ==ECONNRESET || + errno ==EPIPE )) { + fds.events &= ~POLLOUT ; +continue ; + } +perror ("write" );return 111 ; }
@@ -682,8 +688,10 @@ static int copyfd_io_poll(int infd, int }if (fds.revents & (POLLERR |POLLNVAL )) { -if (cfg_rcv_trunc) -return 0 ; +if (cfg_rcv_trunc) { + fds.events &= ~(POLLERR |POLLNVAL ); +continue ; + }fprintf (stderr,"Unexpected revents: " "POLLERR/POLLNVAL(%x)\n" , fds.revents);return 5 ;
@@ -1332,7 +1340,7 @@ static void parse_opts(int argc, char ***/ if (cfg_truncate <0 ) { cfg_rcv_trunc = true; -signal (SIGPIPE , handle_signal); +signal (SIGPIPE ,SIG_IGN ); }break ;case 'j' :
Greg Kroah-Hartman
maintainerPATCH 413/568 virtio-net: fix received length check in big packets
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bui Quang Minh <[email protected]>
[ Upstream commit 0c716703965ffc5ef4311b65cb5d84a703784717 ]
Since commit 4959aebba8c0 ("virtio-net: use mtu size as buffer length for big packets"), when guest gso is off, the allocated size for big packets is not MAX_SKB_FRAGS * PAGE_SIZE anymore but depends on negotiated MTU. The number of allocated frags for big packets is stored in vi->big_packets_num_skbfrags.
Because the host announced buffer length can be malicious (e.g. the host vhost_net driver's get_rx_bufs is modified to announce incorrect length), we need a check in virtio_net receive path. Currently, the check is not adapted to the new change which can lead to NULL page pointer dereference in the below while loop when receiving length that is larger than the allocated one.
This commit fixes the received length check corresponding to the new change.
--- drivers/net/virtio_net.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
drivers/net/virtio_net.c +13 -13
@@ -542,17 +542,6 @@ static struct sk_buff *page_to_skb(struc goto ok; } -/* -* Verify that we can indeed put this data into a skb. -* This is here to handle cases when the device erroneously -* tries to receive more than is possible. This is usually -* the case of a broken device. -*/ -if (unlikely (len >MAX_SKB_FRAGS *PAGE_SIZE )) { -net_dbg_ratelimited ("%s: too much data\n" , skb->dev->name); -dev_kfree_skb (skb); -return NULL ; - }BUG_ON (offset >=PAGE_SIZE );while (len) {unsigned int frag_size =min ((unsigned )PAGE_SIZE - offset, len);
@@ -955,8 +944,19 @@ static struct sk_buff *receive_big(struc struct virtnet_rq_stats *stats) {struct page *page = buf; -struct sk_buff *skb = -page_to_skb (vi, rq, page,0 , len,PAGE_SIZE , true,0 ,0 ); +struct sk_buff *skb; + +/* Make sure that len does not exceed the size allocated in +* add_recvbuf_big. +*/ +if (unlikely (len > (vi->big_packets_num_skbfrags +1 ) *PAGE_SIZE )) { +pr_debug ("%s: rx error: len %u exceeds allocated size %lu\n" , + dev->name, len, + (vi->big_packets_num_skbfrags +1 ) *PAGE_SIZE ); + goto err; + } + + skb =page_to_skb (vi, rq, page,0 , len,PAGE_SIZE , true,0 ,0 ); stats->bytes += len - vi->hdr_len;if (unlikely (!skb))
Greg Kroah-Hartman
maintainerPATCH 414/568 scsi: ufs: core: Add a quirk to suppress link_startup_again
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
ufshcd_link_startup() has a facility (link_startup_again) to issue DME_LINKSTARTUP a 2nd time even though the 1st time was successful.
Some older hardware benefits from that, however the behaviour is non-standard, and has been found to cause link startup to be unreliable for some Intel Alder Lake based host controllers.
Add UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress link_startup_again, in preparation for setting the quirk for affected controllers.
--- drivers/ufs/core/ufshcd.c | 3 ++- include/ufs/ufshcd.h | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/ufs/core/ufshcd.c +2 -1
@@ -4778,7 +4778,8 @@ static int ufshcd_link_startup(struct uf* If UFS device isn't active then we will have to issue link startup * 2 times to make sure the device state move to active. */ -if (!ufshcd_is_ufs_dev_active (hba)) +if (!(hba->quirks &UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE ) && + !ufshcd_is_ufs_dev_active (hba)) link_startup_again = true; link_startup:
include/ufs/ufshcd.h +7 -0
@@ -592,6 +592,13 @@ enum ufshcd_quirks {* auto-hibernate capability but it's FASTAUTO only. */ UFSHCD_QUIRK_HIBERN_FASTAUTO =1 <<18 , + +/* +* This quirk indicates that DME_LINKSTARTUP should not be issued a 2nd +* time (refer link_startup_again) after the 1st time was successful, +* because it causes link startup to become unreliable. +*/ + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE = 1 << 19, }; enum ufshcd_caps {
Re: [PATCH 6.1 414/568] scsi: ufs: core: Add a quirk to suppress link_startup_again
Quoted 17 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
ufshcd_link_startup()has a facility (link_startup_again) to issueDME_LINKSTARTUPa 2nd time even though the 1st time was successful.Some older hardware benefits from that, however the behaviour is non-standard, and has been found to cause link startup to be unreliable for some Intel Alder Lake based host controllers.
Add
UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCEto suppresslink_startup_again, in preparation for setting the quirk for affected controllers.
Quoted 8 lines
Fixes 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL")Signed-off-by Adrian Hunter <[email protected]>Reviewed-by Bart Van Assche <[email protected]>Signed-off-by Martin K. Petersen <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
This backport's commit message is missing the corresponding upstream commit (which is d34caa89a132cd69efc48361d4772251546fdb88).
Signature · 1 line
-Barry K. Nathan <[email protected]>
Greg Kroah-Hartman
maintainerRe: [PATCH 6.1 414/568] scsi: ufs: core: Add a quirk to suppress link_startup_again
Quoted 27 lines · Barry K. Nathan
Quoted 17 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
ufshcd_link_startup()has a facility (link_startup_again) to issueDME_LINKSTARTUPa 2nd time even though the 1st time was successful.Some older hardware benefits from that, however the behaviour is non-standard, and has been found to cause link startup to be unreliable for some Intel Alder Lake based host controllers.
Add
UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCEto suppresslink_startup_again, in preparation for setting the quirk for affected controllers.Quoted 8 lines
Fixes 7dc9fb47bc9a ("scsi: ufs: ufs-pci: Add support for Intel ADL")Signed-off-by Adrian Hunter <[email protected]>Reviewed-by Bart Van Assche <[email protected]>Signed-off-by Martin K. Petersen <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
Quoted 2 lines
This backport's commit message is missing the corresponding upstream commit (which is
d34caa89a132cd69efc48361d4772251546fdb88).
Ah, good catch, don't know how I missed that, thanks!
greg k-h
Greg Kroah-Hartman
maintainerPATCH 415/568 scsi: ufs: ufs-pci: Set UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE for Intel ADL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
[ Upstream commit d968e99488c4b08259a324a89e4ed17bf36561a4 ]
Link startup becomes unreliable for Intel Alder Lake based host controllers when a 2nd DME_LINKSTARTUP is issued unnecessarily. Employ UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE to suppress that from happening.
--- drivers/ufs/host/ufshcd-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/ufs/host/ufshcd-pci.c +2 -1
@@ -463,7 +463,8 @@ static int ufs_intel_lkf_init(struct ufsstatic int ufs_intel_adl_init (struct ufs_hba *hba) { hba->nop_out_timeout =200 ; - hba->quirks |=UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 ; + hba->quirks |=UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 | +UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE ; hba->caps |=UFSHCD_CAP_WB_EN ;return ufs_intel_common_init (hba); }
Greg Kroah-Hartman
maintainerPATCH 416/568 iommufd: Dont overflow during division for dirty tracking
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit cb30dfa75d55eced379a42fd67bd5fb7ec38555e ]
If pgshift is 63 then BITS_PER_TYPE(*bitmap->bitmap) * pgsize will overflow to 0 and this triggers divide by 0.
In this case the index should just be 0, so reorganize things to divide by shift and avoid hitting any overflows.
--- drivers/vfio/iova_bitmap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/vfio/iova_bitmap.c +2 -3
@@ -126,9 +126,8 @@ struct iova_bitmap {static unsigned long iova_bitmap_offset_to_index (struct iova_bitmap *bitmap,unsigned long iova) { -unsigned long pgsize =1UL << bitmap->mapped.pgshift; - -return iova / (BITS_PER_TYPE (*bitmap->bitmap) * pgsize); +return (iova >> bitmap->mapped.pgshift) / +BITS_PER_TYPE (*bitmap->bitmap); }/*
Greg Kroah-Hartman
maintainerPATCH 417/568 KVM: SVM: Mark VMCB_LBR dirty when MSR_IA32_DEBUGCTLMSR is updated
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
[ Upstream commit dc55b3c3f61246e483e50c85d8d5366f9567e188 ]
The APM lists the DbgCtlMsr field as being tracked by the VMCB_LBR clean bit. Always clear the bit when MSR_IA32_DEBUGCTLMSR is updated.
The history is complicated, it was correctly cleared for L1 before commit 1d5a1b5860ed ("KVM: x86: nSVM: correctly virtualize LBR msrs when L2 is running"). At that point svm_set_msr() started to rely on svm_update_lbrv() to clear the bit, but when nested virtualization is enabled the latter does not always clear it even if MSR_IA32_DEBUGCTLMSR changed. Go back to clearing it directly in svm_set_msr().
--- arch/x86/kvm/svm/svm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/svm.c +8 -2
@@ -3053,11 +3053,17 @@ static int svm_set_msr(struct kvm_vcpu *if (data &DEBUGCTL_RESERVED_BITS )return 1 ; -if (svm->vmcb->control.virt_ext &LBR_CTL_ENABLE_MASK ) +if (svm->vmcb->control.virt_ext &LBR_CTL_ENABLE_MASK ) { +if (svm->vmcb->save.dbgctl == data) +break ; svm->vmcb->save.dbgctl = data; -else + }else { +if (svm->vmcb01.ptr->save.dbgctl == data) +break ; svm->vmcb01.ptr->save.dbgctl = data; + } +vmcb_mark_dirty (svm->vmcb,VMCB_LBR );svm_update_lbrv (vcpu);break ;
Greg Kroah-Hartman
maintainerPATCH 418/568 net: netpoll: fix incorrect refcount handling causing incorrect cleanup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 49c8d2c1f94cc2f4d1a108530d7ba52614b874c2 ]
commit efa95b01da18 ("netpoll: fix use after free") incorrectly ignored the refcount and prematurely set dev->npinfo to NULL during netpoll cleanup, leading to improper behavior and memory leaks.
Scenario causing lack of proper cleanup:
1) A netpoll is associated with a NIC (e.g., eth0) and netdev->npinfo is allocated, and refcnt = 1
- Keep in mind that npinfo is shared among all netpoll instances. In this case, there is just one.
2) Another netpoll is also associated with the same NIC and npinfo->refcnt += 1.
- Now dev->npinfo->refcnt = 2;
- There is just one npinfo associated to the netdev.
3) When the first netpolls goes to clean up:
- The first cleanup succeeds and clears np->dev->npinfo, ignoring refcnt.
- It basically calls RCU_INIT_POINTER(np->dev->npinfo, NULL);
- Set dev->npinfo = NULL, without proper cleanup
- No ->ndo_netpoll_cleanup() is either called
4) Now the second target tries to clean up
- The second cleanup fails because np->dev->npinfo is already NULL.
* In this case, ops->ndo_netpoll_cleanup() was never called, and the skb pool is not cleaned as well (for the second netpoll instance)
- This leaks npinfo and skbpool skbs, which is clearly reported by kmemleak.
Revert commit efa95b01da18 ("netpoll: fix use after free") and adds clarifying comments emphasizing that npinfo cleanup should only happen once the refcount reaches zero, ensuring stable and correct netpoll behavior.
--- net/core/netpoll.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/core/netpoll.c +5 -2
@@ -851,6 +851,10 @@ void __netpoll_cleanup(struct netpoll *nsynchronize_srcu (&netpoll_srcu); +/* At this point, there is a single npinfo instance per netdevice, and +* its refcnt tracks how many netpoll structures are linked to it. We +* only perform npinfo cleanup when the refcnt decrements to zero. +*/ if (refcount_dec_and_test (&npinfo->refcnt)) {const struct net_device_ops *ops;
@@ -860,8 +864,7 @@ void __netpoll_cleanup(struct netpoll *nRCU_INIT_POINTER (np->dev->npinfo,NULL );call_rcu (&npinfo->rcu, rcu_cleanup_netpoll_info); - }else -RCU_INIT_POINTER (np->dev->npinfo,NULL ); + } }EXPORT_SYMBOL_GPL (__netpoll_cleanup);
Greg Kroah-Hartman
maintainerPATCH 419/568 eventpoll: Replace rwlock with spinlock
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao <[email protected]>
[ Upstream commit 0c43094f8cc9d3d99d835c0ac9c4fe1ccc62babd ]
The ready event list of an epoll object is protected by read-write semaphore:
- The consumer (waiter) acquires the write lock and takes items.
- the producer (waker) takes the read lock and adds items.
The point of this design is enabling epoll to scale well with large number of producers, as multiple producers can hold the read lock at the same time.
Unfortunately, this implementation may cause scheduling priority inversion problem. Suppose the consumer has higher scheduling priority than the producer. The consumer needs to acquire the write lock, but may be blocked by the producer holding the read lock. Since read-write semaphore does not support priority-boosting for the readers (even with CONFIG_PREEMPT_RT=y), we have a case of priority inversion: a higher priority consumer is blocked by a lower priority producer. This problem was reported in [1].
Furthermore, this could also cause stall problem, as described in [2].
Fix this problem by replacing rwlock with spinlock.
This reduces the event bandwidth, as the producers now have to contend with each other for the spinlock. According to the benchmark from
https://github.com/rouming/test-tools/blob/master/stress-epoll.c:
On 12 x86 CPUs:
Before After Diff
threads events/ms events/ms
8 7162 4956 -31%
16 8733 5383 -38%
32 7968 5572 -30%
64 10652 5739 -46%
128 11236 5931 -47%
On 4 riscv CPUs:
Before After Diff
threads events/ms events/ms
8 2958 2833 -4%
16 3323 3097 -7%
32 3451 3240 -6%
64 3554 3178 -11%
128 3601 3235 -10%Although the numbers look bad, it should be noted that this benchmark creates multiple threads who do nothing except constantly generating new epoll events, thus contention on the spinlock is high. For real workload, the event rate is likely much lower, and the performance drop is not as bad.
Using another benchmark (perf bench epoll wait) where spinlock contention is lower, improvement is even observed on x86:
On 12 x86 CPUs:
Before: Averaged 110279 operations/sec (+- 1.09%), total secs = 8
After: Averaged 114577 operations/sec (+- 2.25%), total secs = 8
On 4 riscv CPUs:
Before: Averaged 175767 operations/sec (+- 0.62%), total secs = 8
After: Averaged 167396 operations/sec (+- 0.23%), total secs = 8In conclusion, no one is likely to be upset over this change. After all, spinlock was used originally for years, and the commit which converted to rwlock didn't mention a real workload, just that the benchmark numbers are nice.
This patch is not exactly the revert of commit a218cc491420 ("epoll: use rwlock in order to reduce ep_poll_callback() contention"), because git revert conflicts in some places which are not obvious on the resolution. This patch is intended to be backported, therefore go with the obvious approach:
- Replace rwlock_t with spinlock_t one to one
- Delete list_add_tail_lockless() and chain_epi_lockless(). These were introduced to allow producers to concurrently add items to the list. But now that spinlock no longer allows producers to touch the event list concurrently, these two functions are not necessary anymore.
--- fs/eventpoll.c | 139 ++++++++++----------------------------------------------- 1 file changed, 26 insertions(+), 113 deletions(-)
fs/eventpoll.c +26 -113
@@ -45,10 +45,10 @@* * 1) epmutex (mutex) * 2) ep->mtx (mutex) -* 3) ep->lock (rwlock) +* 3) ep->lock (spinlock) * * The acquire order is the one listed above, from 1 to 3. -* We need a rwlock (ep->lock) because we manipulate objects +* We need a spinlock (ep->lock) because we manipulate objects * from inside the poll callback, that might be triggered from * a wake_up() that in turn might be called from IRQ context. * So we can't sleep inside the poll callback and hence we need
@@ -193,7 +193,7 @@ struct eventpoll {struct list_head rdllist;/* Lock which protects rdllist and ovflist */ -rwlock_t lock; +spinlock_t lock;/* RB tree root used to store monitored fd structs */ struct rb_root_cached rbr;
@@ -621,10 +621,10 @@ static void ep_start_scan(struct eventpo* in a lockless way. */ lockdep_assert_irqs_enabled (); -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);list_splice_init (&ep->rdllist, txlist);WRITE_ONCE (ep->ovflist,NULL ); -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock); } static void ep_done_scan(struct eventpoll *ep,
@@ -632,7 +632,7 @@ static void ep_done_scan(struct eventpol {struct epitem *epi, *nepi; -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);/* * During the time we spent inside the "sproc" callback, some * other events might have been queued by the poll callback.
@@ -673,7 +673,7 @@ static void ep_done_scan(struct eventpolwake_up (&ep->wq); } -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock); }static void epi_rcu_free (struct rcu_head *head)
@@ -719,10 +719,10 @@ static int ep_remove(struct eventpoll *erb_erase_cached (&epi->rbn, &ep->rbr); -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);if (ep_is_linked (epi))list_del_init (&epi->rdllink); -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock);wakeup_source_unregister (ep_wakeup_source (epi));/*
@@ -986,7 +986,7 @@ static int ep_alloc(struct eventpoll **p goto free_uid;mutex_init (&ep->mtx); -rwlock_init (&ep->lock); +spin_lock_init (&ep->lock);init_waitqueue_head (&ep->wq);init_waitqueue_head (&ep->poll_wait);INIT_LIST_HEAD (&ep->rdllist);
@@ -1077,99 +1077,9 @@ struct file *get_epoll_tfile_raw_ptr(str#endif /* CONFIG_KCMP */ /* -* Adds a new entry to the tail of the list in a lockless way, i.e. -* multiple CPUs are allowed to call this function concurrently. -* -* Beware: it is necessary to prevent any other modifications of the -* existing list until all changes are completed, in other words -* concurrent list_add_tail_lockless() calls should be protected -* with a read lock, where write lock acts as a barrier which -* makes sure all list_add_tail_lockless() calls are fully -* completed. -* -* Also an element can be locklessly added to the list only in one -* direction i.e. either to the tail or to the head, otherwise -* concurrent access will corrupt the list. -* -* Return: %false if element has been already added to the list, %true -* otherwise. -*/ -static inline bool list_add_tail_lockless (struct list_head *new, -struct list_head *head) -{ -struct list_head *prev; - -/* -* This is simple 'new->next = head' operation, but cmpxchg() -* is used in order to detect that same element has been just -* added to the list from another CPU: the winner observes -* new->next == new. -*/ -if (!try_cmpxchg (&new->next, &new, head)) -return false; - -/* -* Initially ->next of a new element must be updated with the head -* (we are inserting to the tail) and only then pointers are atomically -* exchanged. XCHG guarantees memory ordering, thus ->next should be -* updated before pointers are actually swapped and pointers are -* swapped before prev->next is updated. -*/ - - prev =xchg (&head->prev, new); - -/* -* It is safe to modify prev->next and new->prev, because a new element -* is added only to the tail and new->next is updated before XCHG. -*/ - - prev->next = new; - new->prev = prev; - -return true; -} - -/* -* Chains a new epi entry to the tail of the ep->ovflist in a lockless way, -* i.e. multiple CPUs are allowed to call this function concurrently. -* -* Return: %false if epi element has been already chained, %true otherwise. -*/ -static inline bool chain_epi_lockless (struct epitem *epi) -{ -struct eventpoll *ep = epi->ep; - -/* Fast preliminary check */ -if (epi->next !=EP_UNACTIVE_PTR ) -return false; - -/* Check that the same epi has not been just chained from another CPU */ -if (cmpxchg (&epi->next,EP_UNACTIVE_PTR ,NULL ) !=EP_UNACTIVE_PTR ) -return false; - -/* Atomically exchange tail */ - epi->next =xchg (&ep->ovflist, epi); - -return true; -} - -/* * This is the callback that is passed to the wait queue wakeup * mechanism. It is called by the stored file descriptors when they * have events to report. -* -* This callback takes a read lock in order not to contend with concurrent -* events from another file descriptor, thus all modifications to ->rdllist -* or ->ovflist are lockless. Read lock is paired with the write lock from -* ep_scan_ready_list(), which stops all list modifications and guarantees -* that lists state is seen correctly. -* -* Another thing worth to mention is that ep_poll_callback() can be called -* concurrently for the same @epi from different CPUs if poll table was inited -* with several wait queues entries. Plural wakeup from different CPUs of a -* single wait queue is serialized by wq.lock, but the case when multiple wait -* queues are used should be detected accordingly. This is detected using -* cmpxchg() operation. */ static int ep_poll_callback (wait_queue_entry_t *wait,unsigned mode,int sync,void *key) {
@@ -1180,7 +1090,7 @@ static int ep_poll_callback(wait_queue_eunsigned long flags;int ewake =0 ; -read_lock_irqsave (&ep->lock, flags); +spin_lock_irqsave (&ep->lock, flags);ep_set_busy_poll_napi_id (epi);
@@ -1209,12 +1119,15 @@ static int ep_poll_callback(wait_queue_e* chained in ep->ovflist and requeued later on. */ if (READ_ONCE (ep->ovflist) !=EP_UNACTIVE_PTR ) { -if (chain_epi_lockless (epi)) +if (epi->next ==EP_UNACTIVE_PTR ) { + epi->next =READ_ONCE (ep->ovflist); +WRITE_ONCE (ep->ovflist, epi);ep_pm_stay_awake_rcu (epi); + } }else if (!ep_is_linked (epi)) {/* In the usual case, add event to ready list. */ -if (list_add_tail_lockless (&epi->rdllink, &ep->rdllist)) -ep_pm_stay_awake_rcu (epi); +list_add_tail (&epi->rdllink, &ep->rdllist); +ep_pm_stay_awake_rcu (epi); }/*
@@ -1247,7 +1160,7 @@ static int ep_poll_callback(wait_queue_e pwake++; out_unlock: -read_unlock_irqrestore (&ep->lock, flags); +spin_unlock_irqrestore (&ep->lock, flags);/* We have to call this outside the lock */ if (pwake)
@@ -1576,7 +1489,7 @@ static int ep_insert(struct eventpoll *e }/* We have to drop the new item inside our item list to keep track of it */ -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);/* record NAPI ID of new item if present */ ep_set_busy_poll_napi_id (epi);
@@ -1593,7 +1506,7 @@ static int ep_insert(struct eventpoll *e pwake++; } -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock);/* We have to call this outside the lock */ if (pwake)
@@ -1657,7 +1570,7 @@ static int ep_modify(struct eventpoll *e* list, push it inside. */ if (ep_item_poll (epi, &pt,1 )) { -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);if (!ep_is_linked (epi)) {list_add_tail (&epi->rdllink, &ep->rdllist);ep_pm_stay_awake (epi);
@@ -1668,7 +1581,7 @@ static int ep_modify(struct eventpoll *eif (waitqueue_active (&ep->poll_wait)) pwake++; } -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock); }/* We have to call this outside the lock */
@@ -1901,7 +1814,7 @@ static int ep_poll(struct eventpoll *ep,init_wait (&wait); wait.func = ep_autoremove_wake_function; -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);/* * Barrierless variant, waitqueue_active() is called under * the same lock on wakeup ep_poll_callback() side, so it
@@ -1920,7 +1833,7 @@ static int ep_poll(struct eventpoll *ep,if (!eavail)__add_wait_queue_exclusive (&ep->wq, &wait); -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock);if (!eavail) timed_out = !schedule_hrtimeout_range(to, slack,
@@ -1935,7 +1848,7 @@ static int ep_poll(struct eventpoll *ep, eavail =1 ;if (!list_empty_careful (&wait.entry)) { -write_lock_irq (&ep->lock); +spin_lock_irq (&ep->lock);/* * If the thread timed out and is not on the wait queue, * it means that the thread was woken up after its
@@ -1946,7 +1859,7 @@ static int ep_poll(struct eventpoll *ep,if (timed_out) eavail =list_empty (&wait.entry);__remove_wait_queue (&ep->wq, &wait); -write_unlock_irq (&ep->lock); +spin_unlock_irq (&ep->lock); } } }