6.13.5-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 1/138 Drivers: hv: vmbus: Log on missing offers if any
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Starks <[email protected]>
commit fcf5203e289ca0ef75a18ce74a9eb716f7f1f569 upstream.
When resuming from hibernation, log any channels that were present before hibernation but now are gone.
In general, the boot-time devices configured for a resuming VM should be the same as the devices in the VM at the time of hibernation. It's uncommon for the configuration to have been changed such that offers are missing. Changing the configuration violates the rules for hibernation anyway.
The cleanup of missing channels is not straight-forward and dependent on individual device driver functionality and implementation, so it can be added in future with separate changes.
Message-ID: <[email protected]>
--- drivers/hv/vmbus_drv.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/hv/vmbus_drv.c +17 -0
@@ -2462,6 +2462,7 @@ static int vmbus_bus_suspend(struct devistatic int vmbus_bus_resume (struct device *dev) { +struct vmbus_channel *channel;struct vmbus_channel_msginfo *msginfo;size_t msgsize;int ret;
@@ -2494,6 +2495,22 @@ static int vmbus_bus_resume(struct devicvmbus_request_offers (); +mutex_lock (&vmbus_connection.channel_mutex); +list_for_each_entry (channel, &vmbus_connection.chn_list, listentry) { +if (channel->offermsg.child_relid !=INVALID_RELID ) +continue ; + +/* hvsock channels are not expected to be present. */ +if (is_hvsock_channel (channel)) +continue ; + +pr_err ("channel %pUl/%pUl not present after resume.\n" , + &channel->offermsg.offer.if_type, + &channel->offermsg.offer.if_instance); +/* ToDo: Cleanup these channels here */ + } +mutex_unlock (&vmbus_connection.channel_mutex); +/* Reset the event for the next suspend. */ reinit_completion (&vmbus_connection.ready_for_suspend_event);
Greg Kroah-Hartman
maintainerPATCH 10/138 serial: sh-sci: Clean sci_ports[0] after at earlycon exit
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 5f1017069933489add0c08659673443c9905659e ]
The early_console_setup() function initializes sci_ports[0].port with an object of type struct uart_port obtained from the struct earlycon_device passed as an argument to early_console_setup().
Later, during serial port probing, the serial port used as earlycon (e.g., port A) might be remapped to a different position in the sci_ports[] array, and a different serial port (e.g., port B) might be assigned to slot
0. For example:
sci_ports[0] = port B
sci_ports[X] = port A
In this scenario, the new port mapped at index zero (port B) retains the data associated with the earlycon configuration. Consequently, after the Linux boot process, any access to the serial port now mapped to sci_ports[0] (port B) will block the original earlycon port (port A).
To address this, introduce an early_console_exit() function to clean up sci_ports[0] when earlycon is exited.
To prevent the cleanup of sci_ports[0] while the serial device is still being used by earlycon, introduce the struct sci_port::probing flag and account for it in early_console_exit().
Stable-dep-of: 651dee03696e ("serial: sh-sci: Increment the runtime usage counter for the earlycon device")
--- drivers/tty/serial/sh-sci.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
drivers/tty/serial/sh-sci.c +30 -2
@@ -166,6 +166,7 @@ static struct sci_port sci_ports[SCI_NPORTS];static unsigned long sci_ports_in_use;static struct uart_driver sci_uart_driver;static bool sci_uart_earlycon; +static bool sci_uart_earlycon_dev_probing;static inline struct sci_port *to_sci_port (struct uart_port *uart)
@@ -3386,7 +3387,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,static int sci_probe_single (struct platform_device *dev,unsigned int index,struct plat_sci_port *p, -struct sci_port *sciport) +struct sci_port *sciport, +struct resource *sci_res) {int ret;
@@ -3433,6 +3435,14 @@ static int sci_probe_single(struct platform_device *dev, sciport->port.flags |=UPF_HARD_FLOW ; } +if (sci_uart_earlycon && sci_ports[0 ].port.mapbase == sci_res->start) { +/* +* Skip cleanup the sci_port[0] in early_console_exit(), this +* port is the same as the earlycon one. +*/ + sci_uart_earlycon_dev_probing = true; + } +return uart_add_one_port (&sci_uart_driver, &sciport->port); }
@@ -3491,7 +3501,7 @@ static int sci_probe(struct platform_device *dev)platform_set_drvdata (dev, sp); - ret =sci_probe_single (dev, dev_id, p, sp); + ret =sci_probe_single (dev, dev_id, p, sp, res);if (ret)return ret;
@@ -3574,6 +3584,22 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver,#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON static struct plat_sci_port port_cfg; +static int early_console_exit (struct console *co) +{ +struct sci_port *sci_port = &sci_ports[0 ]; + +/* +* Clean the slot used by earlycon. A new SCI device might +* map to this slot. +*/ +if (!sci_uart_earlycon_dev_probing) { +memset (sci_port,0 ,sizeof (*sci_port)); + sci_uart_earlycon = false; + } + +return 0 ; +} +static int __init early_console_setup (struct earlycon_device *device,int type) {
@@ -3591,6 +3617,8 @@ static int __init early_console_setup(struct earlycon_device *device, SCSCR_RE | SCSCR_TE | port_cfg.scscr); device->con->write = serial_console_write; + device->con->exit = early_console_exit; +return 0 ; } static int __init sci_early_console_setup(struct earlycon_device *device,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 11/138 serial: sh-sci: Increment the runtime usage counter for the earlycon device
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 651dee03696e1dfde6d9a7e8664bbdcd9a10ea7f ]
In the sh-sci driver, serial ports are mapped to the sci_ports[] array, with earlycon mapped at index zero.
The uart_add_one_port() function eventually calls __device_attach(), which, in turn, calls pm_request_idle(). The identified code path is as follows:
uart_add_one_port() ->
serial_ctrl_register_port() ->
serial_core_register_port() ->
serial_core_port_device_add() ->
serial_base_port_add() ->
device_add() ->
bus_probe_device() ->
device_initial_probe() ->
__device_attach() ->
// ...
if (dev->p->dead) {
// ...
} else if (dev->driver) {
// ...
} else {
// ...
pm_request_idle(dev);
// ...
}The earlycon device clocks are enabled by the bootloader. However, the pm_request_idle() call in __device_attach() disables the SCI port clocks while earlycon is still active.
The earlycon write function, serial_console_write(), calls sci_poll_put_char() via serial_console_putchar(). If the SCI port clocks are disabled, writing to earlycon may sometimes cause the SR.TDFE bit to remain unset indefinitely, causing the while loop in sci_poll_put_char() to never exit. On single-core SoCs, this can result in the system being blocked during boot when this issue occurs.
To resolve this, increment the runtime PM usage counter for the earlycon SCI device before registering the UART port.
--- drivers/tty/serial/sh-sci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/tty/serial/sh-sci.c +16 -0
@@ -3436,6 +3436,22 @@ static int sci_probe_single(struct platform_device *dev, }if (sci_uart_earlycon && sci_ports[0 ].port.mapbase == sci_res->start) { +/* +* In case: +* - this is the earlycon port (mapped on index 0 in sci_ports[]) and +* - it now maps to an alias other than zero and +* - the earlycon is still alive (e.g., "earlycon keep_bootcon" is +* available in bootargs) +* +* we need to avoid disabling clocks and PM domains through the runtime +* PM APIs called in __device_attach(). For this, increment the runtime +* PM reference counter (the clocks and PM domains were already enabled +* by the bootloader). Otherwise the earlycon may access the HW when it +* has no clocks enabled leading to failures (infinite loop in +* sci_poll_put_char()). +*/ +pm_runtime_get_noresume (&dev->dev); +/* * Skip cleanup the sci_port[0] in early_console_exit(), this * port is the same as the earlycon one.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 12/138 PCI: Export pci_intx_unmanaged() and pcim_intx()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philipp Stanner <[email protected]>
[ Upstream commit f546e8033d8f3e45d49622f04ca2fde650b80f6d ]
pci_intx() is a hybrid function which sometimes performs devres operations, depending on whether pcim_enable_device() has been used to enable the pci_dev. This sometimes-managed nature of the function is problematic. Notably, it causes the function to allocate under some circumstances which makes it unusable from interrupt context.
Export pcim_intx() (which is always managed) and rename __pcim_intx() (which is never managed) to pci_intx_unmanaged() and export it as well.
Then all callers of pci_intx() can be ported to the version they need, depending whether they use pci_enable_device() or pcim_enable_device().
Stable-dep-of: d555ed45a5a1 ("PCI: Restore original INTX_DISABLE bit by pcim_intx()")
--- drivers/pci/devres.c | 24 +++--------------------- drivers/pci/pci.c | 29 +++++++++++++++++++++++++++++ include/linux/pci.h | 2 ++ 3 files changed, 34 insertions(+), 21 deletions(-)
drivers/pci/devres.c +3 -21
@@ -411,31 +411,12 @@ static inline bool mask_contains_bar(int mask, int bar)return mask &BIT (bar); } -/* -* This is a copy of pci_intx() used to bypass the problem of recursive -* function calls due to the hybrid nature of pci_intx(). -*/ -static void __pcim_intx (struct pci_dev *pdev,int enable) -{ -u16 pci_command, new; - -pci_read_config_word (pdev,PCI_COMMAND , &pci_command); - -if (enable) - new = pci_command & ~PCI_COMMAND_INTX_DISABLE ; -else - new = pci_command |PCI_COMMAND_INTX_DISABLE ; - -if (new != pci_command) -pci_write_config_word (pdev,PCI_COMMAND , new); -} -static void pcim_intx_restore (struct device *dev,void *data) {struct pci_dev *pdev =to_pci_dev (dev);struct pcim_intx_devres *res = data; -__pcim_intx (pdev, res->orig_intx); +pci_intx_unmanaged (pdev, res->orig_intx); }static struct pcim_intx_devres *get_or_create_intx_devres (struct device *dev)
@@ -472,10 +453,11 @@ int pcim_intx(struct pci_dev *pdev, int enable)return -ENOMEM ; res->orig_intx = !enable; -__pcim_intx (pdev, enable); +pci_intx_unmanaged (pdev, enable);return 0 ; } +EXPORT_SYMBOL_GPL (pcim_intx);static void pcim_disable_device (void *pdev_raw) {
drivers/pci/pci.c +29 -0
@@ -4482,6 +4482,35 @@ void pci_disable_parity(struct pci_dev *dev) } } +/** +* pci_intx_unmanaged - enables/disables PCI INTx for device dev, +* unmanaged version +* @pdev: the PCI device to operate on +* @enable: boolean: whether to enable or disable PCI INTx +* +* Enables/disables PCI INTx for device @pdev +* +* This function behavios identically to pci_intx(), but is never managed with +* devres. +*/ +void pci_intx_unmanaged (struct pci_dev *pdev,int enable) +{ +u16 pci_command, new; + +pci_read_config_word (pdev,PCI_COMMAND , &pci_command); + +if (enable) + new = pci_command & ~PCI_COMMAND_INTX_DISABLE ; +else + new = pci_command |PCI_COMMAND_INTX_DISABLE ; + +if (new == pci_command) +return ; + +pci_write_config_word (pdev,PCI_COMMAND , new); +} +EXPORT_SYMBOL_GPL (pci_intx_unmanaged); +/** * pci_intx - enables/disables PCI INTx for device dev * @pdev: the PCI device to operate on
include/linux/pci.h +2 -0
@@ -1350,6 +1350,7 @@ int __must_check pcim_set_mwi(struct pci_dev *dev);int pci_try_set_mwi (struct pci_dev *dev);void pci_clear_mwi (struct pci_dev *dev);void pci_disable_parity (struct pci_dev *dev); +void pci_intx_unmanaged (struct pci_dev *pdev,int enable);void pci_intx (struct pci_dev *dev,int enable);bool pci_check_and_mask_intx (struct pci_dev *dev);bool pci_check_and_unmask_intx (struct pci_dev *dev);
@@ -2297,6 +2298,7 @@ static inline void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) { }#endif +int pcim_intx (struct pci_dev *pdev,int enabled);int pcim_request_all_regions (struct pci_dev *pdev,const char *name);void __iomem *pcim_iomap (struct pci_dev *pdev,int bar,unsigned long maxlen); void __iomem *pcim_iomap_region(struct pci_dev *pdev, int bar,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 13/138 PCI: Remove devres from pci_intx()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philipp Stanner <[email protected]>
[ Upstream commit dfa2f4d5f9e5d757700cefa8ee480099889f1c69 ]
pci_intx() is a hybrid function which can sometimes be managed through devres. This hybrid nature is undesirable.
Since all users of pci_intx() have by now been ported either to always-managed pcim_intx() or never-managed pci_intx_unmanaged(), the devres functionality can be removed from pci_intx().
Consequently, pci_intx_unmanaged() is now redundant, because pci_intx() itself is now unmanaged.
Remove the devres functionality from pci_intx(). Have all users of pci_intx_unmanaged() call pci_intx(). Remove pci_intx_unmanaged().
Stable-dep-of: d555ed45a5a1 ("PCI: Restore original INTX_DISABLE bit by pcim_intx()")
--- drivers/pci/devres.c | 4 ++-- drivers/pci/pci.c | 43 ++----------------------------------------- include/linux/pci.h | 1 - 3 files changed, 4 insertions(+), 44 deletions(-)
drivers/pci/devres.c +2 -2
@@ -416,7 +416,7 @@ static void pcim_intx_restore(struct device *dev, void *data)struct pci_dev *pdev =to_pci_dev (dev);struct pcim_intx_devres *res = data; -pci_intx_unmanaged (pdev, res->orig_intx); +pci_intx (pdev, res->orig_intx); }static struct pcim_intx_devres *get_or_create_intx_devres (struct device *dev)
@@ -453,7 +453,7 @@ int pcim_intx(struct pci_dev *pdev, int enable)return -ENOMEM ; res->orig_intx = !enable; -pci_intx_unmanaged (pdev, enable); +pci_intx (pdev, enable);return 0 ; }
drivers/pci/pci.c +2 -41
60 lines not on this page · raw message
include/linux/pci.h +0 -1
@@ -1350,7 +1350,6 @@ int __must_check pcim_set_mwi(struct pci_dev *dev);int pci_try_set_mwi (struct pci_dev *dev);void pci_clear_mwi (struct pci_dev *dev);void pci_disable_parity (struct pci_dev *dev); -void pci_intx_unmanaged (struct pci_dev *pdev,int enable);void pci_intx (struct pci_dev *dev,int enable);bool pci_check_and_mask_intx (struct pci_dev *dev);bool pci_check_and_unmask_intx (struct pci_dev *dev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 14/138 PCI: Restore original INTX_DISABLE bit by pcim_intx()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit d555ed45a5a10a813528c7685f432369d536ae3d ]
pcim_intx() tries to restore the INTx bit at removal via devres, but there is a chance that it restores a wrong value.
Because the value to be restored is blindly assumed to be the negative of the enable argument, when a driver calls pcim_intx() unnecessarily for the already enabled state, it'll restore to the disabled state in turn. That is, the function assumes the case like:
// INTx == 1
pcim_intx(pdev, 0); // old INTx value assumed to be 1 -> correct
but it might be like the following, too:
// INTx == 0
pcim_intx(pdev, 0); // old INTx value assumed to be 1 -> wrong
Also, when a driver calls pcim_intx() multiple times with different enable argument values, the last one will win no matter what value it is. This can lead to inconsistency, e.g.
// INTx == 1
pcim_intx(pdev, 0); // OK
...
pcim_intx(pdev, 1); // now old INTx wrongly assumed to be 0
This patch addresses those inconsistencies by saving the original INTx state at the first pcim_intx() call. For that, get_or_create_intx_devres() is folded into pcim_intx() caller side; it allows us to simply check the already allocated devres and record the original INTx along with the devres_alloc() call.
--- drivers/pci/devres.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
drivers/pci/devres.c +19 -15
@@ -419,19 +419,12 @@ static void pcim_intx_restore(struct device *dev, void *data)pci_intx (pdev, res->orig_intx); } -static struct pcim_intx_devres *get_or_create_intx_devres (struct device *dev) +static void save_orig_intx (struct pci_dev *pdev,struct pcim_intx_devres *res) { -struct pcim_intx_devres *res; - - res =devres_find (dev, pcim_intx_restore,NULL ,NULL ); -if (res) -return res; +u16 pci_command; - res =devres_alloc (pcim_intx_restore,sizeof (*res),GFP_KERNEL ); -if (res) -devres_add (dev, res); - -return res; +pci_read_config_word (pdev,PCI_COMMAND , &pci_command); + res->orig_intx = !(pci_command &PCI_COMMAND_INTX_DISABLE ); }/**
@@ -447,12 +440,23 @@ static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev)int pcim_intx (struct pci_dev *pdev,int enable) {struct pcim_intx_devres *res; +struct device *dev = &pdev->dev; - res =get_or_create_intx_devres (&pdev->dev); -if (!res) -return -ENOMEM ; +/* +* pcim_intx() must only restore the INTx value that existed before the +* driver was loaded, i.e., before it called pcim_intx() for the +* first time. +*/ + res =devres_find (dev, pcim_intx_restore,NULL ,NULL ); +if (!res) { + res =devres_alloc (pcim_intx_restore,sizeof (*res),GFP_KERNEL ); +if (!res) +return -ENOMEM ; + +save_orig_intx (pdev, res); +devres_add (dev, res); + } - res->orig_intx = !enable;pci_intx (pdev, enable);return 0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 15/138 drm/amdkfd: Move gfx12 trap handler to separate file
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jay Cornwall <[email protected]>
[ Upstream commit 62498e797aeb2bfa92a823ee1a8253f96d1cbe3f ]
gfx12 derivatives will have substantially different trap handler implementations from gfx10/gfx11. Add a separate source file for gfx12+ and remove unneeded conditional code.
No functional change.
v2: Revert copyright date to 2018, minor comment fixes
Stable-dep-of: d584198a6fe4 ("drm/amdkfd: Ensure consistent barrier state saved in gfx12 trap handler")
--- .../amd/amdkfd/cwsr_trap_handler_gfx10.asm | 202 +-- .../amd/amdkfd/cwsr_trap_handler_gfx12.asm | 1126 +++++++++++++++++ 2 files changed, 1127 insertions(+), 201 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm
drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm +1 -201
@@ -34,41 +34,24 @@ * cpp -DASIC_FAMILY=CHIP_PLUM_BONITO cwsr_trap_handler_gfx10.asm -P -o gfx11.sp3 * sp3 gfx11.sp3 -hex gfx11.hex * - * gfx12: - * cpp -DASIC_FAMILY=CHIP_GFX12 cwsr_trap_handler_gfx10.asm -P -o gfx12.sp3 - * sp3 gfx12.sp3 -hex gfx12.hex */ #define CHIP_NAVI10 26 #define CHIP_SIENNA_CICHLID 30 #define CHIP_PLUM_BONITO 36 -#define CHIP_GFX12 37 #define NO_SQC_STORE (ASIC_FAMILY >= CHIP_SIENNA_CICHLID) #define HAVE_XNACK (ASIC_FAMILY < CHIP_SIENNA_CICHLID) #define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO) #define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO) -#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO && ASIC_FAMILY < CHIP_GFX12) +#define SW_SA_TRAP (ASIC_FAMILY == CHIP_PLUM_BONITO) #define SAVE_AFTER_XNACK_ERROR (HAVE_XNACK && !NO_SQC_STORE) // workaround for TCP store failure after XNACK error when ALLOW_REPLAY=0, for debugger #define SINGLE_STEP_MISSED_WORKAROUND 1 //workaround for lost MODE.DEBUG_EN exception when SAVECTX raised -#if ASIC_FAMILY < CHIP_GFX12 #define S_COHERENCE glc:1 #define V_COHERENCE slc:1 glc:1 #define S_WAITCNT_0 s_waitcnt 0 -#else -#define S_COHERENCE scope:SCOPE_SYS -#define V_COHERENCE scope:SCOPE_SYS -#define S_WAITCNT_0 s_wait_idle - -#define HW_REG_SHADER_FLAT_SCRATCH_LO HW_REG_WAVE_SCRATCH_BASE_LO -#define HW_REG_SHADER_FLAT_SCRATCH_HI HW_REG_WAVE_SCRATCH_BASE_HI -#define HW_REG_GPR_ALLOC HW_REG_WAVE_GPR_ALLOC -#define HW_REG_LDS_ALLOC HW_REG_WAVE_LDS_ALLOC -#define HW_REG_MODE HW_REG_WAVE_MODE -#endif -#if ASIC_FAMILY < CHIP_GFX12 var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006 var SQ_WAVE_STATUS_HALT_MASK = 0x2000 var SQ_WAVE_STATUS_ECC_ERR_MASK = 0x20000
@@ -81,21 +64,6 @@ var S_STATUS_ALWAYS_CLEAR_MASK = SQ_WAVE_STATUS_SPI_PRIO_MASK|SQ_WAVE_STATUS_E var S_STATUS_HALT_MASK = SQ_WAVE_STATUS_HALT_MASK var S_SAVE_PC_HI_TRAP_ID_MASK = 0x00FF0000 var S_SAVE_PC_HI_HT_MASK = 0x01000000 -#else -var SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_MASK = 0x4 -var SQ_WAVE_STATE_PRIV_SCC_SHIFT = 9 -var SQ_WAVE_STATE_PRIV_SYS_PRIO_MASK = 0xC00 -var SQ_WAVE_STATE_PRIV_HALT_MASK = 0x4000 -var SQ_WAVE_STATE_PRIV_POISON_ERR_MASK = 0x8000 -var SQ_WAVE_STATE_PRIV_POISON_ERR_SHIFT = 15 -var SQ_WAVE_STATUS_WAVE64_SHIFT = 29 -var SQ_WAVE_STATUS_WAVE64_SIZE = 1 -var SQ_WAVE_LDS_ALLOC_GRANULARITY = 9 -var S_STATUS_HWREG = HW_REG_WAVE_STATE_PRIV -var S_STATUS_ALWAYS_CLEAR_MASK = SQ_WAVE_STATE_PRIV_SYS_PRIO_MASK|SQ_WAVE_STATE_PRIV_POISON_ERR_MASK -var S_STATUS_HALT_MASK = SQ_WAVE_STATE_PRIV_HALT_MASK -var S_SAVE_PC_HI_TRAP_ID_MASK = 0xF0000000 -#endif var SQ_WAVE_STATUS_NO_VGPRS_SHIFT = 24 var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12
@@ -110,7 +78,6 @@ var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT = 8 var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT = 12 #endif -#if ASIC_FAMILY < CHIP_GFX12 var SQ_WAVE_TRAPSTS_SAVECTX_MASK = 0x400 var SQ_WAVE_TRAPSTS_EXCP_MASK = 0x1FF var SQ_WAVE_TRAPSTS_SAVECTX_SHIFT = 10
@@ -161,39 +128,6 @@ var S_TRAPSTS_RESTORE_PART_3_SIZE = 32 - S_TRAPSTS_RESTORE_PART_3_SHIFT var S_TRAPSTS_HWREG = HW_REG_TRAPSTS var S_TRAPSTS_SAVE_CONTEXT_MASK = SQ_WAVE_TRAPSTS_SAVECTX_MASK var S_TRAPSTS_SAVE_CONTEXT_SHIFT = SQ_WAVE_TRAPSTS_SAVECTX_SHIFT -#else -var SQ_WAVE_EXCP_FLAG_PRIV_ADDR_WATCH_MASK = 0xF -var SQ_WAVE_EXCP_FLAG_PRIV_MEM_VIOL_MASK = 0x10 -var SQ_WAVE_EXCP_FLAG_PRIV_SAVE_CONTEXT_SHIFT = 5 -var SQ_WAVE_EXCP_FLAG_PRIV_SAVE_CONTEXT_MASK = 0x20 -var SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_MASK = 0x40 -var SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_SHIFT = 6 -var SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_MASK = 0x80 -var SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_SHIFT = 7 -var SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_MASK = 0x100 -var SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT = 8 -var SQ_WAVE_EXCP_FLAG_PRIV_WAVE_END_MASK = 0x200 -var SQ_WAVE_EXCP_FLAG_PRIV_TRAP_AFTER_INST_MASK = 0x800 -var SQ_WAVE_TRAP_CTRL_ADDR_WATCH_MASK = 0x80 -var SQ_WAVE_TRAP_CTRL_TRAP_AFTER_INST_MASK = 0x200 - -var S_TRAPSTS_HWREG = HW_REG_WAVE_EXCP_FLAG_PRIV -var S_TRAPSTS_SAVE_CONTEXT_MASK = SQ_WAVE_EXCP_FLAG_PRIV_SAVE_CONTEXT_MASK -var S_TRAPSTS_SAVE_CONTEXT_SHIFT = SQ_WAVE_EXCP_FLAG_PRIV_SAVE_CONTEXT_SHIFT -var S_TRAPSTS_NON_MASKABLE_EXCP_MASK = SQ_WAVE_EXCP_FLAG_PRIV_MEM_VIOL_MASK |\ - SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_MASK |\ - SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_MASK |\ - SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_MASK |\ - SQ_WAVE_EXCP_FLAG_PRIV_WAVE_END_MASK |\ - SQ_WAVE_EXCP_FLAG_PRIV_TRAP_AFTER_INST_MASK -var S_TRAPSTS_RESTORE_PART_1_SIZE = SQ_WAVE_EXCP_FLAG_PRIV_SAVE_CONTEXT_SHIFT -var S_TRAPSTS_RESTORE_PART_2_SHIFT = SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_SHIFT -var S_TRAPSTS_RESTORE_PART_2_SIZE = SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_SHIFT - SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_SHIFT -var S_TRAPSTS_RESTORE_PART_3_SHIFT = SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT -var S_TRAPSTS_RESTORE_PART_3_SIZE = 32 - S_TRAPSTS_RESTORE_PART_3_SHIFT -var BARRIER_STATE_SIGNAL_OFFSET = 16 -var BARRIER_STATE_VALID_OFFSET = 0 -#endif // bits [31:24] unused by SPI debug data var TTMP11_SAVE_REPLAY_W64H_SHIFT = 31
@@ -305,11 +239,7 @@ L_TRAP_NO_BARRIER: L_HALTED: // Host trap may occur while wave is halted. -#if ASIC_FAMILY < CHIP_GFX12 s_and_b32 ttmp2, s_save_pc_hi, S_SAVE_PC_HI_TRAP_ID_MASK -#else - s_and_b32 ttmp2, s_save_trapsts, SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_MASK -#endif s_cbranch_scc1 L_FETCH_2ND_TRAP L_CHECK_SAVE:
@@ -336,7 +266,6 @@ L_NOT_HALTED: // Check for maskable exceptions in trapsts.excp and trapsts.excp_hi. // Maskable exceptions only cause the wave to enter the trap handler if // their respective bit in mode.excp_en is set. -#if ASIC_FAMILY < CHIP_GFX12 s_and_b32 ttmp2, s_save_trapsts, SQ_WAVE_TRAPSTS_EXCP_MASK|SQ_WAVE_TRAPSTS_EXCP_HI_MASK s_cbranch_scc0 L_CHECK_TRAP_ID
@@ -349,17 +278,6 @@ L_NOT_ADDR_WATCH: s_lshl_b32 ttmp2, ttmp2, SQ_WAVE_MODE_EXCP_EN_SHIFT s_and_b32 ttmp2, ttmp2, ttmp3 s_cbranch_scc1 L_FETCH_2ND_TRAP -#else - s_getreg_b32 ttmp2, hwreg(HW_REG_WAVE_EXCP_FLAG_USER) - s_and_b32 ttmp3, s_save_trapsts, SQ_WAVE_EXCP_FLAG_PRIV_ADDR_WATCH_MASK - s_cbranch_scc0 L_NOT_ADDR_WATCH - s_or_b32 ttmp2, ttmp2, SQ_WAVE_TRAP_CTRL_ADDR_WATCH_MASK - -L_NOT_ADDR_WATCH: - s_getreg_b32 ttmp3, hwreg(HW_REG_WAVE_TRAP_CTRL) - s_and_b32 ttmp2, ttmp3, ttmp2 - s_cbranch_scc1 L_FETCH_2ND_TRAP -#endif L_CHECK_TRAP_ID: // Check trap_id != 0
@@ -369,13 +287,8 @@ L_CHECK_TRAP_ID: #if SINGLE_STEP_MISSED_WORKAROUND // Prioritize single step exception over context save. // Second-level trap will halt wave and RFE, re-entering for SAVECTX. -#if ASIC_FAMILY < CHIP_GFX12 s_getreg_b32 ttmp2, hwreg(HW_REG_MODE) s_and_b32 ttmp2, ttmp2, SQ_WAVE_MODE_DEBUG_EN_MASK -#else - // WAVE_TRAP_CTRL is already in ttmp3. - s_and_b32 ttmp3, ttmp3, SQ_WAVE_TRAP_CTRL_TRAP_AFTER_INST_MASK -#endif s_cbranch_scc1 L_FETCH_2ND_TRAP #endif
@@ -425,12 +338,7 @@ L_NO_NEXT_TRAP: s_cbranch_scc1 L_TRAP_CASE // Host trap will not cause trap re-entry. -#if ASIC_FAMILY < CHIP_GFX12 s_and_b32 ttmp2, s_save_pc_hi, S_SAVE_PC_HI_HT_MASK -#else - s_getreg_b32 ttmp2, hwreg(HW_REG_WAVE_EXCP_FLAG_PRIV) - s_and_b32 ttmp2, ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_HOST_TRAP_MASK -#endif s_cbranch_scc1 L_EXIT_TRAP s_or_b32 s_save_status, s_save_status, S_STATUS_HALT_MASK
@@ -457,16 +365,7 @@ L_EXIT_TRAP: s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32 -#if ASIC_FAMILY < CHIP_GFX12 s_setreg_b32 hwreg(S_STATUS_HWREG), s_save_status -#else - // STATE_PRIV.BARRIER_COMPLETE may have changed since we read it. - // Only restore fields which the trap handler changes. - s_lshr_b32 s_save_status, s_save_status, SQ_WAVE_STATE_PRIV_SCC_SHIFT - s_setreg_b32 hwreg(S_STATUS_HWREG, SQ_WAVE_STATE_PRIV_SCC_SHIFT, \ - SQ_WAVE_STATE_PRIV_POISON_ERR_SHIFT - SQ_WAVE_STATE_PRIV_SCC_SHIFT + 1), s_save_status -#endif - s_rfe_b64 [ttmp0, ttmp1] L_SAVE:
@@ -478,14 +377,6 @@ L_SAVE: s_endpgm L_HAVE_VGPRS: #endif -#if ASIC_FAMILY >= CHIP_GFX12 - s_getreg_b32 s_save_tmp, hwreg(HW_REG_WAVE_STATUS) - s_bitcmp1_b32 s_save_tmp, SQ_WAVE_STATUS_NO_VGPRS_SHIFT - s_cbranch_scc0 L_HAVE_VGPRS - s_endpgm -L_HAVE_VGPRS: -#endif - s_and_b32 s_save_pc_hi, s_save_pc_hi, 0x0000ffff //pc[47:32] s_mov_b32 s_save_tmp, 0 s_setreg_b32 hwreg(S_TRAPSTS_HWREG, S_TRAPSTS_SAVE_CONTEXT_SHIFT, 1), s_save_tmp //clear saveCtx bit
@@ -671,19 +562,6 @@ L_SAVE_HWREG: s_mov_b32 m0, 0x0 //Next lane of v2 to write to #endif -#if ASIC_FAMILY >= CHIP_GFX12 - // Ensure no further changes to barrier or LDS state. - // STATE_PRIV.BARRIER_COMPLETE may change up to this point. - s_barrier_signal -2 - s_barrier_wait -2 - - // Re-read final state of BARRIER_COMPLETE field for save. - s_getreg_b32 s_save_tmp, hwreg(S_STATUS_HWREG) - s_and_b32 s_save_tmp, s_save_tmp, SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_MASK - s_andn2_b32 s_save_status, s_save_status, SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_MASK - s_or_b32 s_save_status, s_save_status, s_save_tmp -#endif - write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) write_hwreg_to_mem(s_save_pc_lo, s_save_buf_rsrc0, s_save_mem_offset) s_andn2_b32 s_save_tmp, s_save_pc_hi, S_SAVE_PC_HI_FIRST_WAVE_MASK
@@ -707,21 +585,6 @@ L_SAVE_HWREG: s_getreg_b32 s_save_m0, hwreg(HW_REG_SHADER_FLAT_SCRATCH_HI) write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) -#if ASIC_FAMILY >= CHIP_GFX12 - s_getreg_b32 s_save_m0, hwreg(HW_REG_WAVE_EXCP_FLAG_USER) - write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) - - s_getreg_b32 s_save_m0, hwreg(HW_REG_WAVE_TRAP_CTRL) - write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) - - s_getreg_b32 s_save_tmp, hwreg(HW_REG_WAVE_STATUS) - write_hwreg_to_mem(s_save_tmp, s_save_buf_rsrc0, s_save_mem_offset) - - s_get_barrier_state s_save_tmp, -1 - s_wait_kmcnt (0) - write_hwreg_to_mem(s_save_tmp, s_save_buf_rsrc0, s_save_mem_offset) -#endif - #if NO_SQC_STORE // Write HWREGs with 16 VGPR lanes. TTMPs occupy space after this. s_mov_b32 exec_lo, 0xFFFF
@@ -814,9 +677,7 @@ L_SAVE_LDS_NORMAL: s_and_b32 s_save_alloc_size, s_save_alloc_size, 0xFFFFFFFF //lds_size is zero? s_cbranch_scc0 L_SAVE_LDS_DONE //no lds used? jump to L_SAVE_DONE -#if ASIC_FAMILY < CHIP_GFX12 s_barrier //LDS is used? wait for other waves in the same TG -#endif s_and_b32 s_save_tmp, s_save_pc_hi, S_SAVE_PC_HI_FIRST_WAVE_MASK s_cbranch_scc0 L_SAVE_LDS_DONE
@@ -1081,11 +942,6 @@ L_RESTORE: s_mov_b32 s_restore_buf_rsrc2, 0 //NUM_RECORDS initial value = 0 (in bytes) s_mov_b32 s_restore_buf_rsrc3, S_RESTORE_BUF_RSRC_WORD3_MISC -#if ASIC_FAMILY >= CHIP_GFX12 - // Save s_restore_spi_init_hi for later use. - s_mov_b32 s_restore_spi_init_hi_save, s_restore_spi_init_hi -#endif - //determine it is wave32 or wave64 get_wave_size2(s_restore_size)
@@ -1320,9 +1176,7 @@ L_RESTORE_SGPR: // s_barrier with MODE.DEBUG_EN=1, STATUS.PRIV=1 incorrectly asserts debug exception. // Clear DEBUG_EN before and restore MODE after the barrier. s_setreg_imm32_b32 hwreg(HW_REG_MODE), 0 -#if ASIC_FAMILY < CHIP_GFX12 s_barrier //barrier to ensure the readiness of LDS before access attemps from any other wave in the same TG -#endif /* restore HW registers */ L_RESTORE_HWREG:
@@ -1334,11 +1188,6 @@ L_RESTORE_HWREG: s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes -#if ASIC_FAMILY >= CHIP_GFX12 - // Restore s_restore_spi_init_hi before the saved value gets clobbered. - s_mov_b32 s_restore_spi_init_hi, s_restore_spi_init_hi_save -#endif - read_hwreg_from_mem(s_restore_m0, s_restore_buf_rsrc0, s_restore_mem_offset) read_hwreg_from_mem(s_restore_pc_lo, s_restore_buf_rsrc0, s_restore_mem_offset) read_hwreg_from_mem(s_restore_pc_hi, s_restore_buf_rsrc0, s_restore_mem_offset)
@@ -1358,44 +1207,6 @@ L_RESTORE_HWREG: s_setreg_b32 hwreg(HW_REG_SHADER_FLAT_SCRATCH_HI), s_restore_flat_scratch -#if ASIC_FAMILY >= CHIP_GFX12 - read_hwreg_from_mem(s_restore_tmp, s_restore_buf_rsrc0, s_restore_mem_offset) - S_WAITCNT_0 - s_setreg_b32 hwreg(HW_REG_WAVE_EXCP_FLAG_USER), s_restore_tmp - - read_hwreg_from_mem(s_restore_tmp, s_restore_buf_rsrc0, s_restore_mem_offset) - S_WAITCNT_0 - s_setreg_b32 hwreg(HW_REG_WAVE_TRAP_CTRL), s_restore_tmp - - // Only the first wave needs to restore the workgroup barrier. - s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_FIRST_WAVE_MASK - s_cbranch_scc0 L_SKIP_BARRIER_RESTORE - - // Skip over WAVE_STATUS, since there is no state to restore from it - s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 4 - - read_hwreg_from_mem(s_restore_tmp, s_restore_buf_rsrc0, s_restore_mem_offset) - S_WAITCNT_0 - - s_bitcmp1_b32 s_restore_tmp, BARRIER_STATE_VALID_OFFSET - s_cbranch_scc0 L_SKIP_BARRIER_RESTORE - - // extract the saved signal count from s_restore_tmp - s_lshr_b32 s_restore_tmp, s_restore_tmp, BARRIER_STATE_SIGNAL_OFFSET - - // We need to call s_barrier_signal repeatedly to restore the signal - // count of the work group barrier. The member count is already - // initialized with the number of waves in the work group. -L_BARRIER_RESTORE_LOOP: - s_and_b32 s_restore_tmp, s_restore_tmp, s_restore_tmp - s_cbranch_scc0 L_SKIP_BARRIER_RESTORE - s_barrier_signal -1 - s_add_i32 s_restore_tmp, s_restore_tmp, -1 - s_branch L_BARRIER_RESTORE_LOOP - -L_SKIP_BARRIER_RESTORE: -#endif - s_mov_b32 m0, s_restore_m0 s_mov_b32 exec_lo, s_restore_exec_lo s_mov_b32 exec_hi, s_restore_exec_hi
@@ -1453,13 +1264,6 @@ L_RETURN_WITHOUT_PRIV: s_setreg_b32 hwreg(S_STATUS_HWREG), s_restore_status // SCC is included, which is changed by previous salu -#if ASIC_FAMILY >= CHIP_GFX12 - // Make barrier and LDS state visible to all waves in the group. - // STATE_PRIV.BARRIER_COMPLETE may change after this point. - s_barrier_signal -2 - s_barrier_wait -2 -#endif - s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution L_END_PGM:
@@ -1598,11 +1402,7 @@ function get_hwreg_size_bytes end function get_wave_size2(s_reg) -#if ASIC_FAMILY < CHIP_GFX12 s_getreg_b32 s_reg, hwreg(HW_REG_IB_STS2,SQ_WAVE_IB_STS2_WAVE64_SHIFT,SQ_WAVE_IB_STS2_WAVE64_SIZE) -#else - s_getreg_b32 s_reg, hwreg(HW_REG_WAVE_STATUS,SQ_WAVE_STATUS_WAVE64_SHIFT,SQ_WAVE_STATUS_WAVE64_SIZE) -#endif s_lshl_b32 s_reg, s_reg, S_WAVE_SIZE end
drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm new file +1126 -0
1,126 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 16/138 drm/amdkfd: Ensure consistent barrier state saved in gfx12 trap handler
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lancelot SIX <[email protected]>
[ Upstream commit d584198a6fe4c51f4aa88ad72f258f8961a0f11c ]
It is possible for some waves in a workgroup to finish their save sequence before the group leader has had time to capture the workgroup barrier state. When this happens, having those waves exit do impact the barrier state. As a consequence, the state captured by the group leader is invalid, and is eventually incorrectly restored.
This patch proposes to have all waves in a workgroup wait for each other at the end of their save sequence (just before calling s_endpgm_saved).
--- drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h | 3 ++- drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h +2 -1
@@ -4117,7 +4117,8 @@ static const uint32_t cwsr_trap_gfx12_hex[] = {0x0000ffff ,0x8bfe7e7e ,0x8bea6a6a ,0xb97af804 ,0xbe804ec2 ,0xbf94fffe , -0xbe804a6c ,0xbfb10000 , +0xbe804a6c ,0xbe804ec2 , +0xbf94fffe ,0xbfb10000 ,0xbf9f0000 ,0xbf9f0000 ,0xbf9f0000 ,0xbf9f0000 , 0xbf9f0000, 0x00000000,
drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm +4 -0
@@ -1049,6 +1049,10 @@ L_SKIP_BARRIER_RESTORE: s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution L_END_PGM: + // Make sure that no wave of the workgroup can exit the trap handler + // before the workgroup barrier state is saved. + s_barrier_signal -2 + s_barrier_wait -2 s_endpgm_saved end
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 17/138 tracing: Switch trace.c code over to use guard()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
[ Upstream commit d33b10c0c73adca00f72bf4a153a07b7f5f34715 ]
There are several functions in trace.c that have "goto out;" or equivalent on error in order to release locks or free values that were allocated. This can be error prone or just simply make the code more complex.
Switch every location that ends with unlocking a mutex or freeing on error over to using the guard(mutex)() and __free() infrastructure to let the compiler worry about releasing locks. This makes the code easier to read and understand.
There's one place that should probably return an error but instead return
0. This does not change the return as the only changes are to do the conversion without changing the logic. Fixing that location will have to come later.
Stable-dep-of: 60b8f711143d ("tracing: Have the error of __tracing_resize_ring_buffer() passed to user")
--- kernel/trace/trace.c | 266 +++++++++++++++---------------------------- 1 file changed, 94 insertions(+), 172 deletions(-)
kernel/trace/trace.c +94 -172
@@ -26,6 +26,7 @@#include <linux/hardirq.h> #include <linux/linkage.h> #include <linux/uaccess.h> +#include <linux/cleanup.h> #include <linux/vmalloc.h> #include <linux/ftrace.h> #include <linux/module.h>
@@ -535,19 +536,16 @@ LIST_HEAD(ftrace_trace_arrays);int trace_array_get (struct trace_array *this_tr) {struct trace_array *tr; -int ret = -ENODEV ; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock);list_for_each_entry (tr, &ftrace_trace_arrays, list) {if (tr == this_tr) { tr->ref++; - ret =0 ; -break ; +return 0 ; } } -mutex_unlock (&trace_types_lock); -return ret; +return -ENODEV ; }static void __trace_array_put (struct trace_array *this_tr)
@@ -1443,22 +1441,20 @@ EXPORT_SYMBOL_GPL(tracing_snapshot_alloc);int tracing_snapshot_cond_enable (struct trace_array *tr,void *cond_data,cond_update_fn_t update) { -struct cond_snapshot *cond_snapshot; -int ret =0 ; + struct cond_snapshot *cond_snapshot __free(kfree) = +kzalloc (sizeof (*cond_snapshot),GFP_KERNEL ); +int ret; - cond_snapshot =kzalloc (sizeof (*cond_snapshot),GFP_KERNEL );if (!cond_snapshot)return -ENOMEM ; cond_snapshot->cond_data = cond_data; cond_snapshot->update = update; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock); -if (tr->current_trace->use_max_tr) { - ret = -EBUSY ; - goto fail_unlock; - } +if (tr->current_trace->use_max_tr) +return -EBUSY ;/* * The cond_snapshot can only change to NULL without the
@@ -1468,29 +1464,20 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data,* do safely with only holding the trace_types_lock and not * having to take the max_lock. */ -if (tr->cond_snapshot) { - ret = -EBUSY ; - goto fail_unlock; - } +if (tr->cond_snapshot) +return -EBUSY ; ret =tracing_arm_snapshot_locked (tr);if (ret) - goto fail_unlock; +return ret;local_irq_disable ();arch_spin_lock (&tr->max_lock); - tr->cond_snapshot = cond_snapshot; + tr->cond_snapshot =no_free_ptr (cond_snapshot);arch_spin_unlock (&tr->max_lock);local_irq_enable (); -mutex_unlock (&trace_types_lock); - -return ret; - - fail_unlock: -mutex_unlock (&trace_types_lock); -kfree (cond_snapshot); -return ret; +return 0 ; }EXPORT_SYMBOL_GPL (tracing_snapshot_cond_enable);
@@ -2203,10 +2190,10 @@ static __init int init_trace_selftests(void) selftests_can_run = true; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock);if (list_empty (&postponed_selftests)) - goto out; +return 0 ;pr_info ("Running postponed tracer tests:\n" );
@@ -2235,9 +2222,6 @@ static __init int init_trace_selftests(void) } tracing_selftest_running = false; - out: -mutex_unlock (&trace_types_lock); -return 0 ; }core_initcall (init_trace_selftests);
@@ -2807,7 +2791,7 @@ int tracepoint_printk_sysctl(const struct ctl_table *table, int write,int save_tracepoint_printk;int ret; -mutex_lock (&tracepoint_printk_mutex); +guard (mutex)(&tracepoint_printk_mutex); save_tracepoint_printk = tracepoint_printk; ret =proc_dointvec (table, write, buffer, lenp, ppos);
@@ -2820,16 +2804,13 @@ int tracepoint_printk_sysctl(const struct ctl_table *table, int write, tracepoint_printk =0 ;if (save_tracepoint_printk == tracepoint_printk) - goto out; +return ret;if (tracepoint_printk)static_key_enable (&tracepoint_printk_key.key);else static_key_disable (&tracepoint_printk_key.key); - out: -mutex_unlock (&tracepoint_printk_mutex); -return ret; }
@@ -5127,7 +5108,8 @@ static int tracing_trace_options_show(struct seq_file *m, void *v)u32 tracer_flags;int i; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock); + tracer_flags = tr->current_trace->flags->val; trace_opts = tr->current_trace->flags->opts;
@@ -5144,7 +5126,6 @@ static int tracing_trace_options_show(struct seq_file *m, void *v)else seq_printf (m,"no%s\n" , trace_opts[i].name); } -mutex_unlock (&trace_types_lock);return 0 ; }
@@ -5809,7 +5790,7 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start,return ; } -mutex_lock (&trace_eval_mutex); +guard (mutex)(&trace_eval_mutex);if (!trace_eval_maps) trace_eval_maps = map_array;
@@ -5833,8 +5814,6 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start, map_array++; }memset (map_array,0 ,sizeof (*map_array)); - -mutex_unlock (&trace_eval_mutex); }static void trace_create_eval_file (struct dentry *d_tracer)
@@ -5998,23 +5977,18 @@ ssize_t tracing_resize_ring_buffer(struct trace_array *tr, {int ret; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock);if (cpu_id !=RING_BUFFER_ALL_CPUS ) {/* make sure, this cpu is enabled in the mask */ -if (!cpumask_test_cpu (cpu_id, tracing_buffer_mask)) { - ret = -EINVAL ; - goto out; - } +if (!cpumask_test_cpu (cpu_id, tracing_buffer_mask)) +return -EINVAL ; } ret =__tracing_resize_ring_buffer (tr, size, cpu_id);if (ret <0 ) ret = -ENOMEM ; -out: -mutex_unlock (&trace_types_lock); -return ret; }
@@ -6106,9 +6080,9 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)#ifdef CONFIG_TRACER_MAX_TRACE bool had_max_tr;#endif -int ret =0 ; +int ret; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock);update_last_data (tr);
@@ -6116,7 +6090,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) ret =__tracing_resize_ring_buffer (tr, trace_buf_size,RING_BUFFER_ALL_CPUS );if (ret <0 ) - goto out; +return ret; ret =0 ; }
@@ -6124,12 +6098,11 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)if (strcmp (t->name, buf) ==0 )break ; } -if (!t) { - ret = -EINVAL ; - goto out; - } +if (!t) +return -EINVAL ; +if (t == tr->current_trace) - goto out; +return 0 ;#ifdef CONFIG_TRACER_SNAPSHOT if (t->use_max_tr) {
@@ -6140,27 +6113,23 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)arch_spin_unlock (&tr->max_lock);local_irq_enable ();if (ret) - goto out; + return ret; }#endif /* Some tracers won't work on kernel command line */ if (system_state <SYSTEM_RUNNING && t->noboot) {pr_warn ("Tracer '%s' is not allowed on command line, ignored\n" , t->name); - goto out; +return 0 ; }/* Some tracers are only allowed for the top level buffer */ -if (!trace_ok_for_array (t, tr)) { - ret = -EINVAL ; - goto out; - } +if (!trace_ok_for_array (t, tr)) +return -EINVAL ;/* If trace pipe files are being read, we can't change the tracer */ -if (tr->trace_ref) { - ret = -EBUSY ; - goto out; - } +if (tr->trace_ref) +return -EBUSY ;trace_branch_disable ();
@@ -6191,7 +6160,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)if (!had_max_tr && t->use_max_tr) { ret =tracing_arm_snapshot_locked (tr);if (ret) - goto out; +return ret; }#else tr->current_trace = &nop_trace;
@@ -6204,17 +6173,15 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)if (t->use_max_tr)tracing_disarm_snapshot (tr);#endif - goto out; +return ret; } } tr->current_trace = t; tr->current_trace->enabled++;trace_branch_enable (tr); - out: -mutex_unlock (&trace_types_lock); -return ret; +return 0 ; } static ssize_t
@@ -6292,22 +6259,18 @@ tracing_thresh_write(struct file *filp, const char __user *ubuf,struct trace_array *tr = filp->private_data;int ret; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock); ret =tracing_nsecs_write (&tracing_thresh, ubuf, cnt, ppos);if (ret <0 ) - goto out; +return ret;if (tr->current_trace->update_thresh) { ret = tr->current_trace->update_thresh (tr);if (ret <0 ) - goto out; +return ret; } - ret = cnt; -out: -mutex_unlock (&trace_types_lock); - -return ret; +return cnt; }#ifdef CONFIG_TRACER_MAX_TRACE
@@ -6526,31 +6489,29 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,* This is just a matter of traces coherency, the ring buffer itself * is protected. */ -mutex_lock (&iter->mutex); +guard (mutex)(&iter->mutex);/* return any leftover data */ sret =trace_seq_to_user (&iter->seq, ubuf, cnt);if (sret != -EBUSY ) - goto out; +return sret;trace_seq_init (&iter->seq);if (iter->trace->read) { sret = iter->trace->read (iter, filp, ubuf, cnt, ppos);if (sret) - goto out; +return sret; } waitagain: sret =tracing_wait_pipe (filp);if (sret <=0 ) - goto out; +return sret;/* stop when tracing is finished */ -if (trace_empty (iter)) { - sret =0 ; - goto out; - } +if (trace_empty (iter)) +return 0 ;if (cnt >=TRACE_SEQ_BUFFER_SIZE ) cnt =TRACE_SEQ_BUFFER_SIZE -1 ;
@@ -6614,9 +6575,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,if (sret == -EBUSY ) goto waitagain; -out: -mutex_unlock (&iter->mutex); -return sret; }
@@ -7208,25 +7166,19 @@ u64 tracing_event_time_stamp(struct trace_buffer *buffer, struct ring_buffer_eve*/ int tracing_set_filter_buffering (struct trace_array *tr,bool set) { -int ret =0 ; - -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock);if (set && tr->no_filter_buffering_ref++) - goto out; +return 0 ;if (!set) { -if (WARN_ON_ONCE (!tr->no_filter_buffering_ref)) { - ret = -EINVAL ; - goto out; - } +if (WARN_ON_ONCE (!tr->no_filter_buffering_ref)) +return -EINVAL ; --tr->no_filter_buffering_ref; } - out: -mutex_unlock (&trace_types_lock); -return ret; +return 0 ; }struct ftrace_buffer_info {
@@ -7302,12 +7254,10 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,if (ret)return ret; -mutex_lock (&trace_types_lock); +guard (mutex)(&trace_types_lock); -if (tr->current_trace->use_max_tr) { - ret = -EBUSY ; - goto out; - } +if (tr->current_trace->use_max_tr) +return -EBUSY ;local_irq_disable ();arch_spin_lock (&tr->max_lock);
@@ -7316,24 +7266,20 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,arch_spin_unlock (&tr->max_lock);local_irq_enable ();if (ret) - goto out; +return ret;switch (val) {case 0 : -if (iter->cpu_file !=RING_BUFFER_ALL_CPUS ) { - ret = -EINVAL ; -break ; - } +if (iter->cpu_file !=RING_BUFFER_ALL_CPUS ) +return -EINVAL ;if (tr->allocated_snapshot)free_snapshot (tr);break ;case 1 :/* Only allow per-cpu swap if the ring buffer supports it */ #ifndef CONFIG_RING_BUFFER_ALLOW_SWAP -if (iter->cpu_file !=RING_BUFFER_ALL_CPUS ) { - ret = -EINVAL ; -break ; - } +if (iter->cpu_file !=RING_BUFFER_ALL_CPUS ) +return -EINVAL ;#endif if (tr->allocated_snapshot) ret = resize_buffer_duplicate_size(&tr->max_buffer,
@@ -7341,7 +7287,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, ret =tracing_arm_snapshot_locked (tr);if (ret) -break ; +return ret;/* Now, we're going to swap */ if (iter->cpu_file ==RING_BUFFER_ALL_CPUS ) {
@@ -7368,8 +7314,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, *ppos += cnt; ret = cnt; } -out: -mutex_unlock (&trace_types_lock); +return ret; }
@@ -7755,12 +7700,11 @@ void tracing_log_err(struct trace_array *tr, len +=sizeof (CMD_PREFIX ) +2 *sizeof ("\n" ) +strlen (cmd) +1 ; -mutex_lock (&tracing_err_log_lock); +guard (mutex)(&tracing_err_log_lock); + err =get_tracing_log_err (tr, len); -if (PTR_ERR (err) == -ENOMEM ) { -mutex_unlock (&tracing_err_log_lock); +if (PTR_ERR (err) == -ENOMEM )return ; - }snprintf (err->loc,TRACING_LOG_LOC_MAX ,"%s: error: " , loc);snprintf (err->cmd, len,"\n" CMD_PREFIX "%s\n" , cmd);
@@ -7771,7 +7715,6 @@ void tracing_log_err(struct trace_array *tr, err->info.ts =local_clock ();list_add_tail (&err->list, &tr->err_log); -mutex_unlock (&tracing_err_log_lock); }static void clear_tracing_err_log (struct trace_array *tr)
@@ -9519,20 +9462,17 @@ static int instance_mkdir(const char *name)struct trace_array *tr;int ret; -mutex_lock (&event_mutex); -mutex_lock (&trace_types_lock); +guard (mutex)(&event_mutex); +guard (mutex)(&trace_types_lock); ret = -EEXIST ;if (trace_array_find (name)) - goto out_unlock; +return -EEXIST ; tr =trace_array_create (name); ret =PTR_ERR_OR_ZERO (tr); -out_unlock: -mutex_unlock (&trace_types_lock); -mutex_unlock (&event_mutex);return ret; }
@@ -9582,24 +9522,23 @@ struct trace_array *trace_array_get_by_name(const char *name, const char *system {struct trace_array *tr; -mutex_lock (&event_mutex); -mutex_lock (&trace_types_lock); +guard (mutex)(&event_mutex); +guard (mutex)(&trace_types_lock);list_for_each_entry (tr, &ftrace_trace_arrays, list) { -if (tr->name &&strcmp (tr->name, name) ==0 ) - goto out_unlock; +if (tr->name &&strcmp (tr->name, name) ==0 ) { + tr->ref++; +return tr; + } } tr =trace_array_create_systems (name, systems,0 ,0 );if (IS_ERR (tr)) tr =NULL ; -out_unlock: -if (tr) +else tr->ref++; -mutex_unlock (&trace_types_lock); -mutex_unlock (&event_mutex);return tr; }EXPORT_SYMBOL_GPL (trace_array_get_by_name);
@@ -9650,48 +9589,36 @@ static int __remove_instance(struct trace_array *tr)int trace_array_destroy (struct trace_array *this_tr) {struct trace_array *tr; -int ret;if (!this_tr)return -EINVAL ; -mutex_lock (&event_mutex); -mutex_lock (&trace_types_lock); +guard (mutex)(&event_mutex); +guard (mutex)(&trace_types_lock); - ret = -ENODEV ;/* Making sure trace array exists before destroying it. */ list_for_each_entry (tr, &ftrace_trace_arrays, list) { -if (tr == this_tr) { - ret =__remove_instance (tr); -break ; - } +if (tr == this_tr) +return __remove_instance (tr); } -mutex_unlock (&trace_types_lock); -mutex_unlock (&event_mutex); - -return ret; +return -ENODEV ; }EXPORT_SYMBOL_GPL (trace_array_destroy);static int instance_rmdir (const char *name) {struct trace_array *tr; -int ret; -mutex_lock (&event_mutex); -mutex_lock (&trace_types_lock); +guard (mutex)(&event_mutex); +guard (mutex)(&trace_types_lock); - ret = -ENODEV ; tr =trace_array_find (name); -if (tr) - ret =__remove_instance (tr); - -mutex_unlock (&trace_types_lock); -mutex_unlock (&event_mutex); +if (!tr) +return -ENODEV ; -return ret; +return __remove_instance (tr); }static __init void create_trace_instances (struct dentry *d_tracer)
@@ -9704,19 +9631,16 @@ static __init void create_trace_instances(struct dentry *d_tracer)if (MEM_FAIL (!trace_instance_dir,"Failed to create instances directory\n" ))return ; -mutex_lock (&event_mutex); -mutex_lock (&trace_types_lock); +guard (mutex)(&event_mutex); +guard (mutex)(&trace_types_lock);list_for_each_entry (tr, &ftrace_trace_arrays, list) {if (!tr->name)continue ;if (MEM_FAIL (trace_array_create_dir (tr) <0 ,"Failed to create instance directory\n" )) -break ; +return ; } - -mutex_unlock (&trace_types_lock); -mutex_unlock (&event_mutex); } static void
@@ -9930,7 +9854,7 @@ static void trace_module_remove_evals(struct module *mod)if (!mod->num_trace_evals)return ; -mutex_lock (&trace_eval_mutex); +guard (mutex)(&trace_eval_mutex); map = trace_eval_maps;
@@ -9942,12 +9866,10 @@ static void trace_module_remove_evals(struct module *mod) map = map->tail.next; }if (!map) - goto out; +return ; *last =trace_eval_jmp_to_tail (map)->tail.next;kfree (map); - out: -mutex_unlock (&trace_eval_mutex); }#else static inline void trace_module_remove_evals (struct module *mod) { }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 18/138 tracing: Have the error of __tracing_resize_ring_buffer() passed to user
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
[ Upstream commit 60b8f711143de7cd9c0f55be0fe7eb94b19eb5c7 ]
Currently if __tracing_resize_ring_buffer() returns an error, the tracing_resize_ringbuffer() returns -ENOMEM. But it may not be a memory issue that caused the function to fail. If the ring buffer is memory mapped, then the resizing of the ring buffer will be disabled. But if the user tries to resize the buffer, it will get an -ENOMEM returned, which is confusing because there is plenty of memory. The actual error returned was -EBUSY, which would make much more sense to the user.
--- kernel/trace/trace.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
kernel/trace/trace.c +1 -7
@@ -5975,8 +5975,6 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,ssize_t tracing_resize_ring_buffer (struct trace_array *tr,unsigned long size,int cpu_id) { -int ret; -guard (mutex)(&trace_types_lock);if (cpu_id !=RING_BUFFER_ALL_CPUS ) {
@@ -5985,11 +5983,7 @@ ssize_t tracing_resize_ring_buffer(struct trace_array *tr,return -EINVAL ; } - ret =__tracing_resize_ring_buffer (tr, size, cpu_id); -if (ret <0 ) - ret = -ENOMEM ; - -return ret; +return __tracing_resize_ring_buffer (tr, size, cpu_id); }static void update_last_data (struct trace_array *tr)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 19/138 USB: gadget: f_midi: f_midi_complete to call queue_work
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jill Donahue <[email protected]>
[ Upstream commit 4ab37fcb42832cdd3e9d5e50653285ca84d6686f ]
When using USB MIDI, a lock is attempted to be acquired twice through a re-entrant call to f_midi_transmit, causing a deadlock.
Fix it by using queue_work() to schedule the inner f_midi_transmit() via a high priority work queue from the completion handler.
--- drivers/usb/gadget/function/f_midi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/function/f_midi.c +1 -1
@@ -283,7 +283,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)/* Our transmit completed. See if there's more to go. * f_midi_transmit eats req, don't queue it again. */ req->length =0 ; -f_midi_transmit (midi); +queue_work (system_highpri_wq, &midi->work);return ; }break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 2/138 btrfs: use btrfs_inode in extent_writepage()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit 011a9a1f244656cc3cbde47edba2b250f794d440 ]
As extent_writepage() is internal helper we should use our inode type, so change it from struct inode.
Stable-dep-of: 8bf334beb349 ("btrfs: fix double accounting race when extent_writepage_io() failed")
--- fs/btrfs/extent_io.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/btrfs/extent_io.c +7 -7
@@ -1467,15 +1467,15 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,*/ static int extent_writepage (struct folio *folio,struct btrfs_bio_ctrl *bio_ctrl) { -struct inode *inode = folio->mapping->host; -struct btrfs_fs_info *fs_info =inode_to_fs_info (inode); +struct btrfs_inode *inode =BTRFS_I (folio->mapping->host); +struct btrfs_fs_info *fs_info = inode->root->fs_info;const u64 page_start =folio_pos (folio);int ret;size_t pg_offset; -loff_t i_size =i_size_read (inode); +loff_t i_size =i_size_read (&inode->vfs_inode);unsigned long end_index = i_size >>PAGE_SHIFT ; -trace_extent_writepage (folio, inode, bio_ctrl->wbc); +trace_extent_writepage (folio, &inode->vfs_inode, bio_ctrl->wbc);WARN_ON (!folio_test_locked (folio));
@@ -1499,13 +1499,13 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrlif (ret <0 ) goto done; - ret =writepage_delalloc (BTRFS_I (inode), folio, bio_ctrl); + ret =writepage_delalloc (inode, folio, bio_ctrl);if (ret ==1 )return 0 ;if (ret) goto done; - ret =extent_writepage_io (BTRFS_I (inode), folio,folio_pos (folio), + ret =extent_writepage_io (inode, folio,folio_pos (folio),PAGE_SIZE , bio_ctrl, i_size);if (ret ==1 )return 0 ;
@@ -1514,7 +1514,7 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl done:if (ret) { -btrfs_mark_ordered_io_finished (BTRFS_I (inode), folio, +btrfs_mark_ordered_io_finished (inode, folio, page_start,PAGE_SIZE , !ret);mapping_set_error (folio->mapping, ret); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 20/138 ASoC: rockchip: i2s-tdm: fix shift config for SND_SOC_DAIFMT_DSP_[AB]
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
[ Upstream commit 6b24e67b4056ba83b1e95e005b7e50fdb1cc6cf4 ]
Commit 2f45a4e289779 ("ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B") applied a partial change to fix the configuration for DSP A and DSP B formats.
The shift control also needs updating to set the correct offset for frame data compared to LRCK. Set the correct values.
--- sound/soc/rockchip/rockchip_i2s_tdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/rockchip/rockchip_i2s_tdm.c +2 -2
@@ -451,11 +451,11 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,break ;case SND_SOC_DAIFMT_DSP_A : val =I2S_TXCR_TFS_TDM_PCM ; - tdm_val =TDM_SHIFT_CTRL (0 ); + tdm_val =TDM_SHIFT_CTRL (2 );break ;case SND_SOC_DAIFMT_DSP_B : val =I2S_TXCR_TFS_TDM_PCM ; - tdm_val =TDM_SHIFT_CTRL (2 ); + tdm_val =TDM_SHIFT_CTRL (4 );break ;default : ret = -EINVAL ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 21/138 ASoC: SOF: ipc4-topology: Harden loops for looking up ALH copiers
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
[ Upstream commit 6fd60136d256b3b948333ebdb3835f41a95ab7ef ]
Other, non DAI copier widgets could have the same stream name (sname) as the ALH copier and in that case the copier->data is NULL, no alh_data is attached, which could lead to NULL pointer dereference.
We could check for this NULL pointer in sof_ipc4_prepare_copier_module() and avoid the crash, but a similar loop in sof_ipc4_widget_setup_comp_dai() will miscalculate the ALH device count, causing broken audio.
The correct fix is to harden the matching logic by making sure that the
1. widget is a DAI widget - so dai = w->private is valid
2. the dai (and thus the copier) is ALH copier
--- sound/soc/sof/ipc4-topology.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
sound/soc/sof/ipc4-topology.c +10 -2
@@ -765,10 +765,16 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) }list_for_each_entry (w, &sdev->widget_list, list) { -if (w->widget->sname && +struct snd_sof_dai *alh_dai; + +if (!WIDGET_IS_DAI (w->id) || !w->widget->sname ||strcmp (w->widget->sname, swidget->widget->sname))continue ; + alh_dai = w->private; +if (alh_dai->type !=SOF_DAI_INTEL_ALH ) +continue ; + blob->alh_cfg.device_count++; }
@@ -2061,11 +2067,13 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,list_for_each_entry (w, &sdev->widget_list, list) {u32 node_type; -if (w->widget->sname && +if (!WIDGET_IS_DAI (w->id) || !w->widget->sname ||strcmp (w->widget->sname, swidget->widget->sname))continue ; dai = w->private; +if (dai->type !=SOF_DAI_INTEL_ALH ) +continue ; alh_copier = (struct sof_ipc4_copier *)dai->private; alh_data = &alh_copier->data; node_type =SOF_IPC4_GET_NODE_TYPE (alh_data->gtw_cfg.node_id);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 3/138 btrfs: fix double accounting race when btrfs_run_delalloc_range() failed
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 72dad8e377afa50435940adfb697e070d3556670 ]
[BUG]
When running btrfs with block size (4K) smaller than page size (64K, aarch64), there is a very high chance to crash the kernel at generic/750, with the following messages:
(before the call traces, there are 3 extra debug messages added)
BTRFS warning (device dm-3): read-write for sector size 4096 with page size 65536 is experimental
BTRFS info (device dm-3): checking UUID tree
hrtimer: interrupt took 5451385 ns
BTRFS error (device dm-3): cow_file_range failed, root=4957 inode=257 start=1605632 len=69632: -28
BTRFS error (device dm-3): run_delalloc_nocow failed, root=4957 inode=257 start=1605632 len=69632: -28
BTRFS error (device dm-3): failed to run delalloc range, root=4957 ino=257 folio=1572864 submit_bitmap=8-15 start=1605632 len=69632: -28
------------[ cut here ]------------
WARNING: CPU: 2 PID: 3020984 at ordered-data.c:360 can_finish_ordered_extent+0x370/0x3b8 [btrfs]
CPU: 2 UID: 0 PID: 3020984 Comm: kworker/u24:1 Tainted: G OE 6.13.0-rc1-custom+ #89
Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs]
pc : can_finish_ordered_extent+0x370/0x3b8 [btrfs]
lr : can_finish_ordered_extent+0x1ec/0x3b8 [btrfs]
Call trace:
can_finish_ordered_extent+0x370/0x3b8 [btrfs] (P)
can_finish_ordered_extent+0x1ec/0x3b8 [btrfs] (L)
btrfs_mark_ordered_io_finished+0x130/0x2b8 [btrfs]
extent_writepage+0x10c/0x3b8 [btrfs]
extent_write_cache_pages+0x21c/0x4e8 [btrfs]
btrfs_writepages+0x94/0x160 [btrfs]
do_writepages+0x74/0x190
filemap_fdatawrite_wbc+0x74/0xa0
start_delalloc_inodes+0x17c/0x3b0 [btrfs]
btrfs_start_delalloc_roots+0x17c/0x288 [btrfs]
shrink_delalloc+0x11c/0x280 [btrfs]
flush_space+0x288/0x328 [btrfs]
btrfs_async_reclaim_data_space+0x180/0x228 [btrfs]
process_one_work+0x228/0x680
worker_thread+0x1bc/0x360
kthread+0x100/0x118
ret_from_fork+0x10/0x20
---[ end trace 0000000000000000 ]---
BTRFS critical (device dm-3): bad ordered extent accounting, root=4957 ino=257 OE offset=1605632 OE len=16384 to_dec=16384 left=0
BTRFS critical (device dm-3): bad ordered extent accounting, root=4957 ino=257 OE offset=1622016 OE len=12288 to_dec=12288 left=0
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
BTRFS critical (device dm-3): bad ordered extent accounting, root=4957 ino=257 OE offset=1634304 OE len=8192 to_dec=4096 left=0
CPU: 1 UID: 0 PID: 3286940 Comm: kworker/u24:3 Tainted: G W OE 6.13.0-rc1-custom+ #89
Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
Workqueue: btrfs_work_helper [btrfs] (btrfs-endio-write)
pstate: 404000c5 (nZcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : process_one_work+0x110/0x680
lr : worker_thread+0x1bc/0x360
Call trace:
process_one_work+0x110/0x680 (P)
worker_thread+0x1bc/0x360 (L)
worker_thread+0x1bc/0x360
kthread+0x100/0x118
ret_from_fork+0x10/0x20
Code: f84086a1 f9000fe1 53041c21 b9003361 (f9400661)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
SMP: failed to stop secondary CPUs 2-3
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: 0x275bb9540000 from 0xffff800080000000
PHYS_OFFSET: 0xffff8fbba0000000
CPU features: 0x100,00000070,00801250,8201720b[CAUSE]
The above warning is triggered immediately after the delalloc range failure, this happens in the following sequence:
- Range [1568K, 1636K) is dirty
1536K 1568K 1600K 1636K 1664K | |/////////|////////| |
Where 1536K, 1600K and 1664K are page boundaries (64K page size)
- Enter extent_writepage() for page 1536K
- Enter run_delalloc_nocow() with locked page 1536K and range [1568K, 1636K)
This is due to the inode having preallocated extents.
- Enter cow_file_range() with locked page 1536K and range [1568K, 1636K)
- btrfs_reserve_extent() only reserved two extents
The main loop of cow_file_range() only reserved two data extents,
Now we have:
1536K 1568K 1600K 1636K 1664K
| |<-->|<--->|/|///////| |
1584K 1596KRange [1568K, 1596K) has an ordered extent reserved.
- btrfs_reserve_extent() failed inside cow_file_range() for file offset 1596K
This is already a bug in our space reservation code, but for now let's focus on the error handling path.
Now cow_file_range() returned -ENOSPC.
- btrfs_run_delalloc_range() do error cleanup <<< ROOT CAUSE Call btrfs_cleanup_ordered_extents() with locked folio 1536K and range [1568K, 1636K)
Function btrfs_cleanup_ordered_extents() normally needs to skip the ranges inside the folio, as it will normally be cleaned up by extent_writepage().
Such split error handling is already problematic in the first place.
What's worse is the folio range skipping itself, which is not taking subpage cases into consideration at all, it will only skip the range if the page start >= the range start.
In our case, the page start < the range start, since for subpage cases we can have delalloc ranges inside the folio but not covering the folio.
So it doesn't skip the page range at all.
This means all the ordered extents, both [1568K, 1584K) and [1584K, 1596K) will be marked as IOERR.
And these two ordered extents have no more pending ios, they are marked finished, and *QUEUED* to be deleted from the io tree.
- extent_writepage() do error cleanup
Call btrfs_mark_ordered_io_finished() for the range [1536K, 1600K).
Although ranges [1568K, 1584K) and [1584K, 1596K) are finished, the deletion from io tree is async, it may or may not happen at this time.
If the ranges have not yet been removed, we will do double cleaning on those ranges, triggering the above ordered extent warnings.
In theory there are other bugs, like the cleanup in extent_writepage() can cause double accounting on ranges that are submitted asynchronously (compression for example).
But that's much harder to trigger because normally we do not mix regular and compression delalloc ranges.
[FIX]
The folio range split is already buggy and not subpage compatible, it was introduced a long time ago where subpage support was not even considered.
So instead of splitting the ordered extents cleanup into the folio range and out of folio range, do all the cleanup inside writepage_delalloc().
- Pass @NULL as locked_folio for btrfs_cleanup_ordered_extents() in btrfs_run_delalloc_range()
- Skip the btrfs_cleanup_ordered_extents() if writepage_delalloc() failed
So all ordered extents are only cleaned up by
btrfs_run_delalloc_range().
- Handle the ranges that already have ordered extents allocated If part of the folio already has ordered extent allocated, and btrfs_run_delalloc_range() failed, we also need to cleanup that range.
Now we have a concentrated error handling for ordered extents during btrfs_run_delalloc_range().
Stable-dep-of: 8bf334beb349 ("btrfs: fix double accounting race when extent_writepage_io() failed")
--- fs/btrfs/extent_io.c | 59 +++++++++++++++++++++++++++++++++++--------- fs/btrfs/inode.c | 3 +-- 2 files changed, 49 insertions(+), 13 deletions(-)
fs/btrfs/extent_io.c +48 -11
@@ -1145,14 +1145,19 @@ static bool find_next_delalloc_bitmap(struct folio *folio, }/* -* helper for extent_writepage(), doing all of the delayed allocation setup. +* Do all of the delayed allocation setup. * -* This returns 1 if btrfs_run_delalloc_range function did all the work required -* to write the page (copy into inline extent). In this case the IO has -* been started and the page is already unlocked. +* Return >0 if all the dirty blocks are submitted async (compression) or inlined. +* The @folio should no longer be touched (treat it as already unlocked). * -* This returns 0 if all went well (page still locked) -* This returns < 0 if there were errors (page still locked) +* Return 0 if there is still dirty block that needs to be submitted through +* extent_writepage_io(). +* bio_ctrl->submit_bitmap will indicate which blocks of the folio should be +* submitted, and @folio is still kept locked. +* +* Return <0 if there is any error hit. +* Any allocated ordered extent range covering this folio will be marked +* finished (IOERR), and @folio is still kept locked. */ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode, struct folio *folio,
@@ -1170,6 +1175,16 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,* last delalloc end. */ u64 last_delalloc_end =0 ; +/* +* The range end (exclusive) of the last successfully finished delalloc +* range. +* Any range covered by ordered extent must either be manually marked +* finished (error handling), or has IO submitted (and finish the +* ordered extent normally). +* +* This records the end of ordered extent cleanup if we hit an error. +*/ +u64 last_finished_delalloc_end = page_start;u64 delalloc_start = page_start;u64 delalloc_end = page_end;u64 delalloc_to_write =0 ;
@@ -1238,11 +1253,19 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode, found_len = last_delalloc_end +1 - found_start;if (ret >=0 ) { +/* +* Some delalloc range may be created by previous folios. +* Thus we still need to clean up this range during error +* handling. +*/ + last_finished_delalloc_end = found_start;/* No errors hit so far, run the current delalloc range. */ ret =btrfs_run_delalloc_range (inode, folio, found_start, found_start + found_len -1 , wbc); +if (ret >=0 ) + last_finished_delalloc_end = found_start + found_len; }else {/* * We've hit an error during previous delalloc range,
@@ -1277,8 +1300,22 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode, delalloc_start = found_start + found_len; } -if (ret <0 ) +/* +* It's possible we had some ordered extents created before we hit +* an error, cleanup non-async successfully created delalloc ranges. +*/ +if (unlikely (ret <0 )) { +unsigned int bitmap_size =min ( + (last_finished_delalloc_end - page_start) >> + fs_info->sectorsize_bits, + fs_info->sectors_per_page); + +for_each_set_bit (bit, &bio_ctrl->submit_bitmap, bitmap_size) +btrfs_mark_ordered_io_finished (inode, folio, + page_start + (bit << fs_info->sectorsize_bits), + fs_info->sectorsize, false);return ret; + } out:if (last_delalloc_end) delalloc_end = last_delalloc_end;
@@ -1512,13 +1549,13 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl bio_ctrl->wbc->nr_to_write--; -done: -if (ret) { +if (ret)btrfs_mark_ordered_io_finished (inode, folio, page_start,PAGE_SIZE , !ret); -mapping_set_error (folio->mapping, ret); - } +done: +if (ret <0 ) +mapping_set_error (folio->mapping, ret);/* * Only unlock ranges that are submitted. As there can be some async * submitted ranges inside the folio.
fs/btrfs/inode.c +1 -2
@@ -2385,8 +2385,7 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct folio *locked_fol out:if (ret <0 ) -btrfs_cleanup_ordered_extents (inode, locked_folio, start, - end - start +1 ); +btrfs_cleanup_ordered_extents (inode,NULL , start, end - start +1 );return ret; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 4/138 btrfs: fix double accounting race when extent_writepage_io() failed
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 8bf334beb3496da3c3fbf3daf3856f7eec70dacc ]
[BUG]
If submit_one_sector() failed inside extent_writepage_io() for sector size < page size cases (e.g. 4K sector size and 64K page size), then we can hit double ordered extent accounting error.
This should be very rare, as submit_one_sector() only fails when we failed to grab the extent map, and such extent map should exist inside the memory and has been pinned.
[CAUSE]
For example we have the following folio layout:
0 4K 32K 48K 60K 64K
|//| |//////| |///|Where |///| is the dirty range we need to writeback. The 3 different dirty ranges are submitted for regular COW.
Now we hit the following sequence:
- submit_one_sector() returned 0 for [0, 4K)
- submit_one_sector() returned 0 for [32K, 48K)
- submit_one_sector() returned error for [60K, 64K)
- btrfs_mark_ordered_io_finished() called for the whole folio This will mark the following ranges as finished:
* [0, 4K)
* [32K, 48K)
Both ranges have their IO already submitted, this cleanup will lead to double accounting.
* [60K, 64K)
That's the correct cleanup.
The only good news is, this error is only theoretical, as the target extent map is always pinned, thus we should directly grab it from memory, other than reading it from the disk.
[FIX]
Instead of calling btrfs_mark_ordered_io_finished() for the whole folio range, which can touch ranges we should not touch, instead move the error handling inside extent_writepage_io().
So that we can cleanup exact sectors that ought to be submitted but failed.
This provides much more accurate cleanup, avoiding the double accounting.
--- fs/btrfs/extent_io.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
fs/btrfs/extent_io.c +24 -13
@@ -1431,6 +1431,7 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,struct btrfs_fs_info *fs_info = inode->root->fs_info;unsigned long range_bitmap =0 ;bool submitted_io = false; +bool error = false;const u64 folio_start =folio_pos (folio);u64 cur;int bit;
@@ -1473,11 +1474,26 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,break ; } ret =submit_one_sector (inode, folio, cur, bio_ctrl, i_size); -if (ret <0 ) - goto out; +if (unlikely (ret <0 )) { +/* +* bio_ctrl may contain a bio crossing several folios. +* Submit it immediately so that the bio has a chance +* to finish normally, other than marked as error. +*/ +submit_one_bio (bio_ctrl); +/* +* Failed to grab the extent map which should be very rare. +* Since there is no bio submitted to finish the ordered +* extent, we have to manually finish this sector. +*/ +btrfs_mark_ordered_io_finished (inode, folio, cur, + fs_info->sectorsize, false); + error = true; +continue ; + } submitted_io = true; } -out: +/* * If we didn't submitted any sector (>= i_size), folio dirty get * cleared but PAGECACHE_TAG_DIRTY is not cleared (only cleared
@@ -1485,8 +1501,11 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,* * Here we set writeback and clear for the range. If the full folio * is no longer dirty then we clear the PAGECACHE_TAG_DIRTY tag. +* +* If we hit any error, the corresponding sector will still be dirty +* thus no need to clear PAGECACHE_TAG_DIRTY. */ -if (!submitted_io) { +if (!submitted_io && !error) {btrfs_folio_set_writeback (fs_info, folio, start, len);btrfs_folio_clear_writeback (fs_info, folio, start, len); }
@@ -1506,7 +1525,6 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl {struct btrfs_inode *inode =BTRFS_I (folio->mapping->host);struct btrfs_fs_info *fs_info = inode->root->fs_info; -const u64 page_start =folio_pos (folio);int ret;size_t pg_offset;loff_t i_size =i_size_read (&inode->vfs_inode);
@@ -1549,10 +1567,6 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl bio_ctrl->wbc->nr_to_write--; -if (ret) -btrfs_mark_ordered_io_finished (inode, folio, - page_start,PAGE_SIZE , !ret); - done:if (ret <0 )mapping_set_error (folio->mapping, ret);
@@ -2332,11 +2346,8 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_fif (ret ==1 ) goto next_page; -if (ret) { -btrfs_mark_ordered_io_finished (BTRFS_I (inode), folio, - cur, cur_len, !ret); +if (ret)mapping_set_error (mapping, ret); - }btrfs_folio_end_lock (fs_info, folio, cur, cur_len);if (ret <0 ) found_error = true;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 5/138 drm/amd/display: update dcn351 used clock offset
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charlene Liu <[email protected]>
[ Upstream commit a1fc2837f4960e84e9375e12292584ad2ae472da ]
[why]
hw register offset delta
Stable-dep-of: f88192d2335b ("drm/amd/display: Correct register address in dcn35")
--- .../gpu/drm/amd/display/dc/clk_mgr/Makefile | 2 +- .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 5 +- .../display/dc/clk_mgr/dcn35/dcn351_clk_mgr.c | 140 ++++++++++++++++++ .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 132 +++++++++++++---- .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h | 4 + .../amd/display/dc/inc/hw/clk_mgr_internal.h | 59 ++++++++ 6 files changed, 308 insertions(+), 34 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn351_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +1 -1
@@ -174,7 +174,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN32) ############################################################################### # DCN35 ############################################################################### -CLK_MGR_DCN35 = dcn35_smu.o dcn35_clk_mgr.o +CLK_MGR_DCN35 = dcn35_smu.o dcn351_clk_mgr.o dcn35_clk_mgr.o AMD_DAL_CLK_MGR_DCN35 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn35/,$(CLK_MGR_DCN35))
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +4 -1
@@ -355,8 +355,11 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pBREAK_TO_DEBUGGER ();return NULL ; } +if (ctx->dce_version ==DCN_VERSION_3_51 ) +dcn351_clk_mgr_construct (ctx, clk_mgr, pp_smu, dccg); +else +dcn35_clk_mgr_construct (ctx, clk_mgr, pp_smu, dccg); -dcn35_clk_mgr_construct (ctx, clk_mgr, pp_smu, dccg);return &clk_mgr->base.base; }break ;
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn351_clk_mgr.c new file +140 -0
140 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +100 -32
185 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h +4 -0
@@ -60,4 +60,8 @@ void dcn35_clk_mgr_construct(struct dc_context *ctx,void dcn35_clk_mgr_destroy (struct clk_mgr_internal *clk_mgr_int); +void dcn351_clk_mgr_construct (struct dc_context *ctx, +struct clk_mgr_dcn35 *clk_mgr, +struct pp_smu_funcs *pp_smu, +struct dccg *dccg);#endif //__DCN35_CLK_MGR_H__
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +59 -0
82 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 6/138 drm/amd/display: Correct register address in dcn35
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: loanchen <[email protected]>
[ Upstream commit f88192d2335b5a911fcfa09338cc00624571ec5e ]
[Why]
the offset address of mmCLK5_spll_field_8 was incorrect for dcn35 which causes SSC not to be enabled.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +1 -1
@@ -89,7 +89,7 @@#define mmCLK1_CLK4_ALLOW_DS 0x16EA8#define mmCLK1_CLK5_ALLOW_DS 0x16EB1 -#define mmCLK5_spll_field_8 0x1B04B +#define mmCLK5_spll_field_8 0x1B24B#define mmDENTIST_DISPCLK_CNTL 0x0124#define regDENTIST_DISPCLK_CNTL 0x0064#define regDENTIST_DISPCLK_CNTL_BASE_IDX 1
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 7/138 Bluetooth: qca: Update firmware-name to support board specific nvm
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Jiang <[email protected]>
[ Upstream commit a4c5a468c6329bde7dfd46bacff2cbf5f8a8152e ]
Different connectivity boards may be attached to the same platform. For example, QCA6698-based boards can support either a two-antenna or three-antenna solution, both of which work on the sa8775p-ride platform. Due to differences in connectivity boards and variations in RF performance from different foundries, different NVM configurations are used based on the board ID.
Therefore, in the firmware-name property, if the NVM file has an extension, the NVM file will be used. Otherwise, the system will first try the .bNN (board ID) file, and if that fails, it will fall back to the .bin file.
Possible configurations:
firmware-name = "QCA6698/hpnv21";
firmware-name = "QCA6698/hpnv21.bin";
Stable-dep-of: a2fad248947d ("Bluetooth: qca: Fix poor RF performance for WCN6855")
--- drivers/bluetooth/btqca.c | 113 ++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 28 deletions(-)
drivers/bluetooth/btqca.c +85 -28
@@ -272,6 +272,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) }EXPORT_SYMBOL_GPL (qca_send_pre_shutdown_cmd); +static bool qca_filename_has_extension (const char *filename) +{ +const char *suffix =strrchr (filename,'.' ); + +/* File extensions require a dot, but not as the first or last character */ +if (!suffix || suffix == filename || *(suffix +1 ) =='\0' ) +return 0 ; + +/* Avoid matching directories with names that look like files with extensions */ +return !strchr (suffix,'/' ); +} + +static bool qca_get_alt_nvm_file (char *filename,size_t max_size) +{ +char fwname[64 ]; +const char *suffix; + +/* nvm file name has an extension, replace with .bin */ +if (qca_filename_has_extension (filename)) { + suffix =strrchr (filename,'.' ); +strscpy (fwname, filename, suffix - filename +1 ); +snprintf (fwname + (suffix - filename), +sizeof (fwname) - (suffix - filename),".bin" ); +/* If nvm file is already the default one, return false to skip the retry. */ +if (strcmp (fwname, filename) ==0 ) +return false; + +snprintf (filename, max_size,"%s" , fwname); +return true; + } +return false; +} + static int qca_tlv_check_data(struct hci_dev *hdev, struct qca_fw_config *config, u8 *fw_data, size_t fw_size,
@@ -564,6 +597,19 @@ static int qca_download_firmware(struct hci_dev *hdev, config->fwname, ret);return ret; } + } +/* If the board-specific file is missing, try loading the default +* one, unless that was attempted already. +*/ +else if (config->type ==TLV_TYPE_NVM && +qca_get_alt_nvm_file (config->fwname,sizeof (config->fwname))) { +bt_dev_info (hdev,"QCA Downloading %s" , config->fwname); + ret =request_firmware (&fw, config->fwname, &hdev->dev); +if (ret) { +bt_dev_err (hdev,"QCA Failed to request file: %s (%d)" , + config->fwname, ret); +return ret; + } }else {bt_dev_err (hdev,"QCA Failed to request file: %s (%d)" , config->fwname, ret);
@@ -700,34 +746,38 @@ static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *coreturn 0 ; } -static void qca_generate_hsp_nvm_name (char *fwname,size_t max_size, +static void qca_get_nvm_name_by_board (char *fwname,size_t max_size, +const char *stem,enum qca_btsoc_type soc_type,struct qca_btsoc_version ver,u8 rom_ver,u16 bid) {const char *variant; +const char *prefix; -/* hsp gf chip */ -if ((le32_to_cpu (ver.soc_id) &QCA_HSP_GF_SOC_MASK ) ==QCA_HSP_GF_SOC_ID ) - variant ="g" ; -else - variant ="" ; +/* Set the default value to variant and prefix */ + variant ="" ; + prefix ="b" ; -if (bid ==0x0 ) -snprintf (fwname, max_size,"qca/hpnv%02x%s.bin" , rom_ver, variant); -else -snprintf (fwname, max_size,"qca/hpnv%02x%s.%x" , rom_ver, variant, bid); -} +if (soc_type ==QCA_QCA2066 ) + prefix ="" ; -static inline void qca_get_nvm_name_generic (struct qca_fw_config *cfg, -const char *stem,u8 rom_ver,u16 bid) -{ -if (bid ==0x0 ) -snprintf (cfg->fwname,sizeof (cfg->fwname),"qca/%snv%02x.bin" , stem, rom_ver); -else if (bid &0xff00 ) -snprintf (cfg->fwname,sizeof (cfg->fwname), -"qca/%snv%02x.b%x" , stem, rom_ver, bid); -else -snprintf (cfg->fwname,sizeof (cfg->fwname), -"qca/%snv%02x.b%02x" , stem, rom_ver, bid); +if (soc_type ==QCA_WCN6855 || soc_type ==QCA_QCA2066 ) { +/* If the chip is manufactured by GlobalFoundries */ +if ((le32_to_cpu (ver.soc_id) &QCA_HSP_GF_SOC_MASK ) ==QCA_HSP_GF_SOC_ID ) + variant ="g" ; + } + +if (rom_ver !=0 ) { +if (bid ==0x0 || bid ==0xffff ) +snprintf (fwname, max_size,"qca/%s%02x%s.bin" , stem, rom_ver, variant); +else +snprintf (fwname, max_size,"qca/%s%02x%s.%s%02x" , stem, rom_ver, + variant, prefix, bid); + }else { +if (bid ==0x0 || bid ==0xffff ) +snprintf (fwname, max_size,"qca/%s%s.bin" , stem, variant); +else +snprintf (fwname, max_size,"qca/%s%s.%s%02x" , stem, variant, prefix, bid); + } } int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
@@ -816,8 +866,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,/* Download NVM configuration */ config.type =TLV_TYPE_NVM ;if (firmware_name) { -snprintf (config.fwname,sizeof (config.fwname), -"qca/%s" , firmware_name); +/* The firmware name has an extension, use it directly */ +if (qca_filename_has_extension (firmware_name)) { +snprintf (config.fwname,sizeof (config.fwname),"qca/%s" , firmware_name); + }else { +qca_read_fw_board_id (hdev, &boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), + firmware_name, soc_type, ver,0 , boardid); + } }else {switch (soc_type) {case QCA_WCN3990 :
@@ -836,8 +892,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/apnv%02x.bin", rom_ver);break ;case QCA_QCA2066 : -qca_generate_hsp_nvm_name (config.fwname, -sizeof (config.fwname), ver, rom_ver, boardid); +qca_get_nvm_name_by_board (config.fwname, +sizeof (config.fwname),"hpnv" , soc_type, ver, + rom_ver, boardid);break ;case QCA_QCA6390 : snprintf(config.fwname, sizeof(config.fwname),
@@ -852,9 +909,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/hpnv%02x.bin", rom_ver);break ;case QCA_WCN7850 : -qca_get_nvm_name_generic (&config,"hmt" , rom_ver, boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), +"hmtnv" , soc_type, ver, rom_ver, boardid);break ; -default :snprintf (config.fwname,sizeof (config.fwname),"qca/nvm_%08x.bin" , soc_ver);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 8/138 Bluetooth: qca: Fix poor RF performance for WCN6855
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit a2fad248947d702ed3dcb52b8377c1a3ae201e44 ]
For WCN6855, board ID specific NVM needs to be downloaded once board ID is available, but the default NVM is always downloaded currently.
The wrong NVM causes poor RF performance, and effects user experience for several types of laptop with WCN6855 on the market.
Fix by downloading board ID specific NVM if board ID is available.
--- drivers/bluetooth/btqca.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/bluetooth/btqca.c +3 -2
@@ -905,8 +905,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/msnv%02x.bin", rom_ver);break ;case QCA_WCN6855 : -snprintf (config.fwname,sizeof (config.fwname), -"qca/hpnv%02x.bin" , rom_ver); +qca_read_fw_board_id (hdev, &boardid); +qca_get_nvm_name_by_board (config.fwname,sizeof (config.fwname), +"hpnv" , soc_type, ver, rom_ver, boardid);break ;case QCA_WCN7850 : qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 9/138 serial: sh-sci: Move runtime PM enable to sci_probe_single()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 239f11209e5f282e16f5241b99256e25dd0614b6 ]
Relocate the runtime PM enable operation to sci_probe_single(). This change prepares the codebase for upcoming fixes.
While at it, replace the existing logic with a direct call to devm_pm_runtime_enable() and remove sci_cleanup_single(). The devm_pm_runtime_enable() function automatically handles disabling runtime PM during driver removal.
Stable-dep-of: 651dee03696e ("serial: sh-sci: Increment the runtime usage counter for the earlycon device")
--- drivers/tty/serial/sh-sci.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-)
drivers/tty/serial/sh-sci.c +6 -18
@@ -3057,10 +3057,6 @@ static int sci_init_single(struct platform_device *dev, ret =sci_init_clocks (sci_port, &dev->dev);if (ret <0 )return ret; - - port->dev = &dev->dev; - -pm_runtime_enable (&dev->dev); } port->type = p->type;
@@ -3087,11 +3083,6 @@ static int sci_init_single(struct platform_device *dev,return 0 ; } -static void sci_cleanup_single (struct sci_port *port) -{ -pm_runtime_disable (port->port.dev); -} -#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE ) || \ defined(CONFIG_SERIAL_SH_SCI_EARLYCON )static void serial_console_putchar (struct uart_port *port,unsigned char ch)
@@ -3261,8 +3252,6 @@ static void sci_remove(struct platform_device *dev) sci_ports_in_use &= ~BIT (port->port.line);uart_remove_one_port (&sci_uart_driver, &port->port); -sci_cleanup_single (port); -if (port->port.fifosize >1 )device_remove_file (&dev->dev, &dev_attr_rx_fifo_trigger);if (type ==PORT_SCIFA || type ==PORT_SCIFB || type ==PORT_HSCIF )
@@ -3426,6 +3415,11 @@ static int sci_probe_single(struct platform_device *dev,if (ret)return ret; + sciport->port.dev = &dev->dev; + ret =devm_pm_runtime_enable (&dev->dev); +if (ret) +return ret; + sciport->gpios =mctrl_gpio_init (&sciport->port,0 );if (IS_ERR (sciport->gpios))return PTR_ERR (sciport->gpios);
@@ -3439,13 +3433,7 @@ static int sci_probe_single(struct platform_device *dev, sciport->port.flags |=UPF_HARD_FLOW ; } - ret =uart_add_one_port (&sci_uart_driver, &sciport->port); -if (ret) { -sci_cleanup_single (sciport); -return ret; - } - -return 0 ; +return uart_add_one_port (&sci_uart_driver, &sciport->port); }static int sci_probe (struct platform_device *dev)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainercover 6.13.5-rc1 review
This is the start of the stable review cycle for the 6.13.5 release. There are 138 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Feb 2025 14:25:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.13.5-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.13.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.13.5-rc1
Alex Deucher <[email protected]>
drm/amdgpu: bump version for RV/PCO compute fix
Alex Deucher <[email protected]>
drm/amdgpu/gfx9: manually control gfxoff for CS on RV
Kory Maincent <[email protected]>
net: pse-pd: Fix deadlock in current limit functions
Steven Rostedt <[email protected]>
tracing: Fix using ret variable in tracing_set_tracer()
Arnd Bergmann <[email protected]>
drm: select DRM_KMS_HELPER from DRM_GEM_SHMEM_HELPER
Steven Rostedt <[email protected]>
ftrace: Do not add duplicate entries in subops manager ops
Steven Rostedt <[email protected]>
ftrace: Fix accounting of adding subops to a manager ops
Sebastian Andrzej Siewior <[email protected]>
ftrace: Correct preemption accounting for function tracing.
Komal Bajaj <[email protected]>
EDAC/qcom: Correct interrupt enable register configuration
Haoxiang Li <[email protected]>
smb: client: Add check for next_buffer in receive_encrypted_standard()
Marc Zyngier <[email protected]>
irqchip/gic-v3: Fix rk3399 workaround when secure interrupts are enabled
Kan Liang <[email protected]>
perf/x86/intel: Fix event constraints for LNC
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: fix incorrect device in dma_unmap_single
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: use dma_map_resource for sdma address
Niravkumar L Rabara <[email protected]>
mtd: rawnand: cadence: fix error code in cadence_nand_init()
Amit Kumar Mahapatra <[email protected]>
mtd: spi-nor: sst: Fix SST write failure
Ricardo Cañuelo Navarro <[email protected]>
mm,madvise,hugetlb: check for 0-length range after end address adjustment
Christian Brauner <[email protected]>
acct: block access to kernel internal filesystems
Christian Brauner <[email protected]>
acct: perform last write from workqueue
Peter Ujfalusi <[email protected]>
ASoC: SOF: pcm: Clear the susbstream pointer to NULL on close
John Veness <[email protected]>
ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED
Wentao Liang <[email protected]>
ALSA: hda: Add error check for snd_ctl_rename_id() in snd_hda_create_dig_out_ctls()
Nikita Zhandarovich <[email protected]>
ASoC: fsl_micfil: Enable default case in micfil_set_quality()
Peter Ujfalusi <[email protected]>
ASoC: SOF: stream-ipc: Check for cstream nullity in sof_ipc_msg_data()
Joshua Washington <[email protected]>
gve: set xdp redirect target only when it is available
Haoxiang Li <[email protected]>
nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
Hyeonggon Yoo <[email protected]>
mm/zswap: fix inconsistency when zswap_store_page() fails
Paulo Alcantara <[email protected]>
smb: client: fix chmod(2) regression with ATTR_READONLY
Pavel Begunkov <[email protected]>
lib/iov_iter: fix import_iovec_ubuf iovec management
Darrick J. Wong <[email protected]>
xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n
Heiko Carstens <[email protected]>
s390/boot: Fix ESSA detection
Haoxiang Li <[email protected]>
soc: loongson: loongson2_guts: Add check for devm_kstrdup()
Johan Korsnes <[email protected]>
gpio: vf610: add locking to gpio direction functions
Lukasz Czechowski <[email protected]>
arm64: dts: rockchip: Disable DMA for uart5 on px30-ringneck
Lukasz Czechowski <[email protected]>
arm64: dts: rockchip: Move uart5 pin configuration to px30 ringneck SoM
Alexander Shiyan <[email protected]>
arm64: dts: rockchip: Fix broken tsadc pinctrl names for rk3588
Tianling Shen <[email protected]>
arm64: dts: rockchip: change eth phy mode to rgmii-id for orangepi r1 plus lts
David Hildenbrand <[email protected]>
mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize()
Gavrilov Ilia <[email protected]>
drop_monitor: fix incorrect initialization order
Sumit Garg <[email protected]>
tee: optee: Fix supplicant wait loop
Bartosz Golaszewski <[email protected]>
gpiolib: protect gpio_chip with SRCU in array_info paths in multi get/set
Bartosz Golaszewski <[email protected]>
gpiolib: check the return value of gpio_chip::get_direction()
Pavel Begunkov <[email protected]>
io_uring: prevent opcode speculation
Pavel Begunkov <[email protected]>
io_uring/rw: forbid multishot async reads
Imre Deak <[email protected]>
drm/i915/dsi: Use TRANS_DDI_FUNC_CTL's own port width macro
Krzysztof Karas <[email protected]>
drm/i915/gt: Use spin_lock_irqsave() in interruptible context
Imre Deak <[email protected]>
drm/i915/ddi: Fix HDMI port width programming in DDI_BUF_CTL
Imre Deak <[email protected]>
drm/i915/dp: Fix error handling during 128b/132b link training
Ville Syrjälä <[email protected]>
drm/i915: Make sure all planes in use by the joiner have their crtc included
Jessica Zhang <[email protected]>
drm/msm/dpu: Disable dither in phys encoder cleanup
Abhinav Kumar <[email protected]>
drm/msm/dp: account for widebus and yuv420 during mode validation
Hugo Villeneuve <[email protected]>
drm: panel: jd9365da-h3: fix reset signal polarity
Mathieu Desnoyers <[email protected]>
sched: Compact RSEQ concurrency IDs with reduced threads and affinity
Artur Rojek <[email protected]>
irqchip/jcore-aic, clocksource/drivers/jcore: Fix jcore-pit interrupt request
Aaron Kling <[email protected]>
drm/nouveau/pmu: Fix gp10b firmware guard
Yan Zhai <[email protected]>
bpf: skip non exist keys in generic_map_lookup_batch
Caleb Sander Mateos <[email protected]>
nvme/ioctl: add missing space in err message
Caleb Sander Mateos <[email protected]>
nvme-tcp: fix connect failure on receiving partial ICResp PDU
Damien Le Moal <[email protected]>
nvme: tcp: Fix compilation warning with W=1
Hannes Reinecke <[email protected]>
nvmet: Fix crash when a namespace is disabled
Lucas De Marchi <[email protected]>
drm/xe: Fix error handling in xe_irq_install()
Ilia Levi <[email protected]>
drm/xe/irq: Separate MSI and MSI-X flows
Ilia Levi <[email protected]>
drm/xe: Make irq enabled flag atomic
Krzysztof Kozlowski <[email protected]>
drm/msm/dsi/phy: Do not overwite PHY_CMN_CLK_CFG1 when choosing bitclk source
Krzysztof Kozlowski <[email protected]>
drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG1 against clock driver
Krzysztof Kozlowski <[email protected]>
drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side
Marijn Suijten <[email protected]>
drm/msm/dpu: Don't leak bits_per_component into random DSC_ENC fields
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: enable DPU_WB_INPUT_CTRL for DPU 5.x
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: skip watchdog timer programming through TOP on >= SM8450
Rob Clark <[email protected]>
drm/msm: Avoid rounding up to one jiffy
David Hildenbrand <[email protected]>
nouveau/svm: fix missing folio unlock + put after make_device_exclusive_range()
Geert Uytterhoeven <[email protected]>
platform: cznic: CZNIC_PLATFORMS should depend on ARCH_MVEBU
Geert Uytterhoeven <[email protected]>
firmware: imx: IMX_SCMI_MISC_DRV should depend on ARCH_MXC
Bart Van Assche <[email protected]>
md/raid*: Fix the set_queue_limits implementations
Peng Fan <[email protected]>
firmware: arm_scmi: imx: Correct tx size of scmi_imx_misc_ctrl_set
Patrick Wildt <[email protected]>
arm64: dts: rockchip: adjust SMMU interrupt type on rk3588
Alan Maguire <[email protected]>
bpf: Fix softlockup in arena_map_free on 64k page kernel
Kuniyuki Iwashima <[email protected]>
net: Add rx_skb of kfree_skb to raw_tp_null_args[].
Chris Morgan <[email protected]>
power: supply: axp20x_battery: Fix fault handling for AXP717
Andrey Vatoropin <[email protected]>
power: supply: da9150-fg: fix potential overflow
Andy Yan <[email protected]>
arm64: dts: rockchip: Fix lcdpwr_en pin for Cool Pi GenBook
Heiko Stuebner <[email protected]>
arm64: dts: rockchip: fix fixed-regulator renames on rk3399-gru devices
Abel Wu <[email protected]>
bpf: Fix deadlock when freeing cgroup storage
Jiayuan Chen <[email protected]>
bpf: Disable non stream socket for strparser
Andrii Nakryiko <[email protected]>
bpf: avoid holding freeze_mutex during mmap operation
Andrii Nakryiko <[email protected]>
bpf: unify VM_WRITE vs VM_MAYWRITE use in BPF map mmaping logic
Shigeru Yoshida <[email protected]>
bpf, test_run: Fix use-after-free issue in eth_skb_pkt_type()
Gary Guo <[email protected]>
rust: cleanup unnecessary casts
Gary Guo <[email protected]>
rust: map long to isize and char to u8
Miguel Ojeda <[email protected]>
rust: finish using custom FFI integer types
Paolo Abeni <[email protected]>
net: allow small head cache usage with large MAX_SKB_FRAGS values
Sabrina Dubroca <[email protected]>
tcp: drop secpath at the same time as we currently drop dst
Nick Hu <[email protected]>
net: axienet: Set mac_managed_pm
Breno Leitao <[email protected]>
arp: switch to dev_getbyhwaddr() in arp_req_set_public()
Breno Leitao <[email protected]>
net: Add non-RCU dev_getbyhwaddr() helper
Cong Wang <[email protected]>
flow_dissector: Fix port range key handling in BPF conversion
Cong Wang <[email protected]>
flow_dissector: Fix handling of mixed port and port-range keys
Kuniyuki Iwashima <[email protected]>
geneve: Suppress list corruption splat in geneve_destroy_tunnels().
Kuniyuki Iwashima <[email protected]>
gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
Kory Maincent <[email protected]>
net: pse-pd: pd692x0: Fix power limit retrieval
Kory Maincent <[email protected]>
net: pse-pd: Use power limit at driver side instead of current limit
Kory Maincent <[email protected]>
net: pse-pd: Avoid setting max_uA in regulator constraints
Jakub Kicinski <[email protected]>
tcp: adjust rcvq_space after updating scaling ratio
Michal Luczaj <[email protected]>
vsock/bpf: Warn on socket without transport
Michal Luczaj <[email protected]>
sockmap, vsock: For connectible sockets allow only connected
Nick Child <[email protected]>
ibmvnic: Don't reference skb after sending to VIOS
Julian Ruess <[email protected]>
s390/ism: add release function for struct device
Takashi Iwai <[email protected]>
ALSA: seq: Drop UMP events when no UMP-conversion is set
Pierre Riteau <[email protected]>
net/sched: cls_api: fix error handling causing NULL dereference
Vitaly Rodionov <[email protected]>
ALSA: hda/cirrus: Correct the full scale volume set logic
Kuniyuki Iwashima <[email protected]>
geneve: Fix use-after-free in geneve_find_dev().
Junnan Wu <[email protected]>
vsock/virtio: fix variables initialization during resuming
Shengjiu Wang <[email protected]>
ASoC: imx-audmix: remove cpu_mclk which is from cpu dai device
Christophe Leroy <[email protected]>
powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC
Kailang Yang <[email protected]>
ALSA: hda/realtek: Fixup ALC225 depop procedure
Christophe Leroy <[email protected]>
powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline
Christophe Leroy <[email protected]>
powerpc/code-patching: Disable KASAN report during patching via temporary mm
Peter Ujfalusi <[email protected]>
ASoC: SOF: ipc4-topology: Harden loops for looking up ALH copiers
John Keeping <[email protected]>
ASoC: rockchip: i2s-tdm: fix shift config for SND_SOC_DAIFMT_DSP_[AB]
Jill Donahue <[email protected]>
USB: gadget: f_midi: f_midi_complete to call queue_work
Steven Rostedt <[email protected]>
tracing: Have the error of __tracing_resize_ring_buffer() passed to user
Steven Rostedt <[email protected]>
tracing: Switch trace.c code over to use guard()
Lancelot SIX <[email protected]>
drm/amdkfd: Ensure consistent barrier state saved in gfx12 trap handler
Jay Cornwall <[email protected]>
drm/amdkfd: Move gfx12 trap handler to separate file
Takashi Iwai <[email protected]>
PCI: Restore original INTX_DISABLE bit by pcim_intx()
Philipp Stanner <[email protected]>
PCI: Remove devres from pci_intx()
Philipp Stanner <[email protected]>
PCI: Export pci_intx_unmanaged() and pcim_intx()
Claudiu Beznea <[email protected]>
serial: sh-sci: Increment the runtime usage counter for the earlycon device
Claudiu Beznea <[email protected]>
serial: sh-sci: Clean sci_ports[0] after at earlycon exit
Claudiu Beznea <[email protected]>
serial: sh-sci: Move runtime PM enable to sci_probe_single()
Zijun Hu <[email protected]>
Bluetooth: qca: Fix poor RF performance for WCN6855
Cheng Jiang <[email protected]>
Bluetooth: qca: Update firmware-name to support board specific nvm
loanchen <[email protected]>
drm/amd/display: Correct register address in dcn35
Charlene Liu <[email protected]>
drm/amd/display: update dcn351 used clock offset
Qu Wenruo <[email protected]>
btrfs: fix double accounting race when extent_writepage_io() failed
Qu Wenruo <[email protected]>
btrfs: fix double accounting race when btrfs_run_delalloc_range() failed
David Sterba <[email protected]>
btrfs: use btrfs_inode in extent_writepage()
John Starks <[email protected]>
Drivers: hv: vmbus: Log on missing offers if any
-------------
Diffstat:
Makefile | 4 +- .../boot/dts/rockchip/px30-ringneck-haikou.dts | 1 - arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi | 6 + .../dts/rockchip/rk3328-orangepi-r1-plus-lts.dts | 3 +- .../boot/dts/rockchip/rk3328-orangepi-r1-plus.dts | 1 + .../boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 - .../boot/dts/rockchip/rk3399-gru-chromebook.dtsi | 8 +- .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 6 +- arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 22 +- arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 22 +- .../dts/rockchip/rk3588-coolpi-cm5-genbook.dts | 4 +- arch/powerpc/include/asm/book3s/64/hash-4k.h | 12 +- arch/powerpc/lib/code-patching.c | 4 +- arch/s390/boot/startup.c | 2 +- arch/x86/events/intel/core.c | 20 +- arch/x86/events/intel/ds.c | 2 +- drivers/bluetooth/btqca.c | 118 +- drivers/clocksource/jcore-pit.c | 15 +- drivers/edac/qcom_edac.c | 4 +- .../firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 4 +- drivers/firmware/imx/Kconfig | 1 + drivers/gpio/gpio-vf610.c | 4 + drivers/gpio/gpiolib.c | 92 +- drivers/gpio/gpiolib.h | 4 +- drivers/gpu/drm/Kconfig | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 32 +- drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h | 3 +- .../gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm | 202 +--- .../gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx12.asm | 1130 ++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 5 +- .../amd/display/dc/clk_mgr/dcn35/dcn351_clk_mgr.c | 140 +++ .../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 130 ++- .../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h | 4 + .../drm/amd/display/dc/inc/hw/clk_mgr_internal.h | 59 + drivers/gpu/drm/drm_panic_qr.rs | 2 +- drivers/gpu/drm/i915/display/icl_dsi.c | 4 +- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 18 + .../gpu/drm/i915/display/intel_dp_link_training.c | 15 +- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 +- drivers/gpu/drm/i915/i915_reg.h | 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 2 +- .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 2 +- drivers/gpu/drm/msm/dp/dp_display.c | 11 +- drivers/gpu/drm/msm/dp/dp_drm.c | 5 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 53 +- drivers/gpu/drm/msm/msm_drv.h | 11 +- .../gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 11 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 9 +- drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c | 2 +- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 8 +- drivers/gpu/drm/xe/display/ext/i915_irq.c | 13 +- drivers/gpu/drm/xe/xe_device.c | 4 +- drivers/gpu/drm/xe/xe_device.h | 3 +- drivers/gpu/drm/xe/xe_device_types.h | 8 +- drivers/gpu/drm/xe/xe_irq.c | 298 ++++-- drivers/gpu/drm/xe/xe_irq.h | 3 + drivers/hv/vmbus_drv.c | 17 + drivers/irqchip/irq-gic-v3.c | 49 +- drivers/irqchip/irq-jcore-aic.c | 2 +- drivers/md/raid0.c | 4 +- drivers/md/raid1.c | 4 +- drivers/md/raid10.c | 4 +- drivers/mtd/nand/raw/cadence-nand-controller.c | 42 +- drivers/mtd/spi-nor/sst.c | 2 +- drivers/net/ethernet/google/gve/gve.h | 10 + drivers/net/ethernet/google/gve/gve_main.c | 6 +- drivers/net/ethernet/ibm/ibmvnic.c | 4 +- drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 2 + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 + drivers/net/geneve.c | 16 +- drivers/net/gtp.c | 5 - drivers/net/pse-pd/pd692x0.c | 45 +- drivers/net/pse-pd/pse_core.c | 98 +- drivers/nvme/host/ioctl.c | 3 +- drivers/nvme/host/tcp.c | 7 +- drivers/nvme/target/core.c | 40 +- drivers/pci/devres.c | 58 +- drivers/pci/pci.c | 16 +- drivers/platform/cznic/Kconfig | 1 + drivers/power/supply/axp20x_battery.c | 31 +- drivers/power/supply/da9150-fg.c | 4 +- drivers/s390/net/ism_drv.c | 14 +- drivers/soc/loongson/loongson2_guts.c | 5 +- drivers/tee/optee/supp.c | 35 +- drivers/tty/serial/sh-sci.c | 68 +- drivers/usb/gadget/function/f_midi.c | 2 +- fs/btrfs/extent_io.c | 102 +- fs/btrfs/inode.c | 3 +- fs/smb/client/inode.c | 4 +- fs/smb/client/smb2ops.c | 4 + fs/xfs/scrub/common.h | 5 - fs/xfs/scrub/repair.h | 11 +- fs/xfs/scrub/scrub.c | 12 + include/linux/mm_types.h | 7 +- include/linux/netdevice.h | 2 + include/linux/pci.h | 1 + include/linux/pse-pd/pse.h | 16 +- include/net/gro.h | 3 + include/net/tcp.h | 14 + io_uring/io_uring.c | 2 + io_uring/rw.c | 13 +- kernel/acct.c | 134 ++- kernel/bpf/arena.c | 2 +- kernel/bpf/bpf_cgrp_storage.c | 2 +- kernel/bpf/btf.c | 2 + kernel/bpf/ringbuf.c | 4 - kernel/bpf/syscall.c | 43 +- kernel/sched/sched.h | 25 +- kernel/trace/ftrace.c | 36 +- kernel/trace/trace.c | 277 ++--- kernel/trace/trace_functions.c | 6 +- lib/iov_iter.c | 3 +- mm/madvise.c | 11 +- mm/migrate_device.c | 13 +- mm/zswap.c | 35 +- net/bpf/test_run.c | 5 +- net/core/dev.c | 37 +- net/core/drop_monitor.c | 39 +- net/core/flow_dissector.c | 49 +- net/core/gro.c | 3 - net/core/skbuff.c | 10 +- net/core/sock_map.c | 8 +- net/ipv4/arp.c | 2 +- net/ipv4/tcp_fastopen.c | 4 +- net/ipv4/tcp_input.c | 20 +- net/ipv4/tcp_ipv4.c | 2 +- net/sched/cls_api.c | 2 +- net/vmw_vsock/af_vsock.c | 3 + net/vmw_vsock/virtio_transport.c | 10 +- net/vmw_vsock/vsock_bpf.c | 2 +- rust/ffi.rs | 37 +- rust/kernel/device.rs | 4 +- rust/kernel/error.rs | 5 +- rust/kernel/firmware.rs | 2 +- rust/kernel/miscdevice.rs | 12 +- rust/kernel/print.rs | 4 +- rust/kernel/security.rs | 2 +- rust/kernel/seq_file.rs | 2 +- rust/kernel/str.rs | 6 +- rust/kernel/uaccess.rs | 27 +- samples/rust/rust_print_main.rs | 2 +- sound/core/seq/seq_clientmgr.c | 12 +- sound/pci/hda/hda_codec.c | 4 +- sound/pci/hda/patch_conexant.c | 1 + sound/pci/hda/patch_cs8409-tables.c | 6 +- sound/pci/hda/patch_cs8409.c | 20 +- sound/pci/hda/patch_cs8409.h | 5 +- sound/pci/hda/patch_realtek.c | 1 + sound/soc/fsl/fsl_micfil.c | 2 + sound/soc/fsl/imx-audmix.c | 31 - sound/soc/rockchip/rockchip_i2s_tdm.c | 4 +- sound/soc/sof/ipc4-topology.c | 12 +- sound/soc/sof/pcm.c | 2 + sound/soc/sof/stream-ipc.c | 6 +- 161 files changed, 3061 insertions(+), 1304 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 23/138 powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline
6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit 61bcc752d1b81fde3cae454ff20c1d3c359df500 ]
Rewrite __real_pte() and __rpte_to_hidx() as static inline in order to avoid following warnings/errors when building with 4k page size:
CC arch/powerpc/mm/book3s64/hash_tlb.o
arch/powerpc/mm/book3s64/hash_tlb.c: In function 'hpte_need_flush':
arch/powerpc/mm/book3s64/hash_tlb.c:49:16: error: variable 'offset' set but not used [-Werror=unused-but-set-variable]
49 | int i, offset;
| ^~~~~~
CC arch/powerpc/mm/book3s64/hash_native.o
arch/powerpc/mm/book3s64/hash_native.c: In function 'native_flush_hash_range':
arch/powerpc/mm/book3s64/hash_native.c:782:29: error: variable 'index' set but not used [-Werror=unused-but-set-variable]
782 | unsigned long hash, index, hidx, shift, slot;
| ^~~~~
--- arch/powerpc/include/asm/book3s/64/hash-4k.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/book3s/64/hash-4k.h +10 -2
@@ -77,9 +77,17 @@/* * With 4K page size the real_pte machinery is all nops. */ -#define __real_pte (e, p, o) ((real_pte_t){(e)}) +static inline real_pte_t __real_pte (pte_t pte,pte_t *ptep,int offset) +{ +return (real_pte_t ){pte}; +} +#define __rpte_to_pte (r) ((r).pte) -#define __rpte_to_hidx (r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) + +static inline unsigned long __rpte_to_hidx (real_pte_t rpte,unsigned long index) +{ +return pte_val (__rpte_to_pte (rpte)) >>H_PAGE_F_GIX_SHIFT ; +}#define pte_iterate_hashed_subpages (rpte, psize, va, index, shift) \ do { \
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 32/138 s390/ism: add release function for struct device
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Ruess <[email protected]>
[ Upstream commit 915e34d5ad35a6a9e56113f852ade4a730fb88f0 ]
According to device_release() in /drivers/base/core.c, a device without a release function is a broken device and must be fixed.
The current code directly frees the device after calling device_add() without waiting for other kernel parts to release their references. Thus, a reference could still be held to a struct device, e.g., by sysfs, leading to potential use-after-free
issues if a proper release function is not set.
--- drivers/s390/net/ism_drv.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/s390/net/ism_drv.c +12 -2
@@ -588,6 +588,15 @@ static int ism_dev_init(struct ism_dev *ism)return ret; } +static void ism_dev_release (struct device *dev) +{ +struct ism_dev *ism; + + ism = container_of(dev, struct ism_dev, dev); + +kfree (ism); +} +static int ism_probe (struct pci_dev *pdev,const struct pci_device_id *id) {struct ism_dev *ism;
@@ -601,6 +610,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)dev_set_drvdata (&pdev->dev, ism); ism->pdev = pdev; ism->dev.parent = &pdev->dev; + ism->dev.release = ism_dev_release;device_initialize (&ism->dev);dev_set_name (&ism->dev,dev_name (&pdev->dev)); ret =device_add (&ism->dev);
@@ -637,7 +647,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)device_del (&ism->dev); err_dev:dev_set_drvdata (&pdev->dev,NULL ); -kfree (ism); +put_device (&ism->dev);return ret; }
@@ -682,7 +692,7 @@ static void ism_remove(struct pci_dev *pdev)pci_disable_device (pdev);device_del (&ism->dev);dev_set_drvdata (&pdev->dev,NULL ); -kfree (ism); +put_device (&ism->dev); }static struct pci_driver ism_driver = {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 33/138 ibmvnic: Dont reference skb after sending to VIOS
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <[email protected]>
[ Upstream commit bdf5d13aa05ec314d4385b31ac974d6c7e0997c9 ]
Previously, after successfully flushing the xmit buffer to VIOS, the tx_bytes stat was incremented by the length of the skb.
It is invalid to access the skb memory after sending the buffer to the VIOS because, at any point after sending, the VIOS can trigger an interrupt to free this memory. A race between reading skb->len and freeing the skb is possible (especially during LPM) and will result in use-after-free:
==================================================================
BUG: KASAN: slab-use-after-free in ibmvnic_xmit+0x75c/0x1808 [ibmvnic] Read of size 4 at addr c00000024eb48a70 by task hxecom/14495 <...> Call Trace: [c000000118f66cf0] [c0000000018cba6c] dump_stack_lvl+0x84/0xe8 (unreliable) [c000000118f66d20] [c0000000006f0080] print_report+0x1a8/0x7f0 [c000000118f66df0] [c0000000006f08f0] kasan_report+0x128/0x1f8 [c000000118f66f00] [c0000000006f2868] __asan_load4+0xac/0xe0 [c000000118f66f20] [c0080000046eac84] ibmvnic_xmit+0x75c/0x1808 [ibmvnic] [c000000118f67340] [c0000000014be168] dev_hard_start_xmit+0x150/0x358 <...> Freed by task 0: kasan_save_stack+0x34/0x68 kasan_save_track+0x2c/0x50 kasan_save_free_info+0x64/0x108 __kasan_mempool_poison_object+0x148/0x2d4 napi_skb_cache_put+0x5c/0x194 net_tx_action+0x154/0x5b8 handle_softirqs+0x20c/0x60c do_softirq_own_stack+0x6c/0x88 <...> The buggy address belongs to the object at c00000024eb48a00 which belongs to the cache skbuff_head_cache of size 224 ==================================================================
--- drivers/net/ethernet/ibm/ibmvnic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/ibm/ibmvnic.c +3 -1
@@ -2408,6 +2408,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)dma_addr_t data_dma_addr;struct netdev_queue *txq;unsigned long lpar_rc; +unsigned int skblen;union sub_crq tx_crq;unsigned int offset;bool use_scrq_send_direct = false;
@@ -2522,6 +2523,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) tx_buff->skb = skb; tx_buff->index = bufidx; tx_buff->pool_index = queue_num; + skblen = skb->len;memset (&tx_crq,0 ,sizeof (tx_crq)); tx_crq.v1.first =IBMVNIC_CRQ_CMD ;
@@ -2614,7 +2616,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)netif_stop_subqueue (netdev, queue_num); } - tx_bytes += skb->len; + tx_bytes += skblen;txq_trans_cond_update (txq); ret =NETDEV_TX_OK ; goto out;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 34/138 sockmap, vsock: For connectible sockets allow only connected
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 8fb5bb169d17cdd12c2dcc2e96830ed487d77a0f ]
sockmap expects all vsocks to have a transport assigned, which is expressed in vsock_proto::psock_update_sk_prot(). However, there is an edge case where an unconnected (connectible) socket may lose its previously assigned transport. This is handled with a NULL check in the vsock/BPF recv path.
Another design detail is that listening vsocks are not supposed to have any transport assigned at all. Which implies they are not supported by the sockmap. But this is complicated by the fact that a socket, before switching to TCP_LISTEN, may have had some transport assigned during a failed connect() attempt. Hence, we may end up with a listening vsock in a sockmap, which blows up quickly:
KASAN: null-ptr-deref in range [0x0000000000000120-0x0000000000000127] CPU: 7 UID: 0 PID: 56 Comm: kworker/7:0 Not tainted 6.14.0-rc1+ Workqueue: vsock-loopback vsock_loopback_work RIP: 0010:vsock_read_skb+0x4b/0x90 Call Trace: sk_psock_verdict_data_ready+0xa4/0x2e0 virtio_transport_recv_pkt+0x1ca8/0x2acc vsock_loopback_work+0x27d/0x3f0 process_one_work+0x846/0x1420 worker_thread+0x5b3/0xf80 kthread+0x35a/0x700 ret_from_fork+0x2d/0x70 ret_from_fork_asm+0x1a/0x30
For connectible sockets, instead of relying solely on the state of vsk->transport, tell sockmap to only allow those representing established connections. This aligns with the behaviour for AF_INET and AF_UNIX.
--- net/core/sock_map.c | 3 +++ 1 file changed, 3 insertions(+)
net/core/sock_map.c +3 -0
@@ -541,6 +541,9 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)return (1 << sk->sk_state) & (TCPF_ESTABLISHED |TCPF_LISTEN );if (sk_is_stream_unix (sk))return (1 << sk->sk_state) &TCPF_ESTABLISHED ; +if (sk_is_vsock (sk) && + (sk->sk_type ==SOCK_STREAM || sk->sk_type ==SOCK_SEQPACKET )) +return (1 << sk->sk_state) &TCPF_ESTABLISHED ;return true; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 35/138 vsock/bpf: Warn on socket without transport
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 857ae05549ee2542317e7084ecaa5f8536634dd9 ]
In the spirit of commit 91751e248256 ("vsock: prevent null-ptr-deref in vsock_*[has_data|has_space]"), armorize the "impossible" cases with a warning.
--- net/vmw_vsock/af_vsock.c | 3 +++ net/vmw_vsock/vsock_bpf.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-)
net/vmw_vsock/af_vsock.c +3 -0
@@ -1189,6 +1189,9 @@ static int vsock_read_skb(struct sock *sk, skb_read_actor_t read_actor) {struct vsock_sock *vsk =vsock_sk (sk); +if (WARN_ON_ONCE (!vsk->transport)) +return -ENODEV ; +return vsk->transport->read_skb (vsk, read_actor); }
net/vmw_vsock/vsock_bpf.c +1 -1
@@ -87,7 +87,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,lock_sock (sk); vsk =vsock_sk (sk); -if (!vsk->transport) { +if (WARN_ON_ONCE (!vsk->transport)) { copied = -ENODEV ; goto out; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 36/138 tcp: adjust rcvq_space after updating scaling ratio
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit f5da7c45188eea71394bf445655cae2df88a7788 ]
Since commit under Fixes we set the window clamp in accordance to newly measured rcvbuf scaling_ratio. If the scaling_ratio decreased significantly we may put ourselves in a situation where windows become smaller than rcvq_space, preventing tcp_rcv_space_adjust() from increasing rcvbuf.
The significant decrease of scaling_ratio is far more likely since commit 697a6c8cec03 ("tcp: increase the default TCP scaling ratio"), which increased the "default" scaling ratio from ~30% to 50%.
Hitting the bad condition depends a lot on TCP tuning, and drivers at play. One of Meta's workloads hits it reliably under following conditions:
- default rcvbuf of 125k
- sender MTU 1500, receiver MTU 5000
- driver settles on scaling_ratio of 78 for the config above.
Initial rcvq_space gets calculated as TCP_INIT_CWND * tp->advmss (10 * 5k = 50k). Once we find out the true scaling ratio and MSS we clamp the windows to 38k. Triggering the condition also depends on the message sequence of this workload. I can't repro the problem with simple iperf or TCP_RR-style tests.
--- net/ipv4/tcp_input.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
net/ipv4/tcp_input.c +9 -3
@@ -243,9 +243,15 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)do_div (val, skb->truesize);tcp_sk (sk)->scaling_ratio = val ? val :1 ; -if (old_ratio !=tcp_sk (sk)->scaling_ratio) -WRITE_ONCE (tcp_sk (sk)->window_clamp, -tcp_win_from_space (sk, sk->sk_rcvbuf)); +if (old_ratio !=tcp_sk (sk)->scaling_ratio) { +struct tcp_sock *tp =tcp_sk (sk); + + val =tcp_win_from_space (sk, sk->sk_rcvbuf); +tcp_set_window_clamp (sk, val); + +if (tp->window_clamp < tp->rcvq_space.space) + tp->rcvq_space.space = tp->window_clamp; + } } icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,tcp_sk (sk)->advmss);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 37/138 net: pse-pd: Avoid setting max_uA in regulator constraints
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
[ Upstream commit 675d0e3cacc3ae7c29294a5f6a820187f862ad8b ]
Setting the max_uA constraint in the regulator API imposes a current limit during the regulator registration process. This behavior conflicts with preserving the maximum PI power budget configuration across reboots.
Instead, compare the desired current limit to MAX_PI_CURRENT in the pse_pi_set_current_limit() function to ensure proper handling of the power budget.
Stable-dep-of: f6093c5ec74d ("net: pse-pd: pd692x0: Fix power limit retrieval")
--- drivers/net/pse-pd/pse_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/pse-pd/pse_core.c +4 -3
@@ -357,6 +357,9 @@ static int pse_pi_set_current_limit(struct regulator_dev *rdev, int min_uA,if (!ops->pi_set_current_limit)return -EOPNOTSUPP ; +if (max_uA >MAX_PI_CURRENT ) +return -ERANGE ; + id =rdev_get_id (rdev);mutex_lock (&pcdev->lock); ret = ops->pi_set_current_limit (pcdev, id, max_uA);
@@ -403,11 +406,9 @@ devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev, rinit_data->constraints.valid_ops_mask =REGULATOR_CHANGE_STATUS ; -if (pcdev->ops->pi_set_current_limit) { +if (pcdev->ops->pi_set_current_limit) rinit_data->constraints.valid_ops_mask |=REGULATOR_CHANGE_CURRENT ; - rinit_data->constraints.max_uA =MAX_PI_CURRENT ; - } rinit_data->supply_regulator ="vpwr" ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 38/138 net: pse-pd: Use power limit at driver side instead of current limit
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
[ Upstream commit e0a5e2bba38aa61a900934b45d6e846e0a6d7524 ]
The regulator framework uses current limits, but the PSE standard and known PSE controllers rely on power limits. Instead of converting current to power within each driver, perform the conversion in the PSE core. This avoids redundancy in driver implementation and aligns better with the standard, simplifying driver development.
Remove at the same time the _pse_ethtool_get_status() function which is not needed anymore.
Stable-dep-of: f6093c5ec74d ("net: pse-pd: pd692x0: Fix power limit retrieval")
--- drivers/net/pse-pd/pd692x0.c | 45 ++++------------- drivers/net/pse-pd/pse_core.c | 91 ++++++++++++++++------------------- include/linux/pse-pd/pse.h | 16 +++--- 3 files changed, 57 insertions(+), 95 deletions(-)
drivers/net/pse-pd/pd692x0.c +10 -35
@@ -999,13 +999,12 @@ static int pd692x0_pi_get_voltage(struct pse_controller_dev *pcdev, int id)return (buf.sub[0 ] <<8 | buf.sub[1 ]) *100000 ; } -static int pd692x0_pi_get_current_limit (struct pse_controller_dev *pcdev, -int id) +static int pd692x0_pi_get_pw_limit (struct pse_controller_dev *pcdev, +int id) {struct pd692x0_priv *priv =to_pd692x0_priv (pcdev);struct pd692x0_msg msg, buf = {0 }; -int mW, uV, uA, ret; -s64 tmp_64; +int ret; msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM ]; msg.sub[2 ] = id;
@@ -1013,48 +1012,24 @@ static int pd692x0_pi_get_current_limit(struct pse_controller_dev *pcdev,if (ret <0 )return ret; - ret =pd692x0_pi_get_pw_from_table (buf.data[2 ], buf.data[3 ]); -if (ret <0 ) -return ret; - mW = ret; - - ret =pd692x0_pi_get_voltage (pcdev, id); -if (ret <0 ) -return ret; - uV = ret; - - tmp_64 = mW; - tmp_64 *=1000000000ull ; -/* uA = mW * 1000000000 / uV */ - uA =DIV_ROUND_CLOSEST_ULL (tmp_64, uV); -return uA; +return pd692x0_pi_get_pw_from_table (buf.data[2 ], buf.data[3 ]); } -static int pd692x0_pi_set_current_limit (struct pse_controller_dev *pcdev, -int id,int max_uA) +static int pd692x0_pi_set_pw_limit (struct pse_controller_dev *pcdev, +int id,int max_mW) {struct pd692x0_priv *priv =to_pd692x0_priv (pcdev);struct device *dev = &priv->client->dev;struct pd692x0_msg msg, buf = {0 }; -int uV, ret, mW; -s64 tmp_64; +int ret; ret =pd692x0_fw_unavailable (priv);if (ret)return ret; - ret =pd692x0_pi_get_voltage (pcdev, id); -if (ret <0 ) -return ret; - uV = ret; - msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM ]; msg.sub[2 ] = id; - tmp_64 = uV; - tmp_64 *= max_uA; -/* mW = uV * uA / 1000000000 */ - mW =DIV_ROUND_CLOSEST_ULL (tmp_64,1000000000 ); - ret =pd692x0_pi_set_pw_from_table (dev, &msg, mW); + ret =pd692x0_pi_set_pw_from_table (dev, &msg, max_mW);if (ret)return ret;
@@ -1068,8 +1043,8 @@ static const struct pse_controller_ops pd692x0_ops = { .pi_disable = pd692x0_pi_disable, .pi_is_enabled = pd692x0_pi_is_enabled, .pi_get_voltage = pd692x0_pi_get_voltage, - .pi_get_current_limit = pd692x0_pi_get_current_limit, - .pi_set_current_limit = pd692x0_pi_set_current_limit, + .pi_get_pw_limit = pd692x0_pi_get_pw_limit, + .pi_set_pw_limit = pd692x0_pi_set_pw_limit, };#define PD692X0_FW_LINE_MAX_SZ 0xff
drivers/net/pse-pd/pse_core.c +41 -50
148 lines not on this page · raw message
include/linux/pse-pd/pse.h +6 -10
@@ -75,12 +75,8 @@ struct pse_control_status {* @pi_disable: Configure the PSE PI as disabled. * @pi_get_voltage: Return voltage similarly to get_voltage regulator * callback. -* @pi_get_current_limit: Get the configured current limit similarly to -* get_current_limit regulator callback. -* @pi_set_current_limit: Configure the current limit similarly to -* set_current_limit regulator callback. -* Should not return an error in case of MAX_PI_CURRENT -* current value set. +* @pi_get_pw_limit: Get the configured power limit of the PSE PI. +* @pi_set_pw_limit: Configure the power limit of the PSE PI. */ struct pse_controller_ops { int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
@@ -91,10 +87,10 @@ struct pse_controller_ops {int (*pi_enable)(struct pse_controller_dev *pcdev,int id);int (*pi_disable)(struct pse_controller_dev *pcdev,int id);int (*pi_get_voltage)(struct pse_controller_dev *pcdev,int id); -int (*pi_get_current_limit)(struct pse_controller_dev *pcdev, -int id); -int (*pi_set_current_limit)(struct pse_controller_dev *pcdev, -int id,int max_uA); +int (*pi_get_pw_limit)(struct pse_controller_dev *pcdev, +int id); +int (*pi_set_pw_limit)(struct pse_controller_dev *pcdev, +int id,int max_mW); };struct module ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 39/138 net: pse-pd: pd692x0: Fix power limit retrieval
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
[ Upstream commit f6093c5ec74d5cc495f89bd359253d9c738d04d9 ]
Fix incorrect data offset read in the pd692x0_pi_get_pw_limit callback. The issue was previously unnoticed as it was only used by the regulator API and not thoroughly tested, since the PSE is mainly controlled via ethtool.
The function became actively used by ethtool after commit 3e9dbfec4998 ("net: pse-pd: Split ethtool_get_status into multiple callbacks"), which led to the discovery of this issue.
Fix it by using the correct data offset.
--- drivers/net/pse-pd/pd692x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/pse-pd/pd692x0.c +1 -1
@@ -1012,7 +1012,7 @@ static int pd692x0_pi_get_pw_limit(struct pse_controller_dev *pcdev,if (ret <0 )return ret; -return pd692x0_pi_get_pw_from_table (buf.data[2 ], buf.data[3 ]); +return pd692x0_pi_get_pw_from_table (buf.data[0 ], buf.data[1 ]); } static int pd692x0_pi_set_pw_limit(struct pse_controller_dev *pcdev,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 40/138 gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 4ccacf86491d33d2486b62d4d44864d7101b299d ]
Brad Spengler reported the list_del() corruption splat in gtp_net_exit_batch_rtnl(). [0]
Commit eb28fd76c0a0 ("gtp: Destroy device along with udp socket's netns dismantle.") added the for_each_netdev() loop in gtp_net_exit_batch_rtnl() to destroy devices in each netns as done in geneve and ip tunnels.
However, this could trigger ->dellink() twice for the same device during ->exit_batch_rtnl().
Say we have two netns A & B and gtp device B that resides in netns B but whose UDP socket is in netns A.
1. cleanup_net() processes netns A and then B.
2. gtp_net_exit_batch_rtnl() finds the device B while iterating
netns A's gn->gtp_dev_list and calls ->dellink().
[ device B is not yet unlinked from netns B
as unregister_netdevice_many() has not been called. ]
3. gtp_net_exit_batch_rtnl() finds the device B while iterating
netns B's for_each_netdev() and calls ->dellink().
gtp_dellink() cleans up the device's hash table, unlinks the dev from gn->gtp_dev_list, and calls unregister_netdevice_queue().
Basically, calling gtp_dellink() multiple times is fine unless CONFIG_DEBUG_LIST is enabled.
Let's remove for_each_netdev() in gtp_net_exit_batch_rtnl() and delegate the destruction to default_device_exit_batch() as done in bareudp.
[0]:list_del corruption, ffff8880aaa62c00->next (autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object]) is LIST_POISON1 (ffffffffffffff02) (prev is 0xffffffffffffff04) kernel BUG at lib/list_debug.c:58!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 UID: 0 PID: 1804 Comm: kworker/u8:7 Tainted: G T 6.12.13-grsec-full-20250211091339 #1 Tainted: [T]=RANDSTRUCT Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Workqueue: netns cleanup_net RIP: 0010:[<ffffffff84947381>] __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58 Code: c2 76 91 31 c0 e8 9f b1 f7 fc 0f 0b 4d 89 f0 48 c7 c1 02 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 e0 c2 76 91 31 c0 e8 7f b1 f7 fc <0f> 0b 4d 89 e8 48 c7 c1 04 ff ff ff 48 89 ea 48 89 ee 48 c7 c7 60 RSP: 0018:fffffe8040b4fbd0 EFLAGS: 00010283 RAX: 00000000000000cc RBX: dffffc0000000000 RCX: ffffffff818c4054 RDX: ffffffff84947381 RSI: ffffffff818d1512 RDI: 0000000000000000 RBP: ffff8880aaa62c00 R08: 0000000000000001 R09: fffffbd008169f32 R10: fffffe8040b4f997 R11: 0000000000000001 R12: a1988d84f24943e4 R13: ffffffffffffff02 R14: ffffffffffffff04 R15: ffff8880aaa62c08 RBX: kasan shadow of 0x0 RCX: __wake_up_klogd.part.0+0x74/0xe0 kernel/printk/printk.c:4554 RDX: __list_del_entry_valid_or_report+0x141/0x200 lib/list_debug.c:58 RSI: vprintk+0x72/0x100 kernel/printk/printk_safe.c:71 RBP: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc00/0x1000 [slab object] RSP: process kstack fffffe8040b4fbd0+0x7bd0/0x8000 [kworker/u8:7+netns 1804 ] R09: kasan shadow of process kstack fffffe8040b4f990+0x7990/0x8000 [kworker/u8:7+netns 1804 ] R10: process kstack fffffe8040b4f997+0x7997/0x8000 [kworker/u8:7+netns 1804 ] R15: autoslab_size_M_dev_P_net_core_dev_11127_8_1328_8_S_4096_A_64_n_139+0xc08/0x1000 [slab object] FS: 0000000000000000(0000) GS:ffff888116000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000748f5372c000 CR3: 0000000015408000 CR4: 00000000003406f0 shadow CR4: 00000000003406f0 Stack: 0000000000000000 ffffffff8a0c35e7 ffffffff8a0c3603 ffff8880aaa62c00 ffff8880aaa62c00 0000000000000004 ffff88811145311c 0000000000000005 0000000000000001 ffff8880aaa62000 fffffe8040b4fd40 ffffffff8a0c360d Call Trace: <TASK> [<ffffffff8a0c360d>] __list_del_entry_valid include/linux/list.h:131 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] __list_del_entry include/linux/list.h:248 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] list_del include/linux/list.h:262 [inline] fffffe8040b4fc28 [<ffffffff8a0c360d>] gtp_dellink+0x16d/0x360 drivers/net/gtp.c:1557 fffffe8040b4fc28 [<ffffffff8a0d0404>] gtp_net_exit_batch_rtnl+0x124/0x2c0 drivers/net/gtp.c:2495 fffffe8040b4fc88 [<ffffffff8e705b24>] cleanup_net+0x5a4/0xbe0 net/core/net_namespace.c:635 fffffe8040b4fcd0 [<ffffffff81754c97>] process_one_work+0xbd7/0x2160 kernel/workqueue.c:3326 fffffe8040b4fd88 [<ffffffff81757195>] process_scheduled_works kernel/workqueue.c:3407 [inline] fffffe8040b4fec0 [<ffffffff81757195>] worker_thread+0x6b5/0xfa0 kernel/workqueue.c:3488 fffffe8040b4fec0 [<ffffffff817782a0>] kthread+0x360/0x4c0 kernel/kthread.c:397 fffffe8040b4ff78 [<ffffffff814d8594>] ret_from_fork+0x74/0xe0 arch/x86/kernel/process.c:172 fffffe8040b4ffb8 [<ffffffff8110f509>] ret_from_fork_asm+0x29/0xc0 arch/x86/entry/entry_64.S:399 fffffe8040b4ffe8 </TASK> Modules linked in:
--- drivers/net/gtp.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/net/gtp.c +0 -5
@@ -2479,11 +2479,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,list_for_each_entry (net, net_list, exit_list) {struct gtp_net *gn =net_generic (net, gtp_net_id);struct gtp_dev *gtp, *gtp_next; -struct net_device *dev; - -for_each_netdev (net, dev) -if (dev->rtnl_link_ops == >p_link_ops) -gtp_dellink (dev, dev_to_kill);list_for_each_entry_safe (gtp, gtp_next, &gn->gtp_dev_list, list)gtp_dellink (gtp->dev, dev_to_kill);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 41/138 geneve: Suppress list corruption splat in geneve_destroy_tunnels().
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 62fab6eef61f245dc8797e3a6a5b890ef40e8628 ]
As explained in the previous patch, iterating for_each_netdev() and gn->geneve_list during ->exit_batch_rtnl() could trigger ->dellink() twice for the same device.
If CONFIG_DEBUG_LIST is enabled, we will see a list_del() corruption splat in the 2nd call of geneve_dellink().
Let's remove for_each_netdev() in geneve_destroy_tunnels() and delegate that part to default_device_exit_batch().
--- drivers/net/geneve.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/net/geneve.c +0 -7
@@ -1902,14 +1902,7 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) {struct geneve_net *gn =net_generic (net, geneve_net_id);struct geneve_dev *geneve, *next; -struct net_device *dev, *aux; -/* gather any geneve devices that were moved into this ns */ -for_each_netdev_safe (net, dev, aux) -if (dev->rtnl_link_ops == &geneve_link_ops) -geneve_dellink (dev, head); - -/* now gather any other geneve devices that were created in this ns */ list_for_each_entry_safe (geneve, next, &gn->geneve_list, next)geneve_dellink (geneve->dev, head); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 24/138 ALSA: hda/realtek: Fixup ALC225 depop procedure
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
[ Upstream commit 174448badb4409491bfba2e6b46f7aa078741c5e ]
Headset MIC will no function when power_save=0.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -3790,6 +3790,7 @@ static void alc225_init(struct hda_codec *codec) AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);msleep (75 ); +alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 );alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 42/138 flow_dissector: Fix handling of mixed port and port-range keys
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 3e5796862c692ea608d96f0a1437f9290f44953a ]
This patch fixes a bug in TC flower filter where rules combining a specific destination port with a source port range weren't working correctly.
The specific case was when users tried to configure rules like:
tc filter add dev ens38 ingress protocol ip flower ip_proto udp \dst_port 5000 src_port 2000-3000 action drop
The root cause was in the flow dissector code. While both FLOW_DISSECTOR_KEY_PORTS and FLOW_DISSECTOR_KEY_PORTS_RANGE flags were being set correctly in the classifier, the __skb_flow_dissect_ports() function was only populating one of them: whichever came first in the enum check. This meant that when the code needed both a specific port and a port range, one of them would be left as 0, causing the filter to not match packets as expected.
Fix it by removing the either/or logic and instead checking and populating both key types independently when they're in use.
--- net/core/flow_dissector.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
net/core/flow_dissector.c +19 -12
@@ -853,23 +853,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb, void *target_container, const void *data, int nhoff, u8 ip_proto, int hlen) { - enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX; -struct flow_dissector_key_ports *key_ports; + struct flow_dissector_key_ports_range *key_ports_range = NULL; +struct flow_dissector_key_ports *key_ports =NULL ; +__be32 ports;if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) - dissector_ports =FLOW_DISSECTOR_KEY_PORTS ; -else if (dissector_uses_key (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE )) - dissector_ports =FLOW_DISSECTOR_KEY_PORTS_RANGE ; + key_ports =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS , + target_container); -if (dissector_ports ==FLOW_DISSECTOR_KEY_MAX ) +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS_RANGE )) + key_ports_range =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE , + target_container); + +if (!key_ports && !key_ports_range)return ; - key_ports =skb_flow_dissector_target (flow_dissector, - dissector_ports, - target_container); - key_ports->ports =__skb_flow_get_ports (skb, nhoff, ip_proto, - data, hlen); + ports =__skb_flow_get_ports (skb, nhoff, ip_proto, data, hlen); + +if (key_ports) + key_ports->ports = ports; + +if (key_ports_range) + key_ports_range->tp.ports = ports; } static void
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 43/138 flow_dissector: Fix port range key handling in BPF conversion
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 69ab34f705fbfabcace64b5d53bb7a4450fac875 ]
Fix how port range keys are handled in __skb_flow_bpf_to_target() by:
- Separating PORTS and PORTS_RANGE key handling
- Using correct key_ports_range structure for range keys
- Properly initializing both key types independently
This ensures port range information is correctly stored in its dedicated structure rather than incorrectly using the regular ports key structure.
--- net/core/flow_dissector.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
net/core/flow_dissector.c +10 -8
@@ -931,6 +931,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,struct flow_dissector *flow_dissector, void *target_container) { + struct flow_dissector_key_ports_range *key_ports_range = NULL;struct flow_dissector_key_ports *key_ports =NULL ;struct flow_dissector_key_control *key_control;struct flow_dissector_key_basic *key_basic;
@@ -975,20 +976,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, key_control->addr_type =FLOW_DISSECTOR_KEY_IPV6_ADDRS ; } -if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_PORTS )) { key_ports =skb_flow_dissector_target (flow_dissector,FLOW_DISSECTOR_KEY_PORTS , target_container); -else if (dissector_uses_key (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE )) - key_ports =skb_flow_dissector_target (flow_dissector, -FLOW_DISSECTOR_KEY_PORTS_RANGE , - target_container); - -if (key_ports) { key_ports->src = flow_keys->sport; key_ports->dst = flow_keys->dport; } +if (dissector_uses_key (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE )) { + key_ports_range =skb_flow_dissector_target (flow_dissector, +FLOW_DISSECTOR_KEY_PORTS_RANGE , + target_container); + key_ports_range->tp.src = flow_keys->sport; + key_ports_range->tp.dst = flow_keys->dport; + }if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_FLOW_LABEL )) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 44/138 net: Add non-RCU dev_getbyhwaddr() helper
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 4b5a28b38c4a0106c64416a1b2042405166b26ce ]
Add dedicated helper for finding devices by hardware address when holding rtnl_lock, similar to existing dev_getbyhwaddr_rcu(). This prevents PROVE_LOCKING warnings when rtnl_lock is held but RCU read lock is not.
Extract common address comparison logic into dev_addr_cmp().
The context about this change could be found in the following discussion:
Stable-dep-of: 4eae0ee0f1e6 ("arp: switch to dev_getbyhwaddr() in arp_req_set_public()")
--- include/linux/netdevice.h | 2 ++ net/core/dev.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-)
include/linux/netdevice.h +2 -0
@@ -3138,6 +3138,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net) }int netdev_boot_setup_check (struct net_device *dev); +struct net_device *dev_getbyhwaddr (struct net *net,unsigned short type, +const char *hwaddr);struct net_device *dev_getbyhwaddr_rcu (struct net *net,unsigned short type,const char *hwaddr);struct net_device *dev_getfirstbyhwtype (struct net *net,unsigned short type);
net/core/dev.c +34 -3
@@ -1012,6 +1012,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex)return ret; } +static bool dev_addr_cmp (struct net_device *dev,unsigned short type, +const char *ha) +{ +return dev->type == type && !memcmp (dev->dev_addr, ha, dev->addr_len); +} +/** * dev_getbyhwaddr_rcu - find a device by its hardware address * @net: the applicable net namespace
@@ -1020,7 +1026,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex)* * Search for an interface by MAC address. Returns NULL if the device * is not found or a pointer to the device. -* The caller must hold RCU or RTNL. +* The caller must hold RCU. * The returned device has not had its ref count increased * and the caller must therefore be careful about locking *
@@ -1032,14 +1038,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,struct net_device *dev;for_each_netdev_rcu (net, dev) -if (dev->type == type && - !memcmp (dev->dev_addr, ha, dev->addr_len)) +if (dev_addr_cmp (dev, type, ha))return dev;return NULL ; }EXPORT_SYMBOL (dev_getbyhwaddr_rcu); +/** +* dev_getbyhwaddr() - find a device by its hardware address +* @net: the applicable net namespace +* @type: media type of device +* @ha: hardware address +* +* Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold +* rtnl_lock. +* +* Context: rtnl_lock() must be held. +* Return: pointer to the net_device, or NULL if not found +*/ +struct net_device *dev_getbyhwaddr (struct net *net,unsigned short type, +const char *ha) +{ +struct net_device *dev; + +ASSERT_RTNL (); +for_each_netdev (net, dev) +if (dev_addr_cmp (dev, type, ha)) +return dev; + +return NULL ; +} +EXPORT_SYMBOL (dev_getbyhwaddr); +struct net_device *dev_getfirstbyhwtype (struct net *net,unsigned short type) {struct net_device *dev, *ret =NULL ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 45/138 arp: switch to dev_getbyhwaddr() in arp_req_set_public()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 4eae0ee0f1e6256d0b0b9dd6e72f1d9cf8f72e08 ]
The arp_req_set_public() function is called with the rtnl lock held, which provides enough synchronization protection. This makes the RCU variant of dev_getbyhwaddr() unnecessary. Switch to using the simpler dev_getbyhwaddr() function since we already have the required rtnl locking.
This change helps maintain consistency in the networking code by using the appropriate helper function for the existing locking context. Since we're not holding the RCU read lock in arp_req_set_public() existing code could trigger false positive locking warnings.
--- net/ipv4/arp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/arp.c +1 -1
@@ -1077,7 +1077,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,__be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;if (!dev && (r->arp_flags &ATF_COM )) { - dev =dev_getbyhwaddr_rcu (net, r->arp_ha.sa_family, + dev =dev_getbyhwaddr (net, r->arp_ha.sa_family, r->arp_ha.sa_data);if (!dev)return -ENODEV ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 46/138 net: axienet: Set mac_managed_pm
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Hu <[email protected]>
[ Upstream commit a370295367b55662a32a4be92565fe72a5aa79bb ]
The external PHY will undergo a soft reset twice during the resume process when it wake up from suspend. The first reset occurs when the axienet driver calls phylink_of_phy_connect(), and the second occurs when mdio_bus_phy_resume() invokes phy_init_hw(). The second soft reset of the external PHY does not reinitialize the internal PHY, which causes issues with the internal PHY, resulting in the PHY link being down. To prevent this, setting the mac_managed_pm flag skips the mdio_bus_phy_resume() function.
--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +1 -0
@@ -2888,6 +2888,7 @@ static int axienet_probe(struct platform_device *pdev) lp->phylink_config.dev = &ndev->dev; lp->phylink_config.type =PHYLINK_NETDEV ; + lp->phylink_config.mac_managed_pm = true; lp->phylink_config.mac_capabilities =MAC_SYM_PAUSE |MAC_ASYM_PAUSE |MAC_10FD |MAC_100FD |MAC_1000FD ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 47/138 tcp: drop secpath at the same time as we currently drop dst
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <[email protected]>
[ Upstream commit 9b6412e6979f6f9e0632075f8f008937b5cd4efd ]
Xiumei reported hitting the WARN in xfrm6_tunnel_net_exit while running tests that boil down to:
- create a pair of netns
- run a basic TCP test over ipcomp6
- delete the pair of netns
The xfrm_state found on spi_byaddr was not deleted at the time we delete the netns, because we still have a reference on it. This lingering reference comes from a secpath (which holds a ref on the xfrm_state), which is still attached to an skb. This skb is not leaked, it ends up on sk_receive_queue and then gets defer-free'd by skb_attempt_defer_free.
The problem happens when we defer freeing an skb (push it on one CPU's defer_list), and don't flush that list before the netns is deleted. In that case, we still have a reference on the xfrm_state that we don't expect at this point.
We already drop the skb's dst in the TCP receive path when it's no longer needed, so let's also drop the secpath. At this point, tcp_filter has already called into the LSM hooks that may require the secpath, so it should not be needed anymore. However, in some of those places, the MPTCP extension has just been attached to the skb, so we cannot simply drop all extensions.
--- include/net/tcp.h | 14 ++++++++++++++ net/ipv4/tcp_fastopen.c | 4 ++-- net/ipv4/tcp_input.c | 8 ++++---- net/ipv4/tcp_ipv4.c | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-)
include/net/tcp.h +14 -0
@@ -41,6 +41,7 @@#include <net/inet_ecn.h> #include <net/dst.h> #include <net/mptcp.h> +#include <net/xfrm.h> #include <linux/seq_file.h> #include <linux/memcontrol.h>
@@ -683,6 +684,19 @@ void tcp_fin(struct sock *sk);void tcp_check_space (struct sock *sk);void tcp_sack_compress_send_ack (struct sock *sk); +static inline void tcp_cleanup_skb (struct sk_buff *skb) +{ +skb_dst_drop (skb); +secpath_reset (skb); +} + +static inline void tcp_add_receive_queue (struct sock *sk,struct sk_buff *skb) +{ +DEBUG_NET_WARN_ON_ONCE (skb_dst (skb)); +DEBUG_NET_WARN_ON_ONCE (secpath_exists (skb)); +__skb_queue_tail (&sk->sk_receive_queue, skb); +} +/* tcp_timer.c */ void tcp_init_xmit_timers (struct sock *);static inline void tcp_clear_xmit_timers (struct sock *sk)
net/ipv4/tcp_fastopen.c +2 -2
@@ -178,7 +178,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)if (!skb)return ; -skb_dst_drop (skb); +tcp_cleanup_skb (skb);/* segs_in has been initialized to 1 in tcp_create_openreq_child(). * Hence, reset segs_in to 0 before calling tcp_segs_in() * to avoid double counting. Also, tcp_segs_in() expects
@@ -195,7 +195,7 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)TCP_SKB_CB (skb)->tcp_flags &= ~TCPHDR_SYN ; tp->rcv_nxt =TCP_SKB_CB (skb)->end_seq; -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb); tp->syn_data_acked =1 ;/* u64_stats_update_begin(&tp->syncp) not needed here,
net/ipv4/tcp_input.c +4 -4
@@ -4970,7 +4970,7 @@ static void tcp_ofo_queue(struct sock *sk)tcp_rcv_nxt_update (tp,TCP_SKB_CB (skb)->end_seq); fin =TCP_SKB_CB (skb)->tcp_flags &TCPHDR_FIN ;if (!eaten) -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb);else kfree_skb_partial (skb, fragstolen);
@@ -5162,7 +5162,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, skb, fragstolen)) ? 1 : 0;tcp_rcv_nxt_update (tcp_sk (sk),TCP_SKB_CB (skb)->end_seq);if (!eaten) { -__skb_queue_tail (&sk->sk_receive_queue, skb); +tcp_add_receive_queue (sk, skb);skb_set_owner_r (skb, sk); }return eaten;
@@ -5245,7 +5245,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)__kfree_skb (skb);return ; } -skb_dst_drop (skb); +tcp_cleanup_skb (skb);__skb_pull (skb,tcp_hdr (skb)->doff *4 ); reason =SKB_DROP_REASON_NOT_SPECIFIED ;
@@ -6214,7 +6214,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPHPHITS );/* Bulk data transfer: receiver */ -skb_dst_drop (skb); +tcp_cleanup_skb (skb);__skb_pull (skb, tcp_header_len); eaten =tcp_queue_rcv (sk, skb, &fragstolen);
net/ipv4/tcp_ipv4.c +1 -1
@@ -2025,7 +2025,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,*/ skb_condense (skb); -skb_dst_drop (skb); +tcp_cleanup_skb (skb);if (unlikely (tcp_checksum_complete (skb))) {bh_unlock_sock (sk);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 48/138 net: allow small head cache usage with large MAX_SKB_FRAGS values
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 14ad6ed30a10afbe91b0749d6378285f4225d482 ]
Sabrina reported the following splat:
WARNING: CPU: 0 PID: 1 at net/core/dev.c:6935 netif_napi_add_weight_locked+0x8f2/0xba0
Modules linked in:
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.14.0-rc1-net-00092-g011b03359038 #996
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
RIP: 0010:netif_napi_add_weight_locked+0x8f2/0xba0
Code: e8 c3 e6 6a fe 48 83 c4 28 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc c7 44 24 10 ff ff ff ff e9 8f fb ff ff e8 9e e6 6a fe <0f> 0b e9 d3 fe ff ff e8 92 e6 6a fe 48 8b 04 24 be ff ff ff ff 48
RSP: 0000:ffffc9000001fc60 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff88806ce48128 RCX: 1ffff11001664b9e
RDX: ffff888008f00040 RSI: ffffffff8317ca42 RDI: ffff88800b325cb6
RBP: ffff88800b325c40 R08: 0000000000000001 R09: ffffed100167502c
R10: ffff88800b3a8163 R11: 0000000000000000 R12: ffff88800ac1c168
R13: ffff88800ac1c168 R14: ffff88800ac1c168 R15: 0000000000000007
FS: 0000000000000000(0000) GS:ffff88806ce00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff888008201000 CR3: 0000000004c94001 CR4: 0000000000370ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
gro_cells_init+0x1ba/0x270
xfrm_input_init+0x4b/0x2a0
xfrm_init+0x38/0x50
ip_rt_init+0x2d7/0x350
ip_init+0xf/0x20
inet_init+0x406/0x590
do_one_initcall+0x9d/0x2e0
do_initcalls+0x23b/0x280
kernel_init_freeable+0x445/0x490
kernel_init+0x20/0x1d0
ret_from_fork+0x46/0x80
ret_from_fork_asm+0x1a/0x30
</TASK>
irq event stamp: 584330
hardirqs last enabled at (584338): [<ffffffff8168bf87>] __up_console_sem+0x77/0xb0
hardirqs last disabled at (584345): [<ffffffff8168bf6c>] __up_console_sem+0x5c/0xb0
softirqs last enabled at (583242): [<ffffffff833ee96d>] netlink_insert+0x14d/0x470
softirqs last disabled at (583754): [<ffffffff8317c8cd>] netif_napi_add_weight_locked+0x77d/0xba0on kernel built with MAX_SKB_FRAGS=45, where SKB_WITH_OVERHEAD(1024) is smaller than GRO_MAX_HEAD.
Such built additionally contains the revert of the single page frag cache so that napi_get_frags() ends up using the page frag allocator, triggering the splat.
Note that the underlying issue is independent from the mentioned revert; address it ensuring that the small head cache will fit either TCP and GRO allocation and updating napi_alloc_skb() and __netdev_alloc_skb() to select kmalloc() usage for any allocation fitting such cache.
--- include/net/gro.h | 3 +++ net/core/gro.c | 3 --- net/core/skbuff.c | 10 +++++++--- 3 files changed, 10 insertions(+), 6 deletions(-)
include/net/gro.h +3 -0
@@ -11,6 +11,9 @@#include <net/udp.h> #include <net/hotdata.h> +/* This should be increased if a protocol with a bigger head is added. */ +#define GRO_MAX_HEAD (MAX_HEADER + 128) + struct napi_gro_cb { union { struct {
net/core/gro.c +0 -3
@@ -7,9 +7,6 @@#define MAX_GRO_SKBS 8 -/* This should be increased if a protocol with a bigger head is added. */ -#define GRO_MAX_HEAD (MAX_HEADER + 128) -static DEFINE_SPINLOCK (offload_lock);/**
net/core/skbuff.c +7 -3
@@ -69,6 +69,7 @@#include <net/dst.h> #include <net/sock.h> #include <net/checksum.h> +#include <net/gro.h> #include <net/gso.h> #include <net/hotdata.h> #include <net/ip6_checksum.h>
@@ -95,7 +96,9 @@static struct kmem_cache *skbuff_ext_cache__ro_after_init ;#endif -#define SKB_SMALL_HEAD_SIZE SKB_HEAD_ALIGN(MAX_TCP_HEADER) +#define GRO_MAX_HEAD_PAD (GRO_MAX_HEAD + NET_SKB_PAD + NET_IP_ALIGN) +#define SKB_SMALL_HEAD_SIZE SKB_HEAD_ALIGN(max(MAX_TCP_HEADER, \ + GRO_MAX_HEAD_PAD))/* We want SKB_SMALL_HEAD_CACHE_SIZE to not be a power of two. * This should ensure that SKB_SMALL_HEAD_HEADROOM is a unique
@@ -736,7 +739,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,/* If requested length is either too small or too big, * we use kmalloc() for skb->head allocation. */ -if (len <=SKB_WITH_OVERHEAD (1024 ) || +if (len <=SKB_WITH_OVERHEAD (SKB_SMALL_HEAD_CACHE_SIZE ) || len >SKB_WITH_OVERHEAD (PAGE_SIZE ) || (gfp_mask & (__GFP_DIRECT_RECLAIM |GFP_DMA ))) { skb =__alloc_skb (len, gfp_mask,SKB_ALLOC_RX ,NUMA_NO_NODE );
@@ -816,7 +819,8 @@ struct sk_buff *napi_alloc_skb(struct napi_struct *napi, unsigned int len)* When the small frag allocator is available, prefer it over kmalloc * for small fragments */ -if ((!NAPI_HAS_SMALL_PAGE_FRAG && len <=SKB_WITH_OVERHEAD (1024 )) || +if ((!NAPI_HAS_SMALL_PAGE_FRAG && + len <=SKB_WITH_OVERHEAD (SKB_SMALL_HEAD_CACHE_SIZE )) || len >SKB_WITH_OVERHEAD (PAGE_SIZE ) || (gfp_mask & (__GFP_DIRECT_RECLAIM |GFP_DMA ))) { skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX | SKB_ALLOC_NAPI,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 49/138 rust: finish using custom FFI integer types
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 27c7518e7f1ccaaa43eb5f25dc362779d2dc2ccb upstream.
In the last kernel cycle we migrated most of the core::ffi cases in commit d072acda4862 ("rust: use custom FFI integer types"):
Currently FFI integer types are defined in libcore. This commit creates the ffi crate and asks bindgen to use that crate for FFI integer types instead of core::ffi.
This commit is preparatory and no type changes are made in this commit yet.
Finish now the few remaining/new cases so that we perform the actual remapping in the next commit as planned.
--- drivers/gpu/drm/drm_panic_qr.rs | 2 +- rust/kernel/device.rs | 4 ++-- rust/kernel/miscdevice.rs | 8 ++------ rust/kernel/security.rs | 2 +- rust/kernel/seq_file.rs | 2 +- samples/rust/rust_print_main.rs | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-)
drivers/gpu/drm/drm_panic_qr.rs +1 -1
@@ -931,7 +931,7 @@ impl QrImage<'_> {/// They must remain valid for the duration of the function call. #[no_mangle] pub unsafe extern "C" fn drm_panic_qr_generate ( - url: *const i8 , + url: *const kernel::ffi::c_char , data: *mut u8 , data_len:usize , data_size: usize,
rust/kernel/device.rs +2 -2
@@ -173,10 +173,10 @@ impl Device {#[cfg( CONFIG_PRINTK )] unsafe { bindings::_dev_printk ( - klevelas *const _ as *const core::ffi::c_char , + klevelas *const _ as *const crate ::ffi::c_char , self.as_raw (),c_str! ("%pA" ).as_char_ptr (), - &msgas *const _ as *const core::ffi::c_void , + &msgas *const _ as *const crate ::ffi::c_void , ) }; }
rust/kernel/miscdevice.rs +2 -6
@@ -11,16 +11,12 @@use crate ::{ bindings, error::{to_result,Error ,Result ,VTABLE_DEFAULT_ERROR }, + ffi::{c_int, c_long, c_uint, c_ulong}, prelude::*, str::CStr , types::{ForeignOwnable ,Opaque }, }; -use core::{ - ffi::{c_int, c_long, c_uint, c_ulong}, - marker::PhantomData , - mem::MaybeUninit , - pin::Pin , -}; +use core::{marker::PhantomData , mem::MaybeUninit , pin::Pin };/// Options for creating a misc device. #[derive( Copy , Clone )]
rust/kernel/security.rs +1 -1
@@ -19,7 +19,7 @@ use crate::{/// successful call to `security_secid_to_secctx`, that has not yet been destroyed by calling /// `security_release_secctx`. pub struct SecurityCtx { - secdata: *mut core::ffi::c_char , + secdata: *mut crate ::ffi::c_char , seclen:usize , }
rust/kernel/seq_file.rs +1 -1
@@ -36,7 +36,7 @@ impl SeqFile { bindings::seq_printf ( self.inner.get (),c_str! ("%pA" ).as_char_ptr (), - &argsas *const _ as *const core::ffi::c_void , + &argsas *const _ as *const crate ::ffi::c_void , ); } }
samples/rust/rust_print_main.rs +1 -1
@@ -83,7 +83,7 @@ impl Drop for RustPrint { }mod trace { -use core::ffi::c_int; +use kernel::ffi::c_int; kernel::declare_trace! {/// # Safety
Greg Kroah-Hartman
maintainerPATCH 50/138 rust: map `long` to `isize` and `char` to `u8`
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <[email protected]>
commit 1bae8729e50a900f41e9a1c17ae81113e4cf62b8 upstream.
The following FFI types are replaced compared to core::ffi:
1. char type is now always mapped to u8, since kernel uses -funsigned-char on the C code. core::ffi maps it to platform default ABI, which can be either signed or unsigned.
2. long is now always mapped to isize. It's very common in the kernel to use long to represent a pointer-sized integer, and in fact intptr_t is a typedef of long in the kernel. Enforce this mapping rather than mapping to i32/i64 depending on platform can save us a lot of unnecessary casts.
[ Moved uaccess changes from the next commit, since they were
irrefutable patterns that Rust >= 1.82.0 warns about. Reworded slightly and reformatted a few documentation comments. Rebased on top of rust-next. Added the removal of two casts to avoid Clippy warnings. - Miguel ]
--- rust/ffi.rs | 37 ++++++++++++++++++++++++++++++++++++- rust/kernel/error.rs | 5 +---- rust/kernel/firmware.rs | 2 +- rust/kernel/miscdevice.rs | 4 ++-- rust/kernel/uaccess.rs | 27 +++++++-------------------- 5 files changed, 47 insertions(+), 28 deletions(-)
rust/ffi.rs +36 -1
@@ -10,4 +10,39 @@#![no_std] -pub use core::ffi::*; +macro_rules! alias { + ($($name:ident = $ty:ty;)*) => {$( +#[allow(non_camel_case_types, missing_docs)] +pub type $name = $ty; + +// Check size compatibility with `core`. +const _: () =assert! ( + core::mem::size_of ::<$name>() == core::mem::size_of ::<core::ffi::$name>() + ); + )*} +} + +alias! { +// `core::ffi::c_char` is either `i8` or `u8` depending on architecture. In the kernel, we use +// `-funsigned-char` so it's always mapped to `u8`. + c_char =u8 ; + + c_schar =i8 ; + c_uchar =u8 ; + + c_short =i16 ; + c_ushort =u16 ; + + c_int =i32 ; + c_uint =u32 ; + +// In the kernel, `intptr_t` is defined to be `long` in all platforms, so we can map the type to +// `isize`. + c_long =isize ; + c_ulong =usize ; + + c_longlong =i64 ; + c_ulonglong =u64 ; +} + +pub use core::ffi::c_void;
rust/kernel/error.rs +1 -4
@@ -153,11 +153,8 @@ impl Error {/// Returns the error encoded as a pointer. pub fn to_ptr <T >(self) -> *mut T { -#[cfg_attr(target_pointer_width = "32" , allow(clippy::useless_conversion))] // SAFETY: `self.0` is a valid error due to its invariant. -unsafe { - bindings::ERR_PTR (self.0 .get ().into ())as *mut _ - } +unsafe { bindings::ERR_PTR (self.0 .get ()as _ )as *mut _ } }/// Returns a string representing the error, if one exists.
rust/kernel/firmware.rs +1 -1
@@ -12,7 +12,7 @@ use core::ptr::NonNull;/// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`, /// `bindings::firmware_request_platform`, `bindings::request_firmware_direct`. struct FwFunc ( -unsafe extern "C" fn (*mut *const bindings::firmware , *const i8 , *mut bindings::device ) ->i32 , +unsafe extern "C" fn (*mut *const bindings::firmware , *const u8 , *mut bindings::device ) ->i32 , );impl FwFunc {
rust/kernel/miscdevice.rs +2 -2
@@ -225,7 +225,7 @@ unsafe extern "C" fn fops_ioctl<T: MiscD// SAFETY: Ioctl calls can borrow the private data of the file. let device =unsafe { <T ::Ptr as ForeignOwnable >::borrow (private) }; -match T ::ioctl (device, cmd, argas usize ) { +match T ::ioctl (device, cmd, arg) {Ok (ret) => retas c_long ,Err (err) => err.to_errno ()as c_long , }
@@ -245,7 +245,7 @@ unsafe extern "C" fn fops_compat_ioctl<T// SAFETY: Ioctl calls can borrow the private data of the file. let device =unsafe { <T ::Ptr as ForeignOwnable >::borrow (private) }; -match T ::compat_ioctl (device, cmd, argas usize ) { +match T ::compat_ioctl (device, cmd, arg) {Ok (ret) => retas c_long ,Err (err) => err.to_errno ()as c_long , }
rust/kernel/uaccess.rs +7 -20
@@ -8,7 +8,7 @@ use crate::{ alloc::Flags, bindings, error::Result, - ffi::{c_ulong, c_void}, + ffi::c_void, prelude::*, transmute::{AsBytes, FromBytes}, };
@@ -224,13 +224,9 @@ impl UserSliceReader {if len > self.length {return Err (EFAULT ); } -let Ok (len_ulong) = c_ulong::try_from (len)else { -return Err (EFAULT ); - }; -// SAFETY: `out_ptr` points into a mutable slice of length `len_ulong`, so we may write +// SAFETY: `out_ptr` points into a mutable slice of length `len`, so we may write // that many bytes to it. -let res = -unsafe { bindings::copy_from_user (out_ptr, self.ptras *const c_void , len_ulong) }; +let res =unsafe { bindings::copy_from_user (out_ptr, self.ptras *const c_void , len) };if res !=0 {return Err (EFAULT ); }
@@ -259,9 +255,6 @@ impl UserSliceReader {if len > self.length {return Err (EFAULT ); } -let Ok (len_ulong) = c_ulong::try_from (len)else { -return Err (EFAULT ); - };let mut out:MaybeUninit <T > =MaybeUninit ::uninit ();// SAFETY: The local variable `out` is valid for writing `size_of::<T>()` bytes. //
@@ -272,7 +265,7 @@ impl UserSliceReader { bindings::_copy_from_user ( out.as_mut_ptr ().cast ::<c_void >(), self.ptras *const c_void , - len_ulong, + len, ) };if res !=0 {
@@ -335,12 +328,9 @@ impl UserSliceWriter {if len > self.length {return Err (EFAULT ); } -let Ok (len_ulong) = c_ulong::try_from (len)else { -return Err (EFAULT ); - }; -// SAFETY: `data_ptr` points into an immutable slice of length `len_ulong`, so we may read +// SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read // that many bytes from it. -let res =unsafe { bindings::copy_to_user (self.ptras *mut c_void , data_ptr, len_ulong) }; +let res =unsafe { bindings::copy_to_user (self.ptras *mut c_void , data_ptr, len) };if res !=0 {return Err (EFAULT ); }
@@ -359,9 +349,6 @@ impl UserSliceWriter {if len > self.length {return Err (EFAULT ); } -let Ok (len_ulong) = c_ulong::try_from (len)else { -return Err (EFAULT ); - };// SAFETY: The reference points to a value of type `T`, so it is valid for reading // `size_of::<T>()` bytes. //
@@ -372,7 +359,7 @@ impl UserSliceWriter { bindings::_copy_to_user ( self.ptras *mut c_void , (valueas *const T ).cast ::<c_void >(), - len_ulong, + len, ) };if res !=0 {
Greg Kroah-Hartman
maintainerPATCH 51/138 rust: cleanup unnecessary casts
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <[email protected]>
commit 9b98be76855f14bd5180b59c1ac646b5add98f33 upstream.
With long mapped to isize, size_t/__kernel_size_t mapped to usize and char mapped to u8, many of the existing casts are no longer necessary.
[ Moved uaccess changes to the previous commit, since they were
irrefutable patterns that Rust >= 1.82.0 warns about. Removed a couple casts that now use c"" literals. Rebased on top of rust-next. - Miguel ]
--- rust/kernel/print.rs | 4 ++-- rust/kernel/str.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-)
rust/kernel/print.rs +2 -2
@@ -107,7 +107,7 @@ pub unsafe fn call_printk(// SAFETY: TODO. unsafe { bindings::_printk ( - format_string.as_ptr ()as _ , + format_string.as_ptr (), module_name.as_ptr (), &argsas *const _ as *const c_void , );
@@ -128,7 +128,7 @@ pub fn call_printk_cont(args: fmt::Argum#[cfg( CONFIG_PRINTK )] unsafe { bindings::_printk ( - format_strings::CONT .as_ptr ()as _ , + format_strings::CONT .as_ptr (), &argsas *const _ as *const c_void , ); }
rust/kernel/str.rs +3 -3
@@ -189,7 +189,7 @@ impl CStr {// to a `NUL`-terminated C string. let len =unsafe { bindings::strlen (ptr) } +1 ;// SAFETY: Lifetime guaranteed by the safety precondition. -let bytes =unsafe { core::slice::from_raw_parts (ptras _ , lenas _ ) }; +let bytes =unsafe { core::slice::from_raw_parts (ptras _ , len) };// SAFETY: As `len` is returned by `strlen`, `bytes` does not contain interior `NUL`. // As we have added 1 to `len`, the last byte is known to be `NUL`. unsafe {Self ::from_bytes_with_nul_unchecked (bytes) }
@@ -248,7 +248,7 @@ impl CStr {/// Returns a C pointer to the string. #[inline] pub const fn as_char_ptr (&self) -> *const crate ::ffi::c_char { - self.0 .as_ptr ()as _ + self.0 .as_ptr () }/// Convert the string to a byte slice without the trailing `NUL` byte.
@@ -838,7 +838,7 @@ impl CString {// SAFETY: The buffer is valid for read because `f.bytes_written()` is bounded by `size` // (which the minimum buffer size) and is non-zero (we wrote at least the `NUL` terminator) // so `f.bytes_written() - 1` doesn't underflow. -let ptr =unsafe { bindings::memchr (buf.as_ptr ().cast (),0 , (f.bytes_written () -1 )as _ ) }; +let ptr =unsafe { bindings::memchr (buf.as_ptr ().cast (),0 , f.bytes_written () -1 ) };if !ptr.is_null () {return Err (EINVAL ); }
Greg Kroah-Hartman
maintainerPATCH 25/138 powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit d262a192d38e527faa5984629aabda2e0d1c4f54 ]
Erhard reported the following KASAN hit while booting his PowerMac G4 with a KASAN-enabled kernel 6.13-rc6:
BUG: KASAN: vmalloc-out-of-bounds in copy_to_kernel_nofault+0xd8/0x1c8 Write of size 8 at addr f1000000 by task chronyd/1293 CPU: 0 UID: 123 PID: 1293 Comm: chronyd Tainted: G W 6.13.0-rc6-PMacG4 #2 Tainted: [W]=WARN Hardware name: PowerMac3,6 7455 0x80010303 PowerMac Call Trace: [c2437590] [c1631a84] dump_stack_lvl+0x70/0x8c (unreliable) [c24375b0] [c0504998] print_report+0xdc/0x504 [c2437610] [c050475c] kasan_report+0xf8/0x108 [c2437690] [c0505a3c] kasan_check_range+0x24/0x18c [c24376a0] [c03fb5e4] copy_to_kernel_nofault+0xd8/0x1c8 [c24376c0] [c004c014] patch_instructions+0x15c/0x16c [c2437710] [c00731a8] bpf_arch_text_copy+0x60/0x7c [c2437730] [c0281168] bpf_jit_binary_pack_finalize+0x50/0xac [c2437750] [c0073cf4] bpf_int_jit_compile+0xb30/0xdec [c2437880] [c0280394] bpf_prog_select_runtime+0x15c/0x478 [c24378d0] [c1263428] bpf_prepare_filter+0xbf8/0xc14 [c2437990] [c12677ec] bpf_prog_create_from_user+0x258/0x2b4 [c24379d0] [c027111c] do_seccomp+0x3dc/0x1890 [c2437ac0] [c001d8e0] system_call_exception+0x2dc/0x420 [c2437f30] [c00281ac] ret_from_syscall+0x0/0x2c --- interrupt: c00 at 0x5a1274 NIP: 005a1274 LR: 006a3b3c CTR: 005296c8 REGS: c2437f40 TRAP: 0c00 Tainted: G W (6.13.0-rc6-PMacG4) MSR: 0200f932 <VEC,EE,PR,FP,ME,IR,DR,RI> CR: 24004422 XER: 00000000
GPR00: 00000166 af8f3fa0 a7ee3540 00000001 00000000 013b6500 005a5858 0200f932
GPR08: 00000000 00001fe9 013d5fc8 005296c8 2822244c 00b2fcd8 00000000 af8f4b57
GPR16: 00000000 00000001 00000000 00000000 00000000 00000001 00000000 00000002
GPR24: 00afdbb0 00000000 00000000 00000000 006e0004 013ce060 006e7c1c 00000001 NIP [005a1274] 0x5a1274
LR [006a3b3c] 0x6a3b3c
--- interrupt: c00
The buggy address belongs to the virtual mapping at
[f1000000, f1002000) created by:
text_area_cpu_up+0x20/0x190
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:00000000 index:0x0 pfn:0x76e30
flags: 0x80000000(zone=2)
raw: 80000000 00000000 00000122 00000000 00000000 00000000 ffffffff 00000001
raw: 00000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
f0ffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0ffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>f1000000: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
^
f1000080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
f1000100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
==================================================================f8 corresponds to KASAN_VMALLOC_INVALID which means the area is not initialised hence not supposed to be used yet.
Powerpc text patching infrastructure allocates a virtual memory area using get_vm_area() and flags it as VM_ALLOC. But that flag is meant to be used for vmalloc() and vmalloc() allocated memory is not supposed to be used before a call to __vmalloc_node_range() which is never called for that area.
That went undetected until commit e4137f08816b ("mm, kasan, kmsan:
instrument copy_from/to_kernel_nofault")
The area allocated by text_area_cpu_up() is not vmalloc memory, it is mapped directly on demand when needed by map_kernel_page(). There is no VM flag corresponding to such usage, so just pass no flag. That way the area will be unpoisonned and usable immediately.
--- arch/powerpc/lib/code-patching.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/lib/code-patching.c +1 -1
@@ -108,7 +108,7 @@ static int text_area_cpu_up(unsigned int cpu)unsigned long addr;int err; - area =get_vm_area (PAGE_SIZE ,VM_ALLOC ); + area =get_vm_area (PAGE_SIZE ,0 );if (!area) {WARN_ONCE (1 ,"Failed to create text area for cpu %d\n" , cpu);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 52/138 bpf, test_run: Fix use-after-free issue in eth_skb_pkt_type()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shigeru Yoshida <[email protected]>
[ Upstream commit 6b3d638ca897e099fa99bd6d02189d3176f80a47 ]
KMSAN reported a use-after-free issue in eth_skb_pkt_type()[1]. The cause of the issue was that eth_skb_pkt_type() accessed skb's data that didn't contain an Ethernet header. This occurs when bpf_prog_test_run_xdp() passes an invalid value as the user_data argument to bpf_test_init().
Fix this by returning an error when user_data is less than ETH_HLEN in bpf_test_init(). Additionally, remove the check for "if (user_size > size)" as it is unnecessary.
[1]
BUG: KMSAN: use-after-free in eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] BUG: KMSAN: use-after-free in eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 __xdp_build_skb_from_frame+0x5a8/0xa50 net/core/xdp.c:635 xdp_recv_frames net/bpf/test_run.c:272 [inline] xdp_test_run_batch net/bpf/test_run.c:361 [inline] bpf_test_run_xdp_live+0x2954/0x3330 net/bpf/test_run.c:390 bpf_prog_test_run_xdp+0x148e/0x1b10 net/bpf/test_run.c:1318 bpf_prog_test_run+0x5b7/0xa30 kernel/bpf/syscall.c:4371 __sys_bpf+0x6a6/0xe20 kernel/bpf/syscall.c:5777 __do_sys_bpf kernel/bpf/syscall.c:5866 [inline] __se_sys_bpf kernel/bpf/syscall.c:5864 [inline] __x64_sys_bpf+0xa4/0xf0 kernel/bpf/syscall.c:5864 x64_sys_call+0x2ea0/0x3d90 arch/x86/include/generated/asm/syscalls_64.h:322 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xd9/0x1d0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
free_pages_prepare mm/page_alloc.c:1056 [inline] free_unref_page+0x156/0x1320 mm/page_alloc.c:2657 __free_pages+0xa3/0x1b0 mm/page_alloc.c:4838 bpf_ringbuf_free kernel/bpf/ringbuf.c:226 [inline] ringbuf_map_free+0xff/0x1e0 kernel/bpf/ringbuf.c:235 bpf_map_free kernel/bpf/syscall.c:838 [inline] bpf_map_free_deferred+0x17c/0x310 kernel/bpf/syscall.c:862 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa2b/0x1b60 kernel/workqueue.c:3310 worker_thread+0xedf/0x1550 kernel/workqueue.c:3391 kthread+0x535/0x6b0 kernel/kthread.c:389 ret_from_fork+0x6e/0x90 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 CPU: 1 UID: 0 PID: 17276 Comm: syz.1.16450 Not tainted 6.12.0-05490-g9bb88c659673 #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
--- net/bpf/test_run.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
net/bpf/test_run.c +1 -4
@@ -660,12 +660,9 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,void __user *data_in =u64_to_user_ptr (kattr->test.data_in);void *data; -if (size <ETH_HLEN || size >PAGE_SIZE - headroom - tailroom) +if (user_size <ETH_HLEN || user_size >PAGE_SIZE - headroom - tailroom)return ERR_PTR (-EINVAL ); -if (user_size > size) -return ERR_PTR (-EMSGSIZE ); - size =SKB_DATA_ALIGN (size); data =kzalloc (size + headroom + tailroom,GFP_USER );if (!data)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 53/138 bpf: unify VM_WRITE vs VM_MAYWRITE use in BPF map mmaping logic
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit 98671a0fd1f14e4a518ee06b19037c20014900eb ]
For all BPF maps we ensure that VM_MAYWRITE is cleared when memory-mapping BPF map contents as initially read-only VMA. This is because in some cases BPF verifier relies on the underlying data to not be modified afterwards by user space, so once something is mapped read-only, it shouldn't be re-mmap'ed as read-write.
As such, it's not necessary to check VM_MAYWRITE in bpf_map_mmap() and map->ops->map_mmap() callbacks: VM_WRITE should be consistently set for read-write mappings, and if VM_WRITE is not set, there is no way for user space to upgrade read-only mapping to read-write one.
This patch cleans up this VM_WRITE vs VM_MAYWRITE handling within bpf_map_mmap(), which is an entry point for any BPF map mmap()-ing logic. We also drop unnecessary sanitization of VM_MAYWRITE in BPF ringbuf's map_mmap() callback implementation, as it is already performed by common code in bpf_map_mmap().
Note, though, that in bpf_map_mmap_{open,close}() callbacks we can't drop VM_MAYWRITE use, because it's possible (and is outside of subsystem's control) to have initially read-write memory mapping, which is subsequently dropped to read-only by user space through mprotect(). In such case, from BPF verifier POV it's read-write data throughout the lifetime of BPF map, and is counted as "active writer".
But its VMAs will start out as VM_WRITE|VM_MAYWRITE, then mprotect() can change it to just VM_MAYWRITE (and no VM_WRITE), so when its finally munmap()'ed and bpf_map_mmap_close() is called, vm_flags will be just VM_MAYWRITE, but we still need to decrement active writer count with bpf_map_write_active_dec() as it's still considered to be a read-write mapping by the rest of BPF subsystem.
Similar reasoning applies to bpf_map_mmap_open(), which is called whenever mmap(), munmap(), and/or mprotect() forces mm subsystem to split original VMA into multiple discontiguous VMAs.
Memory-mapping handling is a bit tricky, yes.
Stable-dep-of: bc27c52eea18 ("bpf: avoid holding freeze_mutex during mmap operation")
--- kernel/bpf/ringbuf.c | 4 ---- kernel/bpf/syscall.c | 10 ++++++++-- 2 files changed, 8 insertions(+), 6 deletions(-)
kernel/bpf/ringbuf.c +0 -4
@@ -268,8 +268,6 @@ static int ringbuf_map_mmap_kern(struct bpf_map *map, struct vm_area_struct *vma/* allow writable mapping for the consumer_pos only */ if (vma->vm_pgoff !=0 || vma->vm_end - vma->vm_start !=PAGE_SIZE )return -EPERM ; - }else { -vm_flags_clear (vma,VM_MAYWRITE ); }/* remap_vmalloc_range() checks size and offset constraints */ return remap_vmalloc_range(vma, rb_map->rb,
@@ -289,8 +287,6 @@ static int ringbuf_map_mmap_user(struct bpf_map *map, struct vm_area_struct *vma* position, and the ring buffer data itself. */ return -EPERM ; - }else { -vm_flags_clear (vma,VM_MAYWRITE ); }/* remap_vmalloc_range() checks size and offset constraints */ return remap_vmalloc_range (vma, rb_map->rb, vma->vm_pgoff +RINGBUF_PGOFF );
kernel/bpf/syscall.c +8 -2
@@ -1061,15 +1061,21 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &bpf_map_default_vmops; vma->vm_private_data = map;vm_flags_clear (vma,VM_MAYEXEC ); +/* If mapping is read-only, then disallow potentially re-mapping with +* PROT_WRITE by dropping VM_MAYWRITE flag. This VM_MAYWRITE clearing +* means that as far as BPF map's memory-mapped VMAs are concerned, +* VM_WRITE and VM_MAYWRITE and equivalent, if one of them is set, +* both should be set, so we can forget about VM_MAYWRITE and always +* check just VM_WRITE +*/ if (!(vma->vm_flags &VM_WRITE )) -/* disallow re-mapping with PROT_WRITE */ vm_flags_clear (vma,VM_MAYWRITE ); err = map->ops->map_mmap (map, vma);if (err) goto out; -if (vma->vm_flags &VM_MAYWRITE ) +if (vma->vm_flags &VM_WRITE )bpf_map_write_active_inc (map); out:mutex_unlock (&map->freeze_mutex);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 54/138 bpf: avoid holding freeze_mutex during mmap operation
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit bc27c52eea189e8f7492d40739b7746d67b65beb ]
We use map->freeze_mutex to prevent races between map_freeze() and memory mapping BPF map contents with writable permissions. The way we naively do this means we'll hold freeze_mutex for entire duration of all the mm and VMA manipulations, which is completely unnecessary. This can potentially also lead to deadlocks, as reported by syzbot in [0].
So, instead, hold freeze_mutex only during writeability checks, bump (proactively) "write active" count for the map, unlock the mutex and proceed with mmap logic. And only if something went wrong during mmap logic, then undo that "write active" counter increment.
[0] https://lore.kernel.org/bpf/[email protected]/
--- kernel/bpf/syscall.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
kernel/bpf/syscall.c +10 -7
@@ -1031,7 +1031,7 @@ static const struct vm_operations_struct bpf_map_default_vmops = {static int bpf_map_mmap (struct file *filp,struct vm_area_struct *vma) {struct bpf_map *map = filp->private_data; -int err; +int err =0 ;if (!map->ops->map_mmap || !IS_ERR_OR_NULL (map->record))return -ENOTSUPP ;
@@ -1055,7 +1055,12 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) err = -EACCES ; goto out; } +bpf_map_write_active_inc (map); } +out: +mutex_unlock (&map->freeze_mutex); +if (err) +return err;/* set default open/close callbacks */ vma->vm_ops = &bpf_map_default_vmops;
@@ -1072,13 +1077,11 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)vm_flags_clear (vma,VM_MAYWRITE ); err = map->ops->map_mmap (map, vma); -if (err) - goto out; +if (err) { +if (vma->vm_flags &VM_WRITE ) +bpf_map_write_active_dec (map); + } -if (vma->vm_flags &VM_WRITE ) -bpf_map_write_active_inc (map); -out: -mutex_unlock (&map->freeze_mutex);return err; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 55/138 bpf: Disable non stream socket for strparser
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 5459cce6bf49e72ee29be21865869c2ac42419f5 ]
Currently, only TCP supports strparser, but sockmap doesn't intercept non-TCP connections to attach strparser. For example, with UDP, although the read/write handlers are replaced, strparser is not executed due to the lack of a read_sock operation.
Furthermore, in udp_bpf_recvmsg(), it checks whether the psock has data, and if not, it falls back to the native UDP read interface, making UDP + strparser appear to read correctly. According to its commit history, this behavior is unexpected.
Moreover, since UDP lacks the concept of streams, we intercept it directly.
--- net/core/sock_map.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/core/sock_map.c +4 -1
@@ -303,7 +303,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)write_lock_bh (&sk->sk_callback_lock);if (stream_parser && stream_verdict && !psock->saved_data_ready) { - ret =sk_psock_init_strp (sk, psock); +if (sk_is_tcp (sk)) + ret =sk_psock_init_strp (sk, psock); +else + ret = -EOPNOTSUPP ;if (ret) {write_unlock_bh (&sk->sk_callback_lock);sk_psock_put (sk, psock);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 56/138 bpf: Fix deadlock when freeing cgroup storage
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Wu <[email protected]>
[ Upstream commit c78f4afbd962f43a3989f45f3ca04300252b19b5 ]
The following commitbc235cdb423a ("bpf: Prevent deadlock from recursive bpf_task_storage_[get|delete]") first introduced deadlock prevention for fentry/fexit programs attaching on bpf_task_storage helpers. That commit also employed the logic in map free path in its v6 version.
Later bpf_cgrp_storage was first introduced inc4bcfb38a95e ("bpf: Implement cgroup storage available to non-cgroup-attached bpf progs") which faces the same issue as bpf_task_storage, instead of its busy counter, NULL was passed to bpf_local_storage_map_free() which opened
a window to cause deadlock:
<TASK> (acquiring local_storage->lock) _raw_spin_lock_irqsave+0x3d/0x50 bpf_local_storage_update+0xd1/0x460 bpf_cgrp_storage_get+0x109/0x130 bpf_prog_a4d4a370ba857314_cgrp_ptr+0x139/0x170 ? __bpf_prog_enter_recur+0x16/0x80 bpf_trampoline_6442485186+0x43/0xa4 cgroup_storage_ptr+0x9/0x20 (holding local_storage->lock) bpf_selem_unlink_storage_nolock.constprop.0+0x135/0x160 bpf_selem_unlink_storage+0x6f/0x110 bpf_local_storage_map_free+0xa2/0x110 bpf_map_free_deferred+0x5b/0x90 process_one_work+0x17c/0x390 worker_thread+0x251/0x360 kthread+0xd2/0x100 ret_from_fork+0x34/0x50 ret_from_fork_asm+0x1a/0x30 </TASK>
Progs:
- A: SEC("fentry/cgroup_storage_ptr")
- cgid (BPF_MAP_TYPE_HASH)
Record the id of the cgroup the current task belonging to in this hash map, using the address of the cgroup as the map key.
- cgrpa (BPF_MAP_TYPE_CGRP_STORAGE)
If current task is a kworker, lookup the above hash map using function parameter @owner as the key to get its corresponding cgroup id which is then used to get a trusted pointer to the cgroup through bpf_cgroup_from_id(). This trusted pointer can then be passed to bpf_cgrp_storage_get() to finally trigger the deadlock issue.
- B: SEC("tp_btf/sys_enter")
- cgrpb (BPF_MAP_TYPE_CGRP_STORAGE)
The only purpose of this prog is to fill Prog A's hash map by calling bpf_cgrp_storage_get() for as many userspace tasks as possible.
Steps to reproduce:
- Run A;
- while (true) { Run B; Destroy B; }
Fix this issue by passing its busy counter to the free procedure so it can be properly incremented before storage/smap locking.
--- kernel/bpf/bpf_cgrp_storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/bpf_cgrp_storage.c +1 -1
@@ -154,7 +154,7 @@ static struct bpf_map *cgroup_storage_map_alloc(union bpf_attr *attr)static void cgroup_storage_map_free (struct bpf_map *map) { -bpf_local_storage_map_free (map, &cgroup_cache,NULL ); +bpf_local_storage_map_free (map, &cgroup_cache, &bpf_cgrp_storage_busy); }/* *gfp_flags* is a hidden argument provided by the verifier */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 26/138 ASoC: imx-audmix: remove cpu_mclk which is from cpu dai device
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 571b69f2f9b1ec7cf7d0e9b79e52115a87a869c4 ]
When defer probe happens, there may be below error:
platform 59820000.sai: Resources present before probing
The cpu_mclk clock is from the cpu dai device, if it is not released, then the cpu dai device probe will fail for the second time.
The cpu_mclk is used to get rate for rate constraint, rate constraint may be specific for each platform, which is not necessary for machine driver, so remove it.
--- sound/soc/fsl/imx-audmix.c | 31 ------------------------------- 1 file changed, 31 deletions(-)
sound/soc/fsl/imx-audmix.c +0 -31
@@ -23,7 +23,6 @@ struct imx_audmix {struct snd_soc_card card;struct platform_device *audmix_pdev;struct platform_device *out_pdev; -struct clk *cpu_mclk;int num_dai;struct snd_soc_dai_link *dai;int num_dai_conf;
@@ -32,34 +31,11 @@ struct imx_audmix {struct snd_soc_dapm_route *dapm_routes; }; -static const u32 imx_audmix_rates[] = { -8000 ,12000 ,16000 ,24000 ,32000 ,48000 ,64000 ,96000 , -}; - -static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = { - .count =ARRAY_SIZE (imx_audmix_rates), - .list = imx_audmix_rates, -}; -static int imx_audmix_fe_startup (struct snd_pcm_substream *substream) { -struct snd_soc_pcm_runtime *rtd =snd_soc_substream_to_rtd (substream); -struct imx_audmix *priv =snd_soc_card_get_drvdata (rtd->card);struct snd_pcm_runtime *runtime = substream->runtime; -struct device *dev = rtd->card->dev; -unsigned long clk_rate =clk_get_rate (priv->cpu_mclk);int ret; -if (clk_rate %24576000 ==0 ) { - ret =snd_pcm_hw_constraint_list (runtime,0 , -SNDRV_PCM_HW_PARAM_RATE , - &imx_audmix_rate_constraints); -if (ret <0 ) -return ret; - }else { -dev_warn (dev,"mclk may be not supported %lu\n" , clk_rate); - } - ret =snd_pcm_hw_constraint_minmax (runtime,SNDRV_PCM_HW_PARAM_CHANNELS ,1 ,8 );if (ret <0 )
@@ -323,13 +299,6 @@ static int imx_audmix_probe(struct platform_device *pdev) }put_device (&cpu_pdev->dev); - priv->cpu_mclk =devm_clk_get (&cpu_pdev->dev,"mclk1" ); -if (IS_ERR (priv->cpu_mclk)) { - ret =PTR_ERR (priv->cpu_mclk); -dev_err (&cpu_pdev->dev,"failed to get DAI mclk1: %d\n" , ret); -return ret; - } - priv->audmix_pdev = audmix_pdev; priv->out_pdev = cpu_pdev;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 27/138 vsock/virtio: fix variables initialization during resuming
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junnan Wu <[email protected]>
[ Upstream commit 55eff109e76a14e5ed10c8c3c3978d20a35e2a4d ]
When executing suspend to ram twice in a row,
the rx_buf_nr and rx_buf_max_nr increase to three times vq->num_free. Then after virtqueue_get_buf and rx_buf_nr decreased
in function virtio_transport_rx_work,
the condition to fill rx buffer
(rx_buf_nr < rx_buf_max_nr / 2) will never be met.
It is because that rx_buf_nr and rx_buf_max_nr are initialized only in virtio_vsock_probe(),
but they should be reset whenever virtqueues are recreated, like after a suspend/resume.
Move the rx_buf_nr and rx_buf_max_nr initialization in virtio_vsock_vqs_init(), so we are sure that they are properly initialized, every time we initialize the virtqueues, either when we load the driver or after a suspend/resume.
To prevent erroneous atomic load operations on the queued_replies in the virtio_transport_send_pkt_work() function
which may disrupt the scheduling of vsock->rx_work
when transmitting reply-required socket packets,
this atomic variable must undergo synchronized initialization alongside the preceding two variables after a suspend/resume.
--- net/vmw_vsock/virtio_transport.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
net/vmw_vsock/virtio_transport.c +7 -3
@@ -670,6 +670,13 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) };int ret; +mutex_lock (&vsock->rx_lock); + vsock->rx_buf_nr =0 ; + vsock->rx_buf_max_nr =0 ; +mutex_unlock (&vsock->rx_lock); + +atomic_set (&vsock->queued_replies,0 ); + ret =virtio_find_vqs (vdev,VSOCK_VQ_MAX , vsock->vqs, vqs_info,NULL );if (ret <0 )return ret;
@@ -779,9 +786,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) vsock->vdev = vdev; - vsock->rx_buf_nr =0 ; - vsock->rx_buf_max_nr =0 ; -atomic_set (&vsock->queued_replies,0 );mutex_init (&vsock->tx_lock);mutex_init (&vsock->rx_lock);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 28/138 geneve: Fix use-after-free in geneve_find_dev().
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 9593172d93b9f91c362baec4643003dc29802929 ]
syzkaller reported a use-after-free in geneve_find_dev() [0] without repro.
geneve_configure() links struct geneve_dev.next to net_generic(net, geneve_net_id)->geneve_list.
The net here could differ from dev_net(dev) if IFLA_NET_NS_PID, IFLA_NET_NS_FD, or IFLA_TARGET_NETNSID is set.
When dev_net(dev) is dismantled, geneve_exit_batch_rtnl() finally calls unregister_netdevice_queue() for each dev in the netns, and later the dev is freed.
However, its geneve_dev.next is still linked to the backend UDP socket netns.
Then, use-after-free will occur when another geneve dev is created in the netns.
Let's call geneve_dellink() instead in geneve_destroy_tunnels().
[0]:
BUG: KASAN: slab-use-after-free in geneve_find_dev drivers/net/geneve.c:1295 [inline] BUG: KASAN: slab-use-after-free in geneve_configure+0x234/0x858 drivers/net/geneve.c:1343 Read of size 2 at addr ffff000054d6ee24 by task syz.1.4029/13441 CPU: 1 UID: 0 PID: 13441 Comm: syz.1.4029 Not tainted 6.13.0-g0ad9617c78ac #24 dc35ca22c79fb82e8e7bc5c9c9adafea898b1e3d Hardware name: linux,dummy-virt (DT) Call trace: show_stack+0x38/0x50 arch/arm64/kernel/stacktrace.c:466 (C) __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0xbc/0x108 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x16c/0x6f0 mm/kasan/report.c:489 kasan_report+0xc0/0x120 mm/kasan/report.c:602 __asan_report_load2_noabort+0x20/0x30 mm/kasan/report_generic.c:379 geneve_find_dev drivers/net/geneve.c:1295 [inline] geneve_configure+0x234/0x858 drivers/net/geneve.c:1343 geneve_newlink+0xb8/0x128 drivers/net/geneve.c:1634 rtnl_newlink_create+0x23c/0x868 net/core/rtnetlink.c:3795 __rtnl_newlink net/core/rtnetlink.c:3906 [inline] rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021 rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911 netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543 rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:713 [inline] __sock_sendmsg net/socket.c:728 [inline] ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568 ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622 __sys_sendmsg net/socket.c:2654 [inline] __do_sys_sendmsg net/socket.c:2659 [inline] __se_sys_sendmsg net/socket.c:2657 [inline] __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132 do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151 el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600 Allocated by task 13247: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x30/0x68 mm/kasan/common.c:68 kasan_save_alloc_info+0x44/0x58 mm/kasan/generic.c:568 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x84/0xa0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4298 [inline] __kmalloc_node_noprof+0x2a0/0x560 mm/slub.c:4304 __kvmalloc_node_noprof+0x9c/0x230 mm/util.c:645 alloc_netdev_mqs+0xb8/0x11a0 net/core/dev.c:11470 rtnl_create_link+0x2b8/0xb50 net/core/rtnetlink.c:3604 rtnl_newlink_create+0x19c/0x868 net/core/rtnetlink.c:3780 __rtnl_newlink net/core/rtnetlink.c:3906 [inline] rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021 rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911 netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543 rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892 sock_sendmsg_nosec net/socket.c:713 [inline] __sock_sendmsg net/socket.c:728 [inline] ____sys_sendmsg+0x410/0x6f8 net/socket.c:2568 ___sys_sendmsg+0x178/0x1d8 net/socket.c:2622 __sys_sendmsg net/socket.c:2654 [inline] __do_sys_sendmsg net/socket.c:2659 [inline] __se_sys_sendmsg net/socket.c:2657 [inline] __arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132 do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151 el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600 Freed by task 45: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x30/0x68 mm/kasan/common.c:68 kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:582 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x48/0x68 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2353 [inline] slab_free mm/slub.c:4613 [inline] kfree+0x140/0x420 mm/slub.c:4761 kvfree+0x4c/0x68 mm/util.c:688 netdev_release+0x94/0xc8 net/core/net-sysfs.c:2065 device_release+0x98/0x1c0 kobject_cleanup lib/kobject.c:689 [inline] kobject_release lib/kobject.c:720 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x2b0/0x438 lib/kobject.c:737 netdev_run_todo+0xe5c/0xfc8 net/core/dev.c:11185 rtnl_unlock+0x20/0x38 net/core/rtnetlink.c:151 cleanup_net+0x4fc/0x8c0 net/core/net_namespace.c:648 process_one_work+0x700/0x1398 kernel/workqueue.c:3236 process_scheduled_works kernel/workqueue.c:3317 [inline] worker_thread+0x8c4/0xe10 kernel/workqueue.c:3398 kthread+0x4bc/0x608 kernel/kthread.c:464 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:862 The buggy address belongs to the object at ffff000054d6e000 which belongs to the cache kmalloc-cg-4k of size 4096
The buggy address is located 3620 bytes inside of
freed 4096-byte region [ffff000054d6e000, ffff000054d6f000)
The buggy address belongs to the physical page: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x94d68
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 memcg:ffff000016276181
flags: 0x3fffe0000000040(head|node=0|zone=0|lastcpupid=0x1ffff)page_type: f5(slab)
raw: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
head: 03fffe0000000040 ffff0000c000f500 dead000000000122 0000000000000000
head: 0000000000000000 0000000000040004 00000001f5000000 ffff000016276181
head: 03fffe0000000003 fffffdffc1535a01 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff000054d6ed00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff000054d6ed80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff000054d6ee00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff000054d6ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff000054d6ef00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb--- drivers/net/geneve.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/net/geneve.c +3 -8
@@ -1907,16 +1907,11 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head)/* gather any geneve devices that were moved into this ns */ for_each_netdev_safe (net, dev, aux)if (dev->rtnl_link_ops == &geneve_link_ops) -unregister_netdevice_queue (dev, head); +geneve_dellink (dev, head);/* now gather any other geneve devices that were created in this ns */ -list_for_each_entry_safe (geneve, next, &gn->geneve_list, next) { -/* If geneve->dev is in the same netns, it was already added -* to the list by the previous loop. -*/ -if (!net_eq (dev_net (geneve->dev), net)) -unregister_netdevice_queue (geneve->dev, head); - } +list_for_each_entry_safe (geneve, next, &gn->geneve_list, next) +geneve_dellink (geneve->dev, head); } static void __net_exit geneve_exit_batch_rtnl(struct list_head *net_list,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 29/138 ALSA: hda/cirrus: Correct the full scale volume set logic
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaly Rodionov <[email protected]>
[ Upstream commit 08b613b9e2ba431db3bd15cb68ca72472a50ef5c ]
This patch corrects the full-scale volume setting logic. On certain platforms, the full-scale volume bit is required. The current logic mistakenly sets this bit and incorrectly clears reserved bit 0, causing the headphone output to be muted.
--- sound/pci/hda/patch_cs8409-tables.c | 6 +++--- sound/pci/hda/patch_cs8409.c | 20 +++++++++++--------- sound/pci/hda/patch_cs8409.h | 5 +++-- 3 files changed, 17 insertions(+), 14 deletions(-)
sound/pci/hda/patch_cs8409-tables.c +3 -3
@@ -121,7 +121,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f }, - { CS42L42_HP_CTL, 0x03 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIC_DET_CTL1, 0xB6 }, { CS42L42_TIPSENSE_CTL, 0xC2 }, { CS42L42_HS_CLAMP_DISABLE, 0x01 },
@@ -315,7 +315,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { CS42L42_ASP_TX_SZ_EN, 0x01 }, { CS42L42_PWR_CTL1, 0x0A }, { CS42L42_PWR_CTL2, 0x84 }, - { CS42L42_HP_CTL, 0x03 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f },
@@ -371,7 +371,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { CS42L42_ASP_TX_SZ_EN, 0x00 }, { CS42L42_PWR_CTL1, 0x0E }, { CS42L42_PWR_CTL2, 0x84 }, - { CS42L42_HP_CTL, 0x01 }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3f },
sound/pci/hda/patch_cs8409.c +11 -9
@@ -876,7 +876,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) { CS42L42_DET_INT_STATUS2, 0x00 }, { CS42L42_TSRS_PLUG_STATUS, 0x00 }, }; -int fsv_old, fsv_new; +unsigned int fsv;/* Bring CS42L42 out of Reset */ spec->gpio_data =snd_hda_codec_read (codec,CS8409_PIN_AFG ,0 ,AC_VERB_GET_GPIO_DATA ,0 );
@@ -893,13 +893,15 @@ static void cs42l42_resume(struct sub_codec *cs42l42)/* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read (cs42l42, irq_regs,ARRAY_SIZE (irq_regs)); - fsv_old =cs8409_i2c_read (cs42l42,CS42L42_HP_CTL ); -if (cs42l42->full_scale_vol ==CS42L42_FULL_SCALE_VOL_0DB ) - fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK ; -else - fsv_new = fsv_old &CS42L42_FULL_SCALE_VOL_MASK ; -if (fsv_new != fsv_old) -cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv_new); + fsv =cs8409_i2c_read (cs42l42,CS42L42_HP_CTL ); +if (cs42l42->full_scale_vol) { +// Set the full scale volume bit + fsv |=CS42L42_FULL_SCALE_VOL_MASK ; +cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv); + } +// Unmute analog channels A and B + fsv = (fsv & ~CS42L42_ANA_MUTE_AB ); +cs8409_i2c_write (cs42l42,CS42L42_HP_CTL , fsv);/* we have to explicitly allow unsol event handling even during the * resume phase so that the jack event is processed properly
@@ -920,7 +922,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, - { CS42L42_HP_CTL, 0x0F }, + { CS42L42_HP_CTL, 0x0D }, { CS42L42_ASP_RX_DAI0_EN, 0x00 }, { CS42L42_ASP_CLK_CFG, 0x00 }, { CS42L42_PWR_CTL1, 0xFE },
sound/pci/hda/patch_cs8409.h +3 -2
@@ -230,9 +230,10 @@ enum cs8409_coefficient_index_registers {#define CS42L42_PDN_TIMEOUT_US (250000)#define CS42L42_PDN_SLEEP_US (2000)#define CS42L42_INIT_TIMEOUT_MS (45) +#define CS42L42_ANA_MUTE_AB (0x0C)#define CS42L42_FULL_SCALE_VOL_MASK (2) -#define CS42L42_FULL_SCALE_VOL_0DB (1) -#define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) +#define CS42L42_FULL_SCALE_VOL_0DB (0) +#define CS42L42_FULL_SCALE_VOL_MINUS6DB (1)/* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 30/138 net/sched: cls_api: fix error handling causing NULL dereference
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre Riteau <[email protected]>
[ Upstream commit 071ed42cff4fcdd89025d966d48eabef59913bf2 ]
tcf_exts_miss_cookie_base_alloc() calls xa_alloc_cyclic() which can return 1 if the allocation succeeded after wrapping. This was treated as an error, with value 1 returned to caller tcf_exts_init_ex() which sets exts->actions to NULL and returns 1 to caller fl_change().
fl_change() treats err == 1 as success, calling tcf_exts_validate_ex() which calls tcf_action_init() with exts->actions as argument, where it is dereferenced.
Example trace:
BUG: kernel NULL pointer dereference, address: 0000000000000000 CPU: 114 PID: 16151 Comm: handler114 Kdump: loaded Not tainted 5.14.0-503.16.1.el9_5.x86_64 #1 RIP: 0010:tcf_action_init+0x1f8/0x2c0 Call Trace: tcf_action_init+0x1f8/0x2c0 tcf_exts_validate_ex+0x175/0x190 fl_change+0x537/0x1120 [cls_flower]
--- net/sched/cls_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/cls_api.c +1 -1
@@ -97,7 +97,7 @@ tcf_exts_miss_cookie_base_alloc(struct tcf_exts *exts, struct tcf_proto *tp, err =xa_alloc_cyclic (&tcf_exts_miss_cookies_xa, &n->miss_cookie_base, n, xa_limit_32b, &next,GFP_KERNEL ); -if (err) +if (err <0 ) goto err_xa_alloc; exts->miss_cookie_node = n;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 31/138 ALSA: seq: Drop UMP events when no UMP-conversion is set
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit e77aa4b2eaa7fb31b2a7a50214ecb946b2a8b0f6 ]
When a destination client is a user client in the legacy MIDI mode and it sets the no-UMP-conversion flag, currently the all UMP events are still passed as-is. But this may confuse the user-space, because the event packet size is different from the legacy mode.
Since we cannot handle UMP events in user clients unless it's running in the UMP client mode, we should filter out those events instead of accepting blindly. This patch addresses it by slightly adjusting the conditions for UMP event handling at the event delivery time.
--- sound/core/seq/seq_clientmgr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
sound/core/seq/seq_clientmgr.c +9 -3
@@ -678,12 +678,18 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client, dest_port->time_real);#if IS_ENABLED (CONFIG_SND_SEQ_UMP ) -if (!(dest->filter &SNDRV_SEQ_FILTER_NO_CONVERT )) { -if (snd_seq_ev_is_ump (event)) { +if (snd_seq_ev_is_ump (event)) { +if (!(dest->filter &SNDRV_SEQ_FILTER_NO_CONVERT )) { result =snd_seq_deliver_from_ump (client, dest, dest_port, event, atomic, hop); goto __skip; - }else if (snd_seq_client_is_ump (dest)) { + }else if (dest->type ==USER_CLIENT && + !snd_seq_client_is_ump (dest)) { + result =0 ;// drop the event + goto __skip; + } + }else if (snd_seq_client_is_ump (dest)) { +if (!(dest->filter &SNDRV_SEQ_FILTER_NO_CONVERT )) { result =snd_seq_deliver_to_ump (client, dest, dest_port, event, atomic, hop); goto __skip;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 22/138 powerpc/code-patching: Disable KASAN report during patching via temporary mm
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit dc9c5166c3cb044f8a001e397195242fd6796eee ]
Erhard reports the following KASAN hit on Talos II (power9) with kernel 6.13:
[ 12.028126] ================================================================== [ 12.028198] BUG: KASAN: user-memory-access in copy_to_kernel_nofault+0x8c/0x1a0 [ 12.028260] Write of size 8 at addr 0000187e458f2000 by task systemd/1
[ 12.028346] CPU: 87 UID: 0 PID: 1 Comm: systemd Tainted: G T 6.13.0-P9-dirty #3
[ 12.028408] Tainted: [T]=RANDSTRUCT
[ 12.028446] Hardware name: T2P9D01 REV 1.01 POWER9 0x4e1202 opal:skiboot-bc106a0 PowerNV
[ 12.028500] Call Trace:
[ 12.028536] [c000000008dbf3b0] [c000000001656a48] dump_stack_lvl+0xbc/0x110 (unreliable)
[ 12.028609] [c000000008dbf3f0] [c0000000006e2fc8] print_report+0x6b0/0x708
[ 12.028666] [c000000008dbf4e0] [c0000000006e2454] kasan_report+0x164/0x300
[ 12.028725] [c000000008dbf600] [c0000000006e54d4] kasan_check_range+0x314/0x370
[ 12.028784] [c000000008dbf640] [c0000000006e6310] __kasan_check_write+0x20/0x40
[ 12.028842] [c000000008dbf660] [c000000000578e8c] copy_to_kernel_nofault+0x8c/0x1a0
[ 12.028902] [c000000008dbf6a0] [c0000000000acfe4] __patch_instructions+0x194/0x210
[ 12.028965] [c000000008dbf6e0] [c0000000000ade80] patch_instructions+0x150/0x590
[ 12.029026] [c000000008dbf7c0] [c0000000001159bc] bpf_arch_text_copy+0x6c/0xe0
[ 12.029085] [c000000008dbf800] [c000000000424250] bpf_jit_binary_pack_finalize+0x40/0xc0
[ 12.029147] [c000000008dbf830] [c000000000115dec] bpf_int_jit_compile+0x3bc/0x930
[ 12.029206] [c000000008dbf990] [c000000000423720] bpf_prog_select_runtime+0x1f0/0x280
[ 12.029266] [c000000008dbfa00] [c000000000434b18] bpf_prog_load+0xbb8/0x1370
[ 12.029324] [c000000008dbfb70] [c000000000436ebc] __sys_bpf+0x5ac/0x2e00
[ 12.029379] [c000000008dbfd00] [c00000000043a228] sys_bpf+0x28/0x40
[ 12.029435] [c000000008dbfd20] [c000000000038eb4] system_call_exception+0x334/0x610
[ 12.029497] [c000000008dbfe50] [c00000000000c270] system_call_vectored_common+0xf0/0x280
[ 12.029561] --- interrupt: 3000 at 0x3fff82f5cfa8
[ 12.029608] NIP: 00003fff82f5cfa8 LR: 00003fff82f5cfa8 CTR: 0000000000000000
[ 12.029660] REGS: c000000008dbfe80 TRAP: 3000 Tainted: G T (6.13.0-P9-dirty)
[ 12.029735] MSR: 900000000280f032 <SF,HV,VEC,VSX,EE,PR,FP,ME,IR,DR,RI> CR: 42004848 XER: 00000000
[ 12.029855] IRQMASK: 0
GPR00: 0000000000000169 00003fffdcf789a0 00003fff83067100 0000000000000005
GPR04: 00003fffdcf78a98 0000000000000090 0000000000000000 0000000000000008
GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR12: 0000000000000000 00003fff836ff7e0 c000000000010678 0000000000000000
GPR16: 0000000000000000 0000000000000000 00003fffdcf78f28 00003fffdcf78f90
GPR20: 0000000000000000 0000000000000000 0000000000000000 00003fffdcf78f80
GPR24: 00003fffdcf78f70 00003fffdcf78d10 00003fff835c7239 00003fffdcf78bd8
GPR28: 00003fffdcf78a98 0000000000000000 0000000000000000 000000011f547580
[ 12.030316] NIP [00003fff82f5cfa8] 0x3fff82f5cfa8
[ 12.030361] LR [00003fff82f5cfa8] 0x3fff82f5cfa8
[ 12.030405] --- interrupt: 3000
[ 12.030444] ==================================================================Commit c28c15b6d28a ("powerpc/code-patching: Use temporary mm for Radix MMU") is inspired from x86 but unlike x86 is doesn't disable KASAN reports during patching. This wasn't a problem at the begining because __patch_mem() is not instrumented.
Commit 465cabc97b42 ("powerpc/code-patching: introduce patch_instructions()") use copy_to_kernel_nofault() to copy several instructions at once. But when using temporary mm the destination is not regular kernel memory but a kind of kernel-like memory located in user address space. Because it is not in kernel address space it is not covered by KASAN shadow memory. Since commit e4137f08816b ("mm, kasan, kmsan: instrument copy_from/to_kernel_nofault") KASAN reports bad accesses from copy_to_kernel_nofault(). Here a bad access to user memory is reported because KASAN detects the lack of shadow memory and the address is below TASK_SIZE.
Do like x86 in commit b3fd8e83ada0 ("x86/alternatives: Use temporary mm for text poking") and disable KASAN reports during patching when using temporary mm.
Close: https://lore.kernel.org/all/20250201151435.48400261@yea/
--- arch/powerpc/lib/code-patching.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/lib/code-patching.c +2 -0
@@ -493,7 +493,9 @@ static int __do_patch_instructions_mm(u32 *addr, u32 *code, size_t len, bool rep orig_mm =start_using_temp_mm (patching_mm); +kasan_disable_current (); err =__patch_instructions (patch_addr, code, len, repeat_instr); +kasan_enable_current ();/* context synchronisation performed by __patch_instructions */ stop_using_temp_mm (patching_mm, orig_mm);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 58/138 arm64: dts: rockchip: Fix lcdpwr_en pin for Cool Pi GenBook
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Yan <[email protected]>
[ Upstream commit a1d939055a22be06d8c12bf53afb258b9d38575f ]
According to the schematic, the lcdpwr_en pin is GPIO0_C4, not GPIO1_C4.
--- arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts +2 -2
@@ -113,7 +113,7 @@ vcc3v3_lcd: regulator-vcc3v3-lcd { compatible = "regulator-fixed"; regulator-name = "vcc3v3_lcd"; enable-active-high; - gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>; + gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&lcdpwr_en>; vin-supply = <&vcc3v3_sys>;
@@ -241,7 +241,7 @@ &pcie3x4 { &pinctrl { lcd { lcdpwr_en: lcdpwr-en { - rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>; + rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>; }; bl_en: bl-en {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 67/138 platform: cznic: CZNIC_PLATFORMS should depend on ARCH_MVEBU
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit dd0f05b98925111f4530d7dab774398cdb32e9e3 ]
CZ.NIC's Turris devices are based on Marvell EBU SoCs. Hence add a dependency on ARCH_MVEBU, to prevent asking the user about these drivers when configuring a kernel that cannot run on an affected CZ.NIC Turris system.
--- drivers/platform/cznic/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/platform/cznic/Kconfig +1 -0
@@ -6,6 +6,7 @@ menuconfig CZNIC_PLATFORMS bool "Platform support for CZ.NIC's Turris hardware" + depends on ARCH_MVEBU || COMPILE_TEST help Say Y here to be able to choose driver support for CZ.NIC's Turris devices. This option alone does not add any kernel code.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 68/138 nouveau/svm: fix missing folio unlock + put after make_device_exclusive_range()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit b3fefbb30a1691533cb905006b69b2a474660744 ]
In case we have to retry the loop, we are missing to unlock+put the folio. In that case, we will keep failing make_device_exclusive_range() because we cannot grab the folio lock, and even return from the function with the folio locked and referenced, effectively never succeeding the make_device_exclusive_range().
While at it, convert the other unlock+put to use a folio as well.
This was found by code inspection.
--- drivers/gpu/drm/nouveau/nouveau_svm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nouveau_svm.c +7 -2
@@ -590,6 +590,7 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm,unsigned long timeout = jiffies +msecs_to_jiffies (HMM_RANGE_DEFAULT_TIMEOUT );struct mm_struct *mm = svmm->notifier.mm; +struct folio *folio;struct page *page;unsigned long start = args->p.addr;unsigned long notifier_seq;
@@ -616,12 +617,16 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, ret = -EINVAL ; goto out; } + folio =page_folio (page);mutex_lock (&svmm->mutex);if (!mmu_interval_read_retry (¬ifier->notifier, notifier_seq))break ;mutex_unlock (&svmm->mutex); + +folio_unlock (folio); +folio_put (folio); }/* Map the page on the GPU. */
@@ -637,8 +642,8 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, ret =nvif_object_ioctl (&svmm->vmm->vmm.object, args, size,NULL );mutex_unlock (&svmm->mutex); -unlock_page (page); -put_page (page); +folio_unlock (folio); +folio_put (folio); out:mmu_interval_notifier_remove (¬ifier->notifier);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 69/138 drm/msm: Avoid rounding up to one jiffy
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <[email protected]>
[ Upstream commit 669c285620231786fffe9d87ab432e08a6ed922b ]
If userspace is trying to achieve a timeout of zero, let 'em have it. Only round up if the timeout is greater than zero.
Patchwork: https://patchwork.freedesktop.org/patch/632264/
--- drivers/gpu/drm/msm/msm_drv.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/gpu/drm/msm/msm_drv.h +4 -7
@@ -530,15 +530,12 @@ static inline int align_pitch(int width, int bpp)static inline unsigned long timeout_to_jiffies (const ktime_t *timeout) {ktime_t now =ktime_get (); -s64 remaining_jiffies; -if (ktime_compare (*timeout, now) <0 ) { - remaining_jiffies =0 ; - }else { -ktime_t rem =ktime_sub (*timeout, now); - remaining_jiffies =ktime_divns (rem,NSEC_PER_SEC /HZ ); - } +if (ktime_compare (*timeout, now) <=0 ) +return 0 ; +ktime_t rem =ktime_sub (*timeout, now); +s64 remaining_jiffies =ktime_divns (rem,NSEC_PER_SEC /HZ );return clamp (remaining_jiffies,1LL , (s64 )INT_MAX ); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 70/138 drm/msm/dpu: skip watchdog timer programming through TOP on >= SM8450
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 2f69e54584475ac85ea0e3407c9198ac7c6ea8ad ]
The SM8450 and later chips have DPU_MDP_PERIPH_0_REMOVED feature bit set, which means that those platforms have dropped some of the registers, including the WD TIMER-related ones. Stop providing the callback to program WD timer on those platforms.
Patchwork: https://patchwork.freedesktop.org/patch/628874/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +1 -1
@@ -272,7 +272,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,if (cap &BIT (DPU_MDP_VSYNC_SEL )) ops->setup_vsync_source = dpu_hw_setup_vsync_sel; -else +else if (!(cap &BIT (DPU_MDP_PERIPH_0_REMOVED ))) ops->setup_vsync_source = dpu_hw_setup_wd_timer; ops->get_safe_status = dpu_hw_get_safe_status;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 71/138 drm/msm/dpu: enable DPU_WB_INPUT_CTRL for DPU 5.x
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit af0a4a2090cce732c70ad6c5f4145b43f39e3fe9 ]
Several DPU 5.x platforms are supposed to be using DPU_WB_INPUT_CTRL, to bind WB and PINGPONG blocks, but they do not. Change those platforms to use WB_SM8250_MASK, which includes that bit.
Patchwork: https://patchwork.freedesktop.org/patch/628876/
--- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +1 -1
@@ -297,7 +297,7 @@ static const struct dpu_wb_cfg sm8150_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, + .features = WB_SM8250_MASK, .format_list = wb2_formats_rgb, .num_formats = ARRAY_SIZE(wb2_formats_rgb), .clk_ctrl = DPU_CLK_CTRL_WB2,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +1 -1
@@ -304,7 +304,7 @@ static const struct dpu_wb_cfg sc8180x_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, + .features = WB_SM8250_MASK, .format_list = wb2_formats_rgb, .num_formats = ARRAY_SIZE(wb2_formats_rgb), .clk_ctrl = DPU_CLK_CTRL_WB2,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h +1 -1
@@ -144,7 +144,7 @@ static const struct dpu_wb_cfg sm6125_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, + .features = WB_SM8250_MASK, .format_list = wb2_formats_rgb, .num_formats = ARRAY_SIZE(wb2_formats_rgb), .clk_ctrl = DPU_CLK_CTRL_WB2,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 72/138 drm/msm/dpu: Dont leak bits_per_component into random DSC_ENC fields
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marijn Suijten <[email protected]>
[ Upstream commit 144429831f447223253a0e4376489f84ff37d1a7 ]
What used to be the input_10_bits boolean - feeding into the lowest bit of DSC_ENC - on MSM downstream turned into an accidental OR with the full bits_per_component number when it was ported to the upstream kernel.
On typical bpc=8 setups we don't notice this because line_buf_depth is always an odd value (it contains bpc+1) and will also set the 4th bit after left-shifting by 3 (hence this |= bits_per_component is a no-op).
Now that guards are being removed to allow more bits_per_component values besides 8 (possible since commit 49fd30a7153b ("drm/msm/dsi: use DRM DSC helpers for DSC setup")), a bpc of 10 will instead clash with the 5th bit which is convert_rgb. This is "fortunately" also always set to true by MSM's dsi_populate_dsc_params() already, but once a bpc of 12 starts being used it'll write into simple_422 which is normally false.
To solve all these overlaps, simply replicate downstream code and only set this lowest bit if bits_per_component is equal to 10. It is unclear why DSC requires this only for bpc=10 but not bpc=12, and also notice that this lowest bit wasn't set previously despite having a panel and patch on the list using it without any mentioned issues.
Patchwork: https://patchwork.freedesktop.org/patch/636311/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +2 -1
@@ -52,6 +52,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,u32 slice_last_group_size;u32 det_thresh_flatness;bool is_cmd_mode = !(mode &DSC_MODE_VIDEO ); +bool input_10_bits = dsc->bits_per_component ==10 ;DPU_REG_WRITE (c,DSC_COMMON_MODE , mode);
@@ -68,7 +69,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, data |= (dsc->line_buf_depth <<3 ); data |= (dsc->simple_422 <<2 ); data |= (dsc->convert_rgb <<1 ); - data |= dsc->bits_per_component; + data |= input_10_bits;DPU_REG_WRITE (c,DSC_ENC , data);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 73/138 drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 588257897058a0b1aa47912db4fe93c6ff5e3887 ]
PHY_CMN_CLK_CFG0 register is updated by the PHY driver and by two divider clocks from Common Clock Framework:devm_clk_hw_register_divider_parent_hw(). Concurrent access by the clocks side is protected with spinlock, however driver's side in restoring state is not. Restoring state is called from msm_dsi_phy_enable(), so there could be a path leading to concurrent and conflicting updates with clock framework.
Add missing lock usage on the PHY driver side, encapsulated in its own function so the code will be still readable.
While shuffling the code, define and use PHY_CMN_CLK_CFG0 bitfields to make the code more readable and obvious.
Patchwork: https://patchwork.freedesktop.org/patch/637376/
--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 14 ++++++++++++-- .../gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 5 ++++- 2 files changed, 16 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +12 -2
@@ -372,6 +372,15 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)ndelay (250 ); } +static void dsi_pll_cmn_clk_cfg0_write (struct dsi_pll_7nm *pll,u32 val) +{ +unsigned long flags; + +spin_lock_irqsave (&pll->postdiv_lock, flags); +writel (val, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); +spin_unlock_irqrestore (&pll->postdiv_lock, flags); +} +static void dsi_pll_disable_global_clk (struct dsi_pll_7nm *pll) {u32 data;
@@ -574,8 +583,9 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) val |= cached->pll_out_div;writel (val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); -writel (cached->bit_clk_div | (cached->pix_clk_div <<4 ), - phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); +dsi_pll_cmn_clk_cfg0_write (pll_7nm, +DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0 (cached->bit_clk_div) | +DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4 (cached->pix_clk_div)); val =readl (phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); val &= ~0x3 ;
drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +4 -1
@@ -9,7 +9,10 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> <reg32 offset="0x00004" name="REVISION_ID1"/> <reg32 offset="0x00008" name="REVISION_ID2"/> <reg32 offset="0x0000c" name="REVISION_ID3"/> - <reg32 offset="0x00010" name="CLK_CFG0"/> + <reg32 offset="0x00010" name="CLK_CFG0"> + <bitfield name="DIV_CTRL_3_0" low="0" high="3" type="uint"/> + <bitfield name="DIV_CTRL_7_4" low="4" high="7" type="uint"/> + </reg32> <reg32 offset="0x00014" name="CLK_CFG1"/> <reg32 offset="0x00018" name="GLBL_CTRL"/> <reg32 offset="0x0001c" name="RBUF_CTRL"/>
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 74/138 drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG1 against clock driver
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 5a97bc924ae0804b8dbf627e357acaa5ef761483 ]
PHY_CMN_CLK_CFG1 register is updated by the PHY driver and by a mux clock from Common Clock Framework:devm_clk_hw_register_mux_parent_hws(). There could be a path leading to concurrent and conflicting updates between PHY driver and clock framework, e.g. changing the mux and enabling PLL clocks.
Add dedicated spinlock to be sure all PHY_CMN_CLK_CFG1 updates are synchronized.
While shuffling the code, define and use PHY_CMN_CLK_CFG1 bitfields to make the code more readable and obvious.
Patchwork: https://patchwork.freedesktop.org/patch/637378/
--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 35 ++++++++++++------- .../drm/msm/registers/display/dsi_phy_7nm.xml | 5 ++- 2 files changed, 26 insertions(+), 14 deletions(-)
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +22 -13
@@ -83,6 +83,9 @@ struct dsi_pll_7nm {/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ spinlock_t postdiv_lock; +/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG1 register */ +spinlock_t pclk_mux_lock; +struct pll_7nm_cached_state cached_state;struct dsi_pll_7nm *slave;
@@ -381,22 +384,32 @@ static void dsi_pll_cmn_clk_cfg0_write(struct dsi_pll_7nm *pll, u32 val)spin_unlock_irqrestore (&pll->postdiv_lock, flags); } -static void dsi_pll_disable_global_clk (struct dsi_pll_7nm *pll) +static void dsi_pll_cmn_clk_cfg1_update (struct dsi_pll_7nm *pll,u32 mask, +u32 val) { +unsigned long flags;u32 data; +spin_lock_irqsave (&pll->pclk_mux_lock, flags); data =readl (pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); -writel (data & ~BIT (5 ), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + data &= ~mask; + data |= val & mask; + +writel (data, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +spin_unlock_irqrestore (&pll->pclk_mux_lock, flags); +} + +static void dsi_pll_disable_global_clk (struct dsi_pll_7nm *pll) +{ +dsi_pll_cmn_clk_cfg1_update (pll, DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN,0 ); }static void dsi_pll_enable_global_clk (struct dsi_pll_7nm *pll) { -u32 data; +u32 cfg_1 = DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN | DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN_SEL;writel (0x04 , pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3); - - data =readl (pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); -writel (data |BIT (5 ) |BIT (4 ), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +dsi_pll_cmn_clk_cfg1_update (pll, cfg_1, cfg_1); }static void dsi_pll_phy_dig_reset (struct dsi_pll_7nm *pll)
@@ -574,7 +587,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) {struct dsi_pll_7nm *pll_7nm =to_pll_7nm (phy->vco_hw);struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; -void __iomem *phy_base = pll_7nm->phy->base;u32 val;int ret;
@@ -586,11 +598,7 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)dsi_pll_cmn_clk_cfg0_write (pll_7nm,DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0 (cached->bit_clk_div) |DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4 (cached->pix_clk_div)); - - val =readl (phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - val &= ~0x3 ; - val |= cached->pll_mux; -writel (val, phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +dsi_pll_cmn_clk_cfg1_update (pll_7nm,0x3 , cached->pll_mux); ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, pll_7nm->vco_current_rate,
@@ -743,7 +751,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide pll_by_2_bit, }), 2, 0, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, - 0, 1, 0, NULL); + 0, 1, 0, &pll_7nm->pclk_mux_lock);if (IS_ERR (hw)) { ret =PTR_ERR (hw); goto fail;
@@ -788,6 +796,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) pll_7nm_list[phy->id] = pll_7nm;spin_lock_init (&pll_7nm->postdiv_lock); +spin_lock_init (&pll_7nm->pclk_mux_lock); pll_7nm->phy = phy;
drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +4 -1
@@ -13,7 +13,10 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> <bitfield name="DIV_CTRL_3_0" low="0" high="3" type="uint"/> <bitfield name="DIV_CTRL_7_4" low="4" high="7" type="uint"/> </reg32> - <reg32 offset="0x00014" name="CLK_CFG1"/> + <reg32 offset="0x00014" name="CLK_CFG1"> + <bitfield name="CLK_EN" pos="5" type="boolean"/> + <bitfield name="CLK_EN_SEL" pos="4" type="boolean"/> + </reg32> <reg32 offset="0x00018" name="GLBL_CTRL"/> <reg32 offset="0x0001c" name="RBUF_CTRL"/> <reg32 offset="0x00020" name="VREG_CTRL_0"/>
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 75/138 drm/msm/dsi/phy: Do not overwite PHY_CMN_CLK_CFG1 when choosing bitclk source
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 73f69c6be2a9f22c31c775ec03c6c286bfe12cfa ]
PHY_CMN_CLK_CFG1 register has four fields being used in the driver: DSI clock divider, source of bitclk and two for enabling the DSI PHY PLL clocks.
dsi_7nm_set_usecase() sets only the source of bitclk, so should leave all other bits untouched. Use newly introduced dsi_pll_cmn_clk_cfg1_update() to update respective bits without overwriting the rest.
While shuffling the code, define and use PHY_CMN_CLK_CFG1 bitfields to make the code more readable and obvious.
Patchwork: https://patchwork.freedesktop.org/patch/637380/
--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 4 ++-- drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +2 -2
@@ -617,7 +617,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)static int dsi_7nm_set_usecase (struct msm_dsi_phy *phy) {struct dsi_pll_7nm *pll_7nm =to_pll_7nm (phy->vco_hw); -void __iomem *base = phy->base;u32 data =0x0 ;/* internal PLL */ DBG ("DSI PLL%d" , pll_7nm->phy->id);
@@ -636,7 +635,8 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) }/* set PLL src */ -writel (data <<2 , base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +dsi_pll_cmn_clk_cfg1_update (pll_7nm, DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL__MASK, +DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL (data));return 0 ; }
drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +1 -0
@@ -16,6 +16,7 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> <reg32 offset="0x00014" name="CLK_CFG1"> <bitfield name="CLK_EN" pos="5" type="boolean"/> <bitfield name="CLK_EN_SEL" pos="4" type="boolean"/> + <bitfield name="BITCLK_SEL" low="2" high="3" type="uint"/> </reg32> <reg32 offset="0x00018" name="GLBL_CTRL"/> <reg32 offset="0x0001c" name="RBUF_CTRL"/>
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 76/138 drm/xe: Make irq enabled flag atomic
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Levi <[email protected]>
[ Upstream commit 4d79a1266d4cc3c967bc8823502466cad1ac8514 ]
The irq.enabled flag was protected by a spin lock (irq.lock). By making it atomic we no longer need to wait for the spin lock in irq handlers. This will become especially useful for MSI-X irq handlers to prevent lock contention between different interrupts.
Stable-dep-of: 0c455f3a1229 ("drm/xe: Fix error handling in xe_irq_install()")
--- drivers/gpu/drm/xe/display/ext/i915_irq.c | 13 +--------- drivers/gpu/drm/xe/xe_device_types.h | 2 +- drivers/gpu/drm/xe/xe_irq.c | 29 ++++++----------------- 3 files changed, 9 insertions(+), 35 deletions(-)
drivers/gpu/drm/xe/display/ext/i915_irq.c +1 -12
@@ -53,18 +53,7 @@ void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs,bool intel_irqs_enabled (struct xe_device *xe) { -/* -* XXX: i915 has a racy handling of the irq.enabled, since it doesn't -* lock its transitions. Because of that, the irq.enabled sometimes -* is not read with the irq.lock in place. -* However, the most critical cases like vblank and page flips are -* properly using the locks. -* We cannot take the lock in here or run any kind of assert because -* of i915 inconsistency. -* But at this point the xe irq is better protected against races, -* although the full solution would be protecting the i915 side. -*/ -return xe->irq.enabled; +return atomic_read (&xe->irq.enabled); }void intel_synchronize_irq (struct xe_device *xe)
drivers/gpu/drm/xe/xe_device_types.h +1 -1
@@ -345,7 +345,7 @@ struct xe_device {spinlock_t lock;/** @irq.enabled: interrupts enabled on this device */ -bool enabled; +atomic_t enabled; } irq;/** @ttm: ttm device */
drivers/gpu/drm/xe/xe_irq.c +7 -22
@@ -348,12 +348,8 @@ static irqreturn_t xelp_irq_handler(int irq, void *arg)unsigned long intr_dw[2 ];u32 identity[32 ]; -spin_lock (&xe->irq.lock); -if (!xe->irq.enabled) { -spin_unlock (&xe->irq.lock); +if (!atomic_read (&xe->irq.enabled))return IRQ_NONE ; - } -spin_unlock (&xe->irq.lock); master_ctl =xelp_intr_disable (xe);if (!master_ctl) {
@@ -417,12 +413,8 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg)/* TODO: This really shouldn't be copied+pasted */ -spin_lock (&xe->irq.lock); -if (!xe->irq.enabled) { -spin_unlock (&xe->irq.lock); +if (!atomic_read (&xe->irq.enabled))return IRQ_NONE ; - } -spin_unlock (&xe->irq.lock); master_tile_ctl =dg1_intr_disable (xe);if (!master_tile_ctl) {
@@ -644,12 +636,8 @@ static irqreturn_t vf_mem_irq_handler(int irq, void *arg)struct xe_tile *tile;unsigned int id; -spin_lock (&xe->irq.lock); -if (!xe->irq.enabled) { -spin_unlock (&xe->irq.lock); +if (!atomic_read (&xe->irq.enabled))return IRQ_NONE ; - } -spin_unlock (&xe->irq.lock);for_each_tile (tile, xe, id)xe_memirq_handler (&tile->memirq);
@@ -674,10 +662,9 @@ static void irq_uninstall(void *arg)struct pci_dev *pdev =to_pci_dev (xe->drm.dev);int irq; -if (!xe->irq.enabled) +if (!atomic_xchg (&xe->irq.enabled,0 ))return ; - xe->irq.enabled = false;xe_irq_reset (xe); irq =pci_irq_vector (pdev,0 );
@@ -724,7 +711,7 @@ int xe_irq_install(struct xe_device *xe)return err; } - xe->irq.enabled = true; +atomic_set (&xe->irq.enabled,1 );xe_irq_postinstall (xe);
@@ -744,9 +731,7 @@ void xe_irq_suspend(struct xe_device *xe) {int irq =to_pci_dev (xe->drm.dev)->irq; -spin_lock_irq (&xe->irq.lock); - xe->irq.enabled = false;/* no new irqs */ -spin_unlock_irq (&xe->irq.lock); +atomic_set (&xe->irq.enabled,0 );/* no new irqs */ synchronize_irq (irq);/* flush irqs */ xe_irq_reset (xe);/* turn irqs off */
@@ -762,7 +747,7 @@ void xe_irq_resume(struct xe_device *xe)* 1. no irq will arrive before the postinstall * 2. display is not yet resumed */ - xe->irq.enabled = true; +atomic_set (&xe->irq.enabled,1 );xe_irq_reset (xe);xe_irq_postinstall (xe);/* turn irqs on */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 59/138 power: supply: da9150-fg: fix potential overflow
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Vatoropin <[email protected]>
[ Upstream commit 3fb3cb4350befc4f901c54e0cb4a2a47b1302e08 ]
Size of variable sd_gain equals four bytes - DA9150_QIF_SD_GAIN_SIZE. Size of variable shunt_val equals two bytes - DA9150_QIF_SHUNT_VAL_SIZE.
The expression sd_gain * shunt_val is currently being evaluated using 32-bit arithmetic. So during the multiplication an overflow may occur.
As the value of type 'u64' is used as storage for the eventual result, put ULL variable at the first position of each expression in order to give the compiler complete information about the proper arithmetic to use. According to C99 the guaranteed width for a variable of type 'unsigned long long' >= 64 bits.
Remove the explicit cast to u64 as it is meaningless.
Just for the sake of consistency, perform the similar trick with another expression concerning 'iavg'.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/power/supply/da9150-fg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/power/supply/da9150-fg.c +2 -2
@@ -247,9 +247,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg, DA9150_QIF_SD_GAIN_SIZE);da9150_fg_read_sync_end (fg); - div = (u64) (sd_gain * shunt_val *65536ULL ); + div =65536ULL * sd_gain * shunt_val;do_div (div,1000000 ); - res = (u64) (iavg *1000000ULL ); + res =1000000ULL * iavg;do_div (res, div); val->intval = (int ) res;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 77/138 drm/xe/irq: Separate MSI and MSI-X flows
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Levi <[email protected]>
[ Upstream commit da889070be7b26b91e8b90f072687ca437d3ed7b ]
A new flow is added for devices that support MSI-X:
- MSI-X vector 0 is used for GuC-to-host interrupt
- MSI-X vector 1 (aka default MSI-X) is used for HW engines
The default MSI-X will be passed to the HW engines in a subsequent patch.
Stable-dep-of: 0c455f3a1229 ("drm/xe: Fix error handling in xe_irq_install()")
--- drivers/gpu/drm/xe/xe_device.c | 4 +- drivers/gpu/drm/xe/xe_device.h | 3 +- drivers/gpu/drm/xe/xe_device_types.h | 6 + drivers/gpu/drm/xe/xe_irq.c | 257 +++++++++++++++++++++++---- drivers/gpu/drm/xe/xe_irq.h | 3 + 5 files changed, 237 insertions(+), 36 deletions(-)
drivers/gpu/drm/xe/xe_device.c +3 -1
@@ -324,7 +324,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, xe->info.revid = pdev->revision; xe->info.force_execlist = xe_modparam.force_execlist; -spin_lock_init (&xe->irq.lock); + err =xe_irq_init (xe); +if (err) + goto err;init_waitqueue_head (&xe->ufence_wq);
drivers/gpu/drm/xe/xe_device.h +1 -2
@@ -157,8 +157,7 @@ static inline bool xe_device_has_sriov(struct xe_device *xe)static inline bool xe_device_has_msix (struct xe_device *xe) { -/* TODO: change this when MSI-X support is fully integrated */ -return false; +return xe->irq.msix.nvec >0 ; }static inline bool xe_device_has_memirq (struct xe_device *xe)
drivers/gpu/drm/xe/xe_device_types.h +6 -0
@@ -346,6 +346,12 @@ struct xe_device {/** @irq.enabled: interrupts enabled on this device */ atomic_t enabled; + +/** @irq.msix: irq info for platforms that support MSI-X */ +struct { +/** @irq.msix.nvec: number of MSI-X interrupts */ +u16 nvec; + } msix; } irq;/** @ttm: ttm device */
drivers/gpu/drm/xe/xe_irq.c +224 -33
329 lines not on this page · raw message
drivers/gpu/drm/xe/xe_irq.h +3 -0
@@ -6,10 +6,13 @@#ifndef _XE_IRQ_H_#define _XE_IRQ_H_ +#define XE_IRQ_DEFAULT_MSIX 1 +struct xe_device ;struct xe_tile ;struct xe_gt ; +int xe_irq_init (struct xe_device *xe);int xe_irq_install (struct xe_device *xe);void xe_irq_suspend (struct xe_device *xe);void xe_irq_resume (struct xe_device *xe);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 78/138 drm/xe: Fix error handling in xe_irq_install()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas De Marchi <[email protected]>
[ Upstream commit 0c455f3a12298e9c89a78d2f3327e15e52c0adc5 ]
When devm_add_action_or_reset() fails, it already calls the function passed as parameter and that function is already free'ing the irqs. Drop the goto and just return.
The caller, xe_device_probe(), should also do the same thing instead of wrongly doing goto err and calling the unrelated xe_display_fini() function.
--- drivers/gpu/drm/xe/xe_irq.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-)
drivers/gpu/drm/xe/xe_irq.c +1 -13
@@ -757,19 +757,7 @@ int xe_irq_install(struct xe_device *xe)xe_irq_postinstall (xe); - err =devm_add_action_or_reset (xe->drm.dev, irq_uninstall, xe); -if (err) - goto free_irq_handler; - -return 0 ; - -free_irq_handler: -if (xe_device_has_msix (xe)) -xe_irq_msix_free (xe); -else -xe_irq_msi_free (xe); - -return err; +return devm_add_action_or_reset (xe->drm.dev, irq_uninstall, xe); }static void xe_irq_msi_synchronize_irq (struct xe_device *xe)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 79/138 nvmet: Fix crash when a namespace is disabled
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
[ Upstream commit 4082326807072b71496501b6a0c55ffe8d5092a5 ]
The namespace percpu counter protects pending I/O, and we can only safely diable the namespace once the counter drop to zero. Otherwise we end up with a crash when running blktests/nvme/058 (eg for loop transport):
[ 2352.930426] [ T53909] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN PTI [ 2352.930431] [ T53909] KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] [ 2352.930434] [ T53909] CPU: 3 UID: 0 PID: 53909 Comm: kworker/u16:5 Tainted: G W 6.13.0-rc6 #232 [ 2352.930438] [ T53909] Tainted: [W]=WARN [ 2352.930440] [ T53909] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 [ 2352.930443] [ T53909] Workqueue: nvmet-wq nvme_loop_execute_work [nvme_loop] [ 2352.930449] [ T53909] RIP: 0010:blkcg_set_ioprio+0x44/0x180
as the queue is already torn down when calling submit_bio();
So we need to init the percpu counter in nvmet_ns_enable(), and wait for it to drop to zero in nvmet_ns_disable() to avoid having I/O pending after the namespace has been disabled.
--- drivers/nvme/target/core.c | 40 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-)
drivers/nvme/target/core.c +19 -21
@@ -606,6 +606,9 @@ int nvmet_ns_enable(struct nvmet_ns *ns) goto out_dev_put; } +if (percpu_ref_init (&ns->ref, nvmet_destroy_namespace,0 ,GFP_KERNEL )) + goto out_pr_exit; +nvmet_ns_changed (subsys, ns->nsid); ns->enabled = true;xa_set_mark (&subsys->namespaces, ns->nsid,NVMET_NS_ENABLED );
@@ -613,6 +616,9 @@ int nvmet_ns_enable(struct nvmet_ns *ns) out_unlock:mutex_unlock (&subsys->lock);return ret; +out_pr_exit: +if (ns->pr.enable) +nvmet_pr_exit_ns (ns); out_dev_put:list_for_each_entry (ctrl, &subsys->ctrls, subsys_entry)pci_dev_put (radix_tree_delete (&ctrl->p2p_ns_map, ns->nsid));
@@ -638,6 +644,19 @@ void nvmet_ns_disable(struct nvmet_ns *ns)mutex_unlock (&subsys->lock); +/* +* Now that we removed the namespaces from the lookup list, we +* can kill the per_cpu ref and wait for any remaining references +* to be dropped, as well as a RCU grace period for anyone only +* using the namepace under rcu_read_lock(). Note that we can't +* use call_rcu here as we need to ensure the namespaces have +* been fully destroyed before unloading the module. +*/ +percpu_ref_kill (&ns->ref); +synchronize_rcu (); +wait_for_completion (&ns->disable_done); +percpu_ref_exit (&ns->ref); +if (ns->pr.enable)nvmet_pr_exit_ns (ns);
@@ -660,22 +679,6 @@ void nvmet_ns_free(struct nvmet_ns *ns)if (ns->nsid == subsys->max_nsid) subsys->max_nsid =nvmet_max_nsid (subsys); -mutex_unlock (&subsys->lock); - -/* -* Now that we removed the namespaces from the lookup list, we -* can kill the per_cpu ref and wait for any remaining references -* to be dropped, as well as a RCU grace period for anyone only -* using the namepace under rcu_read_lock(). Note that we can't -* use call_rcu here as we need to ensure the namespaces have -* been fully destroyed before unloading the module. -*/ -percpu_ref_kill (&ns->ref); -synchronize_rcu (); -wait_for_completion (&ns->disable_done); -percpu_ref_exit (&ns->ref); - -mutex_lock (&subsys->lock); subsys->nr_namespaces--;mutex_unlock (&subsys->lock);
@@ -705,9 +708,6 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid) ns->nsid = nsid; ns->subsys = subsys; -if (percpu_ref_init (&ns->ref, nvmet_destroy_namespace,0 ,GFP_KERNEL )) - goto out_free; -if (ns->nsid > subsys->max_nsid) subsys->max_nsid = nsid;
@@ -730,8 +730,6 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)return ns; out_exit: subsys->max_nsid =nvmet_max_nsid (subsys); -percpu_ref_exit (&ns->ref); -out_free:kfree (ns); out_unlock:mutex_unlock (&subsys->lock);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 80/138 nvme: tcp: Fix compilation warning with W=1
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit cd513e0434c3e736c549bc99bf7982658b25114d ]
When compiling with W=1, a warning result for the function nvme_tcp_set_queue_io_cpu():
host/tcp.c:1578: warning: Function parameter or struct member 'queue' not described in 'nvme_tcp_set_queue_io_cpu' host/tcp.c:1578: warning: expecting prototype for Track the number of queues assigned to each cpu using a global per(). Prototype was for nvme_tcp_set_queue_io_cpu() instead
Avoid this warning by using the regular comment format for the function nvme_tcp_set_queue_io_cpu() instead of the kdoc comment format.
--- drivers/nvme/host/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/tcp.c +1 -1
@@ -1565,7 +1565,7 @@ static bool nvme_tcp_poll_queue(struct nvme_tcp_queue *queue) ctrl->io_queues[HCTX_TYPE_POLL ]; } -/** +/* * Track the number of queues assigned to each cpu using a global per-cpu * counter and select the least used cpu from the mq_map. Our goal is to spread * different controllers I/O threads across different cpu cores.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 81/138 nvme-tcp: fix connect failure on receiving partial ICResp PDU
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos <[email protected]>
[ Upstream commit 578539e0969028f711c34d9a4565931edfe1d730 ]
nvme_tcp_init_connection() attempts to receive an ICResp PDU but only checks that the return value from recvmsg() is non-negative. If the sender closes the TCP connection or sends fewer than 128 bytes, this check will pass even though the full PDU wasn't received.
Ensure the full ICResp PDU is received by checking that recvmsg() returns the expected 128 bytes.
Additionally set the MSG_WAITALL flag for recvmsg(), as a sender could split the ICResp over multiple TCP frames. Without MSG_WAITALL, recvmsg() could return prematurely with only part of the PDU.
--- drivers/nvme/host/tcp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/nvme/host/tcp.c +4 -1
@@ -1449,11 +1449,14 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue) msg.msg_control = cbuf; msg.msg_controllen =sizeof (cbuf); } + msg.msg_flags =MSG_WAITALL ; ret =kernel_recvmsg (queue->sock, &msg, &iov,1 , iov.iov_len, msg.msg_flags); -if (ret <0 ) { +if (ret <sizeof (*icresp)) {pr_warn ("queue %d: failed to receive icresp, error %d\n" ,nvme_tcp_queue_id (queue), ret); +if (ret >=0 ) + ret = -ECONNRESET ; goto free_icresp; } ret = -ENOTCONN ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 82/138 nvme/ioctl: add missing space in err message
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos <[email protected]>
[ Upstream commit 487a3ea7b1b8ba2ca7d2c2bb3c3594dc360d6261 ]
nvme_validate_passthru_nsid() logs an err message whose format string is split over 2 lines. There is a missing space between the two pieces, resulting in log lines like "... does not match nsid (1)of namespace". Add the missing space between ")" and "of". Also combine the format string pieces onto a single line to make the err message easier to grep.
--- drivers/nvme/host/ioctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/nvme/host/ioctl.c +1 -2
@@ -283,8 +283,7 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, {if (ns && nsid != ns->head->ns_id) {dev_err (ctrl->device, -"%s: nsid (%u) in cmd does not match nsid (%u)" -"of namespace\n" , +"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n" , current->comm, nsid, ns->head->ns_id);return false; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 83/138 bpf: skip non exist keys in generic_map_lookup_batch
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhai <[email protected]>
[ Upstream commit 5644c6b50ffee0a56c1e01430a8c88e34decb120 ]
The generic_map_lookup_batch currently returns EINTR if it fails with ENOENT and retries several times on bpf_map_copy_value. The next batch would start from the same location, presuming it's a transient issue. This is incorrect if a map can actually have "holes", i.e. "get_next_key" can return a key that does not point to a valid value. At least the array of maps type may contain such holes legitly. Right now these holes show up, generic batch lookup cannot proceed any more. It will always fail with EINTR errors.
Rather, do not retry in generic_map_lookup_batch. If it finds a non existing element, skip to the next key. This simple solution comes with a price that transient errors may not be recovered, and the iteration might cycle back to the first key under parallel deletion. For example, Hou Tao <[email protected]> pointed out a following scenario:
For LPM trie map:
(1) ->map_get_next_key(map, prev_key, key) returns a valid key
(2) bpf_map_copy_value() return -ENOMENT
It means the key must be deleted concurrently.
(3) goto next_key
It swaps the prev_key and key
(4) ->map_get_next_key(map, prev_key, key) againprev_key points to a non-existing key, for LPM trie it will treat just like prev_key=NULL case, the returned key will be duplicated.
With the retry logic, the iteration can continue to the key next to the deleted one. But if we directly skip to the next key, the iteration loop would restart from the first key for the lpm_trie type.
However, not all races may be recovered. For example, if current key is deleted after instead of before bpf_map_copy_value, or if the prev_key also gets deleted, then the loop will still restart from the first key for lpm_tire anyway. For generic lookup it might be better to stay simple, i.e. just skip to the next key. To guarantee that the output keys are not duplicated, it is better to implement map type specific batch operations, which can properly lock the trie and synchronize with concurrent mutators.
--- kernel/bpf/syscall.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-)
kernel/bpf/syscall.c +5 -13
@@ -1973,8 +1973,6 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file,return err; } -#define MAP_LOOKUP_RETRIES 3 -int generic_map_lookup_batch (struct bpf_map *map,const union bpf_attr *attr,union bpf_attr __user *uattr)
@@ -1984,8 +1982,8 @@ int generic_map_lookup_batch(struct bpf_map *map,void __user *values =u64_to_user_ptr (attr->batch.values);void __user *keys =u64_to_user_ptr (attr->batch.keys);void *buf, *buf_prevkey, *prev_key, *key, *value; -int err, retry =MAP_LOOKUP_RETRIES ;u32 value_size, cp, max_count; +int err;if (attr->batch.elem_flags & ~BPF_F_LOCK )return -EINVAL ;
@@ -2031,14 +2029,8 @@ int generic_map_lookup_batch(struct bpf_map *map, err =bpf_map_copy_value (map, key, value, attr->batch.elem_flags); -if (err == -ENOENT ) { -if (retry) { - retry--; -continue ; - } - err = -EINTR ; -break ; - } +if (err == -ENOENT ) + goto next_key;if (err) goto free_buf;
@@ -2053,12 +2045,12 @@ int generic_map_lookup_batch(struct bpf_map *map, goto free_buf; } + cp++; +next_key:if (!prev_key) prev_key = buf_prevkey;swap (prev_key, key); - retry =MAP_LOOKUP_RETRIES ; - cp++;cond_resched (); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 84/138 drm/nouveau/pmu: Fix gp10b firmware guard
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Kling <[email protected]>
[ Upstream commit 3dbc0215e3c502a9f3221576da0fdc9847fb9721 ]
Most kernel configs enable multiple Tegra SoC generations, causing this typo to go unnoticed. But in the case where a kernel config is strictly for Tegra186, this is a problem.
--- drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c +1 -1
@@ -75,7 +75,7 @@ gp10b_pmu_acr = { .bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons, }; -#if IS_ENABLED (CONFIG_ARCH_TEGRA_210_SOC ) +#if IS_ENABLED (CONFIG_ARCH_TEGRA_186_SOC )MODULE_FIRMWARE ("nvidia/gp10b/pmu/desc.bin" );MODULE_FIRMWARE ("nvidia/gp10b/pmu/image.bin" );MODULE_FIRMWARE ("nvidia/gp10b/pmu/sig.bin" );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 85/138 irqchip/jcore-aic, clocksource/drivers/jcore: Fix jcore-pit interrupt request
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artur Rojek <[email protected]>
[ Upstream commit d7e3fd658248f257006227285095d190e70ee73a ]
The jcore-aic irqchip does not have separate interrupt numbers reserved for cpu-local vs global interrupts. Therefore the device drivers need to request the given interrupt as per CPU interrupt.
69a9dcbd2d65 ("clocksource/drivers/jcore: Use request_percpu_irq()") converted the clocksource driver over to request_percpu_irq(), but failed to do add all the required changes, resulting in a failure to register PIT interrupts.
Fix this by:
1) Explicitly mark the interrupt via irq_set_percpu_devid() in
jcore_pit_init().
2) Enable and disable the per CPU interrupt in the CPU hotplug callbacks.
3) Pass the correct per-cpu cookie to the irq handler by using handle_percpu_devid_irq() instead of handle_percpu_irq() in handle_jcore_irq().
[ tglx: Massage change log ]
--- drivers/clocksource/jcore-pit.c | 15 ++++++++++++++- drivers/irqchip/irq-jcore-aic.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-)
drivers/clocksource/jcore-pit.c +14 -1
@@ -114,6 +114,18 @@ static int jcore_pit_local_init(unsigned cpu) pit->periodic_delta =DIV_ROUND_CLOSEST (NSEC_PER_SEC ,HZ * buspd);clockevents_config_and_register (&pit->ced, freq,1 ,ULONG_MAX ); +enable_percpu_irq (pit->ced.irq,IRQ_TYPE_NONE ); + +return 0 ; +} + +static int jcore_pit_local_teardown (unsigned cpu) +{ +struct jcore_pit *pit =this_cpu_ptr (jcore_pit_percpu); + +pr_info ("Local J-Core PIT teardown on cpu %u\n" , cpu); + +disable_percpu_irq (pit->ced.irq);return 0 ; }
@@ -168,6 +180,7 @@ static int __init jcore_pit_init(struct device_node *node)return -ENOMEM ; } +irq_set_percpu_devid (pit_irq); err =request_percpu_irq (pit_irq, jcore_timer_interrupt,"jcore_pit" , jcore_pit_percpu);if (err) {
@@ -237,7 +250,7 @@ static int __init jcore_pit_init(struct device_node *node)cpuhp_setup_state (CPUHP_AP_JCORE_TIMER_STARTING ,"clockevents/jcore:starting" , - jcore_pit_local_init,NULL ); + jcore_pit_local_init, jcore_pit_local_teardown);return 0 ; }
drivers/irqchip/irq-jcore-aic.c +1 -1
@@ -38,7 +38,7 @@ static struct irq_chip jcore_aic;static void handle_jcore_irq (struct irq_desc *desc) {if (irqd_is_per_cpu (irq_desc_get_irq_data (desc))) -handle_percpu_irq (desc); +handle_percpu_devid_irq (desc);else handle_simple_irq (desc); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 86/138 sched: Compact RSEQ concurrency IDs with reduced threads and affinity
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathieu Desnoyers <[email protected]>
[ Upstream commit 02d954c0fdf91845169cdacc7405b120f90afe01 ]
When a process reduces its number of threads or clears bits in its CPU affinity mask, the mm_cid allocation should eventually converge towards smaller values.
However, the change introduced by:
commit 7e019dcc470f ("sched: Improve cache locality of RSEQ concurrency IDs for intermittent workloads")
adds a per-mm/CPU recent_cid which is never unset unless a thread migrates.
This is a tradeoff between:
A) Preserving cache locality after a transition from many threads to few threads, or after reducing the hamming weight of the allowed CPU mask.
B) Making the mm_cid upper bounds wrt nr threads and allowed CPU mask easy to document and understand.
C) Allowing applications to eventually react to mm_cid compaction after reduction of the nr threads or allowed CPU mask, making the tracking of mm_cid compaction easier by shrinking it back towards 0 or not.
D) Making sure applications that periodically reduce and then increase again the nr threads or allowed CPU mask still benefit from good cache locality with mm_cid.
Introduce the following changes:
* After shrinking the number of threads or reducing the number of allowed CPUs, reduce the value of max_nr_cid so expansion of CID allocation will preserve cache locality if the number of threads or allowed CPUs increase again.
* Only re-use a recent_cid if it is within the max_nr_cid upper bound, else find the first available CID.
--- include/linux/mm_types.h | 7 ++++--- kernel/sched/sched.h | 25 ++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-)
include/linux/mm_types.h +4 -3
@@ -873,10 +873,11 @@ struct mm_struct {*/ unsigned int nr_cpus_allowed;/** -* @max_nr_cid: Maximum number of concurrency IDs allocated. +* @max_nr_cid: Maximum number of allowed concurrency +* IDs allocated. * -* Track the highest number of concurrency IDs allocated for the -* mm. +* Track the highest number of allowed concurrency IDs +* allocated for the mm. */ atomic_t max_nr_cid;/**
kernel/sched/sched.h +22 -3
@@ -3666,10 +3666,28 @@ static inline int __mm_cid_try_get(struct task_struct *t, struct mm_struct *mm) {struct cpumask *cidmask =mm_cidmask (mm);struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; -int cid =__this_cpu_read (pcpu_cid->recent_cid); +int cid, max_nr_cid, allowed_max_nr_cid; +/* +* After shrinking the number of threads or reducing the number +* of allowed cpus, reduce the value of max_nr_cid so expansion +* of cid allocation will preserve cache locality if the number +* of threads or allowed cpus increase again. +*/ + max_nr_cid =atomic_read (&mm->max_nr_cid); +while ((allowed_max_nr_cid =min_t (int,READ_ONCE (mm->nr_cpus_allowed), +atomic_read (&mm->mm_users))), + max_nr_cid > allowed_max_nr_cid) { +/* atomic_try_cmpxchg loads previous mm->max_nr_cid into max_nr_cid. */ +if (atomic_try_cmpxchg (&mm->max_nr_cid, &max_nr_cid, allowed_max_nr_cid)) { + max_nr_cid = allowed_max_nr_cid; +break ; + } + }/* Try to re-use recent cid. This improves cache locality. */ -if (!mm_cid_is_unset (cid) && !cpumask_test_and_set_cpu (cid, cidmask)) + cid =__this_cpu_read (pcpu_cid->recent_cid); +if (!mm_cid_is_unset (cid) && cid < max_nr_cid && + !cpumask_test_and_set_cpu (cid, cidmask))return cid;/* * Expand cid allocation if the maximum number of concurrency
@@ -3677,8 +3695,9 @@ static inline int __mm_cid_try_get(struct task_struct *t, struct mm_struct *mm)* and number of threads. Expanding cid allocation as much as * possible improves cache locality. */ - cid =atomic_read (&mm->max_nr_cid); + cid = max_nr_cid;while (cid <READ_ONCE (mm->nr_cpus_allowed) && cid <atomic_read (&mm->mm_users)) { +/* atomic_try_cmpxchg loads previous mm->max_nr_cid into cid. */ if (!atomic_try_cmpxchg (&mm->max_nr_cid, &cid, cid +1 ))continue ;if (!cpumask_test_and_set_cpu (cid, cidmask))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 60/138 power: supply: axp20x_battery: Fix fault handling for AXP717
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Morgan <[email protected]>
[ Upstream commit 98380110bd48fbfd6a798ee11fffff893d36062c ]
Correct the fault handling for the AXP717 by changing the i2c write from regmap_update_bits() to regmap_write_bits(). The update bits function does not work properly on a RW1C register where we must write a 1 back to an existing register to clear it.
Additionally, as part of this testing I confirmed the behavior of errors reappearing, so remove comment about assumptions.
--- drivers/power/supply/axp20x_battery.c | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-)
drivers/power/supply/axp20x_battery.c +15 -16
@@ -466,10 +466,9 @@ static int axp717_battery_get_prop(struct power_supply *psy,/* * If a fault is detected it must also be cleared; if the -* condition persists it should reappear (This is an -* assumption, it's actually not documented). A restart was -* not sufficient to clear the bit in testing despite the -* register listed as POR. +* condition persists it should reappear. A restart was not +* sufficient to clear the bit in testing despite the register +* listed as POR. */ case POWER_SUPPLY_PROP_HEALTH : ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_FAULT,
@@ -480,26 +479,26 @@ static int axp717_battery_get_prop(struct power_supply *psy,switch (reg &AXP717_BATT_PMU_FAULT_MASK ) {case AXP717_BATT_UVLO_2_5V : val->intval =POWER_SUPPLY_HEALTH_DEAD ; -regmap_update_bits (axp20x_batt->regmap, -AXP717_PMU_FAULT , -AXP717_BATT_UVLO_2_5V , -AXP717_BATT_UVLO_2_5V ); +regmap_write_bits (axp20x_batt->regmap, +AXP717_PMU_FAULT , +AXP717_BATT_UVLO_2_5V , +AXP717_BATT_UVLO_2_5V );return 0 ;case AXP717_BATT_OVER_TEMP : val->intval =POWER_SUPPLY_HEALTH_HOT ; -regmap_update_bits (axp20x_batt->regmap, -AXP717_PMU_FAULT , -AXP717_BATT_OVER_TEMP , -AXP717_BATT_OVER_TEMP ); +regmap_write_bits (axp20x_batt->regmap, +AXP717_PMU_FAULT , +AXP717_BATT_OVER_TEMP , +AXP717_BATT_OVER_TEMP );return 0 ;case AXP717_BATT_UNDER_TEMP : val->intval =POWER_SUPPLY_HEALTH_COLD ; -regmap_update_bits (axp20x_batt->regmap, -AXP717_PMU_FAULT , -AXP717_BATT_UNDER_TEMP , -AXP717_BATT_UNDER_TEMP ); +regmap_write_bits (axp20x_batt->regmap, +AXP717_PMU_FAULT , +AXP717_BATT_UNDER_TEMP , +AXP717_BATT_UNDER_TEMP );return 0 ;default :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 87/138 drm: panel: jd9365da-h3: fix reset signal polarity
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit a8972d5a49b408248294b5ecbdd0a085e4726349 upstream.
In jadard_prepare() a reset pulse is generated with the following statements (delays ommited for clarity):
gpiod_set_value(jadard->reset, 1); --> Deassert reset
gpiod_set_value(jadard->reset, 0); --> Assert reset for 10ms
gpiod_set_value(jadard->reset, 1); --> Deassert resetHowever, specifying second argument of "0" to gpiod_set_value() means to deassert the GPIO, and "1" means to assert it. If the reset signal is defined as GPIO_ACTIVE_LOW in the DTS, the above statements will incorrectly generate the reset pulse (inverted) and leave it asserted (LOW) at the end of jadard_prepare().
Fix reset behavior by inverting gpiod_set_value() second argument in jadard_prepare(). Also modify second argument to devm_gpiod_get() in jadard_dsi_probe() to assert the reset when probing.
Do not modify it in jadard_unprepare() as it is already properly asserted with "1", which seems to be the intended behavior.
--- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +4 -4
@@ -109,13 +109,13 @@ static int jadard_prepare(struct drm_panif (jadard->desc->lp11_to_reset_delay_ms)msleep (jadard->desc->lp11_to_reset_delay_ms); -gpiod_set_value (jadard->reset,1 ); +gpiod_set_value (jadard->reset,0 );msleep (5 ); -gpiod_set_value (jadard->reset,0 ); +gpiod_set_value (jadard->reset,1 );msleep (10 ); -gpiod_set_value (jadard->reset,1 ); +gpiod_set_value (jadard->reset,0 );msleep (130 ); ret = jadard->desc->init (jadard);
@@ -1130,7 +1130,7 @@ static int jadard_dsi_probe(struct mipi_ dsi->format = desc->format; dsi->lanes = desc->lanes; - jadard->reset =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); + jadard->reset =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_HIGH );if (IS_ERR (jadard->reset)) {DRM_DEV_ERROR (&dsi->dev,"failed to get our reset GPIO\n" );return PTR_ERR (jadard->reset);
Greg Kroah-Hartman
maintainerPATCH 88/138 drm/msm/dp: account for widebus and yuv420 during mode validation
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhinav Kumar <[email protected]>
commit df9cf852ca3099feb8fed781bdd5d3863af001c8 upstream.
Widebus allows the DP controller to operate in 2 pixel per clock mode. The mode validation logic validates the mode->clock against the max DP pixel clock. However the max DP pixel clock limit assumes widebus is already enabled. Adjust the mode validation logic to only compare the adjusted pixel clock which accounts for widebus against the max DP pixel clock. Also fix the mode validation logic for YUV420 modes as in that case as well, only half the pixel clock is needed.
Patchwork: https://patchwork.freedesktop.org/patch/635789/
--- drivers/gpu/drm/msm/dp/dp_display.c | 11 ++++++----- drivers/gpu/drm/msm/dp/dp_drm.c | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-)
drivers/gpu/drm/msm/dp/dp_display.c +6 -5
@@ -937,16 +937,17 @@ enum drm_mode_status msm_dp_bridge_mode_return -EINVAL ; } -if (mode->clock >DP_MAX_PIXEL_CLK_KHZ ) -return MODE_CLOCK_HIGH ; - msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); link_info = &msm_dp_display->panel->link_info; -if (drm_mode_is_420_only (&dp->connector->display_info, mode) && - msm_dp_display->panel->vsc_sdp_supported) +if ((drm_mode_is_420_only (&dp->connector->display_info, mode) && + msm_dp_display->panel->vsc_sdp_supported) || +msm_dp_wide_bus_available (dp)) mode_pclk_khz /=2 ; +if (mode_pclk_khz >DP_MAX_PIXEL_CLK_KHZ ) +return MODE_CLOCK_HIGH ; + mode_bpp = dp->connector->display_info.bpc * num_components;if (!mode_bpp) mode_bpp = default_bpp;
drivers/gpu/drm/msm/dp/dp_drm.c +4 -1
@@ -257,7 +257,10 @@ static enum drm_mode_status msm_edp_bridreturn -EINVAL ; } -if (mode->clock >DP_MAX_PIXEL_CLK_KHZ ) +if (msm_dp_wide_bus_available (dp)) + mode_pclk_khz /=2 ; + +if (mode_pclk_khz >DP_MAX_PIXEL_CLK_KHZ )return MODE_CLOCK_HIGH ;/*
Greg Kroah-Hartman
maintainerPATCH 89/138 drm/msm/dpu: Disable dither in phys encoder cleanup
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jessica Zhang <[email protected]>
commit f063ac6b55df03ed25996bdc84d9e1c50147cfa1 upstream.
Disable pingpong dither in dpu_encoder_helper_phys_cleanup().
This avoids the issue where an encoder unknowingly uses dither after reserving a pingpong block that was previously bound to an encoder that had enabled dither.
Patchwork: https://patchwork.freedesktop.org/patch/636517/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +3 -0
@@ -2281,6 +2281,9 @@ void dpu_encoder_helper_phys_cleanup(str } } +if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither) + phys_enc->hw_pp->ops.setup_dither (phys_enc->hw_pp,NULL ); +/* reset the merge 3D HW block */ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
Greg Kroah-Hartman
maintainerPATCH 90/138 drm/i915: Make sure all planes in use by the joiner have their crtc included
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit 07fb70d82e0df085980246bf17bc12537588795f upstream.
Any active plane needs to have its crtc included in the atomic state. For planes enabled via uapi that is all handler in the core. But when we use a plane for joiner the uapi code things the plane is disabled and therefore doesn't have a crtc. So we need to pull those in by hand. We do it first thing in intel_joiner_add_affected_crtcs() so that any newly added crtc will subsequently pull in all of its joined crtcs as well.
The symptoms from failing to do this are:
- duct tape in the form of commit 1d5b09f8daf8 ("drm/i915: Fix NULL ptr deref by checking new_crtc_state")
- the plane's hw state will get overwritten by the disabled uapi state if it can't find the uapi counterpart plane in the atomic state from where it should copy the correct state
--- drivers/gpu/drm/i915/display/intel_display.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/gpu/drm/i915/display/intel_display.c +18 -0
@@ -6641,12 +6641,30 @@ static int intel_async_flip_check_hw(strstatic int intel_joiner_add_affected_crtcs (struct intel_atomic_state *state) {struct drm_i915_private *i915 =to_i915 (state->base.dev); +const struct intel_plane_state *plane_state;struct intel_crtc_state *crtc_state; +struct intel_plane *plane;struct intel_crtc *crtc;u8 affected_pipes =0 ;u8 modeset_pipes =0 ;int i; +/* +* Any plane which is in use by the joiner needs its crtc. +* Pull those in first as this will not have happened yet +* if the plane remains disabled according to uapi. +*/ +for_each_new_intel_plane_in_state (state, plane, plane_state, i) { + crtc =to_intel_crtc (plane_state->hw.crtc); +if (!crtc) +continue ; + + crtc_state =intel_atomic_get_crtc_state (&state->base, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + } + +/* Now pull in all joined crtcs */ for_each_new_intel_crtc_in_state (state, crtc, crtc_state, i) { affected_pipes |= crtc_state->joiner_pipes;if (intel_crtc_needs_modeset (crtc_state))
Greg Kroah-Hartman
maintainerPATCH 91/138 drm/i915/dp: Fix error handling during 128b/132b link training
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit b9275eabe31e6679ae12c46a4a0a18d622db4570 upstream.
At the end of a 128b/132b link training sequence, the HW expects the transcoder training pattern to be set to TPS2 and from that to normal mode (disabling the training pattern). Transitioning from TPS1 directly to normal mode leaves the transcoder in a stuck state, resulting in page-flip timeouts later in the modeset sequence.
Atm, in case of a failure during link training, the transcoder may be still set to output the TPS1 pattern. Later the transcoder is then set from TPS1 directly to normal mode in intel_dp_stop_link_train(), leading to modeset failures later as described above. Fix this by setting the training patter to TPS2, if the link training failed at any point.
The clue in the specification about the above HW behavior is the explicit mention that TPS2 must be set after the link training sequence (and there isn't a similar requirement specified for the 8b/10b link training), see the Bspec links below.
v2: Add bspec aspect/link to the commit log. (Jani)
Bspec: 54128, 65448, 68849
--- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_dp_link_training.c +14 -1
@@ -1565,7 +1565,7 @@ intel_dp_128b132b_link_train(struct inteif (wait_for (intel_dp_128b132b_intra_hop (intel_dp, crtc_state) ==0 ,500 )) {lt_err (intel_dp,DP_PHY_DPRX ,"128b/132b intra-hop not clear\n" ); -return false; + goto out; } if (intel_dp_128b132b_lane_eq(intel_dp, crtc_state) &&
@@ -1577,6 +1577,19 @@ intel_dp_128b132b_link_train(struct inte passed ?"passed" :"failed" , crtc_state->port_clock, crtc_state->lane_count); +out: +/* +* Ensure that the training pattern does get set to TPS2 even in case +* of a failure, as is the case at the end of a passing link training +* and what is expected by the transcoder. Leaving TPS1 set (and +* disabling the link train mode in DP_TP_CTL later from TPS1 directly) +* would result in a stuck transcoder HW state and flip-done timeouts +* later in the modeset sequence. +*/ +if (!passed) +intel_dp_program_link_training_pattern (intel_dp, crtc_state, +DP_PHY_DPRX ,DP_TRAINING_PATTERN_2 ); +return passed; }
Greg Kroah-Hartman
maintainerPATCH 61/138 net: Add rx_skb of kfree_skb to raw_tp_null_args[].
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 5da7e15fb5a12e78de974d8908f348e279922ce9 ]
Yan Zhai reported a BPF prog could trigger a null-ptr-deref [0] in trace_kfree_skb if the prog does not check if rx_sk is NULL.
Commit c53795d48ee8 ("net: add rx_sk to trace_kfree_skb") added rx_sk to trace_kfree_skb, but rx_sk is optional and could be NULL.
Let's add kfree_skb to raw_tp_null_args[] to let the BPF verifier validate such a prog and prevent the issue.
Now we fail to load such a prog:
libbpf: prog 'drop': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; int BPF_PROG(drop, struct sk_buff *skb, void *location, @ kfree_skb_sk_null.bpf.c:21 0: (79) r3 = *(u64 *)(r1 +24)
func 'kfree_skb' arg3 has btf_id 5253 type STRUCT 'sock'
1: R1=ctx() R3_w=trusted_ptr_or_null_sock(id=1)
; bpf_printk("sk: %d, %d\n", sk, sk->__sk_common.skc_family); @ kfree_skb_sk_null.bpf.c:24 1: (69) r4 = *(u16 *)(r3 +16)
R3 invalid mem access 'trusted_ptr_or_null_'
processed 2 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 -- END PROG LOAD LOG --
Note this fix requires commit 838a10bd2ebf ("bpf: Augment raw_tp arguments with PTR_MAYBE_NULL").
[0]:
BUG: kernel NULL pointer dereference, address: 0000000000000010 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 0 P4D 0 PREEMPT SMP RIP: 0010:bpf_prog_5e21a6db8fcff1aa_drop+0x10/0x2d Call Trace: <TASK> ? __die+0x1f/0x60 ? page_fault_oops+0x148/0x420 ? search_bpf_extables+0x5b/0x70 ? fixup_exception+0x27/0x2c0 ? exc_page_fault+0x75/0x170 ? asm_exc_page_fault+0x22/0x30 ? bpf_prog_5e21a6db8fcff1aa_drop+0x10/0x2d bpf_trace_run4+0x68/0xd0 ? unix_stream_connect+0x1f4/0x6f0 sk_skb_reason_drop+0x90/0x120 unix_stream_connect+0x1f4/0x6f0 __sys_connect+0x7f/0xb0 __x64_sys_connect+0x14/0x20 do_syscall_64+0x47/0xc30 entry_SYSCALL_64_after_hwframe+0x4b/0x53
--- kernel/bpf/btf.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/bpf/btf.c +2 -0
@@ -6507,6 +6507,8 @@ static const struct bpf_raw_tp_null_args raw_tp_null_args[] = {/* rxrpc */ { "rxrpc_recvdata", 0x1 }, { "rxrpc_resend", 0x10 }, +/* skb */ + {"kfree_skb", 0x1000},/* sunrpc */ { "xs_stream_read_data", 0x1 },/* ... from xprt_cong_event event class */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 62/138 bpf: Fix softlockup in arena_map_free on 64k page kernel
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Maguire <[email protected]>
[ Upstream commit 517e8a7835e8cfb398a0aeb0133de50e31cae32b ]
On an aarch64 kernel with CONFIG_PAGE_SIZE_64KB=y, arena_htab tests cause a segmentation fault and soft lockup. The same failure is not observed with 4k pages on aarch64.
It turns out arena_map_free() is calling apply_to_existing_page_range() with the address returned by bpf_arena_get_kern_vm_start(). If this address is not page-aligned the code ends up calling apply_to_pte_range() with that unaligned address causing soft lockup.
Fix it by round up GUARD_SZ to PAGE_SIZE << 1 so that the division by 2 in bpf_arena_get_kern_vm_start() returns a page-aligned value.
--- kernel/bpf/arena.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/arena.c +1 -1
@@ -39,7 +39,7 @@*/ /* number of bytes addressable by LDX/STX insn with 16-bit 'off' field */ -#define GUARD_SZ (1ull << sizeof_field(struct bpf_insn, off) * 8) +#define GUARD_SZ round_up(1ull << sizeof_field(struct bpf_insn, off) * 8, PAGE_SIZE << 1)#define KERN_VM_SZ (SZ_4G + GUARD_SZ)struct bpf_arena {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 63/138 arm64: dts: rockchip: adjust SMMU interrupt type on rk3588
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Wildt <[email protected]>
[ Upstream commit 8546cfd08aa4b982acd2357403a1f15495d622ec ]
The SMMU architecture requires wired interrupts to be edge triggered, which does not align with the DT description for the RK3588. This leads to interrupt storms, as the SMMU continues to hold the pin high and only pulls it down for a short amount when issuing an IRQ. Update the DT description to be in line with the spec and perceived reality.
--- arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +8 -8
@@ -549,10 +549,10 @@ usb_host2_xhci: usb@fcd00000 { mmu600_pcie: iommu@fc900000 { compatible = "arm,smmu-v3"; reg = <0x0 0xfc900000 0x0 0x200000>; - interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>; + interrupts = <GIC_SPI 369 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 371 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 374 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 367 IRQ_TYPE_EDGE_RISING 0>; interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; #iommu-cells = <1>; status = "disabled";
@@ -561,10 +561,10 @@ mmu600_pcie: iommu@fc900000 { mmu600_php: iommu@fcb00000 { compatible = "arm,smmu-v3"; reg = <0x0 0xfcb00000 0x0 0x200000>; - interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>, - <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>; + interrupts = <GIC_SPI 381 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 383 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 386 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 379 IRQ_TYPE_EDGE_RISING 0>; interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; #iommu-cells = <1>; status = "disabled";
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 64/138 firmware: arm_scmi: imx: Correct tx size of scmi_imx_misc_ctrl_set
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit ab027c488fc4a1fff0a5b712d4bdb2d2d324e8f8 ]
'struct scmi_imx_misc_ctrl_set_in' has a zero length array in the end, The sizeof will not count 'value[]', and hence Tx size will be smaller than actual size for Tx,and SCMI firmware will flag this as protocol error.
Fix this by enlarge the Tx size with 'num * sizeof(__le32)' to count in the size of data.
Message-Id: <[email protected]> (sudeep.holla: Commit rewording and replace hardcoded sizeof(__le32) value)
--- drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c +2 -2
@@ -254,8 +254,8 @@ static int scmi_imx_misc_ctrl_set(const struct scmi_protocol_handle *ph,if (num > max_num)return -EINVAL ; - ret = ph->xops->xfer_get_init (ph,SCMI_IMX_MISC_CTRL_SET ,sizeof (*in), -0 , &t); + ret = ph->xops->xfer_get_init (ph,SCMI_IMX_MISC_CTRL_SET , +sizeof (*in) + num *sizeof (__le32),0 , &t);if (ret)return ret;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 65/138 md/raid*: Fix the set_queue_limits implementations
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit fbe8f2fa971c537571994a0df532c511c4fb5537 ]
queue_limits_cancel_update() must only be called if queue_limits_start_update() is called first. Remove the queue_limits_cancel_update() calls from the raid*_set_limits() functions because there is no corresponding queue_limits_start_update() call.
--- drivers/md/raid0.c | 4 +--- drivers/md/raid1.c | 4 +--- drivers/md/raid10.c | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-)
drivers/md/raid0.c +1 -3
@@ -386,10 +386,8 @@ static int raid0_set_limits(struct mddev *mddev) lim.io_opt = lim.io_min * mddev->raid_disks; lim.features |=BLK_FEAT_ATOMIC_WRITES_STACKED ; err =mddev_stack_rdev_limits (mddev, &lim,MDDEV_STACK_INTEGRITY ); -if (err) { -queue_limits_cancel_update (mddev->gendisk->queue); +if (err)return err; - }return queue_limits_set (mddev->gendisk->queue, &lim); }
drivers/md/raid1.c +1 -3
@@ -3219,10 +3219,8 @@ static int raid1_set_limits(struct mddev *mddev) lim.max_write_zeroes_sectors =0 ; lim.features |=BLK_FEAT_ATOMIC_WRITES_STACKED ; err =mddev_stack_rdev_limits (mddev, &lim,MDDEV_STACK_INTEGRITY ); -if (err) { -queue_limits_cancel_update (mddev->gendisk->queue); +if (err)return err; - }return queue_limits_set (mddev->gendisk->queue, &lim); }
drivers/md/raid10.c +1 -3
@@ -4020,10 +4020,8 @@ static int raid10_set_queue_limits(struct mddev *mddev) lim.io_opt = lim.io_min *raid10_nr_stripes (conf); lim.features |=BLK_FEAT_ATOMIC_WRITES_STACKED ; err =mddev_stack_rdev_limits (mddev, &lim,MDDEV_STACK_INTEGRITY ); -if (err) { -queue_limits_cancel_update (mddev->gendisk->queue); +if (err)return err; - }return queue_limits_set (mddev->gendisk->queue, &lim); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 66/138 firmware: imx: IMX_SCMI_MISC_DRV should depend on ARCH_MXC
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit be6686b823b30a69b1f71bde228ce042c78a1941 ]
The i.MX System Controller Management Interface firmware is only present on Freescale i.MX SoCs. Hence add a dependency on ARCH_MXC, to prevent asking the user about this driver when configuring a kernel without Freescale i.MX platform support.
--- drivers/firmware/imx/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/imx/Kconfig +1 -0
@@ -25,6 +25,7 @@ config IMX_SCU config IMX_SCMI_MISC_DRV tristate "IMX SCMI MISC Protocol driver" + depends on ARCH_MXC || COMPILE_TEST default y if ARCH_MXC help The System Controller Management Interface firmware (SCMI FW) is
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 57/138 arm64: dts: rockchip: fix fixed-regulator renames on rk3399-gru devices
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Stuebner <[email protected]>
[ Upstream commit 2f9eb5262e63396a315c7da34a6c80c5d335df9f ]
rk3399-gru chromebooks have a regulator chains where one named regulator supplies multiple regulators pp900-usb pp900_pcie that supply the named peripherals.
The dtsi used somewhat creative structure to describe that in creating the base node 3 times with different phandles and describing the EC dependency in a comment.
This didn't register in the recent regulator-node renaming, as the additional nodes were empty, so adapt the missing node names for now.
--- .../dts/rockchip/rk3399-gru-chromebook.dtsi | 8 +++---- .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 6 ++--- arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 22 +++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-)
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +4 -4
@@ -22,11 +22,11 @@ pp900_ap: regulator-pp900-ap { }; /* EC turns on w/ pp900_usb_en */ - pp900_usb: pp900-ap { + pp900_usb: regulator-pp900-ap { }; /* EC turns on w/ pp900_pcie_en */ - pp900_pcie: pp900-ap { + pp900_pcie: regulator-pp900-ap { }; pp3000: regulator-pp3000 {
@@ -126,7 +126,7 @@ pp1800_pcie: regulator-pp1800-pcie { }; /* Always on; plain and simple */ - pp3000_ap: pp3000_emmc: pp3000 { + pp3000_ap: pp3000_emmc: regulator-pp3000 { }; pp1500_ap_io: regulator-pp1500-ap-io {
@@ -160,7 +160,7 @@ pp3300_disp: regulator-pp3300-disp { }; /* EC turns on w/ pp3300_usb_en_l */ - pp3300_usb: pp3300 { + pp3300_usb: regulator-pp3300 { }; /* gpio is shared with pp1800_pcie and pinctrl is set there */
arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi +3 -3
@@ -92,7 +92,7 @@ pp900_s3: regulator-pp900-s3 { }; /* EC turns on pp1800_s3_en */ - pp1800_s3: pp1800 { + pp1800_s3: regulator-pp1800 { }; /* pp3300 children, sorted by name */
@@ -109,11 +109,11 @@ pp2800_cam: regulator-pp2800-avdd { }; /* EC turns on pp3300_s0_en */ - pp3300_s0: pp3300 { + pp3300_s0: regulator-pp3300 { }; /* EC turns on pp3300_s3_en */ - pp3300_s3: pp3300 { + pp3300_s3: regulator-pp3300 { }; /*
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +11 -11
@@ -189,39 +189,39 @@ ppvar_gpu: ppvar-gpu { }; /* EC turns on w/ pp900_ddrpll_en */ - pp900_ddrpll: pp900-ap { + pp900_ddrpll: regulator-pp900-ap { }; /* EC turns on w/ pp900_pll_en */ - pp900_pll: pp900-ap { + pp900_pll: regulator-pp900-ap { }; /* EC turns on w/ pp900_pmu_en */ - pp900_pmu: pp900-ap { + pp900_pmu: regulator-pp900-ap { }; /* EC turns on w/ pp1800_s0_en_l */ - pp1800_ap_io: pp1800_emmc: pp1800_nfc: pp1800_s0: pp1800 { + pp1800_ap_io: pp1800_emmc: pp1800_nfc: pp1800_s0: regulator-pp1800 { }; /* EC turns on w/ pp1800_avdd_en_l */ - pp1800_avdd: pp1800 { + pp1800_avdd: regulator-pp1800 { }; /* EC turns on w/ pp1800_lid_en_l */ - pp1800_lid: pp1800_mic: pp1800 { + pp1800_lid: pp1800_mic: regulator-pp1800 { }; /* EC turns on w/ lpddr_pwr_en */ - pp1800_lpddr: pp1800 { + pp1800_lpddr: regulator-pp1800 { }; /* EC turns on w/ pp1800_pmu_en_l */ - pp1800_pmu: pp1800 { + pp1800_pmu: regulator-pp1800 { }; /* EC turns on w/ pp1800_usb_en_l */ - pp1800_usb: pp1800 { + pp1800_usb: regulator-pp1800 { }; pp3000_sd_slot: regulator-pp3000-sd-slot {
@@ -259,11 +259,11 @@ ppvar_sd_card_io: ppvar-sd-card-io { }; /* EC turns on w/ pp3300_trackpad_en_l */ - pp3300_trackpad: pp3300-trackpad { + pp3300_trackpad: regulator-pp3300-trackpad { }; /* EC turns on w/ usb_a_en */ - pp5000_usb_a_vbus: pp5000 { + pp5000_usb_a_vbus: regulator-pp5000 { }; ap_rtc_clk: ap-rtc-clk {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 93/138 drm/i915/gt: Use spin_lock_irqsave() in interruptible context
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <[email protected]>
commit e49477f7f78598295551d486ecc7f020d796432e upstream.
spin_lock/unlock() functions used in interrupt contexts could result in a deadlock, as seen in GitLab issue #13399, which occurs when interrupt comes in while holding a lock.
Try to remedy the problem by saving irq state before spin lock acquisition.
v2: add irqs' state save/restore calls to all locks/unlocks in
signal_irq_work() execution (Maciej)
v3: use with spin_lock_irqsave() in guc_lrc_desc_unpin() instead
of other lock/unlock calls and add Fixes and Cc tags (Tvrtko); change title and commit message
--- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +2 -2
@@ -3425,10 +3425,10 @@ static inline int guc_lrc_desc_unpin(str*/ ret =deregister_context (ce, ce->guc_id.id);if (ret) { -spin_lock (&ce->guc_state.lock); +spin_lock_irqsave (&ce->guc_state.lock, flags);set_context_registered (ce);clr_context_destroyed (ce); -spin_unlock (&ce->guc_state.lock); +spin_unlock_irqrestore (&ce->guc_state.lock, flags);/* * As gt-pm is awake at function entry, intel_wakeref_put_async merely decrements * the wakeref immediately but per function spec usage call this after unlock.
Greg Kroah-Hartman
maintainerPATCH 102/138 arm64: dts: rockchip: change eth phy mode to rgmii-id for orangepi r1 plus lts
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianling Shen <[email protected]>
commit a6a7cba17c544fb95d5a29ab9d9ed4503029cb29 upstream.
In general the delay should be added by the PHY instead of the MAC, and this improves network stability on some boards which seem to need different delay.
--- arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts | 3 +-- arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts | 1 + arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 - 3 files changed, 2 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +1 -2
@@ -17,8 +17,7 @@ &gmac2io { phy-handle = <&yt8531c>; - tx_delay = <0x19>; - rx_delay = <0x05>; + phy-mode = "rgmii-id"; status = "okay"; mdio {
arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts +1 -0
@@ -15,6 +15,7 @@ &gmac2io { phy-handle = <&rtl8211e>; + phy-mode = "rgmii"; tx_delay = <0x24>; rx_delay = <0x18>; status = "okay";
arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi +0 -1
@@ -109,7 +109,6 @@ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; clock_in_out = "input"; - phy-mode = "rgmii"; phy-supply = <&vcc_io>; pinctrl-0 = <&rgmiim1_pins>; pinctrl-names = "default";
Greg Kroah-Hartman
maintainerPATCH 103/138 arm64: dts: rockchip: Fix broken tsadc pinctrl names for rk3588
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Shiyan <[email protected]>
commit 5c8f9a05336cf5cadbd57ad461621b386aadb762 upstream.
The tsadc driver does not handle pinctrl "gpio" and "otpout". Let's use the correct pinctrl names "default" and "sleep". Additionally, Alexey Charkov's testing [1] has established that it is necessary for pinctrl state to reference the &tsadc_shut_org configuration rather than &tsadc_shut for the driver to function correctly.
[1] https://lkml.org/lkml/2025/1/24/966
--- arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +3 -3
@@ -2667,9 +2667,9 @@ rockchip,hw-tshut-temp = <120000>; rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */ - pinctrl-0 = <&tsadc_gpio_func>; - pinctrl-1 = <&tsadc_shut>; - pinctrl-names = "gpio", "otpout"; + pinctrl-0 = <&tsadc_shut_org>; + pinctrl-1 = <&tsadc_gpio_func>; + pinctrl-names = "default", "sleep"; #thermal-sensor-cells = <1>; status = "disabled"; };
Greg Kroah-Hartman
maintainerPATCH 104/138 arm64: dts: rockchip: Move uart5 pin configuration to px30 ringneck SoM
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukasz Czechowski <[email protected]>
commit 4eee627ea59304cdd66c5d4194ef13486a6c44fc upstream.
In the PX30-uQ7 (Ringneck) SoM, the hardware CTS and RTS pins for uart5 cannot be used for the UART CTS/RTS, because they are already allocated for different purposes. CTS pin is routed to SUS_S3# signal, while RTS pin is used internally and is not available on Q7 connector. Move definition of the pinctrl-0 property from px30-ringneck-haikou.dts to px30-ringneck.dtsi.
This commit is a dependency to next commit in the patch series, that disables DMA for uart5.
--- arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts | 1 - arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts +0 -1
@@ -226,7 +226,6 @@ }; &uart5 { - pinctrl-0 = <&uart5_xfer>; rts-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; status = "okay"; };
arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi +4 -0
@@ -396,6 +396,10 @@ status = "okay"; }; +&uart5 { + pinctrl-0 = <&uart5_xfer>; +}; + /* Mule UCAN */ &usb_host0_ehci { status = "okay";
Greg Kroah-Hartman
maintainerPATCH 105/138 arm64: dts: rockchip: Disable DMA for uart5 on px30-ringneck
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukasz Czechowski <[email protected]>
commit 5ae4dca718eacd0a56173a687a3736eb7e627c77 upstream.
UART controllers without flow control seem to behave unstable in case DMA is enabled. The issues were indicated in the message:
https://lore.kernel.org/linux-arm-kernel/CAMdYzYpXtMocCtCpZLU_xuWmOp2Ja_v0Aj0e6YFNRA-yV7u14g@mail.gmail.com/
In case of PX30-uQ7 Ringneck SoM, it was noticed that after couple of hours of UART communication, the CPU stall was occurring, leading to the system becoming unresponsive.
After disabling the DMA, extensive UART communication tests for up to two weeks were performed, and no issues were further observed.
The flow control pins for uart5 are not available on PX30-uQ7 Ringneck, as configured by pinctrl-0, so the DMA nodes were removed on SoM dtsi.
--- arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi +2 -0
@@ -397,6 +397,8 @@ }; &uart5 { + /delete-property/ dmas; + /delete-property/ dma-names; pinctrl-0 = <&uart5_xfer>; };
Greg Kroah-Hartman
maintainerPATCH 106/138 gpio: vf610: add locking to gpio direction functions
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Korsnes <[email protected]>
commit 4e667a1968099c6deadee2313ecd648f8f0a8956 upstream.
Add locking to vf610_gpio_direction_input|output() functions. Without this locking, a race condition exists between concurrent calls to these functions, potentially leading to incorrect GPIO direction settings.
To verify the correctness of this fix, a trylock patch was applied, where after a couple of reboots the race was confirmed. I.e., one user had to wait before acquiring the lock. With this patch the race has not been encountered. It's worth mentioning that any type of debugging (printing, tracing, etc.) would "resolve"/hide the issue.
--- drivers/gpio/gpio-vf610.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpio/gpio-vf610.c +4 -0
@@ -36,6 +36,7 @@ struct vf610_gpio_port {struct clk *clk_port;struct clk *clk_gpio;int irq; +spinlock_t lock;/* protect gpio direction registers */ };#define GPIO_PDOR 0x00
@@ -124,6 +125,7 @@ static int vf610_gpio_direction_input(stu32 val;if (port->sdata->have_paddr) { +guard (spinlock_irqsave)(&port->lock); val =vf610_gpio_readl (port->gpio_base +GPIO_PDDR ); val &= ~mask;vf610_gpio_writel (val, port->gpio_base +GPIO_PDDR );
@@ -142,6 +144,7 @@ static int vf610_gpio_direction_output(svf610_gpio_set (chip, gpio, value);if (port->sdata->have_paddr) { +guard (spinlock_irqsave)(&port->lock); val =vf610_gpio_readl (port->gpio_base +GPIO_PDDR ); val |= mask;vf610_gpio_writel (val, port->gpio_base +GPIO_PDDR );
@@ -297,6 +300,7 @@ static int vf610_gpio_probe(struct platfreturn -ENOMEM ; port->sdata =device_get_match_data (dev); +spin_lock_init (&port->lock); dual_base = port->sdata->have_dual_base;
Greg Kroah-Hartman
maintainerPATCH 107/138 soc: loongson: loongson2_guts: Add check for devm_kstrdup()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit e31e3f6c0ce473f7ce1e70d54ac8e3ed190509f8 upstream.
Add check for the return value of devm_kstrdup() in loongson2_guts_probe() to catch potential exception.
--- drivers/soc/loongson/loongson2_guts.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/soc/loongson/loongson2_guts.c +4 -1
@@ -114,8 +114,11 @@ static int loongson2_guts_probe(struct pif (of_property_read_string (root,"model" , &machine))of_property_read_string_index (root,"compatible" ,0 , &machine);of_node_put (root); -if (machine) +if (machine) { soc_dev_attr.machine =devm_kstrdup (dev, machine,GFP_KERNEL ); +if (!soc_dev_attr.machine) +return -ENOMEM ; + } svr =loongson2_guts_get_svr (); soc_die =loongson2_soc_die_match (svr, loongson2_soc_die);
Greg Kroah-Hartman
maintainerPATCH 108/138 s390/boot: Fix ESSA detection
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit c3a589fd9fcbf295a7402a4b188dc9277d505f4f upstream.
The cmma_test_essa() inline assembly uses tmp as input and output, however tmp is specified as output only, which allows the compiler to optimize the initialization of tmp away.
Therefore the ESSA detection may or may not work depending on previous contents of the register that the compiler selected for tmp.
Fix this by using the correct constraint modifier.
--- arch/s390/boot/startup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/boot/startup.c +1 -1
@@ -75,7 +75,7 @@ static int cmma_test_essa(void) : [reg1] "=&d" (reg1), [reg2] "=&a" (reg2), [rc] "+&d" (rc), - [tmp] "=&d" (tmp), + [tmp] "+&d" (tmp), "+Q" (get_lowcore()->program_new_psw), "=Q" (old) : [psw_old] "a" (&old),
Greg Kroah-Hartman
maintainerPATCH 109/138 xfs: fix online repair probing when CONFIG_XFS_ONLINE_REPAIR=n
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
commit 66314e9a57a050f95cb0ebac904f5ab047a8926e upstream.
I received a report from the release engineering side of the house that xfs_scrub without the -n flag (aka fix it mode) would try to fix a broken filesystem even on a kernel that doesn't have online repair built into it:
# xfs_scrub -dTvn /mnt/test EXPERIMENTAL xfs_scrub program in use! Use at your own risk! Phase 1: Find filesystem geometry. /mnt/test: using 1 threads to scrub. Phase 1: Memory used: 132k/0k (108k/25k), time: 0.00/ 0.00/ 0.00s <snip> Phase 4: Repair filesystem. <snip> Info: /mnt/test/some/victimdir directory entries: Attempting repair. (repair.c line 351) Corruption: /mnt/test/some/victimdir directory entries: Repair unsuccessful; offline repair required. (repair.c line 204)
Source: https://blogs.oracle.com/linux/post/xfs-online-filesystem-repair
It is strange that xfs_scrub doesn't refuse to run, because the kernel is supposed to return EOPNOTSUPP if we actually needed to run a repair, and xfs_io's repair subcommand will perror that. And yet:
# xfs_io -x -c 'repair probe' /mnt/test #
The first problem is commit dcb660f9222fd9 (4.15) which should have had xchk_probe set the CORRUPT OFLAG so that any of the repair machinery will get called at all.
It turns out that some refactoring that happened in the 6.6-6.8 era broke the operation of this corner case. What we *really* want to happen is that all the predicates that would steer xfs_scrub_metadata() towards calling xrep_attempt() should function the same way that they do when repair is compiled in; and then xrep_attempt gets to return the fatal EOPNOTSUPP error code that causes the probe to fail.
Instead, commit 8336a64eb75cba (6.6) started the failwhale swimming by hoisting OFLAG checking logic into a helper whose non-repair stub always returns false, causing scrub to return "repair not needed" when in fact the repair is not supported. Prior to that commit, the oflag checking that was open-coded in scrub.c worked correctly.
Similarly, in commit 4bdfd7d15747b1 (6.8) we hoisted the IFLAG_REPAIR and ALREADY_FIXED logic into a helper whose non-repair stub always returns false, so we never enter the if test body that would have called xrep_attempt, let alone fail to decode the OFLAGs correctly.
The final insult (yes, we're doing The Naked Gun now) is commit 48a72f60861f79 (6.8) in which we hoisted the "are we going to try a repair?" predicate into yet another function with a non-repair stub always returns false.
Fix xchk_probe to trigger xrep_probe if repair is enabled, or return EOPNOTSUPP directly if it is not. For all the other scrub types, we need to fix the header predicates so that the ->repair functions (which are all xrep_notsupported) get called to return EOPNOTSUPP. Commit 48a72 is tagged here because the scrub code prior to LTS 6.12 are incomplete and not worth patching.
--- fs/xfs/scrub/common.h | 5 ----- fs/xfs/scrub/repair.h | 11 ++++++++++- fs/xfs/scrub/scrub.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-)
fs/xfs/scrub/common.h +0 -5
@@ -212,7 +212,6 @@ static inline bool xchk_skip_xref(structbool xchk_dir_looks_zapped (struct xfs_inode *dp);bool xchk_pptr_looks_zapped (struct xfs_inode *ip); -#ifdef CONFIG_XFS_ONLINE_REPAIR /* Decide if a repair is required. */ static inline bool xchk_needs_repair (const struct xfs_scrub_metadata *sm) {
@@ -232,10 +231,6 @@ static inline bool xchk_could_repair(conreturn (sc->sm->sm_flags &XFS_SCRUB_IFLAG_REPAIR ) && !(sc->flags &XREP_ALREADY_FIXED ); } -#else -# define xchk_needs_repair (sc) (false) -# define xchk_could_repair (sc) (false) -#endif /* CONFIG_XFS_ONLINE_REPAIR */ int xchk_metadata_inode_forks (struct xfs_scrub *sc);
fs/xfs/scrub/repair.h +10 -1
@@ -173,7 +173,16 @@ bool xrep_buf_verify_struct(struct xfs_b#else #define xrep_ino_dqattach (sc) (0) -#define xrep_will_attempt (sc) (false) + +/* +* When online repair is not built into the kernel, we still want to attempt +* the repair so that the stub xrep_attempt below will return EOPNOTSUPP. +*/ +static inline bool xrep_will_attempt (const struct xfs_scrub *sc) +{ +return (sc->sm->sm_flags &XFS_SCRUB_IFLAG_FORCE_REBUILD ) || +xchk_needs_repair (sc->sm); +}static inline int xrep_attempt(
fs/xfs/scrub/scrub.c +12 -0
@@ -149,6 +149,18 @@ xchk_probe(if (xchk_should_terminate (sc, &error))return error; +/* +* If the caller is probing to see if repair works but repair isn't +* built into the kernel, return EOPNOTSUPP because that's the signal +* that userspace expects. If online repair is built in, set the +* CORRUPT flag (without any of the usual tracing/logging) to force us +* into xrep_probe. +*/ +if (xchk_could_repair (sc)) { +if (!IS_ENABLED (CONFIG_XFS_ONLINE_REPAIR )) +return -EOPNOTSUPP ; + sc->sm->sm_flags |=XFS_SCRUB_OFLAG_CORRUPT ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 110/138 lib/iov_iter: fix import_iovec_ubuf iovec management
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <[email protected]>
commit f4b78260fc678ccd7169f32dc9f3bfa3b93931c7 upstream.
import_iovec() says that it should always be fine to kfree the iovec returned in @iovp regardless of the error code. __import_iovec_ubuf() never reallocates it and thus should clear the pointer even in cases when copy_iovec_*() fail.
--- lib/iov_iter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/iov_iter.c +2 -1
@@ -1428,6 +1428,8 @@ static ssize_t __import_iovec_ubuf(int tstruct iovec *iov = *iovp;ssize_t ret; + *iovp =NULL ; +if (compat) ret =copy_compat_iovec_from_user (iov, uvec,1 );else
@@ -1438,7 +1440,6 @@ static ssize_t __import_iovec_ubuf(int t ret =import_ubuf (type, iov->iov_base, iov->iov_len, i);if (unlikely (ret))return ret; - *iovp =NULL ;return i->count; }
Greg Kroah-Hartman
maintainerPATCH 111/138 smb: client: fix chmod(2) regression with ATTR_READONLY
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 654292a0b264e9b8c51b98394146218a21612aa1 upstream.
When the user sets a file or directory as read-only (e.g. ~S_IWUGO), the client will set the ATTR_READONLY attribute by sending an SMB2_SET_INFO request to the server in cifs_setattr_{,nounix}(), but cifsInodeInfo::cifsAttrs will be left unchanged as the client will only update the new file attributes in the next call to {smb311_posix,cifs}_get_inode_info() with the new metadata filled in @data parameter.
Commit a18280e7fdea ("smb: cilent: set reparse mount points as automounts") mistakenly removed the @data NULL check when calling is_inode_cache_good(), which broke the above case as the new ATTR_READONLY attribute would end up not being updated on files with a read lease.
Fix this by updating the inode whenever we have cached metadata in @data parameter.
--- fs/smb/client/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/smb/client/inode.c +2 -2
@@ -1403,7 +1403,7 @@ int cifs_get_inode_info(struct inode **istruct cifs_fattr fattr = {};int rc; -if (is_inode_cache_good (*inode)) { +if (!data &&is_inode_cache_good (*inode)) {cifs_dbg (FYI ,"No need to revalidate cached inode sizes\n" );return 0 ; }
@@ -1502,7 +1502,7 @@ int smb311_posix_get_inode_info(struct istruct cifs_fattr fattr = {};int rc; -if (is_inode_cache_good (*inode)) { +if (!data &&is_inode_cache_good (*inode)) {cifs_dbg (FYI ,"No need to revalidate cached inode sizes\n" );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 94/138 drm/i915/dsi: Use TRANS_DDI_FUNC_CTLs own port width macro
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit 879f70382ff3e92fc854589ada3453e3f5f5b601 upstream.
The format of the port width field in the DDI_BUF_CTL and the TRANS_DDI_FUNC_CTL registers are different starting with MTL, where the x3 lane mode for HDMI FRL has a different encoding in the two registers. To account for this use the TRANS_DDI_FUNC_CTL's own port width macro.
--- drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/icl_dsi.c +2 -2
@@ -808,8 +808,8 @@ gen11_dsi_configure_transcoder(struct in/* select data lane width */ tmp =intel_de_read (display,TRANS_DDI_FUNC_CTL (display, dsi_trans)); - tmp &= ~DDI_PORT_WIDTH_MASK ; - tmp |=DDI_PORT_WIDTH (intel_dsi->lane_count); + tmp &= ~TRANS_DDI_PORT_WIDTH_MASK ; + tmp |=TRANS_DDI_PORT_WIDTH (intel_dsi->lane_count);/* select input pipe */ tmp &= ~TRANS_DDI_EDP_INPUT_MASK ;
Greg Kroah-Hartman
maintainerPATCH 112/138 mm/zswap: fix inconsistency when zswap_store_page() fails
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyeonggon Yoo <[email protected]>
commit 63895d20d63b446f5049a963983489319c2ea3e2 upstream.
Commit b7c0ccdfbafd ("mm: zswap: support large folios in zswap_store()") skips charging any zswap entries when it failed to zswap the entire folio.
However, when some base pages are zswapped but it failed to zswap the entire folio, the zswap operation is rolled back. When freeing zswap entries for those pages, zswap_entry_free() uncharges the zswap entries that were not previously charged, causing zswap charging to become inconsistent.
This inconsistency triggers two warnings with following steps:
# On a machine with 64GiB of RAM and 36GiB of zswap
$ stress-ng --bigheap 2 # wait until the OOM-killer kills stress-ng $ sudo reboot
The two warnings are:
in mm/memcontrol.c:163, function obj_cgroup_release():
WARN_ON_ONCE(nr_bytes & (PAGE_SIZE - 1));
in mm/page_counter.c:60, function page_counter_cancel():
if (WARN_ONCE(new < 0, "page_counter underflow: %ld nr_pages=%lu\n",
new, nr_pages))
zswap_stored_pages also becomes inconsistent in the same way.
As suggested by Kanchana, increment zswap_stored_pages and charge zswap entries within zswap_store_page() when it succeeds. This way, zswap_entry_free() will decrement the counter and uncharge the entries when it failed to zswap the entire folio.
While this could potentially be optimized by batching objcg charging and incrementing the counter, let's focus on fixing the bug this time and leave the optimization for later after some evaluation.
After resolving the inconsistency, the warnings disappear.
--- mm/zswap.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-)
mm/zswap.c +16 -19
@@ -1445,9 +1445,9 @@ resched:* main API **********************************/ -static ssize_t zswap_store_page (struct page *page, -struct obj_cgroup *objcg, -struct zswap_pool *pool) +static bool zswap_store_page (struct page *page, +struct obj_cgroup *objcg, +struct zswap_pool *pool) {swp_entry_t page_swpentry =page_swap_entry (page);struct zswap_entry *entry, *old;
@@ -1456,7 +1456,7 @@ static ssize_t zswap_store_page(struct page *page, entry =zswap_entry_cache_alloc (GFP_KERNEL ,page_to_nid (page));if (!entry) { zswap_reject_kmemcache_fail++; -return -EINVAL ; +return false; }if (!zswap_compress (page, entry, pool))
@@ -1483,13 +1483,17 @@ static ssize_t zswap_store_page(struct page *page,/* * The entry is successfully compressed and stored in the tree, there is -* no further possibility of failure. Grab refs to the pool and objcg. -* These refs will be dropped by zswap_entry_free() when the entry is -* removed from the tree. +* no further possibility of failure. Grab refs to the pool and objcg, +* charge zswap memory, and increment zswap_stored_pages. +* The opposite actions will be performed by zswap_entry_free() +* when the entry is removed from the tree. */ zswap_pool_get (pool); -if (objcg) +if (objcg) {obj_cgroup_get (objcg); +obj_cgroup_charge_zswap (objcg, entry->length); + } +atomic_long_inc (&zswap_stored_pages);/* * We finish initializing the entry while it's already in xarray.
@@ -1510,13 +1514,13 @@ static ssize_t zswap_store_page(struct page *page,zswap_lru_add (&zswap_list_lru, entry); } -return entry->length; +return true; store_failed:zpool_free (pool->zpool, entry->handle); compress_failed:zswap_entry_cache_free (entry); -return -EINVAL ; +return false; }bool zswap_store (struct folio *folio)
@@ -1526,7 +1530,6 @@ bool zswap_store(struct folio *folio)struct obj_cgroup *objcg =NULL ;struct mem_cgroup *memcg =NULL ;struct zswap_pool *pool; -size_t compressed_bytes =0 ;bool ret = false;long index;
@@ -1564,20 +1567,14 @@ bool zswap_store(struct folio *folio)for (index =0 ; index < nr_pages; ++index) {struct page *page =folio_page (folio, index); -ssize_t bytes; - bytes =zswap_store_page (page, objcg, pool); -if (bytes <0 ) +if (!zswap_store_page (page, objcg, pool)) goto put_pool; - compressed_bytes += bytes; } -if (objcg) { -obj_cgroup_charge_zswap (objcg, compressed_bytes); +if (objcg)count_objcg_events (objcg,ZSWPOUT , nr_pages); - } -atomic_long_add (nr_pages, &zswap_stored_pages);count_vm_events (ZSWPOUT , nr_pages); ret = true;
Signature · 1 line
2.48.1
Greg Kroah-Hartman
maintainerPATCH 113/138 nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 878e7b11736e062514e58f3b445ff343e6705537 upstream.
Add check for the return value of nfp_app_ctrl_msg_alloc() in nfp_bpf_cmsg_alloc() to prevent null pointer dereference.
--- drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +2 -0
@@ -20,6 +20,8 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bstruct sk_buff *skb; skb =nfp_app_ctrl_msg_alloc (bpf->app, size,GFP_KERNEL ); +if (!skb) +return NULL ;skb_put (skb, size);return skb;
Greg Kroah-Hartman
maintainerPATCH 114/138 gve: set xdp redirect target only when it is available
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Washington <[email protected]>
commit 415cadd505464d9a11ff5e0f6e0329c127849da5 upstream.
Before this patch the NETDEV_XDP_ACT_NDO_XMIT XDP feature flag is set by default as part of driver initialization, and is never cleared. However, this flag differs from others in that it is used as an indicator for whether the driver is ready to perform the ndo_xdp_xmit operation as part of an XDP_REDIRECT. Kernel helpers xdp_features_(set|clear)_redirect_target exist to convey this meaning.
This patch ensures that the netdev is only reported as a redirect target when XDP queues exist to forward traffic.
--- drivers/net/ethernet/google/gve/gve.h | 10 ++++++++++ drivers/net/ethernet/google/gve/gve_main.c | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-)
drivers/net/ethernet/google/gve/gve.h +10 -0
@@ -1116,6 +1116,16 @@ static inline u32 gve_xdp_tx_start_queuereturn gve_xdp_tx_queue_id (priv,0 ); } +static inline bool gve_supports_xdp_xmit (struct gve_priv *priv) +{ +switch (priv->queue_format) { +case GVE_GQI_QPL_FORMAT : +return true; +default : +return false; + } +} +/* gqi napi handler defined in gve_main.c */ int gve_napi_poll (struct napi_struct *napi,int budget);
drivers/net/ethernet/google/gve/gve_main.c +5 -1
@@ -1903,6 +1903,8 @@ static void gve_turndown(struct gve_priv/* Stop tx queues */ netif_tx_disable (priv->dev); +xdp_features_clear_redirect_target (priv->dev); +gve_clear_napi_enabled (priv);gve_clear_report_stats (priv);
@@ -1972,6 +1974,9 @@ static void gve_turnup(struct gve_priv *napi_schedule (&block->napi); } +if (priv->num_xdp_queues &&gve_supports_xdp_xmit (priv)) +xdp_features_set_redirect_target (priv->dev, false); +gve_set_napi_enabled (priv); }
@@ -2246,7 +2251,6 @@ static void gve_set_netdev_xdp_features(if (priv->queue_format ==GVE_GQI_QPL_FORMAT ) { xdp_features =NETDEV_XDP_ACT_BASIC ; xdp_features |=NETDEV_XDP_ACT_REDIRECT ; - xdp_features |=NETDEV_XDP_ACT_NDO_XMIT ; xdp_features |=NETDEV_XDP_ACT_XSK_ZEROCOPY ; }else { xdp_features =0 ;
Greg Kroah-Hartman
maintainerPATCH 115/138 ASoC: SOF: stream-ipc: Check for cstream nullity in sof_ipc_msg_data()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
commit d8d99c3b5c485f339864aeaa29f76269cc0ea975 upstream.
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function.
Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference.
--- sound/soc/sof/stream-ipc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/soc/sof/stream-ipc.c +5 -1
@@ -43,7 +43,7 @@ int sof_ipc_msg_data(struct snd_sof_devreturn -ESTRPIPE ; posn_offset = stream->posn_offset; - }else { + }else if (sps->cstream) {struct sof_compr_stream *sstream = sps->cstream->runtime->private_data;
@@ -51,6 +51,10 @@ int sof_ipc_msg_data(struct snd_sof_devreturn -ESTRPIPE ; posn_offset = sstream->posn_offset; + + }else { +dev_err (sdev->dev,"%s: No stream opened\n" , __func__); +return -EINVAL ; }snd_sof_dsp_mailbox_read (sdev, posn_offset, p, sz);
Greg Kroah-Hartman
maintainerPATCH 116/138 ASoC: fsl_micfil: Enable default case in micfil_set_quality()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit a8c9a453387640dbe45761970f41301a6985e7fa upstream.
If 'micfil->quality' received from micfil_quality_set() somehow ends up with an unpredictable value, switch() operator will fail to initialize local variable qsel before regmap_update_bits() tries to utilize it.
While it is unlikely, play it safe and enable a default case that returns -EINVAL error.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- sound/soc/fsl/fsl_micfil.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/fsl/fsl_micfil.c +2 -0
@@ -157,6 +157,8 @@ static int micfil_set_quality(struct fslcase QUALITY_VLOW2 : qsel =MICFIL_QSEL_VLOW2_QUALITY ;break ; +default : +return -EINVAL ; } return regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
Greg Kroah-Hartman
maintainerPATCH 117/138 ALSA: hda: Add error check for snd_ctl_rename_id() in snd_hda_create_dig_out_ctls()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit 822b7ec657e99b44b874e052d8540d8b54fe8569 upstream.
Check the return value of snd_ctl_rename_id() in snd_hda_create_dig_out_ctls(). Ensure that failures are properly handled.
[ Note: the error cannot happen practically because the only error
condition in snd_ctl_rename_id() is the missing ID, but this is a rename, hence it must be present. But for the code consistency, it's safer to have always the proper return check -- tiwai ]
--- sound/pci/hda/hda_codec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/pci/hda/hda_codec.c +3 -1
@@ -2470,7 +2470,9 @@ int snd_hda_create_dig_out_ctls(struct hbreak ; id = kctl->id; id.index = spdif_index; -snd_ctl_rename_id (codec->card, &kctl->id, &id); + err =snd_ctl_rename_id (codec->card, &kctl->id, &id); +if (err <0 ) +return err; } bus->primary_dig_out_type =HDA_PCM_TYPE_HDMI ; }
Greg Kroah-Hartman
maintainerPATCH 118/138 ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Veness <[email protected]>
commit 6d1f86610f23b0bc334d6506a186f21a98f51392 upstream.
Allows the LED on the dedicated mute button on the HP ProBook 450 G4 laptop to change colour correctly.
--- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_conexant.c +1 -0
@@ -1080,6 +1080,7 @@ static const struct hda_quirk cxt5066_fiSND_PCI_QUIRK (0x103c ,0x814f ,"HP ZBook 15u G3" ,CXT_FIXUP_MUTE_LED_GPIO ),SND_PCI_QUIRK (0x103c ,0x8174 ,"HP Spectre x360" ,CXT_FIXUP_HP_SPECTRE ),SND_PCI_QUIRK (0x103c ,0x822e ,"HP ProBook 440 G4" ,CXT_FIXUP_MUTE_LED_GPIO ), +SND_PCI_QUIRK (0x103c ,0x8231 ,"HP ProBook 450 G4" ,CXT_FIXUP_MUTE_LED_GPIO ),SND_PCI_QUIRK (0x103c ,0x828c ,"HP EliteBook 840 G4" ,CXT_FIXUP_HP_DOCK ),SND_PCI_QUIRK (0x103c ,0x8299 ,"HP 800 G3 SFF" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 119/138 ASoC: SOF: pcm: Clear the susbstream pointer to NULL on close
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
commit 46c7b901e2a03536df5a3cb40b3b26e2be505df6 upstream.
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not.
For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams.
--- sound/soc/sof/pcm.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/sof/pcm.c +2 -0
@@ -511,6 +511,8 @@ static int sof_pcm_close(struct snd_soc_*/ } + spcm->stream[substream->stream].substream =NULL ; +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 120/138 acct: perform last write from workqueue
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit 56d5f3eba3f5de0efdd556de4ef381e109b973a9 upstream.
In [1] it was reported that the acct(2) system call can be used to trigger NULL deref in cases where it is set to write to a file that triggers an internal lookup. This can e.g., happen when pointing acc(2) to /sys/power/resume. At the point the where the write to this file happens the calling task has already exited and called exit_fs(). A lookup will thus trigger a NULL-deref when accessing current->fs.
Reorganize the code so that the the final write happens from the workqueue but with the caller's credentials. This preserves the (strange) permission model and has almost no regression risk.
This api should stop to exist though.
--- kernel/acct.c | 120 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 50 deletions(-)
kernel/acct.c +70 -50
@@ -103,48 +103,50 @@ struct bsd_acct_struct {atomic_long_t count;struct rcu_head rcu;struct mutex lock; -int active; +bool active; +bool check_space;unsigned long needcheck;struct file *file;struct pid_namespace *ns;struct work_struct work;struct completion done; +acct_t ac; }; -static void do_acct_process (struct bsd_acct_struct *acct); +static void fill_ac (struct bsd_acct_struct *acct); +static void acct_write_process (struct bsd_acct_struct *acct);/* * Check the amount of free space and suspend/resume accordingly. */ -static int check_free_space (struct bsd_acct_struct *acct) +static bool check_free_space (struct bsd_acct_struct *acct) {struct kstatfs sbuf; -if (time_is_after_jiffies (acct->needcheck)) - goto out; +if (!acct->check_space) +return acct->active;/* May block */ if (vfs_statfs (&acct->file->f_path, &sbuf)) - goto out; +return acct->active;if (acct->active) {u64 suspend = sbuf.f_blocks *SUSPEND ;do_div (suspend,100 );if (sbuf.f_bavail <= suspend) { - acct->active =0 ; + acct->active = false;pr_info ("Process accounting paused\n" ); } }else {u64 resume = sbuf.f_blocks *RESUME ;do_div (resume,100 );if (sbuf.f_bavail >= resume) { - acct->active =1 ; + acct->active = true;pr_info ("Process accounting resumed\n" ); } } acct->needcheck = jiffies +ACCT_TIMEOUT *HZ ; -out:return acct->active; }
@@ -189,7 +191,11 @@ static void acct_pin_kill(struct fs_pin {struct bsd_acct_struct *acct =to_acct (pin);mutex_lock (&acct->lock); -do_acct_process (acct); +/* +* Fill the accounting struct with the exiting task's info +* before punting to the workqueue. +*/ +fill_ac (acct);schedule_work (&acct->work);wait_for_completion (&acct->done);cmpxchg (&acct->ns->bacct, pin,NULL );
@@ -202,6 +208,9 @@ static void close_work(struct work_struc { struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work);struct file *file = acct->file; + +/* We were fired by acct_pin_kill() which holds acct->lock. */ +acct_write_process (acct);if (file->f_op->flush) file->f_op->flush (file,NULL );__fput_sync (file);
@@ -430,13 +439,27 @@ static u32 encode_float(u64 value)* do_exit() or when switching to a different output file. */ -static void fill_ac (acct_t *ac) +static void fill_ac (struct bsd_acct_struct *acct) {struct pacct_struct *pacct = ¤t->signal->pacct; +struct file *file = acct->file; +acct_t *ac = &acct->ac;u64 elapsed, run_time;time64_t btime;struct tty_struct *tty; +lockdep_assert_held (&acct->lock); + +if (time_is_after_jiffies (acct->needcheck)) { + acct->check_space = false; + +/* Don't fill in @ac if nothing will be written. */ +if (!acct->active) +return ; + }else { + acct->check_space = true; + } +/* * Fill the accounting struct with the needed info as recorded * by the different kernel functions.
@@ -484,64 +507,61 @@ static void fill_ac(acct_t *ac) ac->ac_majflt =encode_comp_t (pacct->ac_majflt); ac->ac_exitcode = pacct->ac_exitcode;spin_unlock_irq (¤t->sighand->siglock); -} -/* -* do_acct_process does all actual work. Caller holds the reference to file. -*/ -static void do_acct_process (struct bsd_acct_struct *acct) -{ -acct_t ac; -unsigned long flim; -const struct cred *orig_cred; -struct file *file = acct->file; - -/* -* Accounting records are not subject to resource limits. -*/ - flim =rlimit (RLIMIT_FSIZE ); - current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ; -/* Perform file operations on behalf of whoever enabled accounting */ - orig_cred =override_creds (file->f_cred); -/* -* First check to see if there is enough free_space to continue -* the process accounting system. -*/ -if (!check_free_space (acct)) - goto out; - -fill_ac (&ac);/* we really need to bite the bullet and change layout */ - ac.ac_uid =from_kuid_munged (file->f_cred->user_ns, orig_cred->uid); - ac.ac_gid =from_kgid_munged (file->f_cred->user_ns, orig_cred->gid); + ac->ac_uid =from_kuid_munged (file->f_cred->user_ns,current_uid ()); + ac->ac_gid =from_kgid_munged (file->f_cred->user_ns,current_gid ());#if ACCT_VERSION ==1 ||ACCT_VERSION ==2 /* backward-compatible 16 bit fields */ - ac.ac_uid16 = ac.ac_uid; - ac.ac_gid16 = ac.ac_gid; + ac->ac_uid16 = ac->ac_uid; + ac->ac_gid16 = ac->ac_gid;#elif ACCT_VERSION ==3 {struct pid_namespace *ns = acct->ns; - ac.ac_pid =task_tgid_nr_ns (current, ns); + ac->ac_pid =task_tgid_nr_ns (current, ns);rcu_read_lock (); - ac.ac_ppid =task_tgid_nr_ns (rcu_dereference (current->real_parent), - ns); + ac->ac_ppid =task_tgid_nr_ns (rcu_dereference (current->real_parent), ns);rcu_read_unlock (); }#endif +} + +static void acct_write_process (struct bsd_acct_struct *acct) +{ +struct file *file = acct->file; +const struct cred *cred; +acct_t *ac = &acct->ac; + +/* Perform file operations on behalf of whoever enabled accounting */ + cred =override_creds (file->f_cred); +/* -* Get freeze protection. If the fs is frozen, just skip the write -* as we could deadlock the system otherwise. +* First check to see if there is enough free_space to continue +* the process accounting system. Then get freeze protection. If +* the fs is frozen, just skip the write as we could deadlock +* the system otherwise. */ -if (file_start_write_trylock (file)) { +if (check_free_space (acct) &&file_start_write_trylock (file)) {/* it's been opened O_APPEND, so position is irrelevant */ loff_t pos =0 ; -__kernel_write (file, &ac,sizeof (acct_t), &pos); +__kernel_write (file, ac,sizeof (acct_t), &pos);file_end_write (file); } -out: + +revert_creds (cred); +} + +static void do_acct_process (struct bsd_acct_struct *acct) +{ +unsigned long flim; + +/* Accounting records are not subject to resource limits. */ + flim =rlimit (RLIMIT_FSIZE ); + current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ; +fill_ac (acct); +acct_write_process (acct); current->signal->rlim[RLIMIT_FSIZE ].rlim_cur = flim; -revert_creds (orig_cred); }/**
Greg Kroah-Hartman
maintainerPATCH 121/138 acct: block access to kernel internal filesystems
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit 890ed45bde808c422c3c27d3285fc45affa0f930 upstream.
There's no point in allowing anything kernel internal nor procfs or sysfs.
--- kernel/acct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
kernel/acct.c +14 -0
@@ -243,6 +243,20 @@ static int acct_on(struct filename *pathreturn -EACCES ; } +/* Exclude kernel kernel internal filesystems. */ +if (file_inode (file)->i_sb->s_flags & (SB_NOUSER |SB_KERNMOUNT )) { +kfree (acct); +filp_close (file,NULL ); +return -EINVAL ; + } + +/* Exclude procfs and sysfs. */ +if (file_inode (file)->i_sb->s_iflags &SB_I_USERNS_VISIBLE ) { +kfree (acct); +filp_close (file,NULL ); +return -EINVAL ; + } +if (!(file->f_mode &FMODE_CAN_WRITE )) {kfree (acct);filp_close (file,NULL );
Greg Kroah-Hartman
maintainerPATCH 95/138 io_uring/rw: forbid multishot async reads
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <[email protected]>
commit 67b0025d19f99fb9fbb8b62e6975553c183f3a16 upstream.
At the moment we can't sanely handle queuing an async request from a multishot context, so disable them. It shouldn't matter as pollable files / socekts don't normally do async.
Patching it in __io_read() is not the cleanest way, but it's simpler than other options, so let's fix it there and clean up on top.
--- io_uring/rw.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
io_uring/rw.c +11 -2
@@ -866,7 +866,15 @@ static int __io_read(struct io_kiocb *reif (unlikely (ret))return ret; - ret =io_iter_do_read (rw, &io->iter); +if (unlikely (req->opcode ==IORING_OP_READ_MULTISHOT )) { +void *cb_copy = rw->kiocb.ki_complete; + + rw->kiocb.ki_complete =NULL ; + ret =io_iter_do_read (rw, &io->iter); + rw->kiocb.ki_complete = cb_copy; + }else { + ret =io_iter_do_read (rw, &io->iter); + }/* * Some file systems like to return -EOPNOTSUPP for an IOCB_NOWAIT
@@ -891,7 +899,8 @@ static int __io_read(struct io_kiocb *re }else if (ret == -EIOCBQUEUED ) {return IOU_ISSUE_SKIP_COMPLETE ; }else if (ret == req->cqe.res || ret <=0 || !force_nonblock || - (req->flags &REQ_F_NOWAIT ) || !need_complete_io (req)) { + (req->flags &REQ_F_NOWAIT ) || !need_complete_io (req) || + (issue_flags &IO_URING_F_MULTISHOT )) {/* read all, failed, already did sync or don't want to retry */ goto done; }
Greg Kroah-Hartman
maintainerPATCH 122/138 mm,madvise,hugetlb: check for 0-length range after end address adjustment
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Cañuelo Navarro <[email protected]>
commit 2ede647a6fde3e54a6bfda7cf01c716649655900 upstream.
Add a sanity check to madvise_dontneed_free() to address a corner case in madvise where a race condition causes the current vma being processed to be backed by a different page size.
During a madvise(MADV_DONTNEED) call on a memory region registered with a userfaultfd, there's a period of time where the process mm lock is temporarily released in order to send a UFFD_EVENT_REMOVE and let userspace handle the event. During this time, the vma covering the current address range may change due to an explicit mmap done concurrently by another thread.
If, after that change, the memory region, which was originally backed by 4KB pages, is now backed by hugepages, the end address is rounded down to a hugepage boundary to avoid data loss (see "Fixes" below). This rounding may cause the end address to be truncated to the same address as the start.
Make this corner case follow the same semantics as in other similar cases where the requested region has zero length (ie. return 0).
This will make madvise_walk_vmas() continue to the next vma in the range (this time holding the process mm lock) which, due to the prev pointer becoming stale because of the vma change, will be the same hugepage-backed vma that was just checked before. The next time madvise_dontneed_free() runs for this vma, if the start address isn't aligned to a hugepage boundary, it'll return -EINVAL, which is also in line with the madvise api.
Quoted 1 line
From userspace perspective,
madvise()will return EINVAL because the start
address isn't aligned according to the new vma alignment requirements (hugepage), even though it was correctly page-aligned when the call was issued.
--- mm/madvise.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
mm/madvise.c +10 -1
@@ -928,7 +928,16 @@ static long madvise_dontneed_free(struct*/ end = vma->vm_end; } -VM_WARN_ON (start >= end); +/* +* If the memory region between start and end was +* originally backed by 4kB pages and then remapped to +* be backed by hugepages while mmap_lock was dropped, +* the adjustment for hugetlb vma above may have rounded +* end down to the start address. +*/ +if (start == end) +return 0 ; +VM_WARN_ON (start > end); }if (behavior ==MADV_DONTNEED || behavior ==MADV_DONTNEED_LOCKED )
Greg Kroah-Hartman
maintainerPATCH 123/138 mtd: spi-nor: sst: Fix SST write failure
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Kumar Mahapatra <[email protected]>
commit 539bd20352832b9244238a055eb169ccf1c41ff6 upstream.
'commit 18bcb4aa54ea ("mtd: spi-nor: sst: Factor out common write operation to sst_nor_write_data()")' introduced a bug where only one byte of data is written, regardless of the number of bytes passed to sst_nor_write_data(), causing a kernel crash during the write operation. Ensure the correct number of bytes are written as passed to sst_nor_write_data().
Call trace: [ 57.400180] ------------[ cut here ]------------ [ 57.404842] While writing 2 byte written 1 bytes [ 57.409493] WARNING: CPU: 0 PID: 737 at drivers/mtd/spi-nor/sst.c:187 sst_nor_write_data+0x6c/0x74 [ 57.418464] Modules linked in: [ 57.421517] CPU: 0 UID: 0 PID: 737 Comm: mtd_debug Not tainted 6.12.0-g5ad04afd91f9 #30 [ 57.429517] Hardware name: Xilinx Versal A2197 Processor board revA - x-prc-02 revA (DT) [ 57.437600] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 57.444557] pc : sst_nor_write_data+0x6c/0x74 [ 57.448911] lr : sst_nor_write_data+0x6c/0x74 [ 57.453264] sp : ffff80008232bb40 [ 57.456570] x29: ffff80008232bb40 x28: 0000000000010000 x27: 0000000000000001 [ 57.463708] x26: 000000000000ffff x25: 0000000000000000 x24: 0000000000000000 [ 57.470843] x23: 0000000000010000 x22: ffff80008232bbf0 x21: ffff000816230000 [ 57.477978] x20: ffff0008056c0080 x19: 0000000000000002 x18: 0000000000000006 [ 57.485112] x17: 0000000000000000 x16: 0000000000000000 x15: ffff80008232b580 [ 57.492246] x14: 0000000000000000 x13: ffff8000816d1530 x12: 00000000000004a4 [ 57.499380] x11: 000000000000018c x10: ffff8000816fd530 x9 : ffff8000816d1530 [ 57.506515] x8 : 00000000fffff7ff x7 : ffff8000816fd530 x6 : 0000000000000001 [ 57.513649] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 [ 57.520782] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008049b0000 [ 57.527916] Call trace: [ 57.530354] sst_nor_write_data+0x6c/0x74 [ 57.534361] sst_nor_write+0xb4/0x18c [ 57.538019] mtd_write_oob_std+0x7c/0x88 [ 57.541941] mtd_write_oob+0x70/0xbc [ 57.545511] mtd_write+0x68/0xa8 [ 57.548733] mtdchar_write+0x10c/0x290 [ 57.552477] vfs_write+0xb4/0x3a8 [ 57.555791] ksys_write+0x74/0x10c [ 57.559189] __arm64_sys_write+0x1c/0x28 [ 57.563109] invoke_syscall+0x54/0x11c [ 57.566856] el0_svc_common.constprop.0+0xc0/0xe0 [ 57.571557] do_el0_svc+0x1c/0x28 [ 57.574868] el0_svc+0x30/0xcc [ 57.577921] el0t_64_sync_handler+0x120/0x12c [ 57.582276] el0t_64_sync+0x190/0x194 [ 57.585933] ---[ end trace 0000000000000000 ]---
--- drivers/mtd/spi-nor/sst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/sst.c +1 -1
@@ -174,7 +174,7 @@ static int sst_nor_write_data(struct spiint ret; nor->program_opcode = op; - ret =spi_nor_write_data (nor, to,1 , buf); + ret =spi_nor_write_data (nor, to, len, buf);if (ret <0 )return ret;WARN (ret != len,"While writing %zu byte written %i bytes\n" , len, ret);
Greg Kroah-Hartman
maintainerPATCH 124/138 mtd: rawnand: cadence: fix error code in cadence_nand_init()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit 2b9df00cded911e2ca2cfae5c45082166b24f8aa upstream.
Replace dma_request_channel() with dma_request_chan_by_mask() and use helper functions to return proper error code instead of fixed -EBUSY.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +4 -5
@@ -2904,11 +2904,10 @@ static int cadence_nand_init(struct cdnsdma_cap_set (DMA_MEMCPY , mask);if (cdns_ctrl->caps1->has_dma) { - cdns_ctrl->dmac =dma_request_channel (mask,NULL ,NULL ); -if (!cdns_ctrl->dmac) { -dev_err (cdns_ctrl->dev, -"Unable to get a DMA channel\n" ); - ret = -EBUSY ; + cdns_ctrl->dmac =dma_request_chan_by_mask (&mask); +if (IS_ERR (cdns_ctrl->dmac)) { + ret =dev_err_probe (cdns_ctrl->dev,PTR_ERR (cdns_ctrl->dmac), +"%d: Failed to get a DMA channel\n" , ret); goto disable_irq; } }
Greg Kroah-Hartman
maintainerPATCH 125/138 mtd: rawnand: cadence: use dma_map_resource for sdma address
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niravkumar L Rabara <[email protected]>
commit d76d22b5096c5b05208fd982b153b3f182350b19 upstream.
Remap the slave DMA I/O resources to enhance driver portability. Using a physical address causes DMA translation failure when the ARM SMMU is enabled.
--- drivers/mtd/nand/raw/cadence-nand-controller.c | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +25 -4
@@ -471,6 +471,8 @@ struct cdns_nand_ctrl {struct {void __iomem *virt;dma_addr_t dma; +dma_addr_t iova_dma; +u32 size; } io;int irq;
@@ -1835,11 +1837,11 @@ static int cadence_nand_slave_dma_transf }if (dir ==DMA_FROM_DEVICE ) { - src_dma = cdns_ctrl->io.dma; + src_dma = cdns_ctrl->io.iova_dma; dst_dma = buf_dma; }else { src_dma = buf_dma; - dst_dma = cdns_ctrl->io.dma; + dst_dma = cdns_ctrl->io.iova_dma; } tx = dmaengine_prep_dma_memcpy(cdns_ctrl->dmac, dst_dma, src_dma, len,
@@ -2869,6 +2871,7 @@ cadence_nand_irq_cleanup(int irqnum, strstatic int cadence_nand_init (struct cdns_nand_ctrl *cdns_ctrl) {dma_cap_mask_t mask; +struct dma_device *dma_dev = cdns_ctrl->dmac->device;int ret; cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2912,6 +2915,16 @@ static int cadence_nand_init(struct cdns } } + cdns_ctrl->io.iova_dma =dma_map_resource (dma_dev->dev, cdns_ctrl->io.dma, + cdns_ctrl->io.size, +DMA_BIDIRECTIONAL ,0 ); + + ret =dma_mapping_error (dma_dev->dev, cdns_ctrl->io.iova_dma); +if (ret) { +dev_err (cdns_ctrl->dev,"Failed to map I/O resource to DMA\n" ); + goto dma_release_chnl; + } +nand_controller_init (&cdns_ctrl->controller);INIT_LIST_HEAD (&cdns_ctrl->chips);
@@ -2922,18 +2935,22 @@ static int cadence_nand_init(struct cdnsif (ret) {dev_err (cdns_ctrl->dev,"Failed to register MTD: %d\n" , ret); - goto dma_release_chnl; + goto unmap_dma_resource; }kfree (cdns_ctrl->buf); cdns_ctrl->buf =kzalloc (cdns_ctrl->buf_size,GFP_KERNEL );if (!cdns_ctrl->buf) { ret = -ENOMEM ; - goto dma_release_chnl; + goto unmap_dma_resource; }return 0 ; +unmap_dma_resource: +dma_unmap_resource (dma_dev->dev, cdns_ctrl->io.iova_dma, + cdns_ctrl->io.size,DMA_BIDIRECTIONAL ,0 ); + dma_release_chnl:if (cdns_ctrl->dmac)dma_release_channel (cdns_ctrl->dmac);
@@ -2955,6 +2972,8 @@ free_buf_desc:static void cadence_nand_remove (struct cdns_nand_ctrl *cdns_ctrl) {cadence_nand_chips_cleanup (cdns_ctrl); +dma_unmap_resource (cdns_ctrl->dmac->device->dev, cdns_ctrl->io.iova_dma, + cdns_ctrl->io.size,DMA_BIDIRECTIONAL ,0 );cadence_nand_irq_cleanup (cdns_ctrl->irq, cdns_ctrl);kfree (cdns_ctrl->buf); dma_free_coherent(cdns_ctrl->dev, sizeof(struct cadence_nand_cdma_desc),
@@ -3019,7 +3038,9 @@ static int cadence_nand_dt_probe(struct cdns_ctrl->io.virt =devm_platform_get_and_ioremap_resource (ofdev,1 , &res);if (IS_ERR (cdns_ctrl->io.virt))return PTR_ERR (cdns_ctrl->io.virt); + cdns_ctrl->io.dma = res->start; + cdns_ctrl->io.size =resource_size (res); dt->clk =devm_clk_get (cdns_ctrl->dev,"nf_clk" );if (IS_ERR (dt->clk))
Greg Kroah-Hartman
maintainerPATCH 96/138 io_uring: prevent opcode speculation
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <[email protected]>
commit 1e988c3fe1264708f4f92109203ac5b1d65de50b upstream.
sqe->opcode is used for different tables, make sure we santitise it against speculations.
--- io_uring/io_uring.c | 2 ++ 1 file changed, 2 insertions(+)
io_uring/io_uring.c +2 -0
@@ -2045,6 +2045,8 @@ static int io_init_req(struct io_ring_ct req->opcode =0 ;return io_init_fail_req (req, -EINVAL ); } + opcode =array_index_nospec (opcode,IORING_OP_LAST ); + def = &io_issue_defs[opcode];if (unlikely (sqe_flags & ~SQE_COMMON_FLAGS )) {/* enforce forwards compatibility on users */
Greg Kroah-Hartman
maintainerPATCH 97/138 gpiolib: check the return value of gpio_chip::get_direction()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit 9d846b1aebbe488f245f1aa463802ff9c34cc078 upstream.
As per the API contract - gpio_chip::get_direction() may fail and return a negative error number. However, we treat it as if it always returned 0 or 1. Check the return value of the callback and propagate the error number up the stack.
--- drivers/gpio/gpiolib.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-)
drivers/gpio/gpiolib.c +29 -15
@@ -1057,8 +1057,11 @@ int gpiochip_add_data_with_key(struct gp desc->gdev = gdev;if (gc->get_direction &&gpiochip_line_is_valid (gc, desc_index)) { -assign_bit (FLAG_IS_OUT , - &desc->flags, !gc->get_direction (gc, desc_index)); + ret = gc->get_direction (gc, desc_index); +if (ret <0 ) + goto err_cleanup_desc_srcu; + +assign_bit (FLAG_IS_OUT , &desc->flags, !ret); }else {assign_bit (FLAG_IS_OUT , &desc->flags, !gc->direction_input);
@@ -2728,13 +2731,18 @@ int gpiod_direction_input_nonotify(strucif (guard.gc->direction_input) { ret = guard.gc->direction_input (guard.gc,gpio_chip_hwgpio (desc)); - }else if (guard.gc->get_direction && - (guard.gc->get_direction (guard.gc, -gpio_chip_hwgpio (desc)) !=1 )) { -gpiod_warn (desc, -"%s: missing direction_input() operation and line is output\n" , - __func__); -return -EIO ; + }else if (guard.gc->get_direction) { + ret = guard.gc->get_direction (guard.gc, +gpio_chip_hwgpio (desc)); +if (ret <0 ) +return ret; + +if (ret !=GPIO_LINE_DIRECTION_IN ) { +gpiod_warn (desc, +"%s: missing direction_input() operation and line is output\n" , + __func__); +return -EIO ; + } }if (ret ==0 ) {clear_bit (FLAG_IS_OUT , &desc->flags);
@@ -2771,12 +2779,18 @@ static int gpiod_direction_output_raw_co gpio_chip_hwgpio(desc), val); }else {/* Check that we are in output mode if we can */ -if (guard.gc->get_direction && - guard.gc->get_direction (guard.gc,gpio_chip_hwgpio (desc))) { -gpiod_warn (desc, -"%s: missing direction_output() operation\n" , - __func__); -return -EIO ; +if (guard.gc->get_direction) { + ret = guard.gc->get_direction (guard.gc, +gpio_chip_hwgpio (desc)); +if (ret <0 ) +return ret; + +if (ret !=GPIO_LINE_DIRECTION_OUT ) { +gpiod_warn (desc, +"%s: missing direction_output() operation\n" , + __func__); +return -EIO ; + } }/* * If we can't actively set the direction, we are some
Greg Kroah-Hartman
maintainerPATCH 98/138 gpiolib: protect gpio_chip with SRCU in array_info paths in multi get/set
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit 81570d6a7ad37033c7895811551a5a9023706eda upstream.
During the locking rework in GPIOLIB, we omitted one important use-case,
namely: setting and getting values for GPIO descriptor arrays with array_info present.
This patch does two things: first it makes struct gpio_array store the address of the underlying GPIO device and not chip. Next: it protects the chip with SRCU from removal in gpiod_get_array_value_complex() and gpiod_set_array_value_complex().
--- drivers/gpio/gpiolib.c | 48 +++++++++++++++++++++++++++++++++--------------- drivers/gpio/gpiolib.h | 4 ++-- 2 files changed, 35 insertions(+), 17 deletions(-)
drivers/gpio/gpiolib.c +33 -15
@@ -3143,6 +3143,8 @@ static int gpiod_get_raw_value_commit(costatic int gpio_chip_get_multiple (struct gpio_chip *gc,unsigned long *mask,unsigned long *bits) { +lockdep_assert_held (&gc->gpiodev->srcu); +if (gc->get_multiple)return gc->get_multiple (gc, mask, bits);if (gc->get) {
@@ -3173,6 +3175,7 @@ int gpiod_get_array_value_complex(bool rstruct gpio_array *array_info, unsigned long *value_bitmap) { + struct gpio_chip *gc;int ret, i =0 ;/*
@@ -3184,10 +3187,15 @@ int gpiod_get_array_value_complex(bool r array_size <= array_info->size && (void *)array_info == desc_array + array_info->size) {if (!can_sleep) -WARN_ON (array_info->chip->can_sleep); +WARN_ON (array_info->gdev->can_sleep); - ret =gpio_chip_get_multiple (array_info->chip, - array_info->get_mask, +guard (srcu)(&array_info->gdev->srcu); + gc =srcu_dereference (array_info->gdev->chip, + &array_info->gdev->srcu); +if (!gc) +return -ENODEV ; + + ret =gpio_chip_get_multiple (gc, array_info->get_mask, value_bitmap);if (ret)return ret;
@@ -3468,6 +3476,8 @@ static void gpiod_set_raw_value_commit(sstatic void gpio_chip_set_multiple (struct gpio_chip *gc,unsigned long *mask,unsigned long *bits) { +lockdep_assert_held (&gc->gpiodev->srcu); +if (gc->set_multiple) { gc->set_multiple (gc, mask, bits); }else {
@@ -3485,6 +3495,7 @@ int gpiod_set_array_value_complex(bool rstruct gpio_array *array_info, unsigned long *value_bitmap) { + struct gpio_chip *gc;int i =0 ;/*
@@ -3496,14 +3507,19 @@ int gpiod_set_array_value_complex(bool r array_size <= array_info->size && (void *)array_info == desc_array + array_info->size) {if (!can_sleep) -WARN_ON (array_info->chip->can_sleep); +WARN_ON (array_info->gdev->can_sleep); + +guard (srcu)(&array_info->gdev->srcu); + gc =srcu_dereference (array_info->gdev->chip, + &array_info->gdev->srcu); +if (!gc) +return -ENODEV ;if (!raw && !bitmap_empty (array_info->invert_mask, array_size))bitmap_xor (value_bitmap, value_bitmap, array_info->invert_mask, array_size); -gpio_chip_set_multiple (array_info->chip, array_info->set_mask, - value_bitmap); +gpio_chip_set_multiple (gc, array_info->set_mask, value_bitmap); i =find_first_zero_bit (array_info->set_mask, array_size);if (i == array_size)
@@ -4765,9 +4781,10 @@ struct gpio_descs *__must_check gpiod_ge {struct gpio_desc *desc;struct gpio_descs *descs; +struct gpio_device *gdev;struct gpio_array *array_info =NULL ; -struct gpio_chip *gc;int count, bitmap_size; +unsigned long dflags;size_t descs_size; count =gpiod_count (dev, con_id);
@@ -4788,7 +4805,7 @@ struct gpio_descs *__must_check gpiod_ge descs->desc[descs->ndescs] = desc; - gc =gpiod_to_chip (desc); + gdev =gpiod_to_gpio_device (desc);/* * If pin hardware number of array member 0 is also 0, select * its chip as a candidate for fast bitmap processing path.
@@ -4796,8 +4813,8 @@ struct gpio_descs *__must_check gpiod_geif (descs->ndescs ==0 &&gpio_chip_hwgpio (desc) ==0 ) {struct gpio_descs *array; - bitmap_size =BITS_TO_LONGS (gc->ngpio > count ? - gc->ngpio : count); + bitmap_size =BITS_TO_LONGS (gdev->ngpio > count ? + gdev->ngpio : count); array = krealloc(descs, descs_size + struct_size(array_info, invert_mask, 3 * bitmap_size),
@@ -4817,7 +4834,7 @@ struct gpio_descs *__must_check gpiod_ge array_info->desc = descs->desc; array_info->size = count; - array_info->chip = gc; + array_info->gdev = gdev;bitmap_set (array_info->get_mask, descs->ndescs, count - descs->ndescs); bitmap_set(array_info->set_mask, descs->ndescs,
@@ -4830,7 +4847,7 @@ struct gpio_descs *__must_check gpiod_gecontinue ;/* Unmark array members which don't belong to the 'fast' chip */ -if (array_info->chip != gc) { +if (array_info->gdev != gdev) {__clear_bit (descs->ndescs, array_info->get_mask);__clear_bit (descs->ndescs, array_info->set_mask); }
@@ -4853,9 +4870,10 @@ struct gpio_descs *__must_check gpiod_ge array_info->set_mask); } }else { + dflags =READ_ONCE (desc->flags);/* Exclude open drain or open source from fast output */ -if (gpiochip_line_is_open_drain (gc, descs->ndescs) || -gpiochip_line_is_open_source (gc, descs->ndescs)) +if (test_bit (FLAG_OPEN_DRAIN , &dflags) || +test_bit (FLAG_OPEN_SOURCE , &dflags))__clear_bit (descs->ndescs, array_info->set_mask);/* Identify 'fast' pins which require invertion */
@@ -4867,7 +4885,7 @@ struct gpio_descs *__must_check gpiod_geif (array_info)dev_dbg (dev,"GPIO array info: chip=%s, size=%d, get_mask=%lx, set_mask=%lx, invert_mask=%lx\n" , - array_info->chip->label, array_info->size, + array_info->gdev->label, array_info->size, *array_info->get_mask, *array_info->set_mask, *array_info->invert_mask);return descs;
drivers/gpio/gpiolib.h +2 -2
@@ -114,7 +114,7 @@ extern const char *const gpio_suffixes[]* * @desc: Array of pointers to the GPIO descriptors * @size: Number of elements in desc -* @chip: Parent GPIO chip +* @gdev: Parent GPIO device * @get_mask: Get mask used in fastpath * @set_mask: Set mask used in fastpath * @invert_mask: Invert mask used in fastpath
@@ -126,7 +126,7 @@ extern const char *const gpio_suffixes[]struct gpio_array {struct gpio_desc **desc;unsigned int size; -struct gpio_chip *chip; +struct gpio_device *gdev;unsigned long *get_mask;unsigned long *set_mask;unsigned long invert_mask[];
Greg Kroah-Hartman
maintainerPATCH 99/138 tee: optee: Fix supplicant wait loop
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Garg <[email protected]>
commit 70b0d6b0a199c5a3ee6c72f5e61681ed6f759612 upstream.
OP-TEE supplicant is a user-space daemon and it's possible for it be hung or crashed or killed in the middle of processing an OP-TEE RPC call. It becomes more complicated when there is incorrect shutdown ordering of the supplicant process vs the OP-TEE client application which can eventually lead to system hang-up waiting for the closure of the client application.
Allow the client process waiting in kernel for supplicant response to be killed rather than indefinitely waiting in an unkillable state. Also, a normal uninterruptible wait should not have resulted in the hung-task watchdog getting triggered, but the endless loop would.
This fixes issues observed during system reboot/shutdown when supplicant got hung for some reason or gets crashed/killed which lead to client getting hung in an unkillable state. It in turn lead to system being in hung up state requiring hard power off/on to recover.
--- drivers/tee/optee/supp.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-)
drivers/tee/optee/supp.c +8 -27
@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_contestruct optee *optee =tee_get_drvdata (ctx->teedev);struct optee_supp *supp = &optee->supp;struct optee_supp_req *req; -bool interruptable;u32 ret;/*
@@ -111,36 +110,18 @@ u32 optee_supp_thrd_req(struct tee_conte/* * Wait for supplicant to process and return result, once we've * returned from wait_for_completion(&req->c) successfully we have -* exclusive access again. +* exclusive access again. Allow the wait to be killable such that +* the wait doesn't turn into an indefinite state if the supplicant +* gets hung for some reason. */ -while (wait_for_completion_interruptible (&req->c)) { +if (wait_for_completion_killable (&req->c)) {mutex_lock (&supp->mutex); - interruptable = !supp->ctx; -if (interruptable) { -/* -* There's no supplicant available and since the -* supp->mutex currently is held none can -* become available until the mutex released -* again. -* -* Interrupting an RPC to supplicant is only -* allowed as a way of slightly improving the user -* experience in case the supplicant hasn't been -* started yet. During normal operation the supplicant -* will serve all requests in a timely manner and -* interrupting then wouldn't make sense. -*/ -if (req->in_queue) { -list_del (&req->link); - req->in_queue = false; - } +if (req->in_queue) { +list_del (&req->link); + req->in_queue = false; }mutex_unlock (&supp->mutex); - -if (interruptable) { - req->ret =TEEC_ERROR_COMMUNICATION ; -break ; - } + req->ret =TEEC_ERROR_COMMUNICATION ; } ret = req->ret;
Greg Kroah-Hartman
maintainerPATCH 100/138 drop_monitor: fix incorrect initialization order
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gavrilov Ilia <[email protected]>
commit 07b598c0e6f06a0f254c88dafb4ad50f8a8c6eea upstream.
Syzkaller reports the following bug:
BUG: spinlock bad magic on CPU#1, syz-executor.0/7995 lock: 0xffff88805303f3e0, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 CPU: 1 PID: 7995 Comm: syz-executor.0 Tainted: G E 5.10.209+ #1 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x119/0x179 lib/dump_stack.c:118 debug_spin_lock_before kernel/locking/spinlock_debug.c:83 [inline] do_raw_spin_lock+0x1f6/0x270 kernel/locking/spinlock_debug.c:112 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:117 [inline] _raw_spin_lock_irqsave+0x50/0x70 kernel/locking/spinlock.c:159 reset_per_cpu_data+0xe6/0x240 [drop_monitor] net_dm_cmd_trace+0x43d/0x17a0 [drop_monitor] genl_family_rcv_msg_doit+0x22f/0x330 net/netlink/genetlink.c:739 genl_family_rcv_msg net/netlink/genetlink.c:783 [inline] genl_rcv_msg+0x341/0x5a0 net/netlink/genetlink.c:800 netlink_rcv_skb+0x14d/0x440 net/netlink/af_netlink.c:2497 genl_rcv+0x29/0x40 net/netlink/genetlink.c:811 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline] netlink_unicast+0x54b/0x800 net/netlink/af_netlink.c:1348 netlink_sendmsg+0x914/0xe00 net/netlink/af_netlink.c:1916 sock_sendmsg_nosec net/socket.c:651 [inline] __sock_sendmsg+0x157/0x190 net/socket.c:663 ____sys_sendmsg+0x712/0x870 net/socket.c:2378 ___sys_sendmsg+0xf8/0x170 net/socket.c:2432 __sys_sendmsg+0xea/0x1b0 net/socket.c:2461 do_syscall_64+0x30/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x62/0xc7 RIP: 0033:0x7f3f9815aee9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f3f972bf0c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f3f9826d050 RCX: 00007f3f9815aee9 RDX: 0000000020000000 RSI: 0000000020001300 RDI: 0000000000000007 RBP: 00007f3f981b63bd R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000006e R14: 00007f3f9826d050 R15: 00007ffe01ee6768
If drop_monitor is built as a kernel module, syzkaller may have time to send a netlink NET_DM_CMD_START message during the module loading. This will call the net_dm_monitor_start() function that uses a spinlock that has not yet been initialized.
To fix this, let's place resource initialization above the registration of a generic netlink family.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/core/drop_monitor.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
net/core/drop_monitor.c +14 -15
@@ -1734,30 +1734,30 @@ static int __init init_net_drop_monitor(return -ENOSPC ; } - rc =genl_register_family (&net_drop_monitor_family); -if (rc) { -pr_err ("Could not create drop monitor netlink family\n" ); -return rc; +for_each_possible_cpu (cpu) { +net_dm_cpu_data_init (cpu); +net_dm_hw_cpu_data_init (cpu); } -WARN_ON (net_drop_monitor_family.mcgrp_offset !=NET_DM_GRP_ALERT ); rc =register_netdevice_notifier (&dropmon_net_notifier);if (rc <0 ) {pr_crit ("Failed to register netdevice notifier\n" ); +return rc; + } + + rc =genl_register_family (&net_drop_monitor_family); +if (rc) { +pr_err ("Could not create drop monitor netlink family\n" ); goto out_unreg; } +WARN_ON (net_drop_monitor_family.mcgrp_offset !=NET_DM_GRP_ALERT ); rc =0 ; -for_each_possible_cpu (cpu) { -net_dm_cpu_data_init (cpu); -net_dm_hw_cpu_data_init (cpu); - } - goto out; out_unreg: -genl_unregister_family (&net_drop_monitor_family); +WARN_ON (unregister_netdevice_notifier (&dropmon_net_notifier)); out:return rc; }
@@ -1766,19 +1766,18 @@ static void exit_net_drop_monitor(void) {int cpu; -BUG_ON (unregister_netdevice_notifier (&dropmon_net_notifier)); -/* * Because of the module_get/put we do in the trace state change path * we are guaranteed not to have any current users when we get here */ +BUG_ON (genl_unregister_family (&net_drop_monitor_family)); + +BUG_ON (unregister_netdevice_notifier (&dropmon_net_notifier));for_each_possible_cpu (cpu) {net_dm_hw_cpu_data_fini (cpu);net_dm_cpu_data_fini (cpu); } - -BUG_ON (genl_unregister_family (&net_drop_monitor_family)); }module_init (init_net_drop_monitor);
Greg Kroah-Hartman
maintainerPATCH 101/138 mm/migrate_device: dont add folio to be freed to LRU in migrate_device_finalize()
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
commit 41cddf83d8b00f29fd105e7a0777366edc69a5cf upstream.
If migration succeeded, we called folio_migrate_flags()->mem_cgroup_migrate() to migrate the memcg from the old to the new folio. This will set memcg_data of the old folio to 0.
Similarly, if migration failed, memcg_data of the dst folio is left unset.
If we call folio_putback_lru() on such folios (memcg_data == 0), we will add the folio to be freed to the LRU, making memcg code unhappy. Running the hmm selftests:
# ./hmm-tests ... # RUN hmm.hmm_device_private.migrate ... [ 102.078007][T14893] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7ff27d200 pfn:0x13cc00 [ 102.079974][T14893] anon flags: 0x17ff00000020018(uptodate|dirty|swapbacked|node=0|zone=2|lastcpupid=0x7ff) [ 102.082037][T14893] raw: 017ff00000020018 dead000000000100 dead000000000122 ffff8881353896c9 [ 102.083687][T14893] raw: 00000007ff27d200 0000000000000000 00000001ffffffff 0000000000000000 [ 102.085331][T14893] page dumped because: VM_WARN_ON_ONCE_FOLIO(!memcg && !mem_cgroup_disabled()) [ 102.087230][T14893] ------------[ cut here ]------------ [ 102.088279][T14893] WARNING: CPU: 0 PID: 14893 at ./include/linux/memcontrol.h:726 folio_lruvec_lock_irqsave+0x10e/0x170 [ 102.090478][T14893] Modules linked in: [ 102.091244][T14893] CPU: 0 UID: 0 PID: 14893 Comm: hmm-tests Not tainted 6.13.0-09623-g6c216bc522fd #151 [ 102.093089][T14893] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014 [ 102.094848][T14893] RIP: 0010:folio_lruvec_lock_irqsave+0x10e/0x170 [ 102.096104][T14893] Code: ... [ 102.099908][T14893] RSP: 0018:ffffc900236c37b0 EFLAGS: 00010293 [ 102.101152][T14893] RAX: 0000000000000000 RBX: ffffea0004f30000 RCX: ffffffff8183f426 [ 102.102684][T14893] RDX: ffff8881063cb880 RSI: ffffffff81b8117f RDI: ffff8881063cb880 [ 102.104227][T14893] RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000 [ 102.105757][T14893] R10: 0000000000000001 R11: 0000000000000002 R12: ffffc900236c37d8 [ 102.107296][T14893] R13: ffff888277a2bcb0 R14: 000000000000001f R15: 0000000000000000 [ 102.108830][T14893] FS: 00007ff27dbdd740(0000) GS:ffff888277a00000(0000) knlGS:0000000000000000 [ 102.110643][T14893] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 102.111924][T14893] CR2: 00007ff27d400000 CR3: 000000010866e000 CR4: 0000000000750ef0 [ 102.113478][T14893] PKRU: 55555554 [ 102.114172][T14893] Call Trace: [ 102.114805][T14893] <TASK> [ 102.115397][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170 [ 102.116547][T14893] ? __warn.cold+0x110/0x210 [ 102.117461][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170 [ 102.118667][T14893] ? report_bug+0x1b9/0x320 [ 102.119571][T14893] ? handle_bug+0x54/0x90 [ 102.120494][T14893] ? exc_invalid_op+0x17/0x50 [ 102.121433][T14893] ? asm_exc_invalid_op+0x1a/0x20 [ 102.122435][T14893] ? __wake_up_klogd.part.0+0x76/0xd0 [ 102.123506][T14893] ? dump_page+0x4f/0x60 [ 102.124352][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170 [ 102.125500][T14893] folio_batch_move_lru+0xd4/0x200 [ 102.126577][T14893] ? __pfx_lru_add+0x10/0x10 [ 102.127505][T14893] __folio_batch_add_and_move+0x391/0x720 [ 102.128633][T14893] ? __pfx_lru_add+0x10/0x10 [ 102.129550][T14893] folio_putback_lru+0x16/0x80 [ 102.130564][T14893] migrate_device_finalize+0x9b/0x530 [ 102.131640][T14893] dmirror_migrate_to_device.constprop.0+0x7c5/0xad0 [ 102.133047][T14893] dmirror_fops_unlocked_ioctl+0x89b/0xc80
Likely, nothing else goes wrong: putting the last folio reference will remove the folio from the LRU again. So besides memcg complaining, adding the folio to be freed to the LRU is just an unnecessary step.
The new flow resembles what we have in migrate_folio_move(): add the dst to the lru, remove migration ptes, unlock and unref dst.
--- mm/migrate_device.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
mm/migrate_device.c +4 -9
@@ -840,20 +840,15 @@ void migrate_device_finalize(unsigned lo dst = src; } +if (!folio_is_zone_device (dst)) +folio_add_lru (dst);remove_migration_ptes (src, dst,0 );folio_unlock (src); - -if (folio_is_zone_device (src)) -folio_put (src); -else -folio_putback_lru (src); +folio_put (src);if (dst != src) {folio_unlock (dst); -if (folio_is_zone_device (dst)) -folio_put (dst); -else -folio_putback_lru (dst); +folio_put (dst); } } }
Greg Kroah-Hartman
maintainerPATCH 92/138 drm/i915/ddi: Fix HDMI port width programming in DDI_BUF_CTL
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit 166ce267ae3f96e439d8ccc838e8ec4d8b4dab73 upstream.
Fix the port width programming in the DDI_BUF_CTL register on MTLP+, where this had an off-by-one error.
--- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/i915_reg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_ddi.c +1 -1
@@ -3399,7 +3399,7 @@ static void intel_enable_ddi_hdmi(structintel_de_rmw (dev_priv,XELPDP_PORT_BUF_CTL1 (dev_priv, port),XELPDP_PORT_WIDTH_MASK |XELPDP_PORT_REVERSAL , port_buf); - buf_ctl |=DDI_PORT_WIDTH (lane_count); + buf_ctl |=DDI_PORT_WIDTH (crtc_state->lane_count);if (DISPLAY_VER (dev_priv) >=20 ) buf_ctl |=XE2LPD_DDI_BUF_D2D_LINK_ENABLE ;
drivers/gpu/drm/i915/i915_reg.h +1 -1
@@ -3917,7 +3917,7 @@ enum skl_power_gate {#define DDI_BUF_IS_IDLE (1 << 7)#define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6)#define DDI_A_4_LANES (1 << 4) -#define DDI_PORT_WIDTH (width) (((width) - 1) << 1) +#define DDI_PORT_WIDTH (width) (((width) == 3 ? 4 : ((width) - 1)) << 1)#define DDI_PORT_WIDTH_MASK (7 << 1)#define DDI_PORT_WIDTH_SHIFT 1#define DDI_INIT_DISPLAY_DETECTED (1 << 0)
Greg Kroah-Hartman
maintainerPATCH 127/138 perf/x86/intel: Fix event constraints for LNC
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
commit 782cffeec9ad96daa64ffb2d527b2a052fb02552 upstream.
According to the latest event list, update the event constraint tables for Lion Cove core.
The general rule (the event codes < 0x90 are restricted to counters 0-3.) has been removed. There is no restriction for most of the performance monitoring events.
--- arch/x86/events/intel/core.c | 20 +++++++------------- arch/x86/events/intel/ds.c | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-)
arch/x86/events/intel/core.c +7 -13
@@ -397,34 +397,28 @@ static struct event_constraint intel_lncMETRIC_EVENT_CONSTRAINT (INTEL_TD_METRIC_FETCH_LAT ,6 ),METRIC_EVENT_CONSTRAINT (INTEL_TD_METRIC_MEM_BOUND ,7 ), +INTEL_EVENT_CONSTRAINT (0x20 ,0xf ), + +INTEL_UEVENT_CONSTRAINT (0x012a ,0xf ), +INTEL_UEVENT_CONSTRAINT (0x012b ,0xf ),INTEL_UEVENT_CONSTRAINT (0x0148 ,0x4 ),INTEL_UEVENT_CONSTRAINT (0x0175 ,0x4 ),INTEL_EVENT_CONSTRAINT (0x2e ,0x3ff ),INTEL_EVENT_CONSTRAINT (0x3c ,0x3ff ), -/* -* Generally event codes < 0x90 are restricted to counters 0-3. -* The 0x2E and 0x3C are exception, which has no restriction. -*/ -INTEL_EVENT_CONSTRAINT_RANGE (0x01 ,0x8f ,0xf ), -INTEL_UEVENT_CONSTRAINT (0x01a3 ,0xf ), -INTEL_UEVENT_CONSTRAINT (0x02a3 ,0xf ),INTEL_UEVENT_CONSTRAINT (0x08a3 ,0x4 ),INTEL_UEVENT_CONSTRAINT (0x0ca3 ,0x4 ),INTEL_UEVENT_CONSTRAINT (0x04a4 ,0x1 ),INTEL_UEVENT_CONSTRAINT (0x08a4 ,0x1 ),INTEL_UEVENT_CONSTRAINT (0x10a4 ,0x1 ),INTEL_UEVENT_CONSTRAINT (0x01b1 ,0x8 ), +INTEL_UEVENT_CONSTRAINT (0x01cd ,0x3fc ),INTEL_UEVENT_CONSTRAINT (0x02cd ,0x3 ), -INTEL_EVENT_CONSTRAINT (0xce ,0x1 ),INTEL_EVENT_CONSTRAINT_RANGE (0xd0 ,0xdf ,0xf ), -/* -* Generally event codes >= 0x90 are likely to have no restrictions. -* The exception are defined as above. -*/ -INTEL_EVENT_CONSTRAINT_RANGE (0x90 ,0xfe ,0x3ff ), + +INTEL_UEVENT_CONSTRAINT (0x00e0 ,0xf ),EVENT_CONSTRAINT_END };
arch/x86/events/intel/ds.c +1 -1
@@ -1199,7 +1199,7 @@ struct event_constraint intel_lnc_pebs_eINTEL_FLAGS_UEVENT_CONSTRAINT (0x100 ,0x100000000ULL ),/* INST_RETIRED.PREC_DIST */ INTEL_FLAGS_UEVENT_CONSTRAINT (0x0400 ,0x800000000ULL ), -INTEL_HYBRID_LDLAT_CONSTRAINT (0x1cd ,0x3ff ), +INTEL_HYBRID_LDLAT_CONSTRAINT (0x1cd ,0x3fc ),INTEL_HYBRID_STLAT_CONSTRAINT (0x2cd ,0x3 ),INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD (0x11d0 ,0xf ),/* MEM_INST_RETIRED.STLB_MISS_LOADS */ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
Greg Kroah-Hartman
maintainerPATCH 136/138 net: pse-pd: Fix deadlock in current limit functions
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
commit 488fb6effe03e20f38d34da7425de77bbd3e2665 upstream.
Fix a deadlock in pse_pi_get_current_limit and pse_pi_set_current_limit caused by consecutive mutex_lock calls. One in the function itself and another in pse_pi_get_voltage.
Resolve the issue by using the unlocked version of pse_pi_get_voltage instead.
--- drivers/net/pse-pd/pse_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/pse-pd/pse_core.c +2 -2
@@ -309,7 +309,7 @@ static int pse_pi_get_current_limit(stru goto out; mW = ret; - ret =pse_pi_get_voltage (rdev); + ret =_pse_pi_get_voltage (rdev);if (!ret) {dev_err (pcdev->dev,"Voltage null\n" ); ret = -ERANGE ;
@@ -346,7 +346,7 @@ static int pse_pi_set_current_limit(stru id =rdev_get_id (rdev);mutex_lock (&pcdev->lock); - ret =pse_pi_get_voltage (rdev); + ret =_pse_pi_get_voltage (rdev);if (!ret) {dev_err (pcdev->dev,"Voltage null\n" ); ret = -ERANGE ;
Greg Kroah-Hartman
maintainerPATCH 137/138 drm/amdgpu/gfx9: manually control gfxoff for CS on RV
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit b35eb9128ebeec534eed1cefd6b9b1b7282cf5ba upstream.
When mesa started using compute queues more often we started seeing additional hangs with compute queues. Disabling gfxoff seems to mitigate that. Manually control gfxoff and gfx pg with command submissions to avoid any issues related to gfxoff. KFD already does the same thing for these chips.
v2: limit to compute
v3: limit to APUs
v4: limit to Raven/PCO
v5: only update the compute ring_funcs
v6: Disable GFX PG
v7: adjust order
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +30 -2
@@ -7439,6 +7439,34 @@ static void gfx_v9_0_ring_emit_cleaner_samdgpu_ring_write (ring,0 );/* RESERVED field, programmed to zero */ } +static void gfx_v9_0_ring_begin_use_compute (struct amdgpu_ring *ring) +{ +struct amdgpu_device *adev = ring->adev; + +amdgpu_gfx_enforce_isolation_ring_begin_use (ring); + +/* Raven and PCO APUs seem to have stability issues +* with compute and gfxoff and gfx pg. Disable gfx pg during +* submission and allow again afterwards. +*/ +if (amdgpu_ip_version (adev,GC_HWIP ,0 ) ==IP_VERSION (9 ,1 ,0 )) +gfx_v9_0_set_powergating_state (adev,AMD_PG_STATE_UNGATE ); +} + +static void gfx_v9_0_ring_end_use_compute (struct amdgpu_ring *ring) +{ +struct amdgpu_device *adev = ring->adev; + +/* Raven and PCO APUs seem to have stability issues +* with compute and gfxoff and gfx pg. Disable gfx pg during +* submission and allow again afterwards. +*/ +if (amdgpu_ip_version (adev,GC_HWIP ,0 ) ==IP_VERSION (9 ,1 ,0 )) +gfx_v9_0_set_powergating_state (adev,AMD_PG_STATE_GATE ); + +amdgpu_gfx_enforce_isolation_ring_end_use (ring); +} +static const struct amd_ip_funcs gfx_v9_0_ip_funcs = { .name ="gfx_v9_0" , .early_init = gfx_v9_0_early_init,
@@ -7615,8 +7643,8 @@ static const struct amdgpu_ring_funcs gf .emit_wave_limit = gfx_v9_0_emit_wave_limit, .reset = gfx_v9_0_reset_kcq, .emit_cleaner_shader = gfx_v9_0_ring_emit_cleaner_shader, - .begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use, - .end_use = amdgpu_gfx_enforce_isolation_ring_end_use, + .begin_use = gfx_v9_0_ring_begin_use_compute, + .end_use = gfx_v9_0_ring_end_use_compute, };static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = {
Greg Kroah-Hartman
maintainerPATCH 138/138 drm/amdgpu: bump version for RV/PCO compute fix
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 55ed2b1b50d029dd7e49a35f6628ca64db6d75d8 upstream.
Bump the driver version for RV/PCO compute stability fix so mesa can use this check to enable compute queues on RV/PCO.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 -1
@@ -120,9 +120,10 @@* - 3.58.0 - Add GFX12 DCC support * - 3.59.0 - Cleared VRAM * - 3.60.0 - Add AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE (Vulkan requirement) +* - 3.61.0 - Contains fix for RV/PCO compute queues */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 60 +#define KMS_DRIVER_MINOR 61#define KMS_DRIVER_PATCHLEVEL 0/*
Greg Kroah-Hartman
maintainerPATCH 128/138 irqchip/gic-v3: Fix rk3399 workaround when secure interrupts are enabled
In reply to Greg Kroah-Hartman6.13-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit 4cb77793842a351b39a030f77caebace3524840e upstream.
Christoph reports that their rk3399 system dies since commit 773c05f417fa1 ("irqchip/gic-v3: Work around insecure GIC integrations").
It appears that some rk3399 have secure payloads, and that the firmware sets SCR_EL3.FIQ==1. Obivously, disabling security in that configuration leads to even more problems.
Revisit the workaround by:
- making it rk3399 specific
- checking whether Group-0 is available, which is a good proxy for SCR_EL3.FIQ being 0
- either apply the workaround if Group-0 is available, or disable pseudo-NMIs if not
Note that this doesn't mean that the secure side is able to receive interrupts, as all interrupts are made non-secure anyway.
Clearly, nobody ever tested secure interrupts on this platform.
--- drivers/irqchip/irq-gic-v3.c | 53 ++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-)
drivers/irqchip/irq-gic-v3.c +40 -13
@@ -44,6 +44,7 @@ static u8 dist_prio_nmi __ro_after_init#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)#define FLAGS_WORKAROUND_ASR_ERRATUM_8601001 (1ULL << 2) +#define FLAGS_WORKAROUND_INSECURE (1ULL << 3)#define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1)
@@ -83,6 +84,8 @@ static DEFINE_STATIC_KEY_TRUE(supports_d#define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)#define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) +static bool nmi_support_forbidden; +/* * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs * are potentially stolen by the secure side. Some code, especially code dealing
@@ -163,21 +166,27 @@ static void __init gic_prio_init(void) {bool ds; - ds =gic_dist_security_disabled (); -if (!ds) { -u32 val; + cpus_have_group0 =gic_has_group0 (); - val =readl_relaxed (gic_data.dist_base +GICD_CTLR ); - val |=GICD_CTLR_DS ; -writel_relaxed (val, gic_data.dist_base +GICD_CTLR ); - - ds =gic_dist_security_disabled (); -if (ds) -pr_warn ("Broken GIC integration, security disabled" ); + ds =gic_dist_security_disabled (); +if ((gic_data.flags &FLAGS_WORKAROUND_INSECURE ) && !ds) { +if (cpus_have_group0) { +u32 val; + + val =readl_relaxed (gic_data.dist_base +GICD_CTLR ); + val |=GICD_CTLR_DS ; +writel_relaxed (val, gic_data.dist_base +GICD_CTLR ); + + ds =gic_dist_security_disabled (); +if (ds) +pr_warn ("Broken GIC integration, security disabled\n" ); + }else { +pr_warn ("Broken GIC integration, pNMI forbidden\n" ); + nmi_support_forbidden = true; + } } cpus_have_security_disabled = ds; - cpus_have_group0 =gic_has_group0 ();/* * How priority values are used by the GIC depends on two things:
@@ -209,7 +218,7 @@ static void __init gic_prio_init(void)* be in the non-secure range, we program the non-secure values into * the distributor to match the PMR values we want. */ -if (cpus_have_group0 & !cpus_have_security_disabled) { +if (cpus_have_group0 && !cpus_have_security_disabled) { dist_prio_irq =__gicv3_prio_to_ns (dist_prio_irq); dist_prio_nmi =__gicv3_prio_to_ns (dist_prio_nmi); }
@@ -1922,6 +1931,18 @@ static bool gic_enable_quirk_arm64_29416return true; } +static bool gic_enable_quirk_rk3399 (void *data) +{ +struct gic_chip_data *d = data; + +if (of_machine_is_compatible ("rockchip,rk3399" )) { + d->flags |=FLAGS_WORKAROUND_INSECURE ; +return true; + } + +return false; +} +static bool rd_set_non_coherent (void *data) {struct gic_chip_data *d = data;
@@ -1997,6 +2018,12 @@ static const struct gic_quirk gic_quirks .init = rd_set_non_coherent, }, { + .desc = "GICv3: Insecure RK3399 integration", + .iidr = 0x0000043b, + .mask = 0xff000fff, + .init = gic_enable_quirk_rk3399, + }, + { } };
@@ -2004,7 +2031,7 @@ static void gic_enable_nmi_support(void) {int i; -if (!gic_prio_masking_enabled ()) +if (!gic_prio_masking_enabled () || nmi_support_forbidden)return ; rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,