5.10.4-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 465/717 dpaa2-eth: fix the size of the mapped SGT buffer
In reply to Greg Kroah-HartmanFrom: Ioana Ciornei <[email protected]>
[ Upstream commit 54a57d1c449275ee727154ac106ec1accae012e3 ]
This patch fixes an error condition triggered when the code path which transmits a S/G frame descriptor when the skb's headroom is not enough for DPAA2's needs.
We are greated with a splat like the one below when a SGT structure is recycled and that is because even though a dma_unmap is performed on the Tx confirmation path, the unmap is not done with the proper size.
[ 714.464927] WARNING: CPU: 13 PID: 0 at drivers/iommu/io-pgtable-arm.c:281 __arm_lpae_map+0x2d4/0x30c (...) [ 714.465343] Call trace: [ 714.465348] __arm_lpae_map+0x2d4/0x30c [ 714.465353] __arm_lpae_map+0x114/0x30c [ 714.465357] __arm_lpae_map+0x114/0x30c [ 714.465362] __arm_lpae_map+0x114/0x30c [ 714.465366] arm_lpae_map+0xf4/0x180 [ 714.465373] arm_smmu_map+0x4c/0xc0 [ 714.465379] __iommu_map+0x100/0x2bc [ 714.465385] iommu_map_atomic+0x20/0x30 [ 714.465391] __iommu_dma_map+0xb0/0x110 [ 714.465397] iommu_dma_map_page+0xb8/0x120 [ 714.465404] dma_map_page_attrs+0x1a8/0x210 [ 714.465413] __dpaa2_eth_tx+0x384/0xbd0 [fsl_dpaa2_eth] [ 714.465421] dpaa2_eth_tx+0x84/0x134 [fsl_dpaa2_eth] [ 714.465427] dev_hard_start_xmit+0x10c/0x2b0 [ 714.465433] sch_direct_xmit+0x1a0/0x550
(...)
The dpaa2-eth driver uses an area of software annotations to transmit necessary information from the Tx path to the Tx confirmation one. This SWA structure has a different layout for each kind of frame that we are dealing with: linear, S/G or XDP.
The commit referenced was incorrectly setting up the 'sgt_size' field for the S/G type of SWA even though we are dealing with a linear skb here.
--- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +1 -1
@@ -878,7 +878,7 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct dpaa2_eth_priv *priv, swa = (struct dpaa2_eth_swa *)sgt_buf; swa->type =DPAA2_ETH_SWA_SINGLE ; swa->single.skb = skb; - swa->sg.sgt_size = sgt_buf_size; + swa->single.sgt_size = sgt_buf_size;/* Separately map the SGT buffer */ sgt_addr =dma_map_single (dev, sgt_buf, sgt_buf_size,DMA_BIDIRECTIONAL );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 466/717 net: bcmgenet: Fix a resource leak in an error handling path in the probe functin
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 4375ada01963d1ebf733d60d1bb6e5db401e1ac6 ]
If the 'register_netdev()' call fails, we must undo a previous 'bcmgenet_mii_init()' call.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +3 -1
@@ -4069,8 +4069,10 @@ static int bcmgenet_probe(struct platform_device *pdev)clk_disable_unprepare (priv->clk); err =register_netdev (dev); -if (err) +if (err) { +bcmgenet_mii_exit (dev); goto err; + }return err;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 467/717 net: mscc: ocelot: Fix a resource leak in the error handling path of the probe function
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit f87675b836b324d270fd52f1f5e6d6bb9f4bd1d5 ]
In case of error after calling 'ocelot_init()', it must be undone by a corresponding 'ocelot_deinit()' call, as already done in the remove function.
--- drivers/net/ethernet/mscc/ocelot_vsc7514.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/ethernet/mscc/ocelot_vsc7514.c +7 -1
@@ -1267,7 +1267,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev) err =mscc_ocelot_init_ports (pdev, ports);if (err) - goto out_put_ports; + goto out_ocelot_deinit;if (ocelot->ptp) { err =ocelot_init_timestamp (ocelot, &ocelot_ptp_clock_info);
@@ -1282,8 +1282,14 @@ static int mscc_ocelot_probe(struct platform_device *pdev)register_switchdev_notifier (&ocelot_switchdev_nb);register_switchdev_blocking_notifier (&ocelot_switchdev_blocking_nb); +of_node_put (ports); +dev_info (&pdev->dev,"Ocelot switch probed\n" ); +return 0 ; + +out_ocelot_deinit: +ocelot_deinit (ocelot); out_put_ports:of_node_put (ports);return err;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 468/717 net: allwinner: Fix some resources leak in the error handling path of the probe and in the remove function
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 322e53d1e2529ae9d501f5e0f20604a79b873aef ]
'irq_of_parse_and_map()' should be balanced by a corresponding 'irq_dispose_mapping()' call. Otherwise, there is some resources leaks.
Add such a call in the error handling path of the probe function and in the remove function.
--- drivers/net/ethernet/allwinner/sun4i-emac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/allwinner/sun4i-emac.c +5 -2
@@ -828,13 +828,13 @@ static int emac_probe(struct platform_device *pdev) db->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (db->clk)) { ret =PTR_ERR (db->clk); - goto out_iounmap; + goto out_dispose_mapping; } ret =clk_prepare_enable (db->clk);if (ret) {dev_err (&pdev->dev,"Error couldn't enable clock (%d)\n" , ret); - goto out_iounmap; + goto out_dispose_mapping; } ret =sunxi_sram_claim (&pdev->dev);
@@ -893,6 +893,8 @@ out_release_sram:sunxi_sram_release (&pdev->dev); out_clk_disable_unprepare:clk_disable_unprepare (db->clk); +out_dispose_mapping: +irq_dispose_mapping (ndev->irq); out_iounmap:iounmap (db->membase); out:
@@ -911,6 +913,7 @@ static int emac_remove(struct platform_device *pdev)unregister_netdev (ndev);sunxi_sram_release (&pdev->dev);clk_disable_unprepare (db->clk); +irq_dispose_mapping (ndev->irq);iounmap (db->membase);free_netdev (ndev);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 469/717 block/rnbd-clt: Get rid of warning regarding size argument in strlcpy
In reply to Greg Kroah-HartmanFrom: Md Haris Iqbal <[email protected]>
[ Upstream commit e7508d48565060af5d89f10cb83c9359c8ae1310 ]
The kernel test robot triggerred the following warning,
Quoted 1 line
Quoted 1 line
drivers/block/rnbd/rnbd-clt.c:1397:42: warning: size argument in
'strlcpy' call appears to be size of the source; expected the size of the destination [-Wstrlcpy-strlcat-size]
strlcpy(dev->pathname, pathname, strlen(pathname) + 1); ~~~~~~~^~~~~~~~~~~~~
To get rid of the above warning, use a kstrdup as Bart suggested.
--- drivers/block/rnbd/rnbd-clt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/block/rnbd/rnbd-clt.c +1 -2
@@ -1383,12 +1383,11 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, goto out_queues; } - dev->pathname =kzalloc (strlen (pathname) +1 ,GFP_KERNEL ); + dev->pathname =kstrdup (pathname,GFP_KERNEL );if (!dev->pathname) { ret = -ENOMEM ; goto out_queues; } -strlcpy (dev->pathname, pathname,strlen (pathname) +1 ); dev->clt_device_id = ret; dev->sess = sess;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 470/717 block/rnbd-clt: Fix possible memleak
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 46067844efdb8275ade705923120fc5391543b53 ]
In error case, we do not free the memory for blk_symlink_name.
Do it by free the memory in error case, and set to NULL afterwards.
Also fix the condition in rnbd_clt_remove_dev_symlink.
--- drivers/block/rnbd/rnbd-clt-sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/block/rnbd/rnbd-clt-sysfs.c +3 -2
@@ -433,7 +433,7 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev)* i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because * of sysfs link already was removed already. */ -if (strlen (dev->blk_symlink_name) &&try_module_get (THIS_MODULE )) { +if (dev->blk_symlink_name &&try_module_get (THIS_MODULE )) {sysfs_remove_link (rnbd_devs_kobj, dev->blk_symlink_name);kfree (dev->blk_symlink_name);module_put (THIS_MODULE );
@@ -516,7 +516,8 @@ static int rnbd_clt_add_dev_symlink(struct rnbd_clt_dev *dev)return 0 ; out_err: - dev->blk_symlink_name[0 ] ='\0' ; +kfree (dev->blk_symlink_name); + dev->blk_symlink_name =NULL ;return ret; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 471/717 NFS/pNFS: Fix a typo in ff_layout_resend_pnfs_read()
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
[ Upstream commit 52104f274e2d7f134d34bab11cada8913d4544e2 ]
Don't bump the index twice.
--- fs/nfs/flexfilelayout/flexfilelayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/flexfilelayout/flexfilelayout.c +1 -1
@@ -1056,7 +1056,7 @@ static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)u32 idx = hdr->pgio_mirror_idx +1 ;u32 new_idx =0 ; -if (ff_layout_choose_any_ds_for_read (hdr->lseg, idx +1 , &new_idx)) +if (ff_layout_choose_any_ds_for_read (hdr->lseg, idx, &new_idx))ff_layout_send_layouterror (hdr->lseg);else pnfs_error_mark_layout_for_return (hdr->inode, hdr->lseg);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 472/717 net: korina: fix return value
In reply to Greg Kroah-HartmanFrom: Vincent Stehlé <[email protected]>
[ Upstream commit 7eb000bdbe7c7da811ef51942b356f6e819b13ba ]
The ndo_start_xmit() method must not attempt to free the skb to transmit when returning NETDEV_TX_BUSY. Therefore, make sure the korina_send_packet() function returns NETDEV_TX_OK when it frees a packet.
--- drivers/net/ethernet/korina.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/korina.c +1 -1
@@ -219,7 +219,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)dev_kfree_skb_any (skb);spin_unlock_irqrestore (&lp->lock, flags); -return NETDEV_TX_BUSY ; +return NETDEV_TX_OK ; } }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 473/717 devlink: use _BITUL() macro instead of BIT() in the UAPI header
In reply to Greg Kroah-HartmanFrom: Tobias Klauser <[email protected]>
[ Upstream commit 75f4d4544db9fa34e1f04174f27d9f8a387be37d ]
The BIT() macro is not available for the UAPI headers. Moreover, it can be defined differently in user space headers. Thus, replace its usage with the _BITUL() macro which is already used in other macro definitions in <linux/devlink.h>.
--- include/uapi/linux/devlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/linux/devlink.h +1 -1
@@ -322,7 +322,7 @@ enum devlink_reload_limit {DEVLINK_RELOAD_LIMIT_MAX = __DEVLINK_RELOAD_LIMIT_MAX -1 }; -#define DEVLINK_RELOAD_LIMITS_VALID_MASK (BIT(__DEVLINK_RELOAD_LIMIT_MAX) - 1) +#define DEVLINK_RELOAD_LIMITS_VALID_MASK (_BITUL(__DEVLINK_RELOAD_LIMIT_MAX) - 1)enum devlink_attr {/* don't change the order or add anything between, this is ABI! */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 474/717 libnvdimm/label: Return -ENXIO for no slot in __blk_label_update
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 4c46764733c85b82c07e9559b39da4d00a7dd659 ]
Forget to set error code when nd_label_alloc_slot failed, and we add it to avoid overwritten error code.
--- drivers/nvdimm/label.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/nvdimm/label.c +3 -1
@@ -999,8 +999,10 @@ static int __blk_label_update(struct nd_region *nd_region,if (is_old_resource (res, old_res_list, old_num_resources))continue ;/* carry-over */ slot =nd_label_alloc_slot (ndd); -if (slot ==UINT_MAX ) +if (slot ==UINT_MAX ) { + rc = -ENXIO ; goto abort; + }dev_dbg (ndd->dev,"allocated: %d\n" , slot); nd_label =to_label (ndd, slot);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 475/717 powerpc/32s: Fix cleanup_cpu_mmu_context() compile bug
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit c1bea0a840ac75dca19bc6aa05575a33eb9fd058 ]
Currently pmac32_defconfig with SMP=y doesn't build:
arch/powerpc/platforms/powermac/smp.c:
error: implicit declaration of function 'cleanup_cpu_mmu_context'
It would be nice for consistency if all platforms clear mm_cpumask and flush TLBs on unplug, but the TLB invalidation bug described in commit 01b0f0eae081 ("powerpc/64s: Trim offlined CPUs from mm_cpumasks") only applies to 64s and for now we only have the TLB flush code for that platform.
So just add an empty version for 32-bit Book3S.
--- arch/powerpc/include/asm/book3s/32/mmu-hash.h | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/include/asm/book3s/32/mmu-hash.h +1 -0
@@ -94,6 +94,7 @@ typedef struct { } mm_context_t;void update_bats (void ); +static inline void cleanup_cpu_mmu_context (void ) { };/* patch sites */ extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 476/717 watchdog: qcom: Avoid context switch in restart handler
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 7948fab26bcc468aa2a76462f441291b5fb0d5c7 ]
The use of msleep() in the restart handler will cause scheduler to induce a context switch which is not desirable. This generates below warning on SDX55 when WDT is the only available restart source:
[ 39.800188] reboot: Restarting system [ 39.804115] ------------[ cut here ]------------ [ 39.807855] WARNING: CPU: 0 PID: 678 at kernel/rcu/tree_plugin.h:297 rcu_note_context_switch+0x190/0x764 [ 39.812538] Modules linked in: [ 39.821954] CPU: 0 PID: 678 Comm: reboot Not tainted 5.10.0-rc1-00063-g33a9990d1d66-dirty #47 [ 39.824854] Hardware name: Generic DT based system [ 39.833470] [<c0310fbc>] (unwind_backtrace) from [<c030c544>] (show_stack+0x10/0x14) [ 39.838154] [<c030c544>] (show_stack) from [<c0c218f0>] (dump_stack+0x8c/0xa0) [ 39.846049] [<c0c218f0>] (dump_stack) from [<c0322f80>] (__warn+0xd8/0xf0) [ 39.853058] [<c0322f80>] (__warn) from [<c0c1dc08>] (warn_slowpath_fmt+0x64/0xc8) [ 39.859925] [<c0c1dc08>] (warn_slowpath_fmt) from [<c038b6f4>] (rcu_note_context_switch+0x190/0x764) [ 39.867503] [<c038b6f4>] (rcu_note_context_switch) from [<c0c2aa3c>] (__schedule+0x84/0x640) [ 39.876685] [<c0c2aa3c>] (__schedule) from [<c0c2b050>] (schedule+0x58/0x10c) [ 39.885095] [<c0c2b050>] (schedule) from [<c0c2eed0>] (schedule_timeout+0x1e8/0x3d4) [ 39.892135] [<c0c2eed0>] (schedule_timeout) from [<c039ad40>] (msleep+0x2c/0x38) [ 39.899947] [<c039ad40>] (msleep) from [<c0a59d0c>] (qcom_wdt_restart+0xc4/0xcc) [ 39.907319] [<c0a59d0c>] (qcom_wdt_restart) from [<c0a58290>] (watchdog_restart_notifier+0x18/0x28) [ 39.914715] [<c0a58290>] (watchdog_restart_notifier) from [<c03468e0>] (atomic_notifier_call_chain+0x60/0x84) [ 39.923487] [<c03468e0>] (atomic_notifier_call_chain) from [<c030ae64>] (machine_restart+0x78/0x7c) [ 39.933551] [<c030ae64>] (machine_restart) from [<c0348048>] (__do_sys_reboot+0xdc/0x1e0) [ 39.942397] [<c0348048>] (__do_sys_reboot) from [<c0300060>] (ret_fast_syscall+0x0/0x54) [ 39.950721] Exception stack(0xc3e0bfa8 to 0xc3e0bff0) [ 39.958855] bfa0: 0001221c bed2fe24 fee1dead 28121969 01234567 00000000 [ 39.963832] bfc0: 0001221c bed2fe24 00000003 00000058 000225e0 00000000 00000000 00000000 [ 39.971985] bfe0: b6e62560 bed2fc84 00010fd8 b6e62580 [ 39.980124] ---[ end trace 3f578288bad866e4 ]---
Hence, replace msleep() with mdelay() to fix this issue.
--- drivers/watchdog/qcom-wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/qcom-wdt.c +1 -1
@@ -148,7 +148,7 @@ static int qcom_wdt_restart(struct watchdog_device *wdd, unsigned long action,*/ wmb (); -msleep (150 ); +mdelay (150 );return 0 ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 477/717 watchdog: coh901327: add COMMON_CLK dependency
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 36c47df85ee8e1f8a35366ac11324f8875de00eb ]
clang produces a build failure in configurations without COMMON_CLK when a timeout calculation goes wrong:
arm-linux-gnueabi-ld: drivers/watchdog/coh901327_wdt.o: in function `coh901327_enable':
coh901327_wdt.c:(.text+0x50): undefined reference to `__bad_udelay'
Add a Kconfig dependency to only do build testing when COMMON_CLK is enabled.
--- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/Kconfig +1 -1
@@ -632,7 +632,7 @@ config SUNXI_WATCHDOG config COH901327_WATCHDOG bool "ST-Ericsson COH 901 327 watchdog" - depends on ARCH_U300 || (ARM && COMPILE_TEST) + depends on ARCH_U300 || (ARM && COMMON_CLK && COMPILE_TEST) default y if MACH_U300 select WATCHDOG_CORE help
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 478/717 clk: ti: Fix memleak in ti_fapll_synth_setup
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 8c6239f6e95f583bb763d0228e02d4dd0fb3d492 ]
If clk_register fails, we should goto free branch
before function returns to prevent memleak.
--- drivers/clk/ti/fapll.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/clk/ti/fapll.c +9 -2
@@ -498,6 +498,7 @@ static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd, {struct clk_init_data *init;struct fapll_synth *synth; +struct clk *clk =ERR_PTR (-ENOMEM ); init =kzalloc (sizeof (*init),GFP_KERNEL );if (!init)
@@ -520,13 +521,19 @@ static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd, synth->hw.init = init; synth->clk_pll = pll_clk; -return clk_register (NULL , &synth->hw); + clk =clk_register (NULL , &synth->hw); +if (IS_ERR (clk)) { +pr_err ("failed to register clock\n" ); + goto free; + } + +return clk; free:kfree (synth);kfree (init); -return ERR_PTR (-ENOMEM ); +return clk; }static void __init ti_fapll_setup (struct device_node *node)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 479/717 pwm: zx: Add missing cleanup in error path
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit 269effd03f6142df4c74814cfdd5f0b041b30bf9 ]
zx_pwm_probe() called clk_prepare_enable() before; this must be undone in the error path.
--- drivers/pwm/pwm-zx.c | 1 + 1 file changed, 1 insertion(+)
drivers/pwm/pwm-zx.c +1 -0
@@ -238,6 +238,7 @@ static int zx_pwm_probe(struct platform_device *pdev) ret =pwmchip_add (&zpc->chip);if (ret <0 ) {dev_err (&pdev->dev,"failed to add PWM chip: %d\n" , ret); +clk_disable_unprepare (zpc->pclk);return ret; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 481/717 pwm: imx27: Fix overflow for bigger periods
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit 1ce65396e6b2386b4fd54f87beff0647a772e1cd ]
The second parameter of do_div is an u32 and NSEC_PER_SEC * prescale overflows this for bigger periods. Assuming the usual pwm input clk rate of 66 MHz this happens starting at requested period > 606060 ns.
Splitting the division into two operations doesn't loose any precision. It doesn't need to be feared that c / NSEC_PER_SEC doesn't fit into the unsigned long variable "duty_cycles" because in this case the assignment above to period_cycles would already have been overflowing as period >= duty_cycle and then the calculation is moot anyhow.
--- drivers/pwm/pwm-imx27.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pwm/pwm-imx27.c +2 -1
@@ -235,8 +235,9 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, period_cycles /= prescale; c = clkrate * state->duty_cycle; -do_div (c,NSEC_PER_SEC * prescale); +do_div (c,NSEC_PER_SEC ); duty_cycles = c; + duty_cycles /= prescale;/* * according to imx pwm RM, the real period value should be PERIOD
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 482/717 pwm: sun4i: Remove erroneous else branch
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit 6eefb79d6f5bc4086bd02c76f1072dd4a8d9d9f6 ]
Commit d3817a647059 ("pwm: sun4i: Remove redundant needs_delay") changed the logic of an else branch so that the PWM_EN and PWM_CLK_GATING bits are now cleared if the PWM is to be disabled, whereas previously the condition was always false, and hence the branch never got executed.
This code is reported causing backlight issues on boards based on the Allwinner A20 SoC. Fix this by removing the else branch, which restores the behaviour prior to the offending commit.
Note that the PWM_EN and PWM_CLK_GATING bits still get cleared later in sun4i_pwm_apply() if the PWM is to be disabled.
--- drivers/pwm/pwm-sun4i.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/pwm/pwm-sun4i.c +1 -5
@@ -294,12 +294,8 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ctrl |=BIT_CH (PWM_CLK_GATING , pwm->hwpwm); -if (state->enabled) { +if (state->enabled) ctrl |=BIT_CH (PWM_EN , pwm->hwpwm); - }else { - ctrl &= ~BIT_CH (PWM_EN , pwm->hwpwm); - ctrl &= ~BIT_CH (PWM_CLK_GATING , pwm->hwpwm); - }sun4i_pwm_writel (sun4i_pwm, ctrl,PWM_CTRL_REG );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 483/717 io_uring: cancel only requests of current task
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit df9923f96717d0aebb0a73adbcf6285fa79e38cb ]
io_uring_cancel_files() cancels all request that match files regardless of task. There is no real need in that, cancel only requests of the specified task. That also handles SQPOLL case as it already changes task to it.
--- fs/io_uring.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-)
fs/io_uring.c +5 -18
@@ -8421,14 +8421,6 @@ static int io_uring_release(struct inode *inode, struct file *file)return 0 ; } -static bool io_wq_files_match (struct io_wq_work *work,void *data) -{ -struct files_struct *files = data; - -return !files || ((work->flags &IO_WQ_WORK_FILES ) && - work->identity->files == files); -} -/* * Returns true if 'preq' is the link parent of 'req' */
@@ -8566,21 +8558,20 @@ static void io_cancel_defer_files(struct io_ring_ctx *ctx,* Returns true if we found and killed one or more files pinning requests */ static bool io_uring_cancel_files (struct io_ring_ctx *ctx, +struct task_struct *task,struct files_struct *files) {if (list_empty_careful (&ctx->inflight_list))return false; -/* cancel all at once, should be faster than doing it one by one*/ -io_wq_cancel_cb (ctx->io_wq, io_wq_files_match, files, true); -while (!list_empty_careful (&ctx->inflight_list)) {struct io_kiocb *cancel_req =NULL , *req;DEFINE_WAIT (wait);spin_lock_irq (&ctx->inflight_lock);list_for_each_entry (req, &ctx->inflight_list, inflight_entry) { -if (files && (req->work.flags &IO_WQ_WORK_FILES ) && +if (req->task == task && + (req->work.flags &IO_WQ_WORK_FILES ) && req->work.identity->files != files)continue ;/* req is being completed, ignore */
@@ -8623,7 +8614,7 @@ static bool __io_uring_cancel_task_requests(struct io_ring_ctx *ctx, {bool ret; - ret =io_uring_cancel_files (ctx, files); + ret =io_uring_cancel_files (ctx, task, files);if (!files) {enum io_wq_cancel cret;
@@ -8662,11 +8653,7 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,io_sq_thread_park (ctx->sq_data); } -if (files) -io_cancel_defer_files (ctx,NULL , files); -else -io_cancel_defer_files (ctx, task,NULL ); - +io_cancel_defer_files (ctx, task, files);io_cqring_overflow_flush (ctx, true, task, files);while (__io_uring_cancel_task_requests (ctx, task, files)) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 484/717 tools build: Add missing libcap to test-all.bin target
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
[ Upstream commit 09d59c2f3465fb01e65a0c96698697b026ea8e79 ]
We're missing -lcap in test-all.bin target, so in case it's the only library missing (if more are missing test-all.bin fails anyway), we will falsely claim that we detected it and fail build, like:
$ make ... Auto-detecting system features: ... dwarf: [ on ] ... dwarf_getlocations: [ on ] ... glibc: [ on ] ... libbfd: [ on ] ... libbfd-buildid: [ on ] ... libcap: [ on ] ... libelf: [ on ] ... libnuma: [ on ] ... numa_num_possible_cpus: [ on ] ... libperl: [ on ] ... libpython: [ on ] ... libcrypto: [ on ] ... libunwind: [ on ] ... libdw-dwarf-unwind: [ on ] ... zlib: [ on ] ... lzma: [ on ] ... get_cpuid: [ on ] ... bpf: [ on ] ... libaio: [ on ] ... libzstd: [ on ] ... disassembler-four-args: [ on ]
...
CC builtin-ftrace.o
In file included from builtin-ftrace.c:29:
util/cap.h:11:10: fatal error: sys/capability.h: No such file or directory
11 | #include <sys/capability.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
--- tools/build/feature/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/build/feature/Makefile +1 -1
@@ -90,7 +90,7 @@ __BUILDXX = $(CXX) $(CXXFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.cpp,$( ############################### $(OUTPUT)test-all.bin: - $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -I/usr/include/slang -lslang $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma -lzstd + $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -I/usr/include/slang -lslang $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma -lzstd -lcap $(OUTPUT)test-hello.bin: $(BUILD)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 485/717 perf record: Fix memory leak when using --user-regs=? to list registers
In reply to Greg Kroah-HartmanFrom: Zheng Zengkai <[email protected]>
[ Upstream commit 2eb5dd418034ecea2f7031e3d33f2991a878b148 ]
When using 'perf record's option '-I' or '--user-regs=' along with argument '?' to list available register names, memory of variable 'os' allocated by strdup() needs to be released before __parse_regs() returns, otherwise memory leak will occur.
--- tools/perf/util/parse-regs-options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/parse-regs-options.c +1 -1
@@ -54,7 +54,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)#endif fputc ('\n' , stderr);/* just printing available regs */ -return -1 ; + goto error; }#ifdef HAVE_PERF_REGS_SUPPORT for (r = sample_reg_masks; r->name; r++) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 486/717 qlcnic: Fix error code in probe
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 0d52848632a357948028eab67ff9b7cc0c12a0fb ]
Return -EINVAL if we can't find the correct device. Currently it returns success.
--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +1 -0
@@ -2492,6 +2492,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)qlcnic_sriov_vf_register_map (ahw);break ;default : + err = -EINVAL ; goto err_out_free_hw_res; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 487/717 nfp: move indirect block cleanup to flower app stop callback
In reply to Greg Kroah-HartmanFrom: Simon Horman <[email protected]>
[ Upstream commit 5b33afee93a1e7665a5ffae027fc66f9376f4ea7 ]
The indirect block cleanup may cause control messages to be sent if offloaded flows are present. However, by the time the flower app cleanup callback is called txbufs are no longer available and attempts to send control messages result in a NULL-pointer dereference in nfp_ctrl_tx_one().
This problem may be resolved by moving the indirect block cleanup to the stop callback, where txbufs are still available.
As suggested by Jakub Kicinski and Louis Peens.
--- drivers/net/ethernet/netronome/nfp/flower/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/netronome/nfp/flower/main.c +3 -3
@@ -860,9 +860,6 @@ static void nfp_flower_clean(struct nfp_app *app)skb_queue_purge (&app_priv->cmsg_skbs_low);flush_work (&app_priv->cmsg_work); -flow_indr_dev_unregister (nfp_flower_indr_setup_tc_cb, app, - nfp_flower_setup_indr_tc_release); -if (app_priv->flower_ext_feats &NFP_FL_FEATS_VF_RLIM )nfp_flower_qos_cleanup (app);
@@ -951,6 +948,9 @@ static int nfp_flower_start(struct nfp_app *app)static void nfp_flower_stop (struct nfp_app *app) {nfp_tunnel_config_stop (app); + +flow_indr_dev_unregister (nfp_flower_indr_setup_tc_cb, app, + nfp_flower_setup_indr_tc_release); } static int
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 488/717 vdpa/mlx5: Use write memory barrier after updating CQ index
In reply to Greg Kroah-HartmanFrom: Eli Cohen <[email protected]>
[ Upstream commit 83ef73b27eb2363f44faf9c3ee28a3fe752cfd15 ]
Make sure to put dma write memory barrier after updating CQ consumer index so the hardware knows that there are available CQE slots in the queue.
Failure to do this can cause the update of the RX doorbell record to get updated before the CQ consumer index resulting in CQ overrun.
--- drivers/vdpa/mlx5/net/mlx5_vnet.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/vdpa/mlx5/net/mlx5_vnet.c +5 -0
@@ -464,6 +464,11 @@ static int mlx5_vdpa_poll_one(struct mlx5_vdpa_cq *vcq)static void mlx5_vdpa_handle_completions (struct mlx5_vdpa_virtqueue *mvq,int num) {mlx5_cq_set_ci (&mvq->cq.mcq); + +/* make sure CQ cosumer update is visible to the hardware before updating +* RX doorbell record. +*/ +dma_wmb ();rx_post (&mvq->vqqp, num);if (mvq->event_cb.callback) mvq->event_cb.callback (mvq->event_cb.private);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 489/717 virtio_ring: Cut and paste bugs in vring_create_virtqueue_packed()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ae93d8ea0fa701e84ab9df0db9fb60ec6c80d7b8 ]
There is a copy and paste bug in the error handling of this code and it uses "ring_dma_addr" three times instead of "device_event_dma_addr" and "driver_event_dma_addr".
--- drivers/virtio/virtio_ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/virtio/virtio_ring.c +2 -2
@@ -1676,9 +1676,9 @@ err_desc_extra: err_desc_state:kfree (vq); err_vq: -vring_free_queue (vdev, event_size_in_bytes, device, ring_dma_addr); +vring_free_queue (vdev, event_size_in_bytes, device, device_event_dma_addr); err_device: -vring_free_queue (vdev, event_size_in_bytes, driver, ring_dma_addr); +vring_free_queue (vdev, event_size_in_bytes, driver, driver_event_dma_addr); err_driver:vring_free_queue (vdev, ring_size_in_bytes, ring, ring_dma_addr); err_ring:
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 490/717 virtio_net: Fix error code in probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 411ea23a76526e6efed0b601abb603d3c981b333 ]
Set a negative error code intead of returning success if the MTU has been changed to something invalid.
--- drivers/net/virtio_net.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/virtio_net.c +1 -0
@@ -3072,6 +3072,7 @@ static int virtnet_probe(struct virtio_device *vdev)dev_err (&vdev->dev,"device MTU appears to have changed it is now %d < %d" , mtu, dev->min_mtu); + err = -EINVAL ; goto free; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 491/717 virtio_ring: Fix two use after free bugs
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit e152d8af4220a05c9797591609151d404866beaa ]
The "vq" struct is added to the "vdev->vqs" list prematurely. If we encounter an error later in the function then the "vq" is freed, but since it is still on the list that could lead to a use after free bug.
--- drivers/virtio/virtio_ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/virtio/virtio_ring.c +2 -2
@@ -1608,7 +1608,6 @@ static struct virtqueue *vring_create_virtqueue_packed( vq->num_added =0 ; vq->packed_ring = true; vq->use_dma_api =vring_use_dma_api (vdev); -list_add_tail (&vq->vq.list, &vdev->vqs);#ifdef DEBUG vq->in_use = false; vq->last_add_time_valid = false;
@@ -1669,6 +1668,7 @@ static struct virtqueue *vring_create_virtqueue_packed(cpu_to_le16 (vq->packed.event_flags_shadow); } +list_add_tail (&vq->vq.list, &vdev->vqs);return &vq->vq; err_desc_extra:
@@ -2085,7 +2085,6 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, vq->last_used_idx =0 ; vq->num_added =0 ; vq->use_dma_api =vring_use_dma_api (vdev); -list_add_tail (&vq->vq.list, &vdev->vqs);#ifdef DEBUG vq->in_use = false; vq->last_add_time_valid = false;
@@ -2127,6 +2126,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,memset (vq->split.desc_state,0 , vring.num *sizeof (struct vring_desc_state_split )); +list_add_tail (&vq->vq.list, &vdev->vqs);return &vq->vq; }EXPORT_SYMBOL_GPL (__vring_new_virtqueue);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 492/717 vhost scsi: fix error return code in vhost_scsi_set_endpoint()
In reply to Greg Kroah-HartmanFrom: Zhang Changzhong <[email protected]>
[ Upstream commit 2e1139d613c7fb0956e82f72a8281c0a475ad4f8 ]
Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function.
--- drivers/vhost/scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vhost/scsi.c +2 -1
@@ -1643,7 +1643,8 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,if (!vhost_vq_is_setup (vq))continue ; -if (vhost_scsi_setup_vq_cmds (vq, vq->num)) + ret =vhost_scsi_setup_vq_cmds (vq, vq->num); +if (ret) goto destroy_vq_cmds; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 493/717 epoll: check for events when removing a timed out thread from the wait queue
In reply to Greg Kroah-HartmanFrom: Soheil Hassas Yeganeh <[email protected]>
[ Upstream commit 289caf5d8f6c61c6d2b7fd752a7f483cd153f182 ]
Patch series "simplify ep_poll".
This patch series is a followup based on the suggestions and feedback by Linus:
https://lkml.kernel.org/r/CAHk-=wizk=OxUyQPbO8MS41w2Pag1kniUV5WdD5qWL-gq1kjDA@mail.gmail.com
The first patch in the series is a fix for the epoll race in presence of timeouts, so that it can be cleanly backported to all affected stable kernels.
The rest of the patch series simplify the ep_poll() implementation. Some of these simplifications result in minor performance enhancements as well. We have kept these changes under self tests and internal benchmarks for a few days, and there are minor (1-2%) performance enhancements as a result.
This patch (of 8):
After abc610e01c66 ("fs/epoll: avoid barrier after an epoll_wait(2) timeout"), we break out of the ep_poll loop upon timeout, without checking whether there is any new events available. Prior to that patch-series we always called ep_events_available() after exiting the loop.
This can cause races and missed wakeups. For example, consider the following scenario reported by Guantao Liu:
Suppose we have an eventfd added using EPOLLET to an epollfd.
Thread 1: Sleeps for just below 5ms and then writes to an eventfd. Thread 2: Calls epoll_wait with a timeout of 5 ms. If it sees an
event of the eventfd, it will write back on that fd.
Thread 3: Calls epoll_wait with a negative timeout.
Prior to abc610e01c66, it is guaranteed that Thread 3 will wake up either by Thread 1 or Thread 2. After abc610e01c66, Thread 3 can be blocked indefinitely if Thread 2 sees a timeout right before the write to the eventfd by Thread 1. Thread 2 will be woken up from schedule_hrtimeout_range and, with evail 0, it will not call ep_send_events().
To fix this issue:
1) Simplify the timed_out case as suggested by Linus.
2) while holding the lock, recheck whether the thread was woken up after its time out has reached.
Note that (2) is different from Linus' original suggestion: It do not set "eavail = ep_events_available(ep)" to avoid unnecessary contention (when there are too many timed-out threads and a small number of events), as well as races mentioned in the discussion thread.
This is the first patch in the series so that the backport to stable releases is straightforward.
--- fs/eventpoll.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
fs/eventpoll.c +16 -9
@@ -1902,23 +1902,30 @@ fetch_events: }write_unlock_irq (&ep->lock); -if (eavail || res) -break ; +if (!eavail && !res) + timed_out = !schedule_hrtimeout_range (to, slack, +HRTIMER_MODE_ABS ); -if (!schedule_hrtimeout_range (to, slack,HRTIMER_MODE_ABS )) { - timed_out =1 ; -break ; - } - -/* We were woken up, thus go and try to harvest some events */ +/* +* We were woken up, thus go and try to harvest some events. +* If timed out and still on the wait queue, recheck eavail +* carefully under lock, below. +*/ eavail =1 ; - }while (0 );__set_current_state (TASK_RUNNING );if (!list_empty_careful (&wait.entry)) {write_lock_irq (&ep->lock); +/* +* If the thread timed out and is not on the wait queue, it +* means that the thread was woken up after its timeout expired +* before it could reacquire the lock. Thus, when wait.entry is +* empty, it needs to harvest events. +*/ +if (timed_out) + eavail =list_empty (&wait.entry);__remove_wait_queue (&ep->wq, &wait);write_unlock_irq (&ep->lock); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 494/717 clk: bcm: dvp: Add MODULE_DEVICE_TABLE()
In reply to Greg Kroah-HartmanFrom: Nicolas Saenz Julienne <[email protected]>
[ Upstream commit be439cc4c404f646a8ba090fa786d53c10926b12 ]
Add MODULE_DEVICE_TABLE() so as to be able to use the driver as a module. More precisely, for the driver to be loaded automatically at boot.
--- drivers/clk/bcm/clk-bcm2711-dvp.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/bcm/clk-bcm2711-dvp.c +1 -0
@@ -108,6 +108,7 @@ static const struct of_device_id clk_dvp_dt_ids[] = { { .compatible = "brcm,brcm2711-dvp", }, {/* sentinel */ } }; +MODULE_DEVICE_TABLE (of, clk_dvp_dt_ids);static struct platform_driver clk_dvp_driver = { .probe = clk_dvp_probe,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 495/717 clk: at91: sama7g5: fix compilation error
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit 91274497c79170aaadc491d4ffe4de35495a060d ]
pmc_data_allocate() has been changed. pmc_data_free() was removed. Adapt the code taking this into consideration. With this the programmable clocks were also saved in sama7g5_pmc so that they could be later referenced.
--- drivers/clk/at91/sama7g5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/at91/sama7g5.c +4 -2
@@ -838,7 +838,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) sama7g5_pmc =pmc_data_allocate (PMC_I2S1_MUX +1 ,nck (sama7g5_systemck),nck (sama7g5_periphck), -nck (sama7g5_gck)); +nck (sama7g5_gck),8 );if (!sama7g5_pmc)return ;
@@ -980,6 +980,8 @@ static void __init sama7g5_pmc_setup(struct device_node *np) sama7g5_prog_mux_table);if (IS_ERR (hw)) goto err_free; + + sama7g5_pmc->pchws[i] = hw; }for (i =0 ; i <ARRAY_SIZE (sama7g5_systemck); i++) {
@@ -1052,7 +1054,7 @@ err_free:kfree (alloc_mem); } -pmc_data_free (sama7g5_pmc); +kfree (sama7g5_pmc); }/* Some clks are used for a clocksource */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 496/717 clk: at91: sam9x60: remove atmel,osc-bypass support
In reply to Greg Kroah-HartmanFrom: Alexandre Belloni <[email protected]>
[ Upstream commit 01324f9e88b5cfc1f4c26eef66bdcb52596c9af8 ]
The sam9x60 doesn't have the MOSCXTBY bit to enable the crystal oscillator bypass.
--- drivers/clk/at91/sam9x60.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/clk/at91/sam9x60.c +1 -5
@@ -174,7 +174,6 @@ static void __init sam9x60_pmc_setup(struct device_node *np)struct regmap *regmap;struct clk_hw *hw;int i; -bool bypass; i =of_property_match_string (np,"clock-names" ,"td_slck" );if (i <0 )
@@ -209,10 +208,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)if (IS_ERR (hw)) goto err_free; - bypass =of_property_read_bool (np,"atmel,osc-bypass" ); - - hw =at91_clk_register_main_osc (regmap,"main_osc" , mainxtal_name, - bypass); + hw =at91_clk_register_main_osc (regmap,"main_osc" , mainxtal_name,0 );if (IS_ERR (hw)) goto err_free; main_osc_hw = hw;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 497/717 clk: s2mps11: Fix a resource leak in error handling paths in the probe function
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit d2d94fc567624f96187e8b52083795620f93e69f ]
Some resource should be released in the error handling path of the probe function, as already done in the remove function.
The remove function was fixed in commit bf416bd45738 ("clk: s2mps11: Add missing of_node_put and of_clk_del_provider")
--- drivers/clk/clk-s2mps11.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/clk-s2mps11.c +1 -0
@@ -195,6 +195,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)return ret; err_reg: +of_node_put (s2mps11_clks[0 ].clk_np);while (--i >=0 )clkdev_drop (s2mps11_clks[i].lookup);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 498/717 clk: sunxi-ng: Make sure divider tables have sentinel
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 48f68de00c1405351fa0e7bc44bca067c49cd0a3 ]
Two clock divider tables are missing sentinel at the end. Effect of that is that clock framework reads past the last entry. Fix that with adding sentinel at the end.
Issue was discovered with KASan.
--- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 1 + drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 1 + 2 files changed, 2 insertions(+)
drivers/clk/sunxi-ng/ccu-sun50i-a64.c +1 -0
@@ -389,6 +389,7 @@ static struct clk_div_table ths_div_table[] = { { .val = 1, .div = 2 }, { .val = 2, .div = 4 }, { .val = 3, .div = 6 }, + { /* Sentinel */ }, };static const char *const ths_parents[] = {"osc24M" };static struct ccu_div ths_clk = {
drivers/clk/sunxi-ng/ccu-sun8i-h3.c +1 -0
@@ -322,6 +322,7 @@ static struct clk_div_table ths_div_table[] = { { .val = 1, .div = 2 }, { .val = 2, .div = 4 }, { .val = 3, .div = 6 }, + { /* Sentinel */ }, }; static SUNXI_CCU_DIV_TABLE_WITH_GATE(ths_clk, "ths", "osc24M", 0x074, 0, 2, ths_div_table, BIT(31), 0);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 499/717 clk: vc5: Use "idt,voltage-microvolt" instead of "idt,voltage-microvolts"
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 4b003f5fcadfa2d0e087e907b0c65d023f6e29fb ]
Commit 45c940184b501fc6 ("dt-bindings: clk: versaclock5: convert to yaml") accidentally changed "idt,voltage-microvolts" to "idt,voltage-microvolt" in the DT bindings, while the driver still used the former.
Update the driver to match the bindings, as Documentation/devicetree/bindings/property-units.txt actually recommends using "microvolt".
--- drivers/clk/clk-versaclock5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/clk-versaclock5.c +2 -2
@@ -739,8 +739,8 @@ static int vc5_update_power(struct device_node *np_output, {u32 value; -if (!of_property_read_u32 (np_output, -"idt,voltage-microvolts" , &value)) { +if (!of_property_read_u32 (np_output,"idt,voltage-microvolt" , + &value)) { clk_out->clk_output_cfg0_mask |=VC5_CLK_OUTPUT_CFG0_PWR_MASK ;switch (value) {case 1800000 :
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 500/717 kconfig: fix return value of do_error_if()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit 135b4957eac43af2aedf8e2a277b9540f33c2558 ]
$(error-if,...) is expanded to an empty string. Currently, it relies on eval_clause() returning xstrdup("") when all attempts for expansion fail, but the correct implementation is to make do_error_if() return xstrdup("").
--- scripts/kconfig/preprocess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kconfig/preprocess.c +1 -1
@@ -114,7 +114,7 @@ static char *do_error_if(int argc, char *argv[])if (!strcmp (argv[0 ],"y" ))pperror ("%s" , argv[1 ]); -return NULL ; +return xstrdup ("" ); }static char *do_filename (int argc,char *argv[])
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 501/717 powerpc/boot: Fix build of dts/fsl
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit b36f835b636908e4122f2e17310b1dbc380a3b19 ]
The lkp robot reported that some configs fail to build, for example mpc85xx_smp_defconfig, with:
cc1: fatal error: opening output file arch/powerpc/boot/dts/fsl/.mpc8540ads.dtb.dts.tmp: No such file or directory
This bisects to:
cc8a51ca6f05 ("kbuild: always create directories of targets")
Although that commit claims to be about in-tree builds, it somehow breaks out-of-tree builds. But presumably it's just exposing a latent bug in our Makefiles.
We can fix it by adding to targets for dts/fsl in the same way that we do for dts.
--- arch/powerpc/boot/Makefile | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/boot/Makefile +2 -0
@@ -368,6 +368,8 @@ initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) targets += $(foreach x, dtbImage uImage cuImage simpleImage treeImage, \ $(patsubst $(x).%, dts/%.dtb, $(filter $(x).%, $(image-y)))) +targets += $(foreach x, dtbImage uImage cuImage simpleImage treeImage, \ + $(patsubst $(x).%, dts/fsl/%.dtb, $(filter $(x).%, $(image-y)))) $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 502/717 powerpc/smp: Add __init to init_big_cores()
In reply to Greg Kroah-HartmanFrom: Cédric Le Goater <[email protected]>
[ Upstream commit 9014eab6a38c60fd185bc92ed60f46cf99a462ab ]
It fixes this link warning:
WARNING: modpost: vmlinux.o(.text.unlikely+0x2d98): Section mismatch in reference from the function init_big_cores.isra.0() to the function .init.text:init_thread_group_cache_map() The function init_big_cores.isra.0() references
the function __init init_thread_group_cache_map().
This is often because init_big_cores.isra.0 lacks a __init
annotation or the annotation of init_thread_group_cache_map is wrong.
--- arch/powerpc/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/smp.c +1 -1
@@ -919,7 +919,7 @@ static struct sched_domain_topology_level powerpc_topology[] = { { NULL, }, }; -static int init_big_cores (void ) +static int __init init_big_cores (void ) {int cpu;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 503/717 ARM: 9044/1: vfp: use undef hook for VFP support detection
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
[ Upstream commit 3cce9d44321e460e7c88cdec4e4537a6e9ad7c0d ]
Commit f77ac2e378be9dd6 ("ARM: 9030/1: entry: omit FP emulation for UND exceptions taken in kernel mode") failed to take into account that there is in fact a case where we relied on this code path: during boot, the VFP detection code issues a read of FPSID, which will trigger an undef exception on cores that lack VFP support.
So let's reinstate this logic using an undef hook which is registered only for the duration of the initcall to vpf_init(), and which sets VFP_arch to a non-zero value - as before - if no VFP support is present.
--- arch/arm/vfp/entry.S | 17 ----------------- arch/arm/vfp/vfpmodule.c | 25 ++++++++++++++++++++----- 2 files changed, 20 insertions(+), 22 deletions(-)
arch/arm/vfp/entry.S +0 -17
@@ -37,20 +37,3 @@ ENDPROC(vfp_null_entry) .align 2 .LCvfp: .word vfp_vector - -@ This code is called if the VFP does not exist. It needs to flag the -@ failure to the VFP initialisation code. - - __INIT -ENTRY(vfp_testing_entry) - dec_preempt_count_ti r10, r4 - ldr r0, VFP_arch_address - str r0, [r0] @ set to non-zero value - ret r9 @ we have handled the fault -ENDPROC(vfp_testing_entry) - - .align 2 -VFP_arch_address: - .word VFP_arch - - __FINIT
arch/arm/vfp/vfpmodule.c +20 -5
@@ -32,7 +32,6 @@/* * Our undef handlers (in entry.S) */ -asmlinkage void vfp_testing_entry(void); asmlinkage void vfp_support_entry(void); asmlinkage void vfp_null_entry(void);
@@ -43,7 +42,7 @@ asmlinkage void (*vfp_vector)(void) = vfp_null_entry;* Used in startup: set to non-zero if VFP checks fail * After startup, holds VFP architecture */ -unsigned int VFP_arch; +static unsigned int __initdata VFP_arch;/* * The pointer to the vfpstate structure of the thread which currently
@@ -437,7 +436,7 @@ static void vfp_enable(void *unused)* present on all CPUs within a SMP complex. Needs to be called prior to * vfp_init(). */ -void vfp_disable (void ) +void __init vfp_disable (void ) {if (VFP_arch) {pr_debug ("%s: should be called prior to vfp_init\n" , __func__);
@@ -707,7 +706,7 @@ static int __init vfp_kmode_exception_hook_init(void)register_undef_hook (&vfp_kmode_exception_hook[i]);return 0 ; } -core_initcall (vfp_kmode_exception_hook_init); +subsys_initcall (vfp_kmode_exception_hook_init);/* * Kernel-side NEON support functions
@@ -753,6 +752,21 @@ EXPORT_SYMBOL(kernel_neon_end);#endif /* CONFIG_KERNEL_MODE_NEON */ +static int __init vfp_detect (struct pt_regs *regs,unsigned int instr) +{ + VFP_arch =UINT_MAX ;/* mark as not present */ + regs->ARM_pc +=4 ; +return 0 ; +} + +static struct undef_hook vfp_detect_hook__initdata = { + .instr_mask =0x0c000e00 , + .instr_val =0x0c000a00 , + .cpsr_mask =MODE_MASK , + .cpsr_val =SVC_MODE , + .fn = vfp_detect, +}; +/* * VFP support code initialisation. */
@@ -773,10 +787,11 @@ static int __init vfp_init(void)* The handler is already setup to just log calls, so * we just need to read the VFPSID register. */ - vfp_vector = vfp_testing_entry; +register_undef_hook (&vfp_detect_hook);barrier (); vfpsid =fmrx (FPSID );barrier (); +unregister_undef_hook (&vfp_detect_hook); vfp_vector = vfp_null_entry;pr_info ("VFP support v0.3: " );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 504/717 ARM: 9036/1: uncompress: Fix dbgadtb size parameter name
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 1ecec38547d415054fdb63a231234f44396b6d06 ]
The dbgadtb macro is passed the size of the appended DTB, not the end address.
--- arch/arm/boot/compressed/head.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/compressed/head.S +2 -2
@@ -116,7 +116,7 @@ /* * Debug print of the final appended DTB location */ - .macro dbgadtb, begin, end + .macro dbgadtb, begin, size #ifdef DEBUG kputc #'D' kputc #'T'
@@ -129,7 +129,7 @@ kputc #'(' kputc #'0' kputc #'x' - kphex \end, 8 /* End of appended DTB */ + kphex \size, 8 /* Size of appended DTB */ kputc #')' kputc #'\n' #endif
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 505/717 perf probe: Fix memory leak when synthesizing SDT probes
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 5149303fdfe5c67ddb51c911e23262f781cd75eb ]
The argv_split() function must be paired with argv_free(), else we must keep a reference to the argv array received or do the freeing ourselves, in synthesize_sdt_probe_command() we were simply leaking that argv[] array.
--- tools/perf/util/probe-file.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
tools/perf/util/probe-file.c +10 -3
@@ -791,7 +791,7 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note, const char *sdtgrp) {struct strbuf buf; -char *ret =NULL , **args; +char *ret =NULL ;int i, args_count, err;unsigned long long ref_ctr_offset;
@@ -813,12 +813,19 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note, goto out;if (note->args) { - args =argv_split (note->args, &args_count); +char **args =argv_split (note->args, &args_count); + +if (args ==NULL ) + goto error;for (i =0 ; i < args_count; ++i) { -if (synthesize_sdt_probe_arg (&buf, i, args[i]) <0 ) +if (synthesize_sdt_probe_arg (&buf, i, args[i]) <0 ) { +argv_free (args); goto error; + } } + +argv_free (args); } out:
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 506/717 io_uring: fix racy IOPOLL flush overflow
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit 634578f800652035debba3098d8ab0d21af7c7a5 ]
It's not safe to call io_cqring_overflow_flush() for IOPOLL mode without hodling uring_lock, because it does synchronisation differently. Make sure we have it.
As for io_ring_exit_work(), we don't even need it there because io_ring_ctx_wait_and_kill() already set force flag making all overflowed requests to be dropped.
--- fs/io_uring.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/io_uring.c +6 -4
@@ -8369,8 +8369,6 @@ static void io_ring_exit_work(struct work_struct *work)* as nobody else will be looking for them. */ do { -if (ctx->rings) -io_cqring_overflow_flush (ctx, true,NULL ,NULL );io_iopoll_try_reap_events (ctx); }while (!wait_for_completion_timeout (&ctx->ref_comp,HZ /20 ));io_ring_ctx_free (ctx);
@@ -8380,6 +8378,8 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) {mutex_lock (&ctx->uring_lock);percpu_ref_kill (&ctx->refs); +if (ctx->rings) +io_cqring_overflow_flush (ctx, true,NULL ,NULL );mutex_unlock (&ctx->uring_lock);io_kill_timeouts (ctx,NULL );
@@ -8389,8 +8389,6 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx)io_wq_cancel_all (ctx->io_wq);/* if we failed setting up the ctx, we might not have any rings */ -if (ctx->rings) -io_cqring_overflow_flush (ctx, true,NULL ,NULL );io_iopoll_try_reap_events (ctx);idr_for_each (&ctx->personality_idr, io_remove_personalities, ctx);
@@ -8654,7 +8652,9 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, }io_cancel_defer_files (ctx, task, files); +io_ring_submit_lock (ctx, (ctx->flags &IORING_SETUP_IOPOLL ));io_cqring_overflow_flush (ctx, true, task, files); +io_ring_submit_unlock (ctx, (ctx->flags &IORING_SETUP_IOPOLL ));while (__io_uring_cancel_task_requests (ctx, task, files)) {io_run_task_work ();
@@ -8956,8 +8956,10 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,*/ ret =0 ;if (ctx->flags &IORING_SETUP_SQPOLL ) { +io_ring_submit_lock (ctx, (ctx->flags &IORING_SETUP_IOPOLL ));if (!list_empty_careful (&ctx->cq_overflow_list))io_cqring_overflow_flush (ctx, false,NULL ,NULL ); +io_ring_submit_unlock (ctx, (ctx->flags &IORING_SETUP_IOPOLL ));if (flags &IORING_ENTER_SQ_WAKEUP )wake_up (&ctx->sq_data->wait);if (flags &IORING_ENTER_SQ_WAIT )
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 507/717 io_uring: cancel reqs shouldnt kill overflow list
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit cda286f0715c82f8117e166afd42cca068876dde ]
io_uring_cancel_task_requests() doesn't imply that the ring is going away, it may continue to work well after that. The problem is that it sets ->cq_overflow_flushed effectively disabling the CQ overflow feature
Split setting cq_overflow_flushed from flush, and do the first one only on exit. It's ok in terms of cancellations because there is a io_uring->in_idle check in __io_cqring_fill_event().
It also fixes a race with setting ->cq_overflow_flushed in io_uring_cancel_task_requests, whuch's is not atomic and a part of a bitmask with other flags. Though, the only other flag that's not set during init is drain_next, so it's not as bad for sane architectures.
--- fs/io_uring.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/io_uring.c +2 -4
@@ -1641,10 +1641,6 @@ static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,spin_lock_irqsave (&ctx->completion_lock, flags); -/* if force is set, the ring is going away. always drop after that */ -if (force) - ctx->cq_overflow_flushed =1 ; - cqe =NULL ;list_for_each_entry_safe (req, tmp, &ctx->cq_overflow_list, compl.list) {if (tsk && req->task != tsk)
@@ -8378,6 +8374,8 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) {mutex_lock (&ctx->uring_lock);percpu_ref_kill (&ctx->refs); +/* if force is set, the ring is going away. always drop after that */ + ctx->cq_overflow_flushed =1 ;if (ctx->rings)io_cqring_overflow_flush (ctx, true,NULL ,NULL );mutex_unlock (&ctx->uring_lock);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 508/717 Smack: Handle io_uring kernel thread privileges
In reply to Greg Kroah-HartmanFrom: Casey Schaufler <[email protected]>
[ Upstream commit 942cb357ae7d9249088e3687ee6a00ed2745a0c7 ]
Smack assumes that kernel threads are privileged for smackfs operations. This was necessary because the credential of the kernel thread was not related to a user operation. With io_uring the credential does reflect a user's rights and can be used.
--- security/smack/smack_access.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
security/smack/smack_access.c +3 -2
@@ -688,9 +688,10 @@ bool smack_privileged_cred(int cap, const struct cred *cred)bool smack_privileged (int cap) {/* -* All kernel tasks are privileged +* Kernel threads may not have credentials we can use. +* The io_uring kernel threads do have reliable credentials. */ -if (unlikely (current->flags &PF_KTHREAD )) +if ((current->flags & (PF_KTHREAD |PF_IO_WORKER )) ==PF_KTHREAD )return true;return smack_privileged_cred (cap,current_cred ());
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 509/717 proc mountinfo: make splice available again
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit 14e3e989f6a5d9646b6cf60690499cc8bdc11f7d ]
Since commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") we've required that file operation structures explicitly enable splice support, rather than falling back to the default handlers.
Most /proc files use the indirect 'struct proc_ops' to describe their file operations, and were fixed up to support splice earlier in commits 40be821d627c..b24c30c67863, but the mountinfo files interact with the VFS directly using their own 'struct file_operations' and got missed as a result.
This adds the necessary support for splice to work for /proc/*/mountinfo and friends.
--- fs/proc_namespace.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/proc_namespace.c +6 -3
@@ -320,7 +320,8 @@ static int mountstats_open(struct inodeconst struct file_operations proc_mounts_operations = { .open = mounts_open, - .read = seq_read, + .read_iter = seq_read_iter, + .splice_read = generic_file_splice_read, .llseek = seq_lseek, .release = mounts_release, .poll = mounts_poll,
@@ -328,7 +329,8 @@ const struct file_operations proc_mountsconst struct file_operations proc_mountinfo_operations = { .open = mountinfo_open, - .read = seq_read, + .read_iter = seq_read_iter, + .splice_read = generic_file_splice_read, .llseek = seq_lseek, .release = mounts_release, .poll = mounts_poll,
@@ -336,7 +338,8 @@ const struct file_operations proc_mounticonst struct file_operations proc_mountstats_operations = { .open = mountstats_open, - .read = seq_read, + .read_iter = seq_read_iter, + .splice_read = generic_file_splice_read, .llseek = seq_lseek, .release = mounts_release, };
Greg Kroah-Hartman
maintainerPATCH 510/717 io_uring: fix io_cqring_events()s noflush
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 59850d226e4907a6f37c1d2fe5ba97546a8691a4 upstream.
Checking !list_empty(&ctx->cq_overflow_list) around noflush in io_cqring_events() is racy, because if it fails but a request overflowed just after that, io_cqring_overflow_flush() still will be called.
Remove the second check, it shouldn't be a problem for performance, because there is cq_check_overflow bit check just above.
--- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/io_uring.c +1 -1
@@ -2242,7 +2242,7 @@ static unsigned io_cqring_events(struct* we wake up the task, and the next invocation will flush the * entries. We cannot safely to it from here. */ -if (noflush && !list_empty (&ctx->cq_overflow_list)) +if (noflush)return -1U ;io_cqring_overflow_flush (ctx, false,NULL ,NULL );
Greg Kroah-Hartman
maintainerPATCH 511/717 io_uring: fix racy IOPOLL completions
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 31bff9a51b264df6d144931a6a5f1d6cc815ed4b upstream.
IOPOLL allows buffer remove/provide requests, but they doesn't synchronise by rules of IOPOLL, namely it have to hold uring_lock.
--- fs/io_uring.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
fs/io_uring.c +18 -5
@@ -3944,11 +3944,17 @@ static int io_remove_buffers(struct io_k head =idr_find (&ctx->io_buffer_idr, p->bgid);if (head) ret =__io_remove_buffers (ctx, head, p->bgid, p->nbufs); - -io_ring_submit_lock (ctx, !force_nonblock);if (ret <0 )req_set_fail_links (req); -__io_req_complete (req, ret,0 , cs); + +/* need to hold the lock to complete IOPOLL requests */ +if (ctx->flags &IORING_SETUP_IOPOLL ) { +__io_req_complete (req, ret,0 , cs); +io_ring_submit_unlock (ctx, !force_nonblock); + }else { +io_ring_submit_unlock (ctx, !force_nonblock); +__io_req_complete (req, ret,0 , cs); + }return 0 ; }
@@ -4033,10 +4039,17 @@ static int io_provide_buffers(struct io_ } } out: -io_ring_submit_unlock (ctx, !force_nonblock);if (ret <0 )req_set_fail_links (req); -__io_req_complete (req, ret,0 , cs); + +/* need to hold the lock to complete IOPOLL requests */ +if (ctx->flags &IORING_SETUP_IOPOLL ) { +__io_req_complete (req, ret,0 , cs); +io_ring_submit_unlock (ctx, !force_nonblock); + }else { +io_ring_submit_unlock (ctx, !force_nonblock); +__io_req_complete (req, ret,0 , cs); + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 512/717 io_uring: always let io_iopoll_complete() complete polled io
In reply to Greg Kroah-HartmanFrom: Xiaoguang Wang <[email protected]>
commit dad1b1242fd5717af18ae4ac9d12b9f65849e13a upstream.
Abaci Fuzz reported a double-free or invalid-free BUG in io_commit_cqring():
[ 95.504842] BUG: KASAN: double-free or invalid-free in io_commit_cqring+0x3ec/0x8e0 [ 95.505921] [ 95.506225] CPU: 0 PID: 4037 Comm: io_wqe_worker-0 Tainted: G B W 5.10.0-rc5+ #1 [ 95.507434] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 95.508248] Call Trace: [ 95.508683] dump_stack+0x107/0x163 [ 95.509323] ? io_commit_cqring+0x3ec/0x8e0 [ 95.509982] print_address_description.constprop.0+0x3e/0x60 [ 95.510814] ? vprintk_func+0x98/0x140 [ 95.511399] ? io_commit_cqring+0x3ec/0x8e0 [ 95.512036] ? io_commit_cqring+0x3ec/0x8e0 [ 95.512733] kasan_report_invalid_free+0x51/0x80 [ 95.513431] ? io_commit_cqring+0x3ec/0x8e0 [ 95.514047] __kasan_slab_free+0x141/0x160 [ 95.514699] kfree+0xd1/0x390 [ 95.515182] io_commit_cqring+0x3ec/0x8e0 [ 95.515799] __io_req_complete.part.0+0x64/0x90 [ 95.516483] io_wq_submit_work+0x1fa/0x260 [ 95.517117] io_worker_handle_work+0xeac/0x1c00 [ 95.517828] io_wqe_worker+0xc94/0x11a0 [ 95.518438] ? io_worker_handle_work+0x1c00/0x1c00 [ 95.519151] ? __kthread_parkme+0x11d/0x1d0 [ 95.519806] ? io_worker_handle_work+0x1c00/0x1c00 [ 95.520512] ? io_worker_handle_work+0x1c00/0x1c00 [ 95.521211] kthread+0x396/0x470 [ 95.521727] ? _raw_spin_unlock_irq+0x24/0x30 [ 95.522380] ? kthread_mod_delayed_work+0x180/0x180 [ 95.523108] ret_from_fork+0x22/0x30 [ 95.523684] [ 95.523985] Allocated by task 4035: [ 95.524543] kasan_save_stack+0x1b/0x40 [ 95.525136] __kasan_kmalloc.constprop.0+0xc2/0xd0 [ 95.525882] kmem_cache_alloc_trace+0x17b/0x310 [ 95.533930] io_queue_sqe+0x225/0xcb0 [ 95.534505] io_submit_sqes+0x1768/0x25f0 [ 95.535164] __x64_sys_io_uring_enter+0x89e/0xd10 [ 95.535900] do_syscall_64+0x33/0x40 [ 95.536465] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 95.537199] [ 95.537505] Freed by task 4035: [ 95.538003] kasan_save_stack+0x1b/0x40 [ 95.538599] kasan_set_track+0x1c/0x30 [ 95.539177] kasan_set_free_info+0x1b/0x30 [ 95.539798] __kasan_slab_free+0x112/0x160 [ 95.540427] kfree+0xd1/0x390 [ 95.540910] io_commit_cqring+0x3ec/0x8e0 [ 95.541516] io_iopoll_complete+0x914/0x1390 [ 95.542150] io_do_iopoll+0x580/0x700 [ 95.542724] io_iopoll_try_reap_events.part.0+0x108/0x200 [ 95.543512] io_ring_ctx_wait_and_kill+0x118/0x340 [ 95.544206] io_uring_release+0x43/0x50 [ 95.544791] __fput+0x28d/0x940 [ 95.545291] task_work_run+0xea/0x1b0 [ 95.545873] do_exit+0xb6a/0x2c60 [ 95.546400] do_group_exit+0x12a/0x320 [ 95.546967] __x64_sys_exit_group+0x3f/0x50 [ 95.547605] do_syscall_64+0x33/0x40 [ 95.548155] entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason is that once we got a non EAGAIN error in io_wq_submit_work(), we'll complete req by calling io_req_complete(), which will hold completion_lock to call io_commit_cqring(), but for polled io, io_iopoll_complete() won't hold completion_lock to call io_commit_cqring(), then there maybe concurrent access to ctx->defer_list, double free may happen.
To fix this bug, we always let io_iopoll_complete() complete polled io.
--- fs/io_uring.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
fs/io_uring.c +13 -2
@@ -6083,8 +6083,19 @@ static struct io_wq_work *io_wq_submit_w }if (ret) { -req_set_fail_links (req); -io_req_complete (req, ret); +/* +* io_iopoll_complete() does not hold completion_lock to complete +* polled io, so here for polled io, just mark it done and still let +* io_iopoll_complete() complete it. +*/ +if (req->ctx->flags &IORING_SETUP_IOPOLL ) { +struct kiocb *kiocb = &req->rw.kiocb; + +kiocb_done (kiocb, ret,NULL ); + }else { +req_set_fail_links (req); +io_req_complete (req, ret); + } }return io_steal_work (req);
Greg Kroah-Hartman
maintainerPATCH 513/717 vfio/pci: Move dummy_resources_list init in vfio_pci_probe()
In reply to Greg Kroah-HartmanFrom: Eric Auger <[email protected]>
commit 16b8fe4caf499ae8e12d2ab1b1324497e36a7b83 upstream.
In case an error occurs in vfio_pci_enable() before the call to vfio_pci_probe_mmaps(), vfio_pci_disable() will try to iterate on an uninitialized list and cause a kernel panic.
Lets move to the initialization to vfio_pci_probe() to fix the issue.
--- drivers/vfio/pci/vfio_pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/vfio/pci/vfio_pci.c +1 -2
@@ -161,8 +161,6 @@ static void vfio_pci_probe_mmaps(structint i;struct vfio_pci_dummy_resource *dummy_res; -INIT_LIST_HEAD (&vdev->dummy_resources_list); -for (i =0 ; i <PCI_STD_NUM_BARS ; i++) {int bar = i +PCI_STD_RESOURCES ;
@@ -1966,6 +1964,7 @@ static int vfio_pci_probe(struct pci_devmutex_init (&vdev->igate);spin_lock_init (&vdev->irqlock);mutex_init (&vdev->ioeventfds_lock); +INIT_LIST_HEAD (&vdev->dummy_resources_list);INIT_LIST_HEAD (&vdev->ioeventfds_list);mutex_init (&vdev->vma_lock);INIT_LIST_HEAD (&vdev->vma_list);
Greg Kroah-Hartman
maintainerPATCH 514/717 vfio/pci/nvlink2: Do not attempt NPU2 setup on POWER8NVL NPU
In reply to Greg Kroah-HartmanFrom: Alexey Kardashevskiy <[email protected]>
commit d22f9a6c92de96304c81792942ae7c306f08ac77 upstream.
We execute certain NPU2 setup code (such as mapping an LPID to a device in NPU2) unconditionally if an Nvlink bridge is detected. However this cannot succeed on POWER8NVL machines as the init helpers return an error other than ENODEV which means the device is there is and setup failed so vfio_pci_enable() fails and pass through is not possible.
This changes the two NPU2 related init helpers to return -ENODEV if there is no "memory-region" device tree property as this is the distinction between NPU and NPU2.
Tested on
- POWER9 pvr=004e1201, Ubuntu 19.04 host, Ubuntu 18.04 vm, NVIDIA GV100 10de:1db1 driver 418.39
- POWER8 pvr=004c0100, RHEL 7.6 host, Ubuntu 16.10 vm, NVIDIA P100 10de:15f9 driver 396.47
--- drivers/vfio/pci/vfio_pci_nvlink2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/vfio/pci/vfio_pci_nvlink2.c +5 -2
@@ -231,7 +231,7 @@ int vfio_pci_nvdia_v100_nvlink2_init(strreturn -EINVAL ;if (of_property_read_u32 (npu_node,"memory-region" , &mem_phandle)) -return -EINVAL ; +return -ENODEV ; mem_node =of_find_node_by_phandle (mem_phandle);if (!mem_node)
@@ -393,7 +393,7 @@ int vfio_pci_ibm_npu2_init(struct vfio_pint ret;struct vfio_pci_npu2_data *data;struct device_node *nvlink_dn; -u32 nvlink_index =0 ; +u32 nvlink_index =0 , mem_phandle =0 ;struct pci_dev *npdev = vdev->pdev;struct device_node *npu_node =pci_device_to_OF_node (npdev);struct pci_controller *hose =pci_bus_to_host (npdev->bus);
@@ -408,6 +408,9 @@ int vfio_pci_ibm_npu2_init(struct vfio_pif (!pnv_pci_get_gpu_dev (vdev->pdev))return -ENODEV ; +if (of_property_read_u32 (npu_node,"memory-region" , &mem_phandle)) +return -ENODEV ; +/* * NPU2 normally has 8 ATSD registers (for concurrency) and 6 links * so we can allocate one register per link, using nvlink index as
Greg Kroah-Hartman
maintainerPATCH 515/717 media: gspca: Fix memory leak in probe
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit e469d0b09a19496e1972a20974bbf55b728151eb upstream.
The gspca driver leaks memory when a probe fails. gspca_dev_probe2() calls v4l2_device_register(), which takes a reference to the underlying device node (in this case, a USB interface). But the failure pathway neglects to call v4l2_device_unregister(), the routine responsible for dropping this reference. Consequently the memory for the USB interface and its device never gets released.
This patch adds the missing function call.
--- drivers/media/usb/gspca/gspca.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/usb/gspca/gspca.c +1 -0
@@ -1575,6 +1575,7 @@ out:input_unregister_device (gspca_dev->input_dev);#endif v4l2_ctrl_handler_free (gspca_dev->vdev.ctrl_handler); +v4l2_device_unregister (&gspca_dev->v4l2_dev);kfree (gspca_dev->usb_buf);kfree (gspca_dev);return ret;
Greg Kroah-Hartman
maintainerPATCH 516/717 io_uring: fix io_wqe->work_list corruption
In reply to Greg Kroah-HartmanFrom: Xiaoguang Wang <[email protected]>
commit 0020ef04e48571a88d4f482ad08f71052c5c5a08 upstream.
For the first time a req punted to io-wq, we'll initialize io_wq_work's list to be NULL, then insert req to io_wqe->work_list. If this req is not inserted into tail of io_wqe->work_list, this req's io_wq_work list will point to another req's io_wq_work. For splitted bio case, this req maybe inserted to io_wqe->work_list repeatedly, once we insert it to tail of io_wqe->work_list for the second time, now io_wq_work->list->next will be invalid pointer, which then result in many strang error, panic, kernel soft-lockup, rcu stall, etc.
In my vm, kernel doest not have commit cc29e1bf0d63f7 ("block: disable iopoll for split bio"), below fio job can reproduce this bug steadily:
[global]
name=iouring-sqpoll-iopoll-1
ioengine=io_uring
iodepth=128
numjobs=1
thread
rw=randread
direct=1
registerfiles=1
hipri=1
bs=4m
size=100M
runtime=120time_basedgroup_reporting
randrepeat=0
[device]
directory=/home/feiman.wxg/mntpoint/ # an ext4 mount point
If we have commit cc29e1bf0d63f7 ("block: disable iopoll for split bio"), there will no splitted bio case for polled io, but I think we still to need to fix this list corruption, it also should maybe go to stable branchs.
To fix this corruption, if a req is inserted into tail of io_wqe->work_list, initialize req->io_wq_work->list->next to bu NULL.
--- fs/io-wq.h | 1 + 1 file changed, 1 insertion(+)
fs/io-wq.h +1 -0
@@ -59,6 +59,7 @@ static inline void wq_list_add_tail(stru list->last->next = node; list->last = node; } + node->next =NULL ; } static inline void wq_list_cut(struct io_wq_work_list *list,
Greg Kroah-Hartman
maintainerPATCH 517/717 io_uring: fix 0-iov read buffer select
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit dd20166236953c8cd14f4c668bf972af32f0c6be upstream.
Doing vectored buf-select read with 0 iovec passed is meaningless and utterly broken, forbid it.
--- fs/io_uring.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/io_uring.c +1 -3
@@ -3048,9 +3048,7 @@ static ssize_t io_iov_buffer_select(stru iov[0 ].iov_len = kbuf->len;return 0 ; } -if (!req->rw.len) -return 0 ; -else if (req->rw.len >1 ) +if (req->rw.len !=1 )return -EINVAL ;#ifdef CONFIG_COMPAT
Greg Kroah-Hartman
maintainerPATCH 518/717 io_uring: hold uring_lock while completing failed polled io in io_wq_submit_work()
In reply to Greg Kroah-HartmanFrom: Xiaoguang Wang <[email protected]>
commit c07e6719511e77c4b289f62bfe96423eb6ea061d upstream.
io_iopoll_complete() does not hold completion_lock to complete polled io, so in io_wq_submit_work(), we can not call io_req_complete() directly, to complete polled io, otherwise there maybe concurrent access to cqring, defer_list, etc, which is not safe. Commit dad1b1242fd5 ("io_uring: always let io_iopoll_complete() complete polled io") has fixed this issue, but Pavel reported that IOPOLL apart from rw can do buf reg/unreg requests( IORING_OP_PROVIDE_BUFFERS or IORING_OP_REMOVE_BUFFERS), so the fix is not good.
Given that io_iopoll_complete() is always called under uring_lock, so here for polled io, we can also get uring_lock to fix this issue.
--- fs/io_uring.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
fs/io_uring.c +19 -10
@@ -6081,19 +6081,28 @@ static struct io_wq_work *io_wq_submit_w }if (ret) { +struct io_ring_ctx *lock_ctx =NULL ; + +if (req->ctx->flags &IORING_SETUP_IOPOLL ) + lock_ctx = req->ctx; +/* -* io_iopoll_complete() does not hold completion_lock to complete -* polled io, so here for polled io, just mark it done and still let -* io_iopoll_complete() complete it. +* io_iopoll_complete() does not hold completion_lock to +* complete polled io, so here for polled io, we can not call +* io_req_complete() directly, otherwise there maybe concurrent +* access to cqring, defer_list, etc, which is not safe. Given +* that io_iopoll_complete() is always called under uring_lock, +* so here for polled io, we also get uring_lock to complete +* it. */ -if (req->ctx->flags &IORING_SETUP_IOPOLL ) { -struct kiocb *kiocb = &req->rw.kiocb; +if (lock_ctx) +mutex_lock (&lock_ctx->uring_lock); + +req_set_fail_links (req); +io_req_complete (req, ret); -kiocb_done (kiocb, ret,NULL ); - }else { -req_set_fail_links (req); -io_req_complete (req, ret); - } +if (lock_ctx) +mutex_unlock (&lock_ctx->uring_lock); }return io_steal_work (req);
Greg Kroah-Hartman
maintainerPATCH 519/717 io_uring: fix ignoring xa_store errors
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit a528b04ea40690ff40501f50d618a62a02b19620 upstream.
xa_store() may fail, check the result.
--- fs/io_uring.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/io_uring.c +7 -3
@@ -8708,10 +8708,9 @@ static void io_uring_cancel_task_requeststatic int io_uring_add_task_file (struct io_ring_ctx *ctx,struct file *file) {struct io_uring_task *tctx = current->io_uring; +int ret;if (unlikely (!tctx)) { -int ret; - ret =io_uring_alloc_task_context (current);if (unlikely (ret))return ret;
@@ -8722,7 +8721,12 @@ static int io_uring_add_task_file(structif (!old) {get_file (file); -xa_store (&tctx->xa, (unsigned long )file, file,GFP_KERNEL ); + ret =xa_err (xa_store (&tctx->xa, (unsigned long )file, + file,GFP_KERNEL )); +if (ret) { +fput (file); +return ret; + } } tctx->last = file; }
Greg Kroah-Hartman
maintainerPATCH 520/717 io_uring: fix double io_uring free
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 9faadcc8abe4b83d0263216dc3a6321d5bbd616b upstream.
Once we created a file for current context during setup, we should not call io_ring_ctx_wait_and_kill() directly as it'll be done by fput(file)
--- fs/io_uring.c | 71 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 32 deletions(-)
fs/io_uring.c +39 -32
@@ -9195,55 +9195,52 @@ static int io_allocate_scq_urings(structreturn 0 ; } +static int io_uring_install_fd (struct io_ring_ctx *ctx,struct file *file) +{ +int ret, fd; + + fd =get_unused_fd_flags (O_RDWR |O_CLOEXEC ); +if (fd <0 ) +return fd; + + ret =io_uring_add_task_file (ctx, file); +if (ret) { +put_unused_fd (fd); +return ret; + } +fd_install (fd, file); +return fd; +} +/* * Allocate an anonymous fd, this is what constitutes the application * visible backing of an io_uring instance. The application mmaps this * fd to gain access to the SQ/CQ ring details. If UNIX sockets are enabled, * we have to tie this fd to a socket for file garbage collection purposes. */ -static int io_uring_get_fd (struct io_ring_ctx *ctx) +static struct file *io_uring_get_file (struct io_ring_ctx *ctx) {struct file *file; +#if defined(CONFIG_UNIX )int ret; -int fd; -#if defined(CONFIG_UNIX ) ret =sock_create_kern (&init_net,PF_UNIX ,SOCK_RAW ,IPPROTO_IP , &ctx->ring_sock);if (ret) -return ret; +return ERR_PTR (ret);#endif - ret =get_unused_fd_flags (O_RDWR |O_CLOEXEC ); -if (ret <0 ) - goto err; - fd = ret; - file =anon_inode_getfile ("[io_uring]" , &io_uring_fops, ctx,O_RDWR |O_CLOEXEC ); -if (IS_ERR (file)) { -put_unused_fd (fd); - ret =PTR_ERR (file); - goto err; - } -#if defined(CONFIG_UNIX ) - ctx->ring_sock->file = file; -#endif - ret =io_uring_add_task_file (ctx, file); -if (ret) { -fput (file); -put_unused_fd (fd); - goto err; +if (IS_ERR (file)) { +sock_release (ctx->ring_sock); + ctx->ring_sock =NULL ; + }else { + ctx->ring_sock->file = file; } -fd_install (fd, file); -return fd; -err: -#if defined(CONFIG_UNIX ) -sock_release (ctx->ring_sock); - ctx->ring_sock =NULL ;#endif -return ret; +return file; } static int io_uring_create(unsigned entries, struct io_uring_params *p,
@@ -9251,6 +9248,7 @@ static int io_uring_create(unsigned entr {struct user_struct *user =NULL ;struct io_ring_ctx *ctx; +struct file *file;bool limit_mem;int ret;
@@ -9397,13 +9395,22 @@ static int io_uring_create(unsigned entr goto err; } + file =io_uring_get_file (ctx); +if (IS_ERR (file)) { + ret =PTR_ERR (file); + goto err; + } +/* * Install ring fd as the very last thing, so we don't risk someone * having closed it before we finish setup */ - ret =io_uring_get_fd (ctx); -if (ret <0 ) - goto err; + ret =io_uring_install_fd (ctx, file); +if (ret <0 ) { +/* fput will clean it up */ +fput (file); +return ret; + }trace_io_uring_create (ret, ctx, p->sq_entries, p->cq_entries, p->flags);return ret;
Greg Kroah-Hartman
maintainerPATCH 521/717 io_uring: make ctx cancel on exit targeted to actual ctx
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 00c18640c2430c4bafaaeede1f9dd6f7ec0e4b25 upstream.
Before IORING_SETUP_ATTACH_WQ, we could just cancel everything on the io-wq when exiting. But that's not the case if they are shared, so cancel for the specific ctx instead.
--- fs/io_uring.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/io_uring.c +8 -1
@@ -8401,6 +8401,13 @@ static void io_ring_exit_work(struct worio_ring_ctx_free (ctx); } +static bool io_cancel_ctx_cb (struct io_wq_work *work,void *data) +{ + struct io_kiocb *req = container_of(work, struct io_kiocb, work); + +return req->ctx == data; +} +static void io_ring_ctx_wait_and_kill (struct io_ring_ctx *ctx) {mutex_lock (&ctx->uring_lock);
@@ -8415,7 +8422,7 @@ static void io_ring_ctx_wait_and_kill(stio_poll_remove_all (ctx,NULL );if (ctx->io_wq) -io_wq_cancel_all (ctx->io_wq); +io_wq_cancel_cb (ctx->io_wq, io_cancel_ctx_cb, ctx, true);/* if we failed setting up the ctx, we might not have any rings */ io_iopoll_try_reap_events (ctx);
Greg Kroah-Hartman
maintainerPATCH 522/717 media: sunxi-cir: ensure IR is handled when it is continuous
In reply to Greg Kroah-HartmanFrom: Sean Young <[email protected]>
commit 3f56df4c8ffeb120ed41906d3aae71799b7e726a upstream.
If a user holds a button down on a remote, then no ir idle interrupt will be generated until the user releases the button, depending on how quickly the remote repeats. No IR is processed until that point, which means that holding down a button may not do anything.
This also resolves an issue on a Cubieboard 1 where the IR receiver is picking up ambient infrared as IR and spews out endless
"rc rc0: IR event FIFO is full!" messages unless you choose to live in the dark.
--- drivers/media/rc/sunxi-cir.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/rc/sunxi-cir.c +2 -0
@@ -137,6 +137,8 @@ static irqreturn_t sunxi_ir_irq(int irqn }else if (status ®_RXSTA_RPE ) {ir_raw_event_set_idle (ir->rc, true);ir_raw_event_handle (ir->rc); + }else { +ir_raw_event_handle (ir->rc); }spin_unlock (&ir->ir_lock);
Greg Kroah-Hartman
maintainerPATCH 523/717 media: netup_unidvb: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit e297ddf296de35037fa97f4302782def196d350a upstream.
If the call to spi_register_master() fails on probe of the NetUP Universal DVB driver, the spi_master struct is erroneously not freed.
Likewise, if spi_new_device() fails, the spi_controller struct is not unregistered. Plug the leaks.
While at it, fix an ordering issue in netup_spi_release() wherein spi_unregister_master() is called after fiddling with the IRQ control register. The correct order is to call spi_unregister_master() *before* this teardown step because bus accesses may still be ongoing until that function returns.
--- drivers/media/pci/netup_unidvb/netup_unidvb_spi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/media/pci/netup_unidvb/netup_unidvb_spi.c +3 -2
@@ -175,7 +175,7 @@ int netup_spi_init(struct netup_unidvb_dstruct spi_master *master;struct netup_spi *nspi; - master =spi_alloc_master (&ndev->pci_dev->dev, + master =devm_spi_alloc_master (&ndev->pci_dev->dev,sizeof (struct netup_spi ));if (!master) { dev_err(&ndev->pci_dev->dev,
@@ -208,6 +208,7 @@ int netup_spi_init(struct netup_unidvb_d ndev->pci_slot, ndev->pci_func);if (!spi_new_device (master, &netup_spi_board)) { +spi_unregister_master (master); ndev->spi =NULL ;dev_err (&ndev->pci_dev->dev,"%s(): unable to create SPI device\n" , __func__);
@@ -226,13 +227,13 @@ void netup_spi_release(struct netup_unidif (!spi)return ; +spi_unregister_master (spi->master);spin_lock_irqsave (&spi->lock, flags); reg =readw (&spi->regs->control_stat);writew (reg |NETUP_SPI_CTRL_IRQ , &spi->regs->control_stat); reg =readw (&spi->regs->control_stat);writew (reg & ~NETUP_SPI_CTRL_IMASK , &spi->regs->control_stat);spin_unlock_irqrestore (&spi->lock, flags); -spi_unregister_master (spi->master); ndev->spi =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 524/717 media: ipu3-cio2: Remove traces of returned buffers
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit 61e7f892b5ee1dd10ea8bff805f3c3fe6e535959 upstream.
If starting a video buffer queue fails, the buffers are returned to videobuf2. Remove the reference to the buffer from the driver's queue as well.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +1 -0
@@ -791,6 +791,7 @@ static void cio2_vb2_return_all_buffers(atomic_dec (&q->bufs_queued);vb2_buffer_done (&q->bufs[i]->vbb.vb2_buf, state); + q->bufs[i] =NULL ; } } }
Greg Kroah-Hartman
maintainerPATCH 525/717 media: ipu3-cio2: Return actual subdev format
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit 8160e86702e0807bd36d40f82648f9f9820b9d5a upstream.
Return actual subdev format on ipu3-cio2 subdev pads. The earlier implementation was based on an infinite recursion that exhausted the stack.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +3 -21
@@ -1233,29 +1233,11 @@ static int cio2_subdev_get_fmt(struct v4 struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); -struct v4l2_subdev_format format; -int ret; -if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) { +if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) fmt->format = *v4l2_subdev_get_try_format (sd, cfg, fmt->pad); -return 0 ; - } - -if (fmt->pad ==CIO2_PAD_SINK ) { - format.which =V4L2_SUBDEV_FORMAT_ACTIVE ; - ret =v4l2_subdev_call (sd, pad, get_fmt,NULL , - &format); - -if (ret) -return ret; -/* update colorspace etc */ - q->subdev_fmt.colorspace = format.format.colorspace; - q->subdev_fmt.ycbcr_enc = format.format.ycbcr_enc; - q->subdev_fmt.quantization = format.format.quantization; - q->subdev_fmt.xfer_func = format.format.xfer_func; - } - - fmt->format = q->subdev_fmt; +else + fmt->format = q->subdev_fmt;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 526/717 media: ipu3-cio2: Serialise access to pad format
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit 55a6c6b2be3d6670bf5772364d8208bd8dc17da4 upstream.
Pad format can be accessed from user space. Serialise access to it.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 11 +++++++++++ drivers/media/pci/intel/ipu3/ipu3-cio2.h | 1 + 2 files changed, 12 insertions(+)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +11 -0
@@ -1234,11 +1234,15 @@ static int cio2_subdev_get_fmt(struct v4 { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); +mutex_lock (&q->subdev_lock); +if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) fmt->format = *v4l2_subdev_get_try_format (sd, cfg, fmt->pad);else fmt->format = q->subdev_fmt; +mutex_unlock (&q->subdev_lock); +return 0 ; }
@@ -1262,6 +1266,8 @@ static int cio2_subdev_set_fmt(struct v4if (fmt->pad ==CIO2_PAD_SOURCE )return cio2_subdev_get_fmt (sd, cfg, fmt); +mutex_lock (&q->subdev_lock); +if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) { *v4l2_subdev_get_try_format (sd, cfg, fmt->pad) = fmt->format; }else {
@@ -1272,6 +1278,8 @@ static int cio2_subdev_set_fmt(struct v4 fmt->format = q->subdev_fmt; } +mutex_unlock (&q->subdev_lock); +return 0 ; }
@@ -1530,6 +1538,7 @@ static int cio2_queue_init(struct cio2_d/* Initialize miscellaneous variables */ mutex_init (&q->lock); +mutex_init (&q->subdev_lock);/* Initialize formats to default values */ fmt = &q->subdev_fmt;
@@ -1646,6 +1655,7 @@ fail_vdev_media_entity: fail_subdev_media_entity:cio2_fbpt_exit (q, &cio2->pci_dev->dev); fail_fbpt: +mutex_destroy (&q->subdev_lock);mutex_destroy (&q->lock);return r;
@@ -1658,6 +1668,7 @@ static void cio2_queue_exit(struct cio2_v4l2_device_unregister_subdev (&q->subdev);media_entity_cleanup (&q->subdev.entity);cio2_fbpt_exit (q, &cio2->pci_dev->dev); +mutex_destroy (&q->subdev_lock);mutex_destroy (&q->lock); }
drivers/media/pci/intel/ipu3/ipu3-cio2.h +1 -0
@@ -335,6 +335,7 @@ struct cio2_queue {/* Subdev, /dev/v4l-subdevX */ struct v4l2_subdev subdev; +struct mutex subdev_lock;/* Serialise acces to subdev_fmt field */ struct media_pad subdev_pads[CIO2_PADS ];struct v4l2_mbus_framefmt subdev_fmt;atomic_t frame_sequence;
Greg Kroah-Hartman
maintainerPATCH 527/717 media: ipu3-cio2: Validate mbus format in setting subdev format
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit a86cf9b29e8b12811cf53c4970eefe0c1d290476 upstream.
Validate media bus code, width and height when setting the subdev format.
This effectively reworks how setting subdev format is implemented in the driver.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +20 -9
@@ -1258,6 +1258,9 @@ static int cio2_subdev_set_fmt(struct v4 struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); +struct v4l2_mbus_framefmt *mbus; +u32 mbus_code = fmt->format.code; +unsigned int i;/* * Only allow setting sink pad format;
@@ -1266,18 +1269,26 @@ static int cio2_subdev_set_fmt(struct v4if (fmt->pad ==CIO2_PAD_SOURCE )return cio2_subdev_get_fmt (sd, cfg, fmt); -mutex_lock (&q->subdev_lock); +if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) + mbus =v4l2_subdev_get_try_format (sd, cfg, fmt->pad); +else + mbus = &q->subdev_fmt; + + fmt->format.code = formats[0 ].mbus_code; -if (fmt->which ==V4L2_SUBDEV_FORMAT_TRY ) { - *v4l2_subdev_get_try_format (sd, cfg, fmt->pad) = fmt->format; - }else { -/* It's the sink, allow changing frame size */ - q->subdev_fmt.width = fmt->format.width; - q->subdev_fmt.height = fmt->format.height; - q->subdev_fmt.code = fmt->format.code; - fmt->format = q->subdev_fmt; +for (i =0 ; i <ARRAY_SIZE (formats); i++) { +if (formats[i].mbus_code == fmt->format.code) { + fmt->format.code = mbus_code; +break ; + } } + fmt->format.width =min_t (u32, fmt->format.width,CIO2_IMAGE_MAX_WIDTH ); + fmt->format.height =min_t (u32, fmt->format.height, +CIO2_IMAGE_MAX_LENGTH ); + +mutex_lock (&q->subdev_lock); + *mbus = fmt->format;mutex_unlock (&q->subdev_lock);return 0 ;
Re: [PATCH 5.10 527/717] media: ipu3-cio2: Validate mbus format in setting subdev format
Hi!
Quoted 6 lines
commit
a86cf9b29e8b12811cf53c4970eefe0c1d290476upstream.Validate media bus code, width and height when setting the subdev format.
This effectively reworks how setting subdev format is implemented in the driver.
Something is wrong here:
drivers/media/pci/intel/ipu3/ipu3-cio2.c static int cio2_subdev_set_fmt(struct v4 · line 1283
Quoted 6 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +6
-0+ fmt->format.code = formats[0 ].mbus_code; +for (i =0 ; i <ARRAY_SIZE (formats); i++) { +if (formats[i].mbus_code == fmt->format.code) { + fmt->format.code = mbus_code; +break ; + }
This does not make sense. Loop will always exit during the first iteration, making the whole loop crazy/redundant.
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Re: [PATCH 5.10 527/717] media: ipu3-cio2: Validate mbus format in setting subdev format
Quoted 11 lines · Pavel Machek
Quoted 6 lines
commit
a86cf9b29e8b12811cf53c4970eefe0c1d290476upstream.Validate media bus code, width and height when setting the subdev format.
This effectively reworks how setting subdev format is implemented in the driver.
Something is wrong here:
Quoted 2 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +2
-0+ fmt->format.code = formats[0 ].mbus_code; +for (i =0 ; i <ARRAY_SIZE (formats); i++) {
Looks like 'i = 1' should be...
Quoted 7 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c static int cio2_subdev_set_fmt(struct v4 · line 1283
Quoted 4 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +4
-0+if (formats[i].mbus_code == fmt->format.code) { + fmt->format.code = mbus_code; +break ; + }This does not make sense. Loop will always exit during the first iteration, making the whole loop crazy/redundant.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH 5.10 527/717] media: ipu3-cio2: Validate mbus format in setting subdev format
Quoted 9 lines · Andy Shevchenko
Quoted 7 lines · Pavel Machek
Quoted 6 lines
commit
a86cf9b29e8b12811cf53c4970eefe0c1d290476upstream.Validate media bus code, width and height when setting the subdev format.
This effectively reworks how setting subdev format is implemented in the driver.
Quoted 8 lines
Quoted 4 lines
Something is wrong here:
Quoted 2 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +2
-0+ fmt->format.code = formats[0 ].mbus_code; +for (i =0 ; i <ARRAY_SIZE (formats); i++) {Looks like 'i = 1' should be...
Quoted 1 line
Quoted 1 line
+ if (formats[i].mbus_code ==
fmt->format.code) {
More likely
if (formats[i].mbus_code == mbus_code) {I think.
Pavel, would you like to submit a patch ?
Quoted 6 lines
Quoted 6 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c static int cio2_subdev_set_fmt(struct v4 · line 1283
Quoted 3 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +3
-0+ fmt->format.code = mbus_code; +break ; + }This does not make sense. Loop will always exit during the first iteration, making the whole loop crazy/redundant.
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH 5.10 527/717] media: ipu3-cio2: Validate mbus format in setting subdev format
Quoted 17 lines · Laurent Pinchart
Quoted 16 lines · Andy Shevchenko
Quoted 11 lines · Pavel Machek
Quoted 6 lines
commit
a86cf9b29e8b12811cf53c4970eefe0c1d290476upstream.Validate media bus code, width and height when setting the subdev format.
This effectively reworks how setting subdev format is implemented in the driver.
Something is wrong here:
Quoted 2 lines
drivers/media/pci/intel/ipu3/ipu3-cio2.c +2
-0+ fmt->format.code = formats[0 ].mbus_code; +for (i =0 ; i <ARRAY_SIZE (formats); i++) {Looks like 'i = 1' should be...
Quoted 7 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
+ if (formats[i].mbus_code ==
fmt->format.code) {More likely
if (formats[i].mbus_code == mbus_code) {I think.
That looks reasonable, but I don't have hardware to test.
Quoted 1 line
Pavel, would you like to submit a patch ?
Done, should be in your inbox.
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Greg Kroah-Hartman
maintainerPATCH 528/717 media: ipu3-cio2: Make the field on subdev format V4L2_FIELD_NONE
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
commit 219a8b9c04e54872f9a4d566633fb42f08bcbe2a upstream.
The ipu3-cio2 doesn't make use of the field and this is reflected in V4L2 buffers as well as the try format. Do this in active format, too.
--- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/pci/intel/ipu3/ipu3-cio2.c +1 -0
@@ -1286,6 +1286,7 @@ static int cio2_subdev_set_fmt(struct v4 fmt->format.width =min_t (u32, fmt->format.width,CIO2_IMAGE_MAX_WIDTH ); fmt->format.height =min_t (u32, fmt->format.height,CIO2_IMAGE_MAX_LENGTH ); + fmt->format.field =V4L2_FIELD_NONE ;mutex_lock (&q->subdev_lock); *mbus = fmt->format;
Greg Kroah-Hartman
maintainerPATCH 529/717 Input: cyapa_gen6 - fix out-of-bounds stack access
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit f051ae4f6c732c231046945b36234e977f8467c6 upstream.
gcc -Warray-bounds warns about a serious bug incyapa_pip_retrieve_data_structure:
drivers/input/mouse/cyapa_gen6.c: In function 'cyapa_pip_retrieve_data_structure.constprop':include/linux/unaligned/access_ok.h:40:17: warning: array subscript -1 is outside array bounds of 'struct retrieve_data_struct_cmd[1]' [-Warray-bounds]
40 | *((__le16 *)p) = cpu_to_le16(val);drivers/input/mouse/cyapa_gen6.c:569:13: note: while referencing 'cmd'
569 | } __packed cmd;
| ^~~
Apparently the '-2' was added to the pointer instead of the value, writing garbage into the stack next to this variable.
--- drivers/input/mouse/cyapa_gen6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/mouse/cyapa_gen6.c +1 -1
@@ -573,7 +573,7 @@ static int cyapa_pip_retrieve_data_strucmemset (&cmd,0 ,sizeof (cmd));put_unaligned_le16 (PIP_OUTPUT_REPORT_ADDR , &cmd.head.addr); -put_unaligned_le16 (sizeof (cmd), &cmd.head.length -2 ); +put_unaligned_le16 (sizeof (cmd) -2 , &cmd.head.length); cmd.head.report_id =PIP_APP_CMD_REPORT_ID ; cmd.head.cmd_code =PIP_RETRIEVE_DATA_STRUCTURE ;put_unaligned_le16 (read_offset, &cmd.read_offset);
Greg Kroah-Hartman
maintainerPATCH 530/717 ALSA: hda/ca0132 - Change Input Source enum strings.
In reply to Greg Kroah-HartmanFrom: Connor McAdams <[email protected]>
commit 7079f785b50055a32b72eddcb7d9ba5688db24d0 upstream.
Change the Input Source enumerated control's strings to make it play nice with pulseaudio.
--- sound/pci/hda/patch_ca0132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/patch_ca0132.c +1 -1
@@ -95,7 +95,7 @@ enum { };/* Strings for Input Source Enum Control */ -static const char *const in_src_str[3 ] = {"Rear Mic" ,"Line" ,"Front Mic" }; +static const char *const in_src_str[3 ] = {"Microphone" ,"Line In" ,"Front Microphone" };#define IN_SRC_NUM_OF_INPUTS 3enum {REAR_MIC ,
Greg Kroah-Hartman
maintainerPATCH 531/717 ACPI: NFIT: Fix input validation of bus-family
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
commit 9a7e3d7f056831a6193d6d737fb7a26dfdceb04b upstream.
Dan reports that smatch thinks userspace can craft an out-of-bound bus family number. However, nd_cmd_clear_to_send() blocks all non-zero values of bus-family since only the kernel can initiate these commands. However, in the speculation path, family is a user controlled array index value so mask it for speculation safety. Also, since the nd_cmd_clear_to_send() safety is non-obvious and possibly may change in the future include input validation as if userspace could get past the nd_cmd_clear_to_send() gatekeeper.
--- drivers/acpi/nfit/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/acpi/nfit/core.c +5 -1
@@ -5,6 +5,7 @@#include <linux/list_sort.h> #include <linux/libnvdimm.h> #include <linux/module.h> +#include <linux/nospec.h> #include <linux/mutex.h> #include <linux/ndctl.h> #include <linux/sysfs.h>
@@ -478,8 +479,11 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc cmd_mask = nd_desc->cmd_mask;if (cmd ==ND_CMD_CALL && call_pkg->nd_family) { family = call_pkg->nd_family; -if (!test_bit (family, &nd_desc->bus_family_mask)) +if (family >NVDIMM_BUS_FAMILY_MAX || + !test_bit (family, &nd_desc->bus_family_mask))return -EINVAL ; + family =array_index_nospec (family, +NVDIMM_BUS_FAMILY_MAX +1 ); dsm_mask = acpi_desc->family_dsm_mask[family]; guid =to_nfit_bus_uuid (family); }else {
Greg Kroah-Hartman
maintainerPATCH 532/717 PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup()
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit 7482c5cb90e5a7f9e9e12dd154d405e0219656e3 upstream.
The idea behind acpi_pm_set_bridge_wakeup() was to allow bridges to be reference counted for wakeup enabling, because they may be enabled to signal wakeup on behalf of their subordinate devices and that may happen for multiple times in a row, whereas for the other devices it only makes sense to enable wakeup signaling once.
However, this becomes problematic if the bridge itself is suspended, because it is treated as a "regular" device in that case and the reference counting doesn't work.
For instance, suppose that there are two devices below a bridge and they both can signal wakeup. Every time one of them is suspended, wakeup signaling is enabled for the bridge, so when they both have been suspended, the bridge's wakeup reference counter value is 2.
Say that the bridge is suspended subsequently and acpi_pci_wakeup() is called for it. Because the bridge can signal wakeup, that function will invoke acpi_pm_set_device_wakeup() to configure it and __acpi_pm_set_device_wakeup() will be called with the last argument equal to 1. This causes __acpi_device_wakeup_enable() invoked by it to omit the reference counting, because the reference counter of the target device (the bridge) is 2 at that time.
Now say that the bridge resumes and one of the device below it resumes too, so the bridge's reference counter becomes 0 and wakeup signaling is disabled for it, but there is still the other suspended device which may need the bridge to signal wakeup on its behalf and that is not going to work.
To address this scenario, use wakeup enable reference counting for all devices, not just for bridges, so drop the last argument from __acpi_device_wakeup_enable() and __acpi_pm_set_device_wakeup(), which causes acpi_pm_set_device_wakeup() and acpi_pm_set_bridge_wakeup() to become identical, so drop the latter and use the former instead of it everywhere.
--- drivers/acpi/device_pm.c | 41 ++++++++++++----------------------------- drivers/pci/pci-acpi.c | 4 ++-- include/acpi/acpi_bus.h | 5 ----- 3 files changed, 14 insertions(+), 36 deletions(-)
drivers/acpi/device_pm.c +12 -29
@@ -749,7 +749,7 @@ static void acpi_pm_notify_work_func(strstatic DEFINE_MUTEX (acpi_wakeup_lock);static int __acpi_device_wakeup_enable (struct acpi_device *adev, -u32 target_state,int max_count) +u32 target_state) {struct acpi_device_wakeup *wakeup = &adev->wakeup;acpi_status status;
@@ -757,9 +757,10 @@ static int __acpi_device_wakeup_enable(smutex_lock (&acpi_wakeup_lock); -if (wakeup->enable_count >= max_count) +if (wakeup->enable_count >=INT_MAX ) { +acpi_handle_info (adev->handle,"Wakeup enable count out of bounds!\n" ); goto out; - + }if (wakeup->enable_count >0 ) goto inc;
@@ -799,7 +800,7 @@ out:*/ static int acpi_device_wakeup_enable (struct acpi_device *adev,u32 target_state) { -return __acpi_device_wakeup_enable (adev, target_state,1 ); +return __acpi_device_wakeup_enable (adev, target_state); }/**
@@ -829,8 +830,12 @@ out:mutex_unlock (&acpi_wakeup_lock); } -static int __acpi_pm_set_device_wakeup (struct device *dev,bool enable, -int max_count) +/** +* acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device. +* @dev: Device to enable/disable to generate wakeup events. +* @enable: Whether to enable or disable the wakeup functionality. +*/ +int acpi_pm_set_device_wakeup (struct device *dev,bool enable) {struct acpi_device *adev;int error;
@@ -850,37 +855,15 @@ static int __acpi_pm_set_device_wakeup(sreturn 0 ; } - error =__acpi_device_wakeup_enable (adev,acpi_target_system_state (), - max_count); + error =__acpi_device_wakeup_enable (adev,acpi_target_system_state ());if (!error)dev_dbg (dev,"Wakeup enabled by ACPI\n" );return error; } - -/** -* acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device. -* @dev: Device to enable/disable to generate wakeup events. -* @enable: Whether to enable or disable the wakeup functionality. -*/ -int acpi_pm_set_device_wakeup (struct device *dev,bool enable) -{ -return __acpi_pm_set_device_wakeup (dev, enable,1 ); -}EXPORT_SYMBOL_GPL (acpi_pm_set_device_wakeup);/** -* acpi_pm_set_bridge_wakeup - Enable/disable remote wakeup for given bridge. -* @dev: Bridge device to enable/disable to generate wakeup events. -* @enable: Whether to enable or disable the wakeup functionality. -*/ -int acpi_pm_set_bridge_wakeup (struct device *dev,bool enable) -{ -return __acpi_pm_set_device_wakeup (dev, enable,INT_MAX ); -} -EXPORT_SYMBOL_GPL (acpi_pm_set_bridge_wakeup); - -/** * acpi_dev_pm_low_power - Put ACPI device into a low-power state. * @dev: Device to put into a low-power state. * @adev: ACPI device node corresponding to @dev.
drivers/pci/pci-acpi.c +2 -2
@@ -1060,7 +1060,7 @@ static int acpi_pci_propagate_wakeup(str {while (bus->parent) {if (acpi_pm_device_can_wakeup (&bus->self->dev)) -return acpi_pm_set_bridge_wakeup (&bus->self->dev, enable); +return acpi_pm_set_device_wakeup (&bus->self->dev, enable); bus = bus->parent; }
@@ -1068,7 +1068,7 @@ static int acpi_pci_propagate_wakeup(str/* We have reached the root bus. */ if (bus->bridge) {if (acpi_pm_device_can_wakeup (bus->bridge)) -return acpi_pm_set_bridge_wakeup (bus->bridge, enable); +return acpi_pm_set_device_wakeup (bus->bridge, enable); }return 0 ; }
include/acpi/acpi_bus.h +0 -5
@@ -620,7 +620,6 @@ acpi_status acpi_remove_pm_notifier(strubool acpi_pm_device_can_wakeup (struct device *dev);int acpi_pm_device_sleep_state (struct device *,int *,int );int acpi_pm_set_device_wakeup (struct device *dev,bool enable); -int acpi_pm_set_bridge_wakeup (struct device *dev,bool enable);#else static inline void acpi_pm_wakeup_event (struct device *dev) {
@@ -651,10 +650,6 @@ static inline int acpi_pm_set_device_wak {return -ENODEV ; } -static inline int acpi_pm_set_bridge_wakeup (struct device *dev,bool enable) -{ -return -ENODEV ; -}#endif #ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT
Greg Kroah-Hartman
maintainerPATCH 533/717 Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks"
In reply to Greg Kroah-HartmanFrom: Daniel Scally <[email protected]>
commit 12fc4dad94dfac25599f31257aac181c691ca96f upstream.
This reverts commit 8a66790b7850a6669129af078768a1d42076a0ef.
Switching this function to AE_CTRL_TERMINATE broke the documented behaviour of acpi_dev_get_resources() - AE_CTRL_TERMINATE does not, in fact, terminate the resource walk because acpi_walk_resource_buffer() ignores it (specifically converting it to AE_OK), referring to that value as "an OK termination by the user function". This means that acpi_dev_get_resources() does not abort processing when the preproc function returns a negative value.
--- drivers/acpi/resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/resource.c +1 -1
@@ -541,7 +541,7 @@ static acpi_status acpi_dev_process_reso ret = c->preproc (ares, c->preproc_data);if (ret <0 ) { c->error = ret; -return AE_CTRL_TERMINATE ; +return AE_ABORT_METHOD ; }else if (ret >0 ) {return AE_OK ; }
Greg Kroah-Hartman
maintainerPATCH 534/717 ACPI: PNP: compare the string length in the matching_id()
In reply to Greg Kroah-HartmanFrom: Hui Wang <[email protected]>
commit b08221c40febcbda9309dd70c61cf1b0ebb0e351 upstream.
Recently we met a touchscreen problem on some Thinkpad machines, the touchscreen driver (i2c-hid) is not loaded and the touchscreen can't work.
An i2c ACPI device with the name WACF2200 is defined in the BIOS, with the current rule in matching_id(), this device will be regarded as a PNP device since there is WACFXXX in the acpi_pnp_device_ids[] and this PNP device is attached to the acpi device as the 1st physical_node, this will make the i2c bus match fail when i2c bus calls acpi_companion_match() to match the acpi_id_table in the i2c-hid driver.
WACF2200 is an i2c device instead of a PNP device, after adding the string length comparing, the matching_id() will return false when matching WACF2200 and WACFXXX, and it is reasonable to compare the string length when matching two IDs.
--- drivers/acpi/acpi_pnp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/acpi/acpi_pnp.c +3 -0
@@ -319,6 +319,9 @@ static bool matching_id(const char *idst {int i; +if (strlen (idstr) !=strlen (list_id)) +return false; +if (memcmp (idstr, list_id,3 ))return false;
Greg Kroah-Hartman
maintainerPATCH 535/717 ALSA: hda: Fix regressions on clear and reconfig sysfs
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 2506318e382c4c7daa77bdc48f80a0ee82804588 upstream.
It seems that the HD-audio clear and reconfig sysfs don't work any longer after the recent driver core change. There are multiple issues around that: the linked list corruption and the dead device handling. The former issue is fixed by another patch for the driver core itself, while the latter patch needs to be addressed in HD-audio side.
This patch corresponds to the latter, it recovers those broken functions by replacing the device detach and attach actions with the standard core API functions, which are almost equivalent with unbind and bind actions.
--- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_sysfs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/hda_codec.c +1 -1
@@ -1803,7 +1803,7 @@ int snd_hda_codec_reset(struct hda_codecreturn -EBUSY ;/* OK, let it free */ -snd_hdac_device_unregister (&codec->core); +device_release_driver (hda_codec_dev (codec));/* allow device access again */ snd_hda_unlock_devices (bus);
sound/pci/hda/hda_sysfs.c +1 -1
@@ -139,7 +139,7 @@ static int reconfig_codec(struct hda_cod "The codec is being used, can't reconfigure.\n"); goto error; } - err =snd_hda_codec_configure (codec); + err =device_reprobe (hda_codec_dev (codec));if (err <0 ) goto error; err =snd_card_register (codec->card);
Greg Kroah-Hartman
maintainerPATCH 536/717 ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg.
In reply to Greg Kroah-HartmanFrom: Connor McAdams <[email protected]>
commit c697ba85a94b8f65bf90dec5ef9af5c39c3e73b2 upstream.
The Windows driver sets the pincfg for the AE-5's rear-headphone to report as a microphone. This causes issues with Pulseaudio mistakenly believing there is no headphone plugged in. In Linux, we should instead set it to be a headphone.
--- sound/pci/hda/patch_ca0132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/patch_ca0132.c +1 -1
@@ -1223,7 +1223,7 @@ static const struct hda_pintbl ae5_pincf { 0x0e, 0x01c510f0 }, /* SPDIF In */ { 0x0f, 0x01017114 }, /* Port A -- Rear L/R. */ { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */ - { 0x11, 0x01a170ff }, /* Port B -- LineMicIn2 / Rear Headphone */ + { 0x11, 0x012170ff }, /* Port B -- LineMicIn2 / Rear Headphone */ { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */ { 0x13, 0x908700f0 }, /* What U Hear In*/ { 0x18, 0x50d000f0 }, /* N/A */
Greg Kroah-Hartman
maintainerPATCH 537/717 ALSA: hda/realtek: make bass spk volume adjustable on a yoga laptop
In reply to Greg Kroah-HartmanFrom: Hui Wang <[email protected]>
commit c72b9bfe0f914639cc475585f45722a3eb57a56d upstream.
This change could fix 2 issues on this machine:
- the bass speaker's output volume can't be adjusted, that is because the bass speaker is routed to the DAC (Nid 0x6) which has no volume control.
- after plugging a headset with vol+, vol- and pause buttons on it, press those buttons, nothing happens, this means those buttons don't work at all. This machine has alc287 codec, need to add the codec id to the disable/enable_headset_jack_key(), then the headset button could work.
The quirk of ALC285_FIXUP_THINKPAD_HEADSET_JACK could fix both of these 2 issues.
--- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/pci/hda/patch_realtek.c +7 -0
@@ -3104,6 +3104,7 @@ static void alc_disable_headset_jack_keycase 0x10ec0215 :case 0x10ec0225 :case 0x10ec0285 : +case 0x10ec0287 :case 0x10ec0295 :case 0x10ec0289 :case 0x10ec0299 :
@@ -3130,6 +3131,7 @@ static void alc_enable_headset_jack_key(case 0x10ec0215 :case 0x10ec0225 :case 0x10ec0285 : +case 0x10ec0287 :case 0x10ec0295 :case 0x10ec0289 :case 0x10ec0299 :
@@ -8578,6 +8580,11 @@ static const struct snd_hda_pin_quirk al {0x14, 0x90170110}, {0x19, 0x04a11040}, {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_HEADSET_JACK, + {0x14, 0x90170110}, + {0x17, 0x90170111}, + {0x19, 0x03a11030}, + {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE, {0x12, 0x90a60130}, {0x17, 0x90170110},
Greg Kroah-Hartman
maintainerPATCH 538/717 ALSA: hda/realtek - Enable headset mic of ASUS X430UN with ALC256
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
commit 5cfca59604e423f720297e30a9dc493eea623493 upstream.
The ASUS laptop X430UN with ALC256 can't detect the headset microphone until ALC256_FIXUP_ASUS_MIC_NO_PRESENCE quirk applied.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -7958,6 +7958,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x10d0 ,"ASUS X540LA/X540LJ" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x115d ,"Asus 1015E" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x1043 ,0x11c0 ,"ASUS X556UR" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1043 ,0x1271 ,"ASUS X430UN" ,ALC256_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x1290 ,"ASUS X441SA" ,ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x12a0 ,"ASUS X441UV" ,ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
Greg Kroah-Hartman
maintainerPATCH 539/717 ALSA: hda/realtek - Enable headset mic of ASUS Q524UQK with ALC255
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
commit 7e413528474d5895e3e315c019fb0c43522eb6d9 upstream.
The ASUS laptop Q524UQK with ALC255 codec can't detect the headset microphone until ALC255_FIXUP_ASUS_MIC_NO_PRESENCE quirk applied.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -7979,6 +7979,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x1b13 ,"Asus U41SV" ,ALC269_FIXUP_INV_DMIC ),SND_PCI_QUIRK (0x1043 ,0x1bbd ,"ASUS Z550MA" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x1c23 ,"Asus X55U" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ), +SND_PCI_QUIRK (0x1043 ,0x125e ,"ASUS Q524UQK" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x1ccd ,"ASUS X555UB" ,ALC256_FIXUP_ASUS_MIC ),SND_PCI_QUIRK (0x1043 ,0x1d4e ,"ASUS TM420" ,ALC256_FIXUP_ASUS_HPE ), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
Greg Kroah-Hartman
maintainerPATCH 540/717 ALSA: hda/realtek - Add supported for more Lenovo ALC285 Headset Button
In reply to Greg Kroah-HartmanFrom: Kailang Yang <[email protected]>
commit 607184cb1635eaee239fe3fb9648a8b82a5232d7 upstream.
Add supported for more Lenovo ALC285 Headset Button.
--- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/pci/hda/patch_realtek.c +4 -0
@@ -8577,6 +8577,10 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), + SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, + {0x14, 0x90170110}, + {0x19, 0x04a11040}, + {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, {0x12, 0x90a60130}, {0x14, 0x90170110},
Greg Kroah-Hartman
maintainerPATCH 541/717 ALSA: pcm: oss: Fix a few more UBSAN fixes
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 11cb881bf075cea41092a20236ba708b18e1dbb2 upstream.
There are a few places that call round{up|down}_pow_of_two() with the value zero, and this causes undefined behavior warnings. Avoid calling those macros if such a nonsense value is passed; it's a minor optimization as well, as we handle it as either an error or a value to be skipped, instead.
--- sound/core/oss/pcm_oss.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
sound/core/oss/pcm_oss.c +14 -8
@@ -693,6 +693,8 @@ static int snd_pcm_oss_period_size(struc oss_buffer_size =snd_pcm_plug_client_size (substream,snd_pcm_hw_param_value_max (slave_params,SNDRV_PCM_HW_PARAM_BUFFER_SIZE ,NULL )) * oss_frame_size; +if (!oss_buffer_size) +return -EINVAL ; oss_buffer_size =rounddown_pow_of_two (oss_buffer_size);if (atomic_read (&substream->mmap_count)) {if (oss_buffer_size > runtime->oss.mmap_bytes)
@@ -728,17 +730,21 @@ static int snd_pcm_oss_period_size(struc min_period_size =snd_pcm_plug_client_size (substream,snd_pcm_hw_param_value_min (slave_params,SNDRV_PCM_HW_PARAM_PERIOD_SIZE ,NULL )); - min_period_size *= oss_frame_size; - min_period_size =roundup_pow_of_two (min_period_size); -if (oss_period_size < min_period_size) - oss_period_size = min_period_size; +if (min_period_size) { + min_period_size *= oss_frame_size; + min_period_size =roundup_pow_of_two (min_period_size); +if (oss_period_size < min_period_size) + oss_period_size = min_period_size; + } max_period_size =snd_pcm_plug_client_size (substream,snd_pcm_hw_param_value_max (slave_params,SNDRV_PCM_HW_PARAM_PERIOD_SIZE ,NULL )); - max_period_size *= oss_frame_size; - max_period_size =rounddown_pow_of_two (max_period_size); -if (oss_period_size > max_period_size) - oss_period_size = max_period_size; +if (max_period_size) { + max_period_size *= oss_frame_size; + max_period_size =rounddown_pow_of_two (max_period_size); +if (oss_period_size > max_period_size) + oss_period_size = max_period_size; + } oss_periods = oss_buffer_size / oss_period_size;
Greg Kroah-Hartman
maintainerPATCH 542/717 ALSA/hda: apply jack fixup for the Acer Veriton N4640G/N6640G/N2510G
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
commit 13be30f156fda725b168ac89fc91f78651575307 upstream.
This Acer Veriton N4640G/N6640G/N2510G desktops have 2 headphone jacks(front and rear), and a separate Mic In jack.
The rear headphone jack is actually a line out jack but always silent while playing audio. The front 'Mic In' also fails the jack sensing. Apply the ALC269_FIXUP_LIFEBOOK to have all audio jacks to work as expected.
--- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/hda/patch_realtek.c +3 -0
@@ -7805,11 +7805,14 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1025 ,0x0762 ,"Acer Aspire E1-472" ,ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572 ),SND_PCI_QUIRK (0x1025 ,0x0775 ,"Acer Aspire E1-572" ,ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572 ),SND_PCI_QUIRK (0x1025 ,0x079b ,"Acer Aspire V5-573G" ,ALC282_FIXUP_ASPIRE_V5_PINS ), +SND_PCI_QUIRK (0x1025 ,0x101c ,"Acer Veriton N2510G" ,ALC269_FIXUP_LIFEBOOK ),SND_PCI_QUIRK (0x1025 ,0x102b ,"Acer Aspire C24-860" ,ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1025 ,0x1065 ,"Acer Aspire C20-820" ,ALC269VC_FIXUP_ACER_HEADSET_MIC ),SND_PCI_QUIRK (0x1025 ,0x106d ,"Acer Cloudbook 14" ,ALC283_FIXUP_CHROME_BOOK ),SND_PCI_QUIRK (0x1025 ,0x1099 ,"Acer Aspire E5-523G" ,ALC255_FIXUP_ACER_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1025 ,0x110e ,"Acer Aspire ES1-432" ,ALC255_FIXUP_ACER_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1025 ,0x1166 ,"Acer Veriton N4640G" ,ALC269_FIXUP_LIFEBOOK ), +SND_PCI_QUIRK (0x1025 ,0x1167 ,"Acer Veriton N6640G" ,ALC269_FIXUP_LIFEBOOK ),SND_PCI_QUIRK (0x1025 ,0x1246 ,"Acer Predator Helios 500" ,ALC299_FIXUP_PREDATOR_SPK ),SND_PCI_QUIRK (0x1025 ,0x1247 ,"Acer vCopperbox" ,ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS ), SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 543/717 ALSA: hda/realtek: Add quirk for MSI-GP73
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 09926202e939fd699650ac0fc0baa5757e069390 upstream.
MSI-GP73 (with SSID 1462:1229) requires yet again ALC1220_FIXUP_CLEVO_P950 quirk like other MSI models.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -2516,6 +2516,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1458 ,0xa0ce ,"Gigabyte X570 Aorus Xtreme" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x11f7 ,"MSI-GE63" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x1228 ,"MSI-GP63" ,ALC1220_FIXUP_CLEVO_P950 ), +SND_PCI_QUIRK (0x1462 ,0x1229 ,"MSI-GP73" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x1275 ,"MSI-GL63" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x1276 ,"MSI-GL73" ,ALC1220_FIXUP_CLEVO_P950 ), SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Greg Kroah-Hartman
maintainerPATCH 544/717 ALSA: hda/realtek: Apply jack fixup for Quanta NL3
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
commit 6ca653e3f73a1af0f30dbf9c2c79d2897074989f upstream.
The Quanta NL3 laptop has both a headphone output jack and a headset jack, on the right edge of the chassis.
The pin information suggests that both of these are at the Front. The PulseAudio is confused to differentiate them so one of the jack can neither get the jack sense working nor the audio output.
The ALC269_FIXUP_LIFEBOOK chained with ALC269_FIXUP_QUANTA_MUTE can help to differentiate 2 jacks and get the 'Auto-Mute Mode' working correctly.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -8021,6 +8021,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1458 ,0xfa53 ,"Gigabyte BXBT-2807" ,ALC283_FIXUP_HEADSET_MIC ),SND_PCI_QUIRK (0x1462 ,0xb120 ,"MSI Cubi MS-B120" ,ALC283_FIXUP_HEADSET_MIC ),SND_PCI_QUIRK (0x1462 ,0xb171 ,"Cubi N 8GL (MS-B171)" ,ALC283_FIXUP_HEADSET_MIC ), +SND_PCI_QUIRK (0x152d ,0x1082 ,"Quanta NL3" ,ALC269_FIXUP_LIFEBOOK ),SND_PCI_QUIRK (0x1558 ,0x1323 ,"Clevo N130ZU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x1325 ,"System76 Darter Pro (darp5)" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 545/717 ALSA: hda/realtek: Remove dummy lineout on Acer TravelMate P648/P658
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
commit 34cdf405aa5de827b8bef79a6c82c39120b3729b upstream.
Acer TravelMate laptops P648/P658 series with codec ALC282 only have one physical jack for headset but there's a confusing lineout pin on NID 0x1b reported. Audio applications hence misunderstand that there are a speaker and a lineout, and take the lineout as the default audio output.
Add a new quirk to remove the useless lineout and enable the pin 0x18 for jack sensing and headset microphone.
--- sound/pci/hda/patch_realtek.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
sound/pci/hda/patch_realtek.c +27 -0
@@ -6369,6 +6369,7 @@ enum {ALC287_FIXUP_HP_GPIO_LED ,ALC256_FIXUP_HP_HEADSET_MIC ,ALC236_FIXUP_DELL_AIO_HEADSET_MIC , + ALC282_FIXUP_ACER_DISABLE_LINEOUT, }; static const struct hda_fixup alc269_fixups[] = {
@@ -7792,6 +7793,16 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id =ALC255_FIXUP_DELL1_MIC_NO_PRESENCE }, + [ALC282_FIXUP_ACER_DISABLE_LINEOUT] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl []) { + {0x1b ,0x411111f0 }, + {0x18 ,0x01a1913c },/* use as headset mic, without its own jack detect */ + { }, + }, + .chained = true, + .chain_id =ALC269_FIXUP_HEADSET_MODE + }, };static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8569,6 +8580,22 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60140}, {0x19, 0x04a11030}, {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0282, 0x1025, "Acer", ALC282_FIXUP_ACER_DISABLE_LINEOUT, + ALC282_STANDARD_PINS, + {0x12, 0x90a609c0}, + {0x18, 0x03a11830}, + {0x19, 0x04a19831}, + {0x1a, 0x0481303f}, + {0x1b, 0x04211020}, + {0x21, 0x0321101f}), + SND_HDA_PIN_QUIRK(0x10ec0282, 0x1025, "Acer", ALC282_FIXUP_ACER_DISABLE_LINEOUT, + ALC282_STANDARD_PINS, + {0x12, 0x90a60940}, + {0x18, 0x03a11830}, + {0x19, 0x04a19831}, + {0x1a, 0x0481303f}, + {0x1b, 0x04211020}, + {0x21, 0x0321101f}), SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, ALC282_STANDARD_PINS, {0x12, 0x90a60130},
Greg Kroah-Hartman
maintainerPATCH 546/717 ALSA: hda/realtek - Supported Dell fixed type headset
In reply to Greg Kroah-HartmanFrom: Kailang Yang <[email protected]>
commit 150927c3674d7db4dd51a7269e01423c8c78e53b upstream.
This platform only supported iphone type headset.
It can't support Dell headset mode.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -7885,6 +7885,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1028 ,0x09bf ,"Dell Precision" ,ALC233_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x0a2e ,"Dell" ,ALC236_FIXUP_DELL_AIO_HEADSET_MIC ),SND_PCI_QUIRK (0x1028 ,0x0a30 ,"Dell" ,ALC236_FIXUP_DELL_AIO_HEADSET_MIC ), +SND_PCI_QUIRK (0x1028 ,0x0a58 ,"Dell Precision 3650 Tower" ,ALC255_FIXUP_DELL_HEADSET_MIC ),SND_PCI_QUIRK (0x1028 ,0x164a ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x164b ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Greg Kroah-Hartman
maintainerPATCH 547/717 ALSA: usb-audio: Add VID to support native DSD reproduction on FiiO devices
In reply to Greg Kroah-HartmanFrom: Amadej Kastelic <[email protected]>
commit 725124d10d00b2f56bb5bd08b431cc74ab3b3ace upstream.
Add VID to support native DSD reproduction on FiiO devices.
--- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+)
sound/usb/quirks.c +1 -0
@@ -1799,6 +1799,7 @@ u64 snd_usb_interface_dsd_format_quirks(case 0x25ce :/* Mytek devices */ case 0x278b :/* Rotel? */ case 0x292b :/* Gustard/Ess based devices */ +case 0x2972 :/* FiiO devices */ case 0x2ab6 :/* T+A devices */ case 0x3353 :/* Khadas devices */ case 0x3842 :/* EVGA */
Greg Kroah-Hartman
maintainerPATCH 548/717 ALSA: usb-audio: Disable sample read check if firmware doesnt give back
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 9df28edce7c6ab38050235f6f8b43dd7ccd01b6d upstream.
Some buggy firmware don't give the current sample rate but leaves zero. Handle this case more gracefully without warning but just skip the current rate verification from the next time.
--- sound/usb/clock.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/usb/clock.c +6 -0
@@ -531,6 +531,12 @@ static int set_sample_rate_v1(struct snd } crate = data[0 ] | (data[1 ] <<8 ) | (data[2 ] <<16 ); +if (!crate) { +dev_info (&dev->dev,"failed to read current rate; disabling the check\n" ); + chip->sample_rate_read_error =3 ;/* three strikes, see above */ +return 0 ; + } +if (crate != rate) {dev_warn (&dev->dev,"current rate %d is different from the runtime rate %d\n" , crate, rate);// runtime->rate = crate;
Greg Kroah-Hartman
maintainerPATCH 549/717 ALSA: usb-audio: Add alias entry for ASUS PRIME TRX40 PRO-S
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 525d9c57d0eeeb660d9b25e5b2d1c95975e3ba95 upstream.
ASUS PRIME TRX40 PRO-S mobo with 0b05:1918 needs the same quirk alias for another ASUS mobo (0b05:1917) for the proper mixer mapping, etc. Add the corresponding entry.
--- sound/usb/card.c | 3 +++ 1 file changed, 3 insertions(+)
sound/usb/card.c +3 -0
@@ -382,6 +382,9 @@ static const struct usb_audio_device_nam/* ASUS ROG Strix */ PROFILE_NAME (0x0b05 ,0x1917 ,"Realtek" ,"ALC1220-VB-DT" ,"Realtek-ALC1220-VB-Desktop" ), +/* ASUS PRIME TRX40 PRO-S */ +PROFILE_NAME (0x0b05 ,0x1918 , +"Realtek" ,"ALC1220-VB-DT" ,"Realtek-ALC1220-VB-Desktop" ),/* Dell WD15 Dock */ PROFILE_NAME(0x0bda, 0x4014, "Dell", "WD15 Dock", "Dell-WD15-Dock"),
Greg Kroah-Hartman
maintainerPATCH 550/717 ALSA: core: memalloc: add page alignment for iram
In reply to Greg Kroah-HartmanFrom: Robin Gong <[email protected]>
commit 74c64efa1557fef731b59eb813f115436d18078e upstream.
Since mmap for userspace is based on page alignment, add page alignment for iram alloc from pool, otherwise, some good data located in the same page of dmab->area maybe touched wrongly by userspace like pulseaudio.
--- sound/core/memalloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/core/memalloc.c +2 -1
@@ -77,7 +77,8 @@ static void snd_malloc_dev_iram(struct s/* Assign the pool into private_data field */ dmab->private_data = pool; - dmab->area =gen_pool_dma_alloc (pool, size, &dmab->addr); + dmab->area =gen_pool_dma_alloc_align (pool, size, &dmab->addr, +PAGE_SIZE ); }/**
Greg Kroah-Hartman
maintainerPATCH 551/717 s390/smp: perform initial CPU reset also for SMT siblings
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
commit b5e438ebd7e808d1d2435159ac4742e01a94b8da upstream.
Not resetting the SMT siblings might leave them in unpredictable state. One of the observed problems was that the CPU timer wasn't reset and therefore large system time values where accounted during CPU bringup.
--- arch/s390/kernel/smp.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
arch/s390/kernel/smp.c +3 -15
@@ -896,24 +896,12 @@ static void __no_sanitize_address smp_st/* Upping and downing of CPUs */ int __cpu_up (unsigned int cpu,struct task_struct *tidle) { -struct pcpu *pcpu; -int base, i, rc; +struct pcpu *pcpu = pcpu_devices + cpu; +int rc; - pcpu = pcpu_devices + cpu;if (pcpu->state !=CPU_STATE_CONFIGURED )return -EIO ; - base =smp_get_base_cpu (cpu); -for (i =0 ; i <= smp_cpu_mtid; i++) { -if (base + i < nr_cpu_ids) -if (cpu_online (base + i)) -break ; - } -/* -* If this is the first CPU of the core to get online -* do an initial CPU reset. -*/ -if (i > smp_cpu_mtid && -pcpu_sigp_retry (pcpu_devices + base,SIGP_INITIAL_CPU_RESET ,0 ) != +if (pcpu_sigp_retry (pcpu,SIGP_INITIAL_CPU_RESET ,0 ) !=SIGP_CC_ORDER_CODE_ACCEPTED )return -EIO ;
Greg Kroah-Hartman
maintainerPATCH 552/717 s390/kexec_file: fix diag308 subcode when loading crash kernel
In reply to Greg Kroah-HartmanFrom: Philipp Rudo <[email protected]>
commit 613775d62ec60202f98d2c5f520e6e9ba6dd4ac4 upstream.
diag308 subcode 0 performes a clear reset which inlcudes the reset of all registers in the system. While this is the preferred behavior when loading a normal kernel via kexec it prevents the crash kernel to store the register values in the dump. To prevent this use subcode 1 when loading a crash kernel instead.
--- arch/s390/purgatory/head.S | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/s390/purgatory/head.S +5 -4
@@ -62,14 +62,15 @@ jh 10b .endm -.macro START_NEXT_KERNEL base +.macro START_NEXT_KERNEL base subcode lg %r4,kernel_entry-\base(%r13) lg %r5,load_psw_mask-\base(%r13) ogr %r4,%r5 stg %r4,0(%r0) xgr %r0,%r0 - diag %r0,%r0,0x308 + lghi %r1,\subcode + diag %r0,%r1,0x308 .endm .text
@@ -123,7 +124,7 @@ ENTRY(purgatory_start) je .start_crash_kernel /* start normal kernel */ - START_NEXT_KERNEL .base_crash + START_NEXT_KERNEL .base_crash 0 .return_old_kernel: lmg %r6,%r15,gprregs-.base_crash(%r13)
@@ -227,7 +228,7 @@ ENTRY(purgatory_start) MEMCPY %r9,%r10,%r11 /* start crash kernel */ - START_NEXT_KERNEL .base_dst + START_NEXT_KERNEL .base_dst 1 load_psw_mask:
Greg Kroah-Hartman
maintainerPATCH 553/717 s390/idle: add missing mt_cycles calculation
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
commit e259b3fafa7de362b04ecd86e7fa9a9e9273e5fb upstream.
During removal of the critical section cleanup the calculation of mt_cycles during idle was removed. This causes invalid accounting on systems with SMT enabled.
--- arch/s390/kernel/entry.S | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-)
arch/s390/kernel/entry.S +25 -9
@@ -112,7 +112,7 @@ _LPP_OFFSET = __LC_LPP .macro SWITCH_ASYNC savearea,timer tmhh %r8,0x0001 # interrupting from user ? - jnz 2f + jnz 4f #if IS_ENABLED(CONFIG_KVM) lgr %r14,%r9 larl %r13,.Lsie_gmap
@@ -125,9 +125,25 @@ _LPP_OFFSET = __LC_LPP #endif 0: larl %r13,.Lpsw_idle_exit cgr %r13,%r9 - jne 1f + jne 3f - mvc __CLOCK_IDLE_EXIT(8,%r2), __LC_INT_CLOCK + larl %r1,smp_cpu_mtid + llgf %r1,0(%r1) + ltgr %r1,%r1 + jz 2f # no SMT, skip mt_cycles calculation + .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15) + larl %r3,mt_cycles + ag %r3,__LC_PERCPU_OFFSET + la %r4,__SF_EMPTY+16(%r15) +1: lg %r0,0(%r3) + slg %r0,0(%r4) + alg %r0,64(%r4) + stg %r0,0(%r3) + la %r3,8(%r3) + la %r4,8(%r4) + brct %r1,1b + +2: mvc __CLOCK_IDLE_EXIT(8,%r2), __LC_INT_CLOCK mvc __TIMER_IDLE_EXIT(8,%r2), __LC_ASYNC_ENTER_TIMER # account system time going idle ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
@@ -146,17 +162,17 @@ _LPP_OFFSET = __LC_LPP mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) nihh %r8,0xfcfd # clear wait state and irq bits -1: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? +3: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? slgr %r14,%r15 srag %r14,%r14,STACK_SHIFT - jnz 3f + jnz 5f CHECK_STACK \savearea aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) - j 4f -2: UPDATE_VTIME %r14,%r15,\timer + j 6f +4: UPDATE_VTIME %r14,%r15,\timer BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP -3: lg %r15,__LC_ASYNC_STACK # load async stack -4: la %r11,STACK_FRAME_OVERHEAD(%r15) +5: lg %r15,__LC_ASYNC_STACK # load async stack +6: la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro UPDATE_VTIME w1,w2,enter_timer
Greg Kroah-Hartman
maintainerPATCH 554/717 s390/idle: fix accounting with machine checks
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
commit 454efcf82ea17d7efeb86ebaa20775a21ec87d27 upstream.
When a machine check interrupt is triggered during idle, the code is using the async timer/clock for idle time calculation. It should use the machine check enter timer/clock which is passed to the macro.
--- arch/s390/kernel/entry.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/s390/kernel/entry.S +6 -6
@@ -110,7 +110,7 @@ _LPP_OFFSET = __LC_LPP #endif .endm - .macro SWITCH_ASYNC savearea,timer + .macro SWITCH_ASYNC savearea,timer,clock tmhh %r8,0x0001 # interrupting from user ? jnz 4f #if IS_ENABLED(CONFIG_KVM)
@@ -143,8 +143,8 @@ _LPP_OFFSET = __LC_LPP la %r4,8(%r4) brct %r1,1b -2: mvc __CLOCK_IDLE_EXIT(8,%r2), __LC_INT_CLOCK - mvc __TIMER_IDLE_EXIT(8,%r2), __LC_ASYNC_ENTER_TIMER +2: mvc __CLOCK_IDLE_EXIT(8,%r2), \clock + mvc __TIMER_IDLE_EXIT(8,%r2), \timer # account system time going idle ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
@@ -761,7 +761,7 @@ ENTRY(io_int_handler) stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r12,__LC_CURRENT lmg %r8,%r9,__LC_IO_OLD_PSW - SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER + SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER,__LC_INT_CLOCK stmg %r0,%r7,__PT_R0(%r11) # clear user controlled registers to prevent speculative use xgr %r0,%r0
@@ -961,7 +961,7 @@ ENTRY(ext_int_handler) stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r12,__LC_CURRENT lmg %r8,%r9,__LC_EXT_OLD_PSW - SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER + SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER,__LC_INT_CLOCK stmg %r0,%r7,__PT_R0(%r11) # clear user controlled registers to prevent speculative use xgr %r0,%r0
@@ -1183,7 +1183,7 @@ ENTRY(mcck_int_handler) TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID jno .Lmcck_panic 4: ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off - SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER + SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER,__LC_MCCK_CLOCK .Lmcck_skip: lghi %r14,__LC_GPREGS_SAVE_AREA+64 stmg %r0,%r7,__PT_R0(%r11)
Greg Kroah-Hartman
maintainerPATCH 555/717 s390/dasd: fix hanging device offline processing
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 658a337a606f48b7ebe451591f7681d383fa115e upstream.
For an LCU update a read unit address configuration IO is required. This is started using sleep_on(), which has early exit paths in case the device is not usable for IO. For example when it is in offline processing.
In those cases the LCU update should fail and not be retried. Therefore lcu_update_work checks if EOPNOTSUPP is returned or not.
Commit 41995342b40c ("s390/dasd: fix endless loop after read unit address configuration") accidentally removed the EOPNOTSUPP return code from read_unit_address_configuration(), which in turn might lead to an endless loop of the LCU update in offline processing.
Fix by returning EOPNOTSUPP again if the device is not able to perform the request.
--- drivers/s390/block/dasd_alias.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/s390/block/dasd_alias.c +9 -1
@@ -462,11 +462,19 @@ static int read_unit_address_configuratispin_unlock_irqrestore (&lcu->lock, flags); rc =dasd_sleep_on (cqr); -if (rc && !suborder_not_supported (cqr)) { +if (!rc) + goto out; + +if (suborder_not_supported (cqr)) { +/* suborder not supported or device unusable for IO */ + rc = -EOPNOTSUPP ; + }else { +/* IO failed but should be retried */ spin_lock_irqsave (&lcu->lock, flags); lcu->flags |=NEED_UAC_UPDATE ;spin_unlock_irqrestore (&lcu->lock, flags); } +out:dasd_sfree_request (cqr, cqr->memdev);return rc; }
Greg Kroah-Hartman
maintainerPATCH 556/717 s390/dasd: prevent inconsistent LCU device data
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit a29ea01653493b94ea12bb2b89d1564a265081b6 upstream.
Prevent _lcu_update from adding a device to a pavgroup if the LCU still requires an update. The data is not reliable any longer and in parallel devices might have been moved on the lists already.
This might lead to list corruptions or invalid PAV grouping. Only add devices to a pavgroup if the LCU is up to date. Additional steps are taken by the scheduled lcu update.
--- drivers/s390/block/dasd_alias.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/s390/block/dasd_alias.c +9 -0
@@ -511,6 +511,14 @@ static int _lcu_update(struct dasd_devicreturn rc;spin_lock_irqsave (&lcu->lock, flags); +/* +* there is another update needed skip the remaining handling +* the data might already be outdated +* but especially do not add the device to an LCU with pending +* update +*/ +if (lcu->flags &NEED_UAC_UPDATE ) + goto out; lcu->pav =NO_PAV ;for (i =0 ; i <MAX_DEVICES_PER_LCU ; ++i) {switch (lcu->uac->unit[i].ua_type) {
@@ -529,6 +537,7 @@ static int _lcu_update(struct dasd_devic alias_list) {_add_device_to_lcu (lcu, device, refdev); } +out:spin_unlock_irqrestore (&lcu->lock, flags);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 557/717 s390/dasd: fix list corruption of pavgroup group list
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 0ede91f83aa335da1c3ec68eb0f9e228f269f6d8 upstream.
dasd_alias_add_device() moves devices to the active_devices list in case of a scheduled LCU update regardless if they have previously been in a pavgroup or not.
Example: device A and B are in the same pavgroup.
Device A has already been in a pavgroup and the private->pavgroup pointer is set and points to a valid pavgroup. While going through dasd_add_device it is moved from the pavgroup to the active_devices list.
In parallel device B might be removed from the same pavgroup in remove_device_from_lcu() which in turn checks if the group is empty and deletes it accordingly because device A has already been removed from there.
When now device A enters remove_device_from_lcu() it is tried to remove it from the pavgroup again because the pavgroup pointer is still set and again the empty group will be cleaned up which leads to a list corruption.
Fix by setting private->pavgroup to NULL in dasd_add_device.
If the device has been the last device on the pavgroup an empty pavgroup remains but this will be cleaned up by the scheduled lcu_update which iterates over all existing pavgroups.
--- drivers/s390/block/dasd_alias.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/block/dasd_alias.c +1 -0
@@ -642,6 +642,7 @@ int dasd_alias_add_device(struct dasd_de }if (lcu->flags &UPDATE_PENDING ) {list_move (&device->alias_list, &lcu->active_devices); + private->pavgroup =NULL ;_schedule_lcu_update (lcu, device); }spin_unlock_irqrestore (&lcu->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 558/717 s390/dasd: fix list corruption of lcu list
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 53a7f655834c7c335bf683f248208d4fbe4b47bc upstream.
In dasd_alias_disconnect_device_from_lcu the device is removed from any list on the LCU. Afterwards the LCU is removed from the lcu list if it does not contain devices any longer.
The lcu->lock protects the lcu from parallel updates. But to cancel all workers and wait for completion the lcu->lock has to be unlocked.
If two devices are removed in parallel and both are removed from the LCU the first device that takes the lcu->lock again will delete the LCU because it is already empty but the second device also tries to free the LCU which leads to a list corruption of the lcu list.
Fix by removing the device right before the lcu is checked without unlocking the lcu->lock in between.
--- drivers/s390/block/dasd_alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_alias.c +1 -1
@@ -256,7 +256,6 @@ void dasd_alias_disconnect_device_from_lreturn ; device->discipline->get_uid (device, &uid);spin_lock_irqsave (&lcu->lock, flags); -list_del_init (&device->alias_list);/* make sure that the workers don't use this device */ if (device == lcu->suc_data.device) {spin_unlock_irqrestore (&lcu->lock, flags);
@@ -283,6 +282,7 @@ void dasd_alias_disconnect_device_from_lspin_lock_irqsave (&aliastree.lock, flags);spin_lock (&lcu->lock); +list_del_init (&device->alias_list);if (list_empty (&lcu->grouplist) &&list_empty (&lcu->active_devices) &&list_empty (&lcu->inactive_devices)) {
Greg Kroah-Hartman
maintainerPATCH 559/717 binder: add flag to clear buffer on txn complete
In reply to Greg Kroah-HartmanFrom: Todd Kjos <[email protected]>
commit 0f966cba95c78029f491b433ea95ff38f414a761 upstream.
Add a per-transaction flag to indicate that the buffer must be cleared when the transaction is complete to prevent copies of sensitive data from being preserved in memory.
--- drivers/android/binder.c | 1 drivers/android/binder_alloc.c | 48 ++++++++++++++++++++++++++++++++++++ drivers/android/binder_alloc.h | 4 ++- include/uapi/linux/android/binder.h | 1 4 files changed, 53 insertions(+), 1 deletion(-)
drivers/android/binder.c +1 -0
@@ -3146,6 +3146,7 @@ static void binder_transaction(struct bi t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; + t->buffer->clear_on_free = !!(t->flags &TF_CLEAR_BUF );trace_binder_transaction_alloc_buf (t->buffer); if (binder_alloc_copy_user_to_buffer(
drivers/android/binder_alloc.c +48 -0
72 lines not on this page · raw message
drivers/android/binder_alloc.h +3 -1
@@ -23,6 +23,7 @@ struct binder_transaction;* @entry: entry alloc->buffers * @rb_node: node for allocated_buffers/free_buffers rb trees * @free: %true if buffer is free +* @clear_on_free: %true if buffer must be zeroed after use * @allow_user_free: %true if user is allowed to free buffer * @async_transaction: %true if buffer is in use for an async txn * @debug_id: unique ID for debugging
@@ -41,9 +42,10 @@ struct binder_buffer {struct rb_node rb_node;/* free entry by size or allocated entry */ /* by address */ unsigned free:1; + unsigned clear_on_free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned debug_id:29; + unsigned debug_id:28;struct binder_transaction *transaction;
include/uapi/linux/android/binder.h +1 -0
@@ -248,6 +248,7 @@ enum transaction_flags {TF_ROOT_OBJECT =0x04 ,/* contents are the component's root object */ TF_STATUS_CODE =0x08 ,/* contents are a 32-bit status code */ TF_ACCEPT_FDS =0x10 ,/* allow replies with file descriptors */ + TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */ }; struct binder_transaction_data {
Greg Kroah-Hartman
maintainerPATCH 560/717 ASoC: cx2072x: Fix doubly definitions of Playback and Capture streams
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 0d024a8bec084205fdd9fa17479ba91f45f85db3 upstream.
The cx2072x codec driver defines multiple DAIs with the same stream name "Playback" and "Capture". Although the current code works more or less as is as the secondary streams are never used, it still leads the error message like:
debugfs: File 'Playback' in directory 'dapm' already present!
debugfs: File 'Capture' in directory 'dapm' already present!
Fix it by renaming the secondary streams to unique names.
--- sound/soc/codecs/cx2072x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/cx2072x.c +2 -2
@@ -1579,7 +1579,7 @@ static struct snd_soc_dai_driver soc_cod .id = CX2072X_DAI_DSP, .probe = cx2072x_dsp_dai_probe, .playback = { - .stream_name = "Playback", + .stream_name = "DSP Playback", .channels_min = 2, .channels_max = 2, .rates = CX2072X_RATES_DSP,
@@ -1591,7 +1591,7 @@ static struct snd_soc_dai_driver soc_cod .name = "cx2072x-aec", .id = 3, .capture = { - .stream_name = "Capture", + .stream_name = "AEC Capture", .channels_min = 2, .channels_max = 2, .rates = CX2072X_RATES_DSP,
Greg Kroah-Hartman
maintainerPATCH 561/717 ASoC: AMD Renoir - add DMI table to avoid the ACP mic probe (broken BIOS)
In reply to Greg Kroah-HartmanFrom: Jaroslav Kysela <[email protected]>
commit 718c406e1ffaca4eac987b957bbb36ce1090797a upstream.
Users reported that some Lenovo AMD platforms do not have ACP microphone, but the BIOS advertises it via ACPI.
This patch create a simple DMI table, where those machines with the broken BIOS can be added. The DMI description for Lenovo IdeaPad 5 and IdeaPad Flex 5 devices are added there.
Also describe the dmic_acpi_check kernel module parameter in a more understandable way.
--- sound/soc/amd/renoir/rn-pci-acp3x.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
sound/soc/amd/renoir/rn-pci-acp3x.c +23 -5
@@ -6,6 +6,7 @@#include <linux/pci.h> #include <linux/acpi.h> +#include <linux/dmi.h> #include <linux/module.h> #include <linux/io.h> #include <linux/delay.h>
@@ -20,14 +21,13 @@ module_param(acp_power_gating, int, 0644MODULE_PARM_DESC (acp_power_gating,"Enable acp power gating" );/** -* dmic_acpi_check = -1 - Checks ACPI method to know DMIC hardware status runtime -* = 0 - Skips the DMIC device creation and returns probe failure -* = 1 - Assumes that platform has DMIC support and skips ACPI -* method check +* dmic_acpi_check = -1 - Use ACPI/DMI method to detect the DMIC hardware presence at runtime +* = 0 - Skip the DMIC device creation and return probe failure +* = 1 - Force DMIC support */ static int dmic_acpi_check =ACP_DMIC_AUTO ;module_param (dmic_acpi_check, bint,0644 ); -MODULE_PARM_DESC (dmic_acpi_check,"checks Dmic hardware runtime" ); +MODULE_PARM_DESC (dmic_acpi_check,"Digital microphone presence (-1=auto, 0=none, 1=force)" );struct acp_dev_data {void __iomem *acp_base;
@@ -163,6 +163,17 @@ static int rn_acp_deinit(void __iomem *areturn 0 ; } +static const struct dmi_system_id rn_acp_quirk_table[] = { + { +/* Lenovo IdeaPad Flex 5 14ARE05, IdeaPad 5 15ARE05 */ + .matches = { +DMI_EXACT_MATCH (DMI_BOARD_VENDOR ,"LENOVO" ), +DMI_EXACT_MATCH (DMI_BOARD_NAME ,"LNVNB161216" ), + } + }, + {} +}; +static int snd_rn_acp_probe (struct pci_dev *pci,const struct pci_device_id *pci_id) {
@@ -172,6 +183,7 @@ static int snd_rn_acp_probe(struct pci_dacpi_handle handle;acpi_integer dmic_status;#endif +const struct dmi_system_id *dmi_id;unsigned int irqflags;int ret, index;u32 addr;
@@ -232,6 +244,12 @@ static int snd_rn_acp_probe(struct pci_d goto de_init; }#endif + dmi_id =dmi_first_match (rn_acp_quirk_table); +if (dmi_id && !dmi_id->driver_data) { +dev_info (&pci->dev,"ACPI settings override using DMI (ACP mic is not present)" ); + ret = -ENODEV ; + goto de_init; + } } adata->res = devm_kzalloc(&pci->dev,
Greg Kroah-Hartman
maintainerPATCH 562/717 ASoC: AMD Raven/Renoir - fix the PCI probe (PCI revision)
In reply to Greg Kroah-HartmanFrom: Jaroslav Kysela <[email protected]>
commit 55d8e6a85bce21f748c42eedea63681219f70523 upstream.
The Raven and Renoir ACP can be distinguished by the PCI revision. Let's do the check very early, otherwise the wrong probe code can be run.
--- sound/soc/amd/raven/pci-acp3x.c | 4 ++++ sound/soc/amd/renoir/rn-pci-acp3x.c | 4 ++++ 2 files changed, 8 insertions(+)
sound/soc/amd/raven/pci-acp3x.c +4 -0
@@ -118,6 +118,10 @@ static int snd_acp3x_probe(struct pci_deint ret, i;u32 addr, val; +/* Raven device detection */ +if (pci->revision !=0x00 ) +return -ENODEV ; +if (pci_enable_device (pci)) {dev_err (&pci->dev,"pci_enable_device failed\n" );return -ENODEV ;
sound/soc/amd/renoir/rn-pci-acp3x.c +4 -0
@@ -188,6 +188,10 @@ static int snd_rn_acp_probe(struct pci_dint ret, index;u32 addr; +/* Renoir device check */ +if (pci->revision !=0x01 ) +return -ENODEV ; +if (pci_enable_device (pci)) {dev_err (&pci->dev,"pci_enable_device failed\n" );return -ENODEV ;
Greg Kroah-Hartman
maintainerPATCH 563/717 staging: comedi: mf6x4: Fix AI end-of-conversion detection
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
commit 56c90457ebfe9422496aac6ef3d3f0f0ea8b2ec2 upstream.
I have had reports from two different people that attempts to read the analog input channels of the MF624 board fail with an ETIMEDOUT error.
After triggering the conversion, the code calls comedi_timeout() with mf6x4_ai_eoc() as the callback function to check if the conversion is complete. The callback returns 0 if complete or -EBUSY if not yet complete. comedi_timeout() returns -ETIMEDOUT if it has not completed within a timeout period which is propagated as an error to the user application.
The existing code considers the conversion to be complete when the EOLC bit is high. However, according to the user manuals for the MF624 and MF634 boards, this test is incorrect because EOLC is an active low signal that goes high when the conversion is triggered, and goes low when the conversion is complete. Fix the problem by inverting the test of the EOLC bit state.
--- drivers/staging/comedi/drivers/mf6x4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/comedi/drivers/mf6x4.c +2 -1
@@ -112,8 +112,9 @@ static int mf6x4_ai_eoc(struct comedi_destruct mf6x4_private *devpriv = dev->private;unsigned int status; +/* EOLC goes low at end of conversion. */ status =ioread32 (devpriv->gpioc_reg); -if (status &MF6X4_GPIOC_EOLC ) +if ((status &MF6X4_GPIOC_EOLC ) ==0 )return 0 ;return -EBUSY ; }
Greg Kroah-Hartman
maintainerPATCH 564/717 z3fold: simplify freeing slots
In reply to Greg Kroah-HartmanFrom: Vitaly Wool <[email protected]>
commit fc5488651c7d840c9cad9b0f273f2f31bd03413a upstream.
Patch series "z3fold: stability / rt fixes".
Address z3fold stability issues under stress load, primarily in the reclaim and free aspects. Besides, it fixes the locking problems that were only seen in real-time kernel configuration.
This patch (of 3):
There used to be two places in the code where slots could be freed, namely when freeing the last allocated handle from the slots and when releasing the z3fold header these slots aree linked to. The logic to decide on whether to free certain slots was complicated and error prone in both functions and it led to failures in RT case.
To fix that, make free_handle() the single point of freeing slots.
--- mm/z3fold.c | 55 +++++++++++++------------------------------------------ 1 file changed, 13 insertions(+), 42 deletions(-)
mm/z3fold.c +13 -42
@@ -90,7 +90,7 @@ struct z3fold_buddy_slots {* be enough slots to hold all possible variants */ unsigned long slot[BUDDY_MASK +1 ]; -unsigned long pool;/* back link + flags */ +unsigned long pool;/* back link */ rwlock_t lock; };#define HANDLE_FLAG_MASK (0x03)
@@ -182,13 +182,6 @@ enum z3fold_page_flags { };/* -* handle flags, go under HANDLE_FLAG_MASK -*/ -enum z3fold_handle_flags { -HANDLES_ORPHANED =0 , -}; - -/* * Forward declarations */ static struct z3fold_header *__z3fold_alloc (struct z3fold_pool *,size_t ,bool );
@@ -303,10 +296,9 @@ static inline void put_z3fold_header(strz3fold_page_unlock (zhdr); } -static inline void free_handle (unsigned long handle) +static inline void free_handle (unsigned long handle,struct z3fold_header *zhdr) {struct z3fold_buddy_slots *slots; -struct z3fold_header *zhdr;int i;bool is_free;
@@ -316,22 +308,13 @@ static inline void free_handle(unsignedif (WARN_ON (*(unsigned long *)handle ==0 ))return ; - zhdr =handle_to_z3fold_header (handle); slots =handle_to_slots (handle);write_lock (&slots->lock); *(unsigned long *)handle =0 ; -if (zhdr->slots == slots) { -write_unlock (&slots->lock); -return ;/* simple case, nothing else to do */ - } +if (zhdr->slots != slots) + zhdr->foreign_handles--; -/* we are freeing a foreign handle if we are here */ - zhdr->foreign_handles--; is_free = true; -if (!test_bit (HANDLES_ORPHANED , &slots->pool)) { -write_unlock (&slots->lock); -return ; - }for (i =0 ; i <=BUDDY_MASK ; i++) {if (slots->slot[i]) { is_free = false;
@@ -343,6 +326,8 @@ static inline void free_handle(unsignedif (is_free) {struct z3fold_pool *pool =slots_to_pool (slots); +if (zhdr->slots == slots) + zhdr->slots =NULL ;kmem_cache_free (pool->c_handle, slots); } }
@@ -525,8 +510,6 @@ static void __release_z3fold_page(struct {struct page *page =virt_to_page (zhdr);struct z3fold_pool *pool =zhdr_to_pool (zhdr); -bool is_free = true; -int i;WARN_ON (!list_empty (&zhdr->buddy));set_bit (PAGE_STALE , &page->private);
@@ -536,21 +519,6 @@ static void __release_z3fold_page(structlist_del_init (&page->lru);spin_unlock (&pool->lock); -/* If there are no foreign handles, free the handles array */ -read_lock (&zhdr->slots->lock); -for (i =0 ; i <=BUDDY_MASK ; i++) { -if (zhdr->slots->slot[i]) { - is_free = false; -break ; - } - } -if (!is_free) -set_bit (HANDLES_ORPHANED , &zhdr->slots->pool); -read_unlock (&zhdr->slots->lock); - -if (is_free) -kmem_cache_free (pool->c_handle, zhdr->slots); -if (locked)z3fold_page_unlock (zhdr);
@@ -973,6 +941,9 @@ lookup: } } +if (zhdr && !zhdr->slots) + zhdr->slots =alloc_slots (pool, + can_sleep ?GFP_NOIO :GFP_ATOMIC );return zhdr; }
@@ -1270,7 +1241,7 @@ static void z3fold_free(struct z3fold_po }if (!page_claimed) -free_handle (handle); +free_handle (handle, zhdr);if (kref_put (&zhdr->refcount, release_z3fold_page_locked_list)) {atomic64_dec (&pool->pages_nr);return ;
@@ -1429,19 +1400,19 @@ static int z3fold_reclaim_page(struct z3 ret = pool->ops->evict (pool, middle_handle);if (ret) goto next; -free_handle (middle_handle); +free_handle (middle_handle, zhdr); }if (first_handle) { ret = pool->ops->evict (pool, first_handle);if (ret) goto next; -free_handle (first_handle); +free_handle (first_handle, zhdr); }if (last_handle) { ret = pool->ops->evict (pool, last_handle);if (ret) goto next; -free_handle (last_handle); +free_handle (last_handle, zhdr); } next:if (test_bit (PAGE_HEADLESS , &page->private)) {
Greg Kroah-Hartman
maintainerPATCH 565/717 z3fold: stricter locking and more careful reclaim
In reply to Greg Kroah-HartmanFrom: Vitaly Wool <[email protected]>
commit dcf5aedb24f899d537e21c18ea552c780598d352 upstream.
Use temporary slots in reclaim function to avoid possible race when freeing those.
While at it, make sure we check CLAIMED flag under page lock in the reclaim function to make sure we are not racing with z3fold_alloc().
--- mm/z3fold.c | 143 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 58 deletions(-)
mm/z3fold.c +85 -58
@@ -182,6 +182,13 @@ enum z3fold_page_flags { };/* +* handle flags, go under HANDLE_FLAG_MASK +*/ +enum z3fold_handle_flags { +HANDLES_NOFREE =0 , +}; + +/* * Forward declarations */ static struct z3fold_header *__z3fold_alloc (struct z3fold_pool *,size_t ,bool );
@@ -311,6 +318,12 @@ static inline void free_handle(unsigned slots =handle_to_slots (handle);write_lock (&slots->lock); *(unsigned long *)handle =0 ; + +if (test_bit (HANDLES_NOFREE , &slots->pool)) { +write_unlock (&slots->lock); +return ;/* simple case, nothing else to do */ + } +if (zhdr->slots != slots) zhdr->foreign_handles--;
@@ -621,6 +634,28 @@ static inline void add_to_unbuddied(stru } } +static inline enum buddy get_free_buddy (struct z3fold_header *zhdr,int chunks) +{ +enum buddy bud =HEADLESS ; + +if (zhdr->middle_chunks) { +if (!zhdr->first_chunks && + chunks <= zhdr->start_middle -ZHDR_CHUNKS ) + bud =FIRST ; +else if (!zhdr->last_chunks) + bud =LAST ; + }else { +if (!zhdr->first_chunks) + bud =FIRST ; +else if (!zhdr->last_chunks) + bud =LAST ; +else + bud =MIDDLE ; + } + +return bud; +} +static inline void *mchunk_memmove (struct z3fold_header *zhdr,unsigned short dst_chunk) {
@@ -682,18 +717,7 @@ static struct z3fold_header *compact_sinif (WARN_ON (new_zhdr == zhdr)) goto out_fail; -if (new_zhdr->first_chunks ==0 ) { -if (new_zhdr->middle_chunks !=0 && - chunks >= new_zhdr->start_middle) { - new_bud =LAST ; - }else { - new_bud =FIRST ; - } - }else if (new_zhdr->last_chunks ==0 ) { - new_bud =LAST ; - }else if (new_zhdr->middle_chunks ==0 ) { - new_bud =MIDDLE ; - } + new_bud =get_free_buddy (new_zhdr, chunks); q = new_zhdr;switch (new_bud) {case FIRST :
@@ -815,9 +839,8 @@ static void do_compact_page(struct z3folreturn ; } -if (unlikely (PageIsolated (page) || -test_bit (PAGE_CLAIMED , &page->private) || -test_bit (PAGE_STALE , &page->private))) { +if (test_bit (PAGE_STALE , &page->private) || +test_and_set_bit (PAGE_CLAIMED , &page->private)) {z3fold_page_unlock (zhdr);return ; }
@@ -826,13 +849,16 @@ static void do_compact_page(struct z3fol zhdr->mapped_count == 0 && compact_single_buddy(zhdr)) {if (kref_put (&zhdr->refcount, release_z3fold_page_locked))atomic64_dec (&pool->pages_nr); -else +else { +clear_bit (PAGE_CLAIMED , &page->private);z3fold_page_unlock (zhdr); + }return ; }z3fold_compact_page (zhdr);add_to_unbuddied (pool, zhdr); +clear_bit (PAGE_CLAIMED , &page->private);z3fold_page_unlock (zhdr); }
@@ -1080,17 +1106,8 @@ static int z3fold_alloc(struct z3fold_po retry: zhdr =__z3fold_alloc (pool, size, can_sleep);if (zhdr) { -if (zhdr->first_chunks ==0 ) { -if (zhdr->middle_chunks !=0 && - chunks >= zhdr->start_middle) - bud =LAST ; -else - bud =FIRST ; - }else if (zhdr->last_chunks ==0 ) - bud =LAST ; -else if (zhdr->middle_chunks ==0 ) - bud =MIDDLE ; -else { + bud =get_free_buddy (zhdr, chunks); +if (bud ==HEADLESS ) {if (kref_put (&zhdr->refcount, release_z3fold_page_locked))atomic64_dec (&pool->pages_nr);
@@ -1236,7 +1253,6 @@ static void z3fold_free(struct z3fold_popr_err ("%s: unknown bud %d\n" , __func__, bud);WARN_ON (1 );put_z3fold_header (zhdr); -clear_bit (PAGE_CLAIMED , &page->private);return ; }
@@ -1251,8 +1267,7 @@ static void z3fold_free(struct z3fold_poz3fold_page_unlock (zhdr);return ; } -if (unlikely (PageIsolated (page)) || -test_and_set_bit (NEEDS_COMPACTING , &page->private)) { +if (test_and_set_bit (NEEDS_COMPACTING , &page->private)) {put_z3fold_header (zhdr);clear_bit (PAGE_CLAIMED , &page->private);return ;
@@ -1316,6 +1331,10 @@ static int z3fold_reclaim_page(struct z3struct page *page =NULL ;struct list_head *pos;unsigned long first_handle =0 , middle_handle =0 , last_handle =0 ; + struct z3fold_buddy_slots slots __attribute__((aligned(SLOTS_ALIGN))); + +rwlock_init (&slots.lock); + slots.pool = (unsigned long )pool | (1 <<HANDLES_NOFREE );spin_lock (&pool->lock);if (!pool->ops || !pool->ops->evict || retries ==0 ) {
@@ -1330,35 +1349,36 @@ static int z3fold_reclaim_page(struct z3list_for_each_prev (pos, &pool->lru) { page = list_entry(pos, struct page, lru); -/* this bit could have been set by free, in which case -* we pass over to the next page in the pool. -*/ -if (test_and_set_bit (PAGE_CLAIMED , &page->private)) { - page =NULL ; -continue ; - } - -if (unlikely (PageIsolated (page))) { -clear_bit (PAGE_CLAIMED , &page->private); - page =NULL ; -continue ; - } zhdr =page_address (page);if (test_bit (PAGE_HEADLESS , &page->private))break ; +if (kref_get_unless_zero (&zhdr->refcount) ==0 ) { + zhdr =NULL ; +break ; + }if (!z3fold_page_trylock (zhdr)) { -clear_bit (PAGE_CLAIMED , &page->private); +if (kref_put (&zhdr->refcount, + release_z3fold_page)) +atomic64_dec (&pool->pages_nr); zhdr =NULL ;continue ;/* can't evict at this point */ } -if (zhdr->foreign_handles) { -clear_bit (PAGE_CLAIMED , &page->private); -z3fold_page_unlock (zhdr); + +/* test_and_set_bit is of course atomic, but we still +* need to do it under page lock, otherwise checking +* that bit in __z3fold_alloc wouldn't make sense +*/ +if (zhdr->foreign_handles || +test_and_set_bit (PAGE_CLAIMED , &page->private)) { +if (kref_put (&zhdr->refcount, + release_z3fold_page)) +atomic64_dec (&pool->pages_nr); +else +z3fold_page_unlock (zhdr); zhdr =NULL ;continue ;/* can't evict such page */ } -kref_get (&zhdr->refcount);list_del_init (&zhdr->buddy); zhdr->cpu =-1 ;break ;
@@ -1380,12 +1400,16 @@ static int z3fold_reclaim_page(struct z3 first_handle =0 ; last_handle =0 ; middle_handle =0 ; +memset (slots.slot,0 ,sizeof (slots.slot));if (zhdr->first_chunks) - first_handle =encode_handle (zhdr,FIRST ); + first_handle =__encode_handle (zhdr, &slots, +FIRST );if (zhdr->middle_chunks) - middle_handle =encode_handle (zhdr,MIDDLE ); + middle_handle =__encode_handle (zhdr, &slots, +MIDDLE );if (zhdr->last_chunks) - last_handle =encode_handle (zhdr,LAST ); + last_handle =__encode_handle (zhdr, &slots, +LAST );/* * it's safe to unlock here because we hold a * reference to this page
@@ -1400,19 +1424,16 @@ static int z3fold_reclaim_page(struct z3 ret = pool->ops->evict (pool, middle_handle);if (ret) goto next; -free_handle (middle_handle, zhdr); }if (first_handle) { ret = pool->ops->evict (pool, first_handle);if (ret) goto next; -free_handle (first_handle, zhdr); }if (last_handle) { ret = pool->ops->evict (pool, last_handle);if (ret) goto next; -free_handle (last_handle, zhdr); } next:if (test_bit (PAGE_HEADLESS , &page->private)) {
@@ -1426,9 +1447,11 @@ next:spin_unlock (&pool->lock);clear_bit (PAGE_CLAIMED , &page->private); }else { +struct z3fold_buddy_slots *slots = zhdr->slots;z3fold_page_lock (zhdr);if (kref_put (&zhdr->refcount, release_z3fold_page_locked)) { +kmem_cache_free (pool->c_handle, slots);atomic64_dec (&pool->pages_nr);return 0 ; }
@@ -1544,8 +1567,7 @@ static bool z3fold_page_isolate(struct pVM_BUG_ON_PAGE (!PageMovable (page), page);VM_BUG_ON_PAGE (PageIsolated (page), page); -if (test_bit (PAGE_HEADLESS , &page->private) || -test_bit (PAGE_CLAIMED , &page->private)) +if (test_bit (PAGE_HEADLESS , &page->private))return false; zhdr =page_address (page);
@@ -1557,6 +1579,8 @@ static bool z3fold_page_isolate(struct pif (zhdr->mapped_count !=0 || zhdr->foreign_handles !=0 ) goto out; +if (test_and_set_bit (PAGE_CLAIMED , &page->private)) + goto out; pool =zhdr_to_pool (zhdr);spin_lock (&pool->lock);if (!list_empty (&zhdr->buddy))
@@ -1583,16 +1607,17 @@ static int z3fold_page_migrate(struct adVM_BUG_ON_PAGE (!PageMovable (page), page);VM_BUG_ON_PAGE (!PageIsolated (page), page); +VM_BUG_ON_PAGE (!test_bit (PAGE_CLAIMED , &page->private), page);VM_BUG_ON_PAGE (!PageLocked (newpage), newpage); zhdr =page_address (page); pool =zhdr_to_pool (zhdr); -if (!z3fold_page_trylock (zhdr)) { +if (!z3fold_page_trylock (zhdr))return -EAGAIN ; - }if (zhdr->mapped_count !=0 || zhdr->foreign_handles !=0 ) {z3fold_page_unlock (zhdr); +clear_bit (PAGE_CLAIMED , &page->private);return -EBUSY ; }if (work_pending (&zhdr->work)) {
@@ -1634,6 +1659,7 @@ static int z3fold_page_migrate(struct adqueue_work_on (new_zhdr->cpu, pool->compact_wq, &new_zhdr->work);page_mapcount_reset (page); +clear_bit (PAGE_CLAIMED , &page->private);put_page (page);return 0 ; }
@@ -1657,6 +1683,7 @@ static void z3fold_page_putback(struct pspin_lock (&pool->lock);list_add (&page->lru, &pool->lru);spin_unlock (&pool->lock); +clear_bit (PAGE_CLAIMED , &page->private);z3fold_page_unlock (zhdr); }
Greg Kroah-Hartman
maintainerPATCH 566/717 perf/x86/intel: Add event constraint for CYCLE_ACTIVITY.STALLS_MEM_ANY
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit 306e3e91edf1c6739a55312edd110d298ff498dd upstream.
The event CYCLE_ACTIVITY.STALLS_MEM_ANY (0x14a3) should be available on all 8 GP counters on ICL, but it's only scheduled on the first four counters due to the current ICL constraint table.
Add a line for the CYCLE_ACTIVITY.STALLS_MEM_ANY event in the ICL constraint table.
Correct the comments for the CYCLE_ACTIVITY.CYCLES_MEM_ANY event.
--- arch/x86/events/intel/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/events/intel/core.c +2 -1
@@ -257,7 +257,8 @@ static struct event_constraint intel_iclINTEL_EVENT_CONSTRAINT_RANGE (0x48 ,0x54 ,0xf ),INTEL_EVENT_CONSTRAINT_RANGE (0x60 ,0x8b ,0xf ),INTEL_UEVENT_CONSTRAINT (0x04a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_TOTAL */ -INTEL_UEVENT_CONSTRAINT (0x10a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_MEM_ANY */ +INTEL_UEVENT_CONSTRAINT (0x10a3 ,0xff ),/* CYCLE_ACTIVITY.CYCLES_MEM_ANY */ +INTEL_UEVENT_CONSTRAINT (0x14a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_MEM_ANY */ INTEL_EVENT_CONSTRAINT (0xa3 ,0xf ),/* CYCLE_ACTIVITY.* */ INTEL_EVENT_CONSTRAINT_RANGE (0xa8 ,0xb0 ,0xf ), INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf),
Greg Kroah-Hartman
maintainerPATCH 567/717 perf/x86/intel: Fix rtm_abort_event encoding on Ice Lake
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit 46b72e1bf4fc571da0c29c6fb3e5b2a2107a4c26 upstream.
According to the event list from icelake_core_v1.09.json, the encoding of the RTM_RETIRED.ABORTED event on Ice Lake should be,
"EventCode": "0xc9",
"UMask": "0x04",
"EventName": "RTM_RETIRED.ABORTED",Correct the wrong encoding.
--- arch/x86/events/intel/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/core.c +1 -1
@@ -5465,7 +5465,7 @@ __init int intel_pmu_init(void) mem_attr = icl_events_attrs; td_attr = icl_td_events_attrs; tsx_attr = icl_tsx_events_attrs; - x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02); + x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xc9, .umask=0x04); x86_pmu.lbr_pt_coexist = true;intel_pmu_pebs_data_source_skl (pmem); x86_pmu.update_topdown_event = icl_update_topdown_event;
Greg Kroah-Hartman
maintainerPATCH 568/717 perf/x86/intel/lbr: Fix the return type of get_lbr_cycles()
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit f8129cd958b395575e5543ce25a8434874b04d3a upstream.
The cycle count of a timed LBR is always 1 in perf record -D.
The cycle count is stored in the first 16 bits of the IA32_LBR_x_INFO register, but the get_lbr_cycles() return Boolean type.
Use u16 to replace the Boolean type.
--- arch/x86/events/intel/lbr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/lbr.c +1 -1
@@ -919,7 +919,7 @@ static __always_inline bool get_lbr_predreturn !(info &LBR_INFO_MISPRED ); } -static __always_inline bool get_lbr_cycles(u64 info) +static __always_inline u16 get_lbr_cycles(u64 info) {if (static_cpu_has (X86_FEATURE_ARCH_LBR ) && !(x86_pmu.lbr_timed_lbr && info &LBR_INFO_CYC_CNT_VALID ))
Greg Kroah-Hartman
maintainerPATCH 569/717 powerpc/perf: Exclude kernel samples while counting events in user space.
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
commit aa8e21c053d72b6639ea5a7f1d3a1d0209534c94 upstream.
Perf event attritube supports exclude_kernel flag to avoid sampling/profiling in supervisor state (kernel). Based on this event attr flag, Monitor Mode Control Register bit is set to freeze on supervisor state. But sometimes (due to hardware limitation), Sampled Instruction Address Register (SIAR) locks on to kernel address even when freeze on supervisor is set. Patch here adds a check to drop those samples.
--- arch/powerpc/perf/core-book3s.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/powerpc/perf/core-book3s.c +10 -0
@@ -2125,6 +2125,16 @@ static void record_and_restart(struct peperf_event_update_userpage (event);/* +* Due to hardware limitation, sometimes SIAR could sample a kernel +* address even when freeze on supervisor state (kernel) is set in +* MMCR2. Check attr.exclude_kernel and address to drop the sample in +* these cases. +*/ +if (event->attr.exclude_kernel && record) +if (is_kernel_addr (mfspr (SPRN_SIAR ))) + record =0 ; + +/* * Finally record data if requested. */ if (record) {
Greg Kroah-Hartman
maintainerPATCH 570/717 cpufreq: intel_pstate: Use most recent guaranteed performance values
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit e40ad84c26b4deeee46666492ec66b9a534b8e59 upstream.
When turbo has been disabled by the BIOS, but HWP_CAP.GUARANTEED is changed later, user space may want to take advantage of this increased guaranteed performance.
HWP_CAP.GUARANTEED is not a static value. It can be adjusted by an out-of-band agent or during an Intel Speed Select performance level change. The HWP_CAP.MAX is still the maximum achievable performance with turbo disabled by the BIOS, so HWP_CAP.GUARANTEED can still change as long as it remains less than or equal to HWP_CAP.MAX.
When HWP_CAP.GUARANTEED is changed, the sysfs base_frequency attribute shows the most recent guaranteed frequency value. This attribute can be used by user space software to update the scaling min/max limits of the CPU.
Currently, the ->setpolicy() callback already uses the latest HWP_CAP values when setting HWP_REQ, but the ->verify() callback will restrict the user settings to the to old guaranteed performance value which prevents user space from making use of the extra CPU capacity theoretically available to it after increasing HWP_CAP.GUARANTEED.
To address this, read HWP_CAP in intel_pstate_verify_cpu_policy() to obtain the maximum P-state that can be used and use that to confine the policy max limit instead of using the cached and possibly stale pstate.max_freq value for this purpose.
For consistency, update intel_pstate_update_perf_limits() to use the maximum available P-state returned by intel_pstate_get_hwp_max() to compute the maximum frequency instead of using the return value of intel_pstate_get_max_freq() which, again, may be stale.
This issue is a side-effect of fixing the scaling frequency limits in commit eacc9c5a927e ("cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled") which corrected the setting of the reduced scaling frequency values, but caused stale HWP_CAP.GUARANTEED to be used in the case at hand.
--- drivers/cpufreq/intel_pstate.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/cpufreq/intel_pstate.c +13 -3
@@ -2207,9 +2207,9 @@ static void intel_pstate_update_perf_limunsigned int policy_min, unsigned int policy_max) { - int max_freq = intel_pstate_get_max_freq(cpu); int32_t max_policy_perf, min_policy_perf;int max_state, turbo_max; +int max_freq;/* * HWP needs some special consideration, because on BDX the
@@ -2223,6 +2223,7 @@ static void intel_pstate_update_perf_lim cpu->pstate.max_pstate : cpu->pstate.turbo_pstate; turbo_max = cpu->pstate.turbo_pstate; } + max_freq = max_state * cpu->pstate.scaling; max_policy_perf = max_state * policy_max / max_freq;if (policy_max == policy_min) {
@@ -2325,9 +2326,18 @@ static void intel_pstate_adjust_policy_mstatic void intel_pstate_verify_cpu_policy (struct cpudata *cpu,struct cpufreq_policy_data *policy) { +int max_freq; +update_turbo_state (); -cpufreq_verify_within_limits (policy, policy->cpuinfo.min_freq, -intel_pstate_get_max_freq (cpu)); +if (hwp_active) { +int max_state, turbo_max; + +intel_pstate_get_hwp_max (cpu->cpu, &turbo_max, &max_state); + max_freq = max_state * cpu->pstate.scaling; + }else { + max_freq =intel_pstate_get_max_freq (cpu); + } +cpufreq_verify_within_limits (policy, policy->cpuinfo.min_freq, max_freq);intel_pstate_adjust_policy_max (cpu, policy); }
Greg Kroah-Hartman
maintainerPATCH 571/717 crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit 17858b140bf49961b71d4e73f1c3ea9bc8e7dda0 upstream.
ecdh_set_secret() casts a void* pointer to a const u64* in order to feed it into ecc_is_key_valid(). This is not generally permitted by the C standard, and leads to actual misalignment faults on ARMv6 cores. In some cases, these are fixed up in software, but this still leads to performance hits that are entirely avoidable.
So let's copy the key into the ctx buffer first, which we will do anyway in the common case, and which guarantees correct alignment.
--- crypto/ecdh.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
crypto/ecdh.c +5 -4
@@ -53,12 +53,13 @@ static int ecdh_set_secret(struct cryptoreturn ecc_gen_privkey (ctx->curve_id, ctx->ndigits, ctx->private_key); -if (ecc_is_key_valid (ctx->curve_id, ctx->ndigits, - (const u64 *)params.key, params.key_size) <0 ) -return -EINVAL ; -memcpy (ctx->private_key, params.key, params.key_size); +if (ecc_is_key_valid (ctx->curve_id, ctx->ndigits, + ctx->private_key, params.key_size) <0 ) { +memzero_explicit (ctx->private_key, params.key_size); +return -EINVAL ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 572/717 crypto: arm/aes-ce - work around Cortex-A57/A72 silion errata
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit f3456b9fd269c6d0c973b136c5449d46b2510f4b upstream.
ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are affected by silicon errata #1742098 and #1655431, respectively, where the second instruction of a AES instruction pair may execute twice if an interrupt is taken right after the first instruction consumes an input register of which a single 32-bit lane has been updated the last time it was modified.
This is not such a rare occurrence as it may seem: in counter mode, only the least significant 32-bit word is incremented in the absence of a carry, which makes our counter mode implementation susceptible to these errata.
So let's shuffle the counter assignments around a bit so that the most recent updates when the AES instruction pair executes are 128-bit wide.
[0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice
[1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice
--- arch/arm/crypto/aes-ce-core.S | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
arch/arm/crypto/aes-ce-core.S +22 -10
@@ -386,20 +386,32 @@ ENTRY(ce_aes_ctr_encrypt) .Lctrloop4x: subs r4, r4, #4 bmi .Lctr1x - add r6, r6, #1 + + /* + * NOTE: the sequence below has been carefully tweaked to avoid + * a silicon erratum that exists in Cortex-A57 (#1742098) and + * Cortex-A72 (#1655431) cores, where AESE/AESMC instruction pairs + * may produce an incorrect result if they take their input from a + * register of which a single 32-bit lane has been updated the last + * time it was modified. To work around this, the lanes of registers + * q0-q3 below are not manipulated individually, and the different + * counter values are prepared by successive manipulations of q7. + */ + add ip, r6, #1 vmov q0, q7 + rev ip, ip + add lr, r6, #2 + vmov s31, ip @ set lane 3 of q1 via q7 + add ip, r6, #3 + rev lr, lr vmov q1, q7 - rev ip, r6 - add r6, r6, #1 + vmov s31, lr @ set lane 3 of q2 via q7 + rev ip, ip vmov q2, q7 - vmov s7, ip - rev ip, r6 - add r6, r6, #1 + vmov s31, ip @ set lane 3 of q3 via q7 + add r6, r6, #4 vmov q3, q7 - vmov s11, ip - rev ip, r6 - add r6, r6, #1 - vmov s15, ip + vld1.8 {q4-q5}, [r1]! vld1.8 {q6}, [r1]! vld1.8 {q15}, [r1]!
Greg Kroah-Hartman
maintainerPATCH 573/717 m68k: Fix WARNING splat in pmac_zilog driver
In reply to Greg Kroah-HartmanFrom: Finn Thain <[email protected]>
commit a7b5458ce73b235be027cf2658c39b19b7e58cf2 upstream.
Don't add platform resources that won't be used. This avoids a recently-added warning from the driver core, that can show up on a multi-platform kernel when !MACH_IS_MAC.
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at drivers/base/platform.c:224 platform_get_irq_optional+0x8e/0xce
0 is an invalid IRQ number
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.9.0-multi #1
Stack from 004b3f04:
004b3f04 00462c2f 00462c2f 004b3f20 0002e128 004754db 004b6ad4 004b3f4c
0002e19c 004754f7 000000e0 00285ba0 00000009 00000000 004b3f44 ffffffff
004754db 004b3f64 004b3f74 00285ba0 004754f7 000000e0 00000009 004754db
004fdf0c 005269e2 004fdf0c 00000000 004b3f88 00285cae 004b6964 00000000
004fdf0c 004b3fac 0051cc68 004b6964 00000000 004b6964 00000200 00000000
0051cc3e 0023c18a 004b3fc0 0051cd8a 004fdf0c 00000002 0052b43c 004b3fc8
Call Trace: [<0002e128>] __warn+0xa6/0xd6
[<0002e19c>] warn_slowpath_fmt+0x44/0x76
[<00285ba0>] platform_get_irq_optional+0x8e/0xce
[<00285ba0>] platform_get_irq_optional+0x8e/0xce
[<00285cae>] platform_get_irq+0x12/0x4c
[<0051cc68>] pmz_init_port+0x2a/0xa6
[<0051cc3e>] pmz_init_port+0x0/0xa6
[<0023c18a>] strlen+0x0/0x22
[<0051cd8a>] pmz_probe+0x34/0x88
[<0051cde6>] pmz_console_init+0x8/0x28
[<00511776>] console_init+0x1e/0x28
[<0005a3bc>] printk+0x0/0x16
[<0050a8a6>] start_kernel+0x368/0x4ce
[<005094f8>] _sinittext+0x4f8/0xc48
random: get_random_bytes called from print_oops_end_marker+0x56/0x80 with crng_init=0
---[ end trace 392d8e82eed68d6c ]---Commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid"), which introduced the WARNING, suggests that testing for irq == 0 is undesirable. Instead of that comparison, just test for resource existence.
--- arch/m68k/mac/config.c | 17 +++++++++-------- drivers/tty/serial/pmac_zilog.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 13 deletions(-)
arch/m68k/mac/config.c +9 -8
@@ -777,16 +777,12 @@ static struct resource scc_b_rsrcs[] = {struct platform_device scc_a_pdev = { .name ="scc" , .id =0 , - .num_resources =ARRAY_SIZE (scc_a_rsrcs), - .resource = scc_a_rsrcs, };EXPORT_SYMBOL (scc_a_pdev);struct platform_device scc_b_pdev = { .name ="scc" , .id =1 , - .num_resources =ARRAY_SIZE (scc_b_rsrcs), - .resource = scc_b_rsrcs, };EXPORT_SYMBOL (scc_b_pdev);
@@ -813,10 +809,15 @@ static void __init mac_identify(void)/* Set up serial port resources for the console initcall. */ - scc_a_rsrcs[0 ].start = (resource_size_t ) mac_bi_data.sccbase +2 ; - scc_a_rsrcs[0 ].end = scc_a_rsrcs[0 ].start; - scc_b_rsrcs[0 ].start = (resource_size_t ) mac_bi_data.sccbase; - scc_b_rsrcs[0 ].end = scc_b_rsrcs[0 ].start; + scc_a_rsrcs[0 ].start = (resource_size_t )mac_bi_data.sccbase +2 ; + scc_a_rsrcs[0 ].end = scc_a_rsrcs[0 ].start; + scc_a_pdev.num_resources =ARRAY_SIZE (scc_a_rsrcs); + scc_a_pdev.resource = scc_a_rsrcs; + + scc_b_rsrcs[0 ].start = (resource_size_t )mac_bi_data.sccbase; + scc_b_rsrcs[0 ].end = scc_b_rsrcs[0 ].start; + scc_b_pdev.num_resources =ARRAY_SIZE (scc_b_rsrcs); + scc_b_pdev.resource = scc_b_rsrcs;switch (macintosh_config->scc_type) {case MAC_SCC_PSC :
drivers/tty/serial/pmac_zilog.c +9 -5
@@ -1693,22 +1693,26 @@ static int __init pmz_probe(void)#else +/* On PCI PowerMacs, pmz_probe() does an explicit search of the OpenFirmware +* tree to obtain the device_nodes needed to start the console before the +* macio driver. On Macs without OpenFirmware, global platform_devices take +* the place of those device_nodes. +*/ extern struct platform_device scc_a_pdev, scc_b_pdev;static int __init pmz_init_port (struct uart_pmac_port *uap) { -struct resource *r_ports; -int irq; +struct resource *r_ports, *r_irq; r_ports =platform_get_resource (uap->pdev,IORESOURCE_MEM ,0 ); - irq =platform_get_irq (uap->pdev,0 ); -if (!r_ports || irq <=0 ) + r_irq =platform_get_resource (uap->pdev,IORESOURCE_IRQ ,0 ); +if (!r_ports || !r_irq)return -ENODEV ; uap->port.mapbase = r_ports->start; uap->port.membase = (unsigned char __iomem *) r_ports->start; uap->port.iotype =UPIO_MEM ; - uap->port.irq = irq; + uap->port.irq = r_irq->start; uap->port.uartclk =ZS_CLOCK ; uap->port.fifosize =1 ; uap->port.ops = &pmz_pops;
Greg Kroah-Hartman
maintainerPATCH 574/717 Documentation: seqlock: s/LOCKTYPE/LOCKNAME/g
In reply to Greg Kroah-HartmanFrom: Ahmed S. Darwish <[email protected]>
commit cf48647243cc28d15280600292db5777592606c5 upstream.
Sequence counters with an associated write serialization lock are called seqcount_LOCKNAME_t. Fix the documentation accordingly.
While at it, remove a paragraph that inappropriately discussed a seqlock.h implementation detail.
--- Documentation/locking/seqlock.rst | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
Documentation/locking/seqlock.rst +10 -11
@@ -89,7 +89,7 @@ Read path:: .. _seqcount_locktype_t: -Sequence counters with associated locks (``seqcount_LOCKTYPE_t``) +Sequence counters with associated locks (``seqcount_LOCKNAME_t``) ----------------------------------------------------------------- As discussed at :ref:`seqcount_t`, sequence count write side critical
@@ -115,27 +115,26 @@ The following sequence counters with ass - ``seqcount_mutex_t`` - ``seqcount_ww_mutex_t`` -The plain seqcount read and write APIs branch out to the specific -seqcount_LOCKTYPE_t implementation at compile-time. This avoids kernel -API explosion per each new seqcount LOCKTYPE. +The sequence counter read and write APIs can take either a plain +seqcount_t or any of the seqcount_LOCKNAME_t variants above. -Initialization (replace "LOCKTYPE" with one of the supported locks):: +Initialization (replace "LOCKNAME" with one of the supported locks):: /* dynamic */ - seqcount_LOCKTYPE_t foo_seqcount; - seqcount_LOCKTYPE_init(&foo_seqcount, &lock); + seqcount_LOCKNAME_t foo_seqcount; + seqcount_LOCKNAME_init(&foo_seqcount, &lock); /* static */ - static seqcount_LOCKTYPE_t foo_seqcount = - SEQCNT_LOCKTYPE_ZERO(foo_seqcount, &lock); + static seqcount_LOCKNAME_t foo_seqcount = + SEQCNT_LOCKNAME_ZERO(foo_seqcount, &lock); /* C99 struct init */ struct { - .seq = SEQCNT_LOCKTYPE_ZERO(foo.seq, &lock), + .seq = SEQCNT_LOCKNAME_ZERO(foo.seq, &lock), } foo; Write path: same as in :ref:`seqcount_t`, while running from a context -with the associated LOCKTYPE lock acquired. +with the associated write serialization lock acquired. Read path: same as in :ref:`seqcount_t`.
Greg Kroah-Hartman
maintainerPATCH 575/717 EDAC/i10nm: Use readl() to access MMIO registers
In reply to Greg Kroah-HartmanFrom: Qiuxu Zhuo <[email protected]>
commit 83ff51c4e3fecf6b8587ce4d46f6eac59f5d7c5a upstream.
Instead of raw access, use readl() to access MMIO registers of memory controller to avoid possible compiler re-ordering.
--- drivers/edac/i10nm_base.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/edac/i10nm_base.c +7 -4
@@ -6,6 +6,7 @@*/ #include <linux/kernel.h> +#include <linux/io.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h> #include <asm/mce.h>
@@ -19,14 +20,16 @@ #define i10nm_printk(level, fmt, arg...) \ edac_printk(level, "i10nm", fmt, ##arg) -#define I10NM_GET_SCK_BAR (d, reg) \ +#define I10NM_GET_SCK_BAR (d, reg) \ pci_read_config_dword((d)->uracu, 0xd0, &(reg))#define I10NM_GET_IMC_BAR (d, i, reg) \ pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))#define I10NM_GET_DIMMMTR (m, i, j) \ - (*(u32 *)((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)) + readl((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)#define I10NM_GET_MCDDRTCFG (m, i, j) \ - (*(u32 *)((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4)) + readl((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4) +#define I10NM_GET_MCMTR (m, i) \ + readl((m)->mbase + 0x20ef8 + (i) * 0x4000)#define I10NM_GET_SCK_MMIO_BASE (reg) (GET_BITFIELD(reg, 0, 28) << 23)#define I10NM_GET_IMC_MMIO_OFFSET (reg) (GET_BITFIELD(reg, 0, 10) << 12)
@@ -148,7 +151,7 @@ static bool i10nm_check_ecc(struct skx_i {u32 mcmtr; - mcmtr = *(u32 *)(imc->mbase +0x20ef8 + chan *0x4000 ); + mcmtr =I10NM_GET_MCMTR (imc, chan);edac_dbg (1 ,"ch%d mcmtr reg %x\n" , chan, mcmtr);return !!GET_BITFIELD (mcmtr,2 ,2 );
Greg Kroah-Hartman
maintainerPATCH 576/717 EDAC/amd64: Fix PCI component registration
In reply to Greg Kroah-HartmanFrom: Borislav Petkov <[email protected]>
commit 706657b1febf446a9ba37dc51b89f46604f57ee9 upstream.
In order to setup its PCI component, the driver needs any node private instance in order to get a reference to the PCI device and hand that into edac_pci_create_generic_ctl(). For convenience, it uses the 0th memory controller descriptor under the assumption that if any, the 0th will be always present.
However, this assumption goes wrong when the 0th node doesn't have memory and the driver doesn't initialize an instance for it:
EDAC amd64: F17h detected (node 0).
...
EDAC amd64: Node 0: No DIMMs detected.
But looking up node instances is not really needed - all one needs is the pointer to the proper device which gets discovered during instance init.
So stash that pointer into a variable and use it when setting up the EDAC PCI component.
Clear that variable when the driver needs to unwind due to some instances failing init to avoid any registration imbalance.
--- drivers/edac/amd64_edac.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
drivers/edac/amd64_edac.c +14 -12
@@ -18,6 +18,9 @@ static struct amd64_family_type *fam_typ/* Per-node stuff */ static struct ecc_settings **ecc_stngs; +/* Device for the PCI component */ +static struct device *pci_ctl_dev; +/* * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
@@ -2683,6 +2686,9 @@ reserve_mc_sibling_devs(struct amd64_pvtreturn -ENODEV ; } +if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F0->dev; +edac_dbg (1 ,"F0: %s\n" ,pci_name (pvt->F0));edac_dbg (1 ,"F3: %s\n" ,pci_name (pvt->F3));edac_dbg (1 ,"F6: %s\n" ,pci_name (pvt->F6));
@@ -2707,6 +2713,9 @@ reserve_mc_sibling_devs(struct amd64_pvtreturn -ENODEV ; } +if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F2->dev; +edac_dbg (1 ,"F1: %s\n" ,pci_name (pvt->F1));edac_dbg (1 ,"F2: %s\n" ,pci_name (pvt->F2));edac_dbg (1 ,"F3: %s\n" ,pci_name (pvt->F3));
@@ -3623,21 +3632,10 @@ static void remove_one_instance(unsignedstatic void setup_pci_device (void ) { -struct mem_ctl_info *mci; -struct amd64_pvt *pvt; -if (pci_ctl)return ; - mci =edac_mc_find (0 ); -if (!mci) -return ; - - pvt = mci->pvt_info; -if (pvt->umc) - pci_ctl =edac_pci_create_generic_ctl (&pvt->F0->dev,EDAC_MOD_STR ); -else - pci_ctl =edac_pci_create_generic_ctl (&pvt->F2->dev,EDAC_MOD_STR ); + pci_ctl =edac_pci_create_generic_ctl (pci_ctl_dev,EDAC_MOD_STR );if (!pci_ctl) {pr_warn ("%s(): Unable to create PCI control\n" , __func__);pr_warn ("%s(): PCI error report via EDAC not set\n" , __func__);
@@ -3716,6 +3714,8 @@ static int __init amd64_edac_init(void)return 0 ; err_pci: + pci_ctl_dev =NULL ; +msrs_free (msrs); msrs =NULL ;
@@ -3745,6 +3745,8 @@ static void __exit amd64_edac_exit(void)kfree (ecc_stngs); ecc_stngs =NULL ; + pci_ctl_dev =NULL ; +msrs_free (msrs); msrs =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 577/717 cpuset: fix race between hotplug work and later CPU offline
In reply to Greg Kroah-HartmanFrom: Daniel Jordan <[email protected]>
commit 406100f3da08066c00105165db8520bbc7694a36 upstream.
One of our machines keeled over trying to rebuild the scheduler domains. Mainline produces the same splat:
BUG: unable to handle page fault for address: 0000607f820054db CPU: 2 PID: 149 Comm: kworker/1:1 Not tainted 5.10.0-rc1-master+ #6 Workqueue: events cpuset_hotplug_workfn RIP: build_sched_domains Call Trace: partition_sched_domains_locked rebuild_sched_domains_locked cpuset_hotplug_workfn
It happens with cgroup2 and exclusive cpusets only. This reproducer triggers it on an 8-cpu vm and works most effectively with no preexisting child cgroups:
cd $UNIFIED_ROOT
mkdir cg1
echo 4-7 > cg1/cpuset.cpus
echo root > cg1/cpuset.cpus.partition
# with smt/control reading 'on', echo off > /sys/devices/system/cpu/smt/control
RIP maps to
sd->shared = *per_cpu_ptr(sdd->sds, sd_id);
from sd_init(). sd_id is calculated earlier in the same function:
cpumask_and(sched_domain_span(sd), cpu_map, tl->mask(cpu)); sd_id = cpumask_first(sched_domain_span(sd));
tl->mask(cpu), which reads cpu_sibling_map on x86, returns an empty mask and so cpumask_first() returns >= nr_cpu_ids, which leads to the bogus value from per_cpu_ptr() above.
The problem is a race between cpuset_hotplug_workfn() and a later offline of CPU N. cpuset_hotplug_workfn() updates the effective masks when N is still online, the offline clears N from cpu_sibling_map, and then the worker uses the stale effective masks that still have N to generate the scheduling domains, leading the worker to read N's empty cpu_sibling_map in sd_init().
rebuild_sched_domains_locked() prevented the race during the cgroup2 cpuset series up until the Fixes commit changed its check. Make the check more robust so that it can detect an offline CPU in any exclusive cpuset's effective mask, not just the top one.
--- kernel/cgroup/cpuset.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-)
kernel/cgroup/cpuset.c +28 -5
@@ -983,25 +983,48 @@ partition_and_rebuild_sched_domains(int*/ static void rebuild_sched_domains_locked (void ) { +struct cgroup_subsys_state *pos_css;struct sched_domain_attr *attr;cpumask_var_t *doms; +struct cpuset *cs;int ndoms;lockdep_assert_cpus_held ();percpu_rwsem_assert_held (&cpuset_rwsem);/* -* We have raced with CPU hotplug. Don't do anything to avoid +* If we have raced with CPU hotplug, return early to avoid * passing doms with offlined cpu to partition_sched_domains(). -* Anyways, hotplug work item will rebuild sched domains. +* Anyways, cpuset_hotplug_workfn() will rebuild sched domains. +* +* With no CPUs in any subpartitions, top_cpuset's effective CPUs +* should be the same as the active CPUs, so checking only top_cpuset +* is enough to detect racing CPU offlines. */ if (!top_cpuset.nr_subparts_cpus && !cpumask_equal (top_cpuset.effective_cpus, cpu_active_mask))return ; -if (top_cpuset.nr_subparts_cpus && - !cpumask_subset (top_cpuset.effective_cpus, cpu_active_mask)) -return ; +/* +* With subpartition CPUs, however, the effective CPUs of a partition +* root should be only a subset of the active CPUs. Since a CPU in any +* partition root could be offlined, all must be checked. +*/ +if (top_cpuset.nr_subparts_cpus) { +rcu_read_lock (); +cpuset_for_each_descendant_pre (cs, pos_css, &top_cpuset) { +if (!is_partition_root (cs)) { + pos_css =css_rightmost_descendant (pos_css); +continue ; + } +if (!cpumask_subset (cs->effective_cpus, + cpu_active_mask)) { +rcu_read_unlock (); +return ; + } + } +rcu_read_unlock (); + }/* Generate domain masks and attrs */ ndoms =generate_sched_domains (&doms, &attr);
Greg Kroah-Hartman
maintainerPATCH 578/717 dyndbg: fix use before null check
In reply to Greg Kroah-HartmanFrom: Jim Cromie <[email protected]>
commit 3577afb0052fca65e67efdfc8e0859bb7bac87a6 upstream.
In commit a2d375eda771 ("dyndbg: refine export, rename to dynamic_debug_exec_queries()"), a string is copied before checking it isn't NULL. Fix this, report a usage/interface error, and return the proper error code.
--- lib/dynamic_debug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
lib/dynamic_debug.c +7 -2
@@ -561,9 +561,14 @@ static int ddebug_exec_queries(char *queint dynamic_debug_exec_queries (const char *query,const char *modname) {int rc; -char *qry =kstrndup (query,PAGE_SIZE ,GFP_KERNEL ); +char *qry;/* writable copy of query */ -if (!query) +if (!query) { +pr_err ("non-null query/command string expected\n" ); +return -EINVAL ; + } + qry =kstrndup (query,PAGE_SIZE ,GFP_KERNEL ); +if (!qry)return -ENOMEM ; rc =ddebug_exec_queries (qry, modname);
Greg Kroah-Hartman
maintainerPATCH 579/717 USB: serial: mos7720: fix parallel-port state restore
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 975323ab8f116667676c30ca3502a6757bd89e8d upstream.
The parallel-port restore operations is called when a driver claims the port and is supposed to restore the provided state (e.g. saved when releasing the port).
--- drivers/usb/serial/mos7720.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/mos7720.c +2 -0
@@ -639,6 +639,8 @@ static void parport_mos7715_restore_statspin_unlock (&release_lock);return ; } + mos_parport->shadowDCR = s->u.pc.ctr; + mos_parport->shadowECR = s->u.pc.ecr;write_parport_reg_nonblock (mos_parport,MOS7720_DCR , mos_parport->shadowDCR); write_parport_reg_nonblock(mos_parport, MOS7720_ECR,
Greg Kroah-Hartman
maintainerPATCH 580/717 USB: serial: digi_acceleport: fix write-wakeup deadlocks
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5098e77962e7c8947f87bd8c5869c83e000a522a upstream.
The driver must not call tty_wakeup() while holding its private lock as line disciplines are allowed to call back into write() from write_wakeup(), leading to a deadlock.
Also remove the unneeded work struct that was used to defer wakeup in order to work around a possible race in ancient times (see comment about n_tty write_chan() in commit 14b54e39b412 ("USB: serial: remove changelogs and old todo entries")).
--- drivers/usb/serial/digi_acceleport.c | 45 ++++++++++------------------------- 1 file changed, 13 insertions(+), 32 deletions(-)
drivers/usb/serial/digi_acceleport.c +13 -32
@@ -19,7 +19,6 @@#include <linux/tty_flip.h> #include <linux/module.h> #include <linux/spinlock.h> -#include <linux/workqueue.h> #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/wait.h>
@@ -198,14 +197,12 @@ struct digi_port {int dp_throttle_restart;wait_queue_head_t dp_flush_wait;wait_queue_head_t dp_close_wait;/* wait queue for close */ -struct work_struct dp_wakeup_work;struct usb_serial_port *dp_port; };/* Local Function Declarations */ -static void digi_wakeup_write_lock (struct work_struct *work);static int digi_write_oob_command (struct usb_serial_port *port,unsigned char *buf,int count,int interruptible); static int digi_write_inb_command(struct usb_serial_port *port,
@@ -356,26 +353,6 @@ __releases(lock)return timeout; } - -/* -* Digi Wakeup Write -* -* Wake up port, line discipline, and tty processes sleeping -* on writes. -*/ - -static void digi_wakeup_write_lock (struct work_struct *work) -{ -struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); -struct usb_serial_port *port = priv->dp_port; -unsigned long flags; - -spin_lock_irqsave (&priv->dp_port_lock, flags); -tty_port_tty_wakeup (&port->port); -spin_unlock_irqrestore (&priv->dp_port_lock, flags); -} -/* * Digi Write OOB Command *
@@ -986,6 +963,7 @@ static void digi_write_bulk_callback(strunsigned long flags;int ret =0 ;int status = urb->status; +bool wakeup;/* port and serial sanity check */ if (port ==NULL || (priv =usb_get_serial_port_data (port)) ==NULL ) {
@@ -1012,6 +990,7 @@ static void digi_write_bulk_callback(str }/* try to send any buffered data on this port */ + wakeup = true;spin_lock_irqsave (&priv->dp_port_lock, flags); priv->dp_write_urb_in_use =0 ;if (priv->dp_out_buf_len >0 ) {
@@ -1027,19 +1006,18 @@ static void digi_write_bulk_callback(strif (ret ==0 ) { priv->dp_write_urb_in_use =1 ; priv->dp_out_buf_len =0 ; + wakeup = false; } } -/* wake up processes sleeping on writes immediately */ -tty_port_tty_wakeup (&port->port); -/* also queue up a wakeup at scheduler time, in case we */ -/* lost the race in write_chan(). */ -schedule_work (&priv->dp_wakeup_work); -spin_unlock_irqrestore (&priv->dp_port_lock, flags); +if (ret && ret != -EPERM )dev_err_console (port,"%s: usb_submit_urb failed, ret=%d, port=%d\n" , __func__, ret, priv->dp_port_num); + +if (wakeup) +tty_port_tty_wakeup (&port->port); }static int digi_write_room (struct tty_struct *tty)
@@ -1239,7 +1217,6 @@ static int digi_port_init(struct usb_serinit_waitqueue_head (&priv->dp_transmit_idle_wait);init_waitqueue_head (&priv->dp_flush_wait);init_waitqueue_head (&priv->dp_close_wait); -INIT_WORK (&priv->dp_wakeup_work, digi_wakeup_write_lock); priv->dp_port = port;init_waitqueue_head (&port->write_wait);
@@ -1508,13 +1485,14 @@ static int digi_read_oob_callback(struct rts =C_CRTSCTS (tty);if (tty && opcode ==DIGI_CMD_READ_INPUT_SIGNALS ) { +bool wakeup = false; +spin_lock_irqsave (&priv->dp_port_lock, flags);/* convert from digi flags to termiox flags */ if (val &DIGI_READ_INPUT_SIGNALS_CTS ) { priv->dp_modem_signals |=TIOCM_CTS ; -/* port must be open to use tty struct */ if (rts) -tty_port_tty_wakeup (&port->port); + wakeup = true; }else { priv->dp_modem_signals &= ~TIOCM_CTS ;/* port must be open to use tty struct */
@@ -1533,6 +1511,9 @@ static int digi_read_oob_callback(struct priv->dp_modem_signals &= ~TIOCM_CD ;spin_unlock_irqrestore (&priv->dp_port_lock, flags); + +if (wakeup) +tty_port_tty_wakeup (&port->port); }else if (opcode ==DIGI_CMD_TRANSMIT_IDLE ) {spin_lock_irqsave (&priv->dp_port_lock, flags); priv->dp_transmit_idle =1 ;
Greg Kroah-Hartman
maintainerPATCH 581/717 USB: serial: keyspan_pda: fix dropped unthrottle interrupts
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 696c541c8c6cfa05d65aa24ae2b9e720fc01766e upstream.
Commit c528fcb116e6 ("USB: serial: keyspan_pda: fix receive sanity checks") broke write-unthrottle handling by dropping well-formed unthrottle-interrupt packets which are precisely two bytes long. This could lead to blocked writers not being woken up when buffer space again becomes available.
Instead, stop unconditionally printing the third byte which is (presumably) only valid on modem-line changes.
--- drivers/usb/serial/keyspan_pda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/serial/keyspan_pda.c +2 -2
@@ -172,11 +172,11 @@ static void keyspan_pda_rx_interrupt(strbreak ;case 1 :/* status interrupt */ -if (len <3 ) { +if (len <2 ) {dev_warn (&port->dev,"short interrupt message received\n" );break ; } -dev_dbg (&port->dev,"rx int, d1=%d, d2=%d\n" , data[1 ], data[2 ]); +dev_dbg (&port->dev,"rx int, d1=%d\n" , data[1 ]);switch (data[1 ]) {case 1 :/* modemline change */ break ;
Greg Kroah-Hartman
maintainerPATCH 582/717 USB: serial: keyspan_pda: fix write deadlock
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 7353cad7ee4deaefc16e94727e69285563e219f6 upstream.
The write() callback can be called in interrupt context (e.g. when used as a console) so interrupts must be disabled while holding the port lock to prevent a possible deadlock.
--- drivers/usb/serial/keyspan_pda.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/serial/keyspan_pda.c +4 -3
@@ -443,6 +443,7 @@ static int keyspan_pda_write(struct tty_int request_unthrottle =0 ;int rc =0 ;struct keyspan_pda_private *priv; +unsigned long flags; priv =usb_get_serial_port_data (port);/* guess how much room is left in the device's ring buffer, and if we
@@ -462,13 +463,13 @@ static int keyspan_pda_write(struct tty_the TX urb is in-flight (wait until it completes) the device is full (wait until it says there is room) */ -spin_lock_bh (&port->lock); +spin_lock_irqsave (&port->lock, flags);if (!test_bit (0 , &port->write_urbs_free) || priv->tx_throttled) { -spin_unlock_bh (&port->lock); +spin_unlock_irqrestore (&port->lock, flags);return 0 ; }clear_bit (0 , &port->write_urbs_free); -spin_unlock_bh (&port->lock); +spin_unlock_irqrestore (&port->lock, flags);/* At this point the URB is in our control, nobody else can submit it again (the only sudden transition was the one from EINPROGRESS to
Greg Kroah-Hartman
maintainerPATCH 583/717 USB: serial: keyspan_pda: fix stalled writes
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit c01d2c58698f710c9e13ba3e2d296328606f74fd upstream.
Make sure to clear the write-busy flag also in case no new data was submitted due to lack of device buffer space so that writing is resumed once space again becomes available.
--- drivers/usb/serial/keyspan_pda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/keyspan_pda.c +1 -1
@@ -548,7 +548,7 @@ static int keyspan_pda_write(struct tty_ rc = count; exit: -if (rc <0 ) +if (rc <=0 )set_bit (0 , &port->write_urbs_free);return rc; }
Greg Kroah-Hartman
maintainerPATCH 584/717 USB: serial: keyspan_pda: fix write-wakeup use-after-free
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 37faf50615412947868c49aee62f68233307f4e4 upstream.
The driver's deferred write wakeup was never flushed on disconnect, something which could lead to the driver port data being freed while the wakeup work is still scheduled.
Fix this by using the usb-serial write wakeup which gets cancelled properly on disconnect.
--- drivers/usb/serial/keyspan_pda.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-)
drivers/usb/serial/keyspan_pda.c +3 -14
@@ -43,8 +43,7 @@struct keyspan_pda_private {int tx_room;int tx_throttled; -struct work_struct wakeup_work; -struct work_struct unthrottle_work; +struct work_struct unthrottle_work;struct usb_serial *serial;struct usb_serial_port *port; };
@@ -97,15 +96,6 @@ static const struct usb_device_id id_tab };#endif -static void keyspan_pda_wakeup_write (struct work_struct *work) -{ -struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, wakeup_work); -struct usb_serial_port *port = priv->port; - -tty_port_tty_wakeup (&port->port); -} -static void keyspan_pda_request_unthrottle (struct work_struct *work) { struct keyspan_pda_private *priv =
@@ -183,7 +173,7 @@ static void keyspan_pda_rx_interrupt(strcase 2 :/* tx unthrottle interrupt */ priv->tx_throttled =0 ;/* queue up a wakeup at scheduler time */ -schedule_work (&priv->wakeup_work); +usb_serial_port_softint (port);break ;default :break ;
@@ -563,7 +553,7 @@ static void keyspan_pda_write_bulk_callb priv =usb_get_serial_port_data (port);/* queue up a wakeup at scheduler time */ -schedule_work (&priv->wakeup_work); +usb_serial_port_softint (port); }
@@ -715,7 +705,6 @@ static int keyspan_pda_port_probe(structif (!priv)return -ENOMEM ; -INIT_WORK (&priv->wakeup_work, keyspan_pda_wakeup_write);INIT_WORK (&priv->unthrottle_work, keyspan_pda_request_unthrottle); priv->serial = port->serial; priv->port = port;
Greg Kroah-Hartman
maintainerPATCH 585/717 USB: serial: keyspan_pda: fix tx-unthrottle use-after-free
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 49fbb8e37a961396a5b6c82937c70df91de45e9d upstream.
The driver's transmit-unthrottle work was never flushed on disconnect, something which could lead to the driver port data being freed while the unthrottle work is still scheduled.
Fix this by cancelling the unthrottle work when shutting down the port.
--- drivers/usb/serial/keyspan_pda.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/keyspan_pda.c +4 -0
@@ -647,8 +647,12 @@ error: }static void keyspan_pda_close (struct usb_serial_port *port) { +struct keyspan_pda_private *priv =usb_get_serial_port_data (port); +usb_kill_urb (port->write_urb);usb_kill_urb (port->interrupt_in_urb); + +cancel_work_sync (&priv->unthrottle_work); }
Greg Kroah-Hartman
maintainerPATCH 586/717 USB: serial: keyspan_pda: fix write unthrottling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 320f9028c7873c3c7710e8e93e5c979f4c857490 upstream.
The driver did not update its view of the available device buffer space until write() was called in task context. This meant that write_room() would return 0 even after the device had sent a write-unthrottle notification, something which could lead to blocked writers not being woken up (e.g. when using OPOST).
Note that we must also request an unthrottle notification is case a write() request fills the device buffer exactly.
--- drivers/usb/serial/keyspan_pda.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/usb/serial/keyspan_pda.c +20 -9
@@ -40,6 +40,8 @@#define DRIVER_AUTHOR "Brian Warner <[email protected]>"#define DRIVER_DESC "USB Keyspan PDA Converter driver" +#define KEYSPAN_TX_THRESHOLD 16 +struct keyspan_pda_private {int tx_room;int tx_throttled;
@@ -110,7 +112,7 @@ static void keyspan_pda_request_unthrott7 ,/* request_unthrottle */ USB_TYPE_VENDOR |USB_RECIP_INTERFACE |USB_DIR_OUT , -16 ,/* value: threshold */ +KEYSPAN_TX_THRESHOLD ,0 ,/* index */ NULL , 0,
@@ -129,6 +131,8 @@ static void keyspan_pda_rx_interrupt(strint retval;int status = urb->status;struct keyspan_pda_private *priv; +unsigned long flags; + priv =usb_get_serial_port_data (port);switch (status) {
@@ -171,7 +175,10 @@ static void keyspan_pda_rx_interrupt(strcase 1 :/* modemline change */ break ;case 2 :/* tx unthrottle interrupt */ +spin_lock_irqsave (&port->lock, flags); priv->tx_throttled =0 ; + priv->tx_room =max (priv->tx_room,KEYSPAN_TX_THRESHOLD ); +spin_unlock_irqrestore (&port->lock, flags);/* queue up a wakeup at scheduler time */ usb_serial_port_softint (port);break ;
@@ -505,7 +512,8 @@ static int keyspan_pda_write(struct tty_ goto exit; } } -if (count > priv->tx_room) { + +if (count >= priv->tx_room) {/* we're about to completely fill the Tx buffer, so we'll be throttled afterwards. */ count = priv->tx_room;
@@ -560,14 +568,17 @@ static void keyspan_pda_write_bulk_callbstatic int keyspan_pda_write_room (struct tty_struct *tty) {struct usb_serial_port *port = tty->driver_data; -struct keyspan_pda_private *priv; - priv =usb_get_serial_port_data (port); -/* used by n_tty.c for processing of tabs and such. Giving it our -conservative guess is probably good enough, but needs testing by -running a console through the device. */ -return priv->tx_room; -} +struct keyspan_pda_private *priv =usb_get_serial_port_data (port); +unsigned long flags; +int room =0 ; + +spin_lock_irqsave (&port->lock, flags); +if (test_bit (0 , &port->write_urbs_free) && !priv->tx_throttled) + room = priv->tx_room; +spin_unlock_irqrestore (&port->lock, flags); +return room; +}static int keyspan_pda_chars_in_buffer (struct tty_struct *tty) {
Greg Kroah-Hartman
maintainerPATCH 587/717 btrfs: do not shorten unpin len for caching block groups
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 9076dbd5ee837c3882fc42891c14cecd0354a849 upstream.
While fixing up our ->last_byte_to_unpin locking I noticed that we will shorten len based on ->last_byte_to_unpin if we're caching when we're adding back the free space. This is correct for the free space, as we cannot unpin more than ->last_byte_to_unpin, however we use len to adjust the ->bytes_pinned counters and such, which need to track the actual pinned usage. This could result in WARN_ON(space_info->bytes_pinned) triggering at unmount time.
Fix this by using a local variable for the amount to add to free space cache, and leave len untouched in this case.
--- fs/btrfs/extent-tree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/btrfs/extent-tree.c +4 -4
@@ -2816,10 +2816,10 @@ static int unpin_extent_range(struct btr len = cache->start + cache->length - start; len =min (len, end +1 - start); -if (start < cache->last_byte_to_unpin) { - len =min (len, cache->last_byte_to_unpin - start); -if (return_free_space) -btrfs_add_free_space (cache, start, len); +if (start < cache->last_byte_to_unpin && return_free_space) { +u64 add_len =min (len, cache->last_byte_to_unpin - start); + +btrfs_add_free_space (cache, start, add_len); } start += len;
Greg Kroah-Hartman
maintainerPATCH 588/717 btrfs: update last_byte_to_unpin in switch_commit_roots
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 27d56e62e4748c2135650c260024e9904b8c1a0a upstream.
While writing an explanation for the need of the commit_root_sem for btrfs_prepare_extent_commit, I realized we have a slight hole that could result in leaked space if we have to do the old style caching. Consider the following scenario
commit root
+----+----+----+----+----+----+----+ |\\\\| |\\\\|\\\\| |\\\\|\\\\| +----+----+----+----+----+----+----+ 0 1 2 3 4 5 6 7
new commit root
+----+----+----+----+----+----+----+ | | | |\\\\| | |\\\\| +----+----+----+----+----+----+----+ 0 1 2 3 4 5 6 7
Prior to this patch, we run btrfs_prepare_extent_commit, which updates the last_byte_to_unpin, and then we subsequently run switch_commit_roots. In this example lets assume that caching_ctl->progress == 1 at btrfs_prepare_extent_commit() time, which means that cache->last_byte_to_unpin == 1. Then we go and do the switch_commit_roots(), but in the meantime the caching thread has made some more progress, because we drop the commit_root_sem and re-acquired it. Now caching_ctl->progress == 3. We swap out the commit root and carry on to unpin.
The race can happen like:
1) The caching thread was running using the old commit root when it
found the extent for [2, 3);
2) Then it released the commit_root_sem because it was in the last
item of a leaf and the semaphore was contended, and set ->progress
to 3 (value of 'last'), as the last extent item in the current leaf
was for the extent for range [2, 3); 3) Next time it gets the commit_root_sem, will start using the new commit root and search for a key with offset 3, so it never finds the hole for [2, 3).
So the caching thread never saw [2, 3) as free space in any of the commit roots, and by the time finish_extent_commit() was called for the range [0, 3), ->last_byte_to_unpin was 1, so it only returned the subrange [0, 1) to the free space cache, skipping [2, 3).
In the unpin code we have last_byte_to_unpin == 1, so we unpin [0,1), but do not unpin [2,3). However because caching_ctl->progress == 3 we do not see the newly freed section of [2,3), and thus do not add it to our free space cache. This results in us missing a chunk of free space in memory (on disk too, unless we have a power failure before writing the free space cache to disk).
Fix this by making sure the ->last_byte_to_unpin is set at the same time that we swap the commit roots, this ensures that we will always be consistent.
--- fs/btrfs/ctree.h | 1 - fs/btrfs/extent-tree.c | 25 ------------------------- fs/btrfs/transaction.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 28 deletions(-)
fs/btrfs/ctree.h +0 -1
@@ -2593,7 +2593,6 @@ int btrfs_free_reserved_extent(struct bt u64 start, u64 len, int delalloc);int btrfs_pin_reserved_extent (struct btrfs_trans_handle *trans,u64 start,u64 len); -void btrfs_prepare_extent_commit (struct btrfs_fs_info *fs_info);int btrfs_finish_extent_commit (struct btrfs_trans_handle *trans);int btrfs_inc_extent_ref (struct btrfs_trans_handle *trans,struct btrfs_ref *generic_ref);
fs/btrfs/extent-tree.c +0 -25
@@ -2730,31 +2730,6 @@ btrfs_inc_block_group_reservations(strucatomic_inc (&bg->reservations); } -void btrfs_prepare_extent_commit (struct btrfs_fs_info *fs_info) -{ -struct btrfs_caching_control *next; -struct btrfs_caching_control *caching_ctl; -struct btrfs_block_group *cache; - -down_write (&fs_info->commit_root_sem); - -list_for_each_entry_safe (caching_ctl, next, - &fs_info->caching_block_groups, list) { - cache = caching_ctl->block_group; -if (btrfs_block_group_done (cache)) { - cache->last_byte_to_unpin = (u64)-1 ; -list_del_init (&caching_ctl->list); -btrfs_put_caching_control (caching_ctl); - }else { - cache->last_byte_to_unpin = caching_ctl->progress; - } - } - -up_write (&fs_info->commit_root_sem); - -btrfs_update_global_block_rsv (fs_info); -} -/* * Returns the free cluster for the given space info and sets empty_cluster to * what it should be based on the mount options.
fs/btrfs/transaction.c +40 -2
60 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 589/717 btrfs: fix race when defragmenting leads to unnecessary IO
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 7f458a3873ae94efe1f37c8b96c97e7298769e98 upstream.
When defragmenting we skip ranges that have holes or inline extents, so that we don't do unnecessary IO and waste space. We do this check when calling should_defrag_range() at btrfs_defrag_file(). However we do it without holding the inode's lock. The reason we do it like this is to avoid blocking other tasks for too long, that possibly want to operate on other file ranges, since after the call to should_defrag_range() and before locking the inode, we trigger a synchronous page cache readahead. However before we were able to lock the inode, some other task might have punched a hole in our range, or we may now have an inline extent there, in which case we should not set the range for defrag anymore since that would cause unnecessary IO and make us waste space (i.e. allocating extents to contain zeros for a hole).
So after we locked the inode and the range in the iotree, check again if we have holes or an inline extent, and if we do, just skip the range.
I hit this while testing my next patch that fixes races when updating an inode's number of bytes (subject "btrfs: update the number of bytes used by an inode atomically"), and it depends on this change in order to work correctly. Alternatively I could rework that other patch to detect holes and flag their range with the 'new delalloc' bit, but this itself fixes an efficiency problem due a race that from a functional point of view is not harmful (it could be triggered with btrfs/062 from fstests).
--- fs/btrfs/ioctl.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
fs/btrfs/ioctl.c +39 -0
@@ -1275,6 +1275,7 @@ static int cluster_pages_for_defrag(struu64 page_end;u64 page_cnt;u64 start = (u64 )start_index <<PAGE_SHIFT ; +u64 search_start;int ret;int i;int i_done;
@@ -1371,6 +1372,40 @@ again:lock_extent_bits (&BTRFS_I (inode)->io_tree, page_start, page_end -1 , &cached_state); + +/* +* When defragmenting we skip ranges that have holes or inline extents, +* (check should_defrag_range()), to avoid unnecessary IO and wasting +* space. At btrfs_defrag_file(), we check if a range should be defragged +* before locking the inode and then, if it should, we trigger a sync +* page cache readahead - we lock the inode only after that to avoid +* blocking for too long other tasks that possibly want to operate on +* other file ranges. But before we were able to get the inode lock, +* some other task may have punched a hole in the range, or we may have +* now an inline extent, in which case we should not defrag. So check +* for that here, where we have the inode and the range locked, and bail +* out if that happened. +*/ + search_start = page_start; +while (search_start < page_end) { +struct extent_map *em; + + em =btrfs_get_extent (BTRFS_I (inode),NULL ,0 , search_start, + page_end - search_start); +if (IS_ERR (em)) { + ret =PTR_ERR (em); + goto out_unlock_range; + } +if (em->block_start >=EXTENT_MAP_LAST_BYTE ) { +free_extent_map (em); +/* Ok, 0 means we did not defrag anything */ + ret =0 ; + goto out_unlock_range; + } + search_start =extent_map_end (em); +free_extent_map (em); + } +clear_extent_bit (&BTRFS_I (inode)->io_tree, page_start, page_end -1 ,EXTENT_DELALLOC |EXTENT_DO_ACCOUNTING |EXTENT_DEFRAG ,0 ,0 , &cached_state);
@@ -1401,6 +1436,10 @@ again:btrfs_delalloc_release_extents (BTRFS_I (inode), page_cnt <<PAGE_SHIFT );extent_changeset_free (data_reserved);return i_done; + +out_unlock_range: +unlock_extent_cached (&BTRFS_I (inode)->io_tree, + page_start, page_end -1 , &cached_state); out:for (i =0 ; i < i_done; i++) {unlock_page (pages[i]);
Greg Kroah-Hartman
maintainerPATCH 590/717 ext4: fix an IS_ERR() vs NULL check
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit bc18546bf68e47996a359d2533168d5770a22024 upstream.
The ext4_find_extent() function never returns NULL, it returns error pointers.
--- fs/ext4/extents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/extents.c +2 -2
@@ -5815,8 +5815,8 @@ int ext4_ext_replay_update_ex(struct inoint ret; path =ext4_find_extent (inode, start,NULL ,0 ); -if (!path) -return -EINVAL ; +if (IS_ERR (path)) +return PTR_ERR (path); ex = path[path->p_depth].p_ext;if (!ex) { ret = -EFSCORRUPTED ;
Greg Kroah-Hartman
maintainerPATCH 591/717 ext4: fix a memory leak of ext4_free_data
In reply to Greg Kroah-HartmanFrom: Chunguang Xu <[email protected]>
commit cca415537244f6102cbb09b5b90db6ae2c953bdd upstream.
When freeing metadata, we will create an ext4_free_data and insert it into the pending free list. After the current transaction is committed, the object will be freed.
ext4_mb_free_metadata() will check whether the area to be freed overlaps with the pending free list. If true, return directly. At this time, ext4_free_data is leaked. Fortunately, the probability of this problem is small, since it only occurs if the file system is corrupted such that a block is claimed by more one inode and those inodes are deleted within a single jbd2 transaction.
--- fs/ext4/mballoc.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/mballoc.c +1 -0
@@ -5126,6 +5126,7 @@ ext4_mb_free_metadata(handle_t *handle,ext4_group_first_block_no (sb, group) +EXT4_C2B (sbi, cluster), "Block already on to-be-freed list"); +kmem_cache_free (ext4_free_data_cachep, new_entry);return 0 ; } }
Greg Kroah-Hartman
maintainerPATCH 592/717 ext4: fix deadlock with fs freezing and EA inodes
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 46e294efc355c48d1dd4d58501aa56dac461792a upstream.
Xattr code using inodes with large xattr data can end up dropping last inode reference (and thus deleting the inode) from places like ext4_xattr_set_entry(). That function is called with transaction started and so ext4_evict_inode() can deadlock against fs freezing like:
CPU1 CPU2
removexattr() freeze_super()
vfs_removexattr()
ext4_xattr_set()
handle = ext4_journal_start()
...
ext4_xattr_set_entry()
iput(old_ea_inode)
ext4_evict_inode(old_ea_inode)
sb->s_writers.frozen = SB_FREEZE_FS;
sb_wait_write(sb, SB_FREEZE_FS);
ext4_freeze()
jbd2_journal_lock_updates()
-> blocks waiting for all
handles to stop
sb_start_intwrite()
-> blocks as sb is already in SB_FREEZE_FS stateGenerally it is advisable to delete inodes from a separate transaction as it can consume quite some credits however in this case it would be quite clumsy and furthermore the credits for inode deletion are quite limited and already accounted for. So just tweak ext4_evict_inode() to avoid freeze protection if we have transaction already started and thus it is not really needed anyway.
--- fs/ext4/inode.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
fs/ext4/inode.c +15 -6
@@ -175,6 +175,7 @@ void ext4_evict_inode(struct inode *inod*/ int extra_credits =6 ;struct ext4_xattr_inode_array *ea_inode_array =NULL ; +bool freeze_protected = false;trace_ext4_evict_inode (inode);
@@ -232,9 +233,14 @@ void ext4_evict_inode(struct inode *inod/* * Protect us against freezing - iput() caller didn't have to have any -* protection against it -*/ -sb_start_intwrite (inode->i_sb); +* protection against it. When we are in a running transaction though, +* we are already protected against freezing and we cannot grab further +* protection due to lock ordering constraints. +*/ +if (!ext4_journal_current_handle ()) { +sb_start_intwrite (inode->i_sb); + freeze_protected = true; + }if (!IS_NOQUOTA (inode)) extra_credits +=EXT4_MAXQUOTAS_DEL_BLOCKS (inode->i_sb);
@@ -253,7 +259,8 @@ void ext4_evict_inode(struct inode *inod* cleaned up. */ ext4_orphan_del (NULL , inode); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb); goto no_delete; }
@@ -294,7 +301,8 @@ void ext4_evict_inode(struct inode *inod stop_handle:ext4_journal_stop (handle);ext4_orphan_del (NULL , inode); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb);ext4_xattr_inode_array_free (ea_inode_array); goto no_delete; }
@@ -323,7 +331,8 @@ stop_handle:else ext4_free_inode (handle, inode);ext4_journal_stop (handle); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb);ext4_xattr_inode_array_free (ea_inode_array);return ; no_delete:
Greg Kroah-Hartman
maintainerPATCH 593/717 ext4: dont remount read-only with errors=continue on reboot
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit b08070eca9e247f60ab39d79b2c25d274750441f upstream.
ext4_handle_error() with errors=continue mount option can accidentally remount the filesystem read-only when the system is rebooting. Fix that.
--- fs/ext4/super.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
fs/ext4/super.c +6 -8
@@ -666,19 +666,17 @@ static bool system_going_down(void)static void ext4_handle_error (struct super_block *sb) { +journal_t *journal =EXT4_SB (sb)->s_journal; +if (test_opt (sb,WARN_ON_ERROR ))WARN_ON_ONCE (1 ); -if (sb_rdonly (sb)) +if (sb_rdonly (sb) ||test_opt (sb,ERRORS_CONT ))return ; -if (!test_opt (sb,ERRORS_CONT )) { -journal_t *journal =EXT4_SB (sb)->s_journal; - -ext4_set_mount_flag (sb,EXT4_MF_FS_ABORTED ); -if (journal) -jbd2_journal_abort (journal, -EIO ); - } +ext4_set_mount_flag (sb,EXT4_MF_FS_ABORTED ); +if (journal) +jbd2_journal_abort (journal, -EIO );/* * We force ERRORS_RO behavior when system is rebooting. Otherwise we * could panic during 'reboot -f' as the underlying device got already
Greg Kroah-Hartman
maintainerPATCH 594/717 RISC-V: Fix usage of memblock_enforce_memory_limit
In reply to Greg Kroah-HartmanFrom: Atish Patra <[email protected]>
commit de043da0b9e71147ca610ed542d34858aadfc61c upstream.
memblock_enforce_memory_limit accepts the maximum memory size not the maximum address that can be handled by kernel. Fix the function invocation accordingly.
--- arch/riscv/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/mm/init.c +1 -1
@@ -174,7 +174,7 @@ void __init setup_bootmem(void)* Make sure that any memory beyond mem_start + (-PAGE_OFFSET) is removed * as it is unusable by kernel. */ -memblock_enforce_memory_limit (mem_start -PAGE_OFFSET ); +memblock_enforce_memory_limit (-PAGE_OFFSET );/* Reserve from the start of the kernel to the end of the kernel */ memblock_reserve (vmlinux_start, vmlinux_end - vmlinux_start);
Greg Kroah-Hartman
maintainerPATCH 595/717 arm64: dts: ti: k3-am65: mark dss as dma-coherent
In reply to Greg Kroah-HartmanFrom: Tomi Valkeinen <[email protected]>
commit 50301e8815c681bc5de8ca7050c4b426923d4e19 upstream.
DSS is IO coherent on AM65, so we should mark it as such with 'dma-coherent' property in the DT file.
--- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/ti/k3-am65-main.dtsi +2 -0
@@ -867,6 +867,8 @@ status = "disabled"; + dma-coherent; + dss_ports: ports { #address-cells = <1>; #size-cells = <0>;
Greg Kroah-Hartman
maintainerPATCH 596/717 arm64: dts: marvell: keep SMMU disabled by default for Armada 7040 and 8040
In reply to Greg Kroah-HartmanFrom: Tomasz Nowicki <[email protected]>
commit f43cadef2df260101497a6aace05e24201f00202 upstream.
FW has to configure devices' StreamIDs so that SMMU is able to lookup context and do proper translation later on. For Armada 7040 & 8040 and publicly available FW, most of the devices are configured properly, but some like ap_sdhci0, PCIe, NIC still remain unassigned which results in SMMU faults about unmatched StreamID (assuming ARM_SMMU_DISABLE_BYPASS_BY_DEFAUL=y).
Since there is dependency on custom FW let SMMU be disabled by default. People who still willing to use SMMU need to enable manually and use ARM_SMMU_DISABLE_BYPASS_BY_DEFAUL=n (or via kernel command line) with extra caution.
--- arch/arm64/boot/dts/marvell/armada-7040.dtsi | 4 ---- arch/arm64/boot/dts/marvell/armada-8040.dtsi | 4 ---- 2 files changed, 8 deletions(-)
arch/arm64/boot/dts/marvell/armada-7040.dtsi +0 -4
@@ -15,10 +15,6 @@ "marvell,armada-ap806"; }; -&smmu { - status = "okay"; -}; - &cp0_pcie0 { iommu-map = <0x0 &smmu 0x480 0x20>,
arch/arm64/boot/dts/marvell/armada-8040.dtsi +0 -4
@@ -15,10 +15,6 @@ "marvell,armada-ap806"; }; -&smmu { - status = "okay"; -}; - &cp0_pcie0 { iommu-map = <0x0 &smmu 0x480 0x20>,
Greg Kroah-Hartman
maintainerPATCH 597/717 KVM: arm64: Introduce handling of AArch32 TTBCR2 traps
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit ca4e514774930f30b66375a974b5edcbebaf0e7e upstream.
ARMv8.2 introduced TTBCR2, which shares TCR_EL1 with TTBCR. Gracefully handle traps to this register when HCR_EL2.TVM is set.
--- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/sys_regs.c | 1 + 2 files changed, 2 insertions(+)
arch/arm64/include/asm/kvm_host.h +1 -0
@@ -214,6 +214,7 @@ enum vcpu_sysreg {#define c2_TTBR1 (TTBR1_EL1 * 2)/* Translation Table Base Register 1 */ #define c2_TTBR1_high (c2_TTBR1 + 1)/* TTBR1 top 32 bits */ #define c2_TTBCR (TCR_EL1 * 2)/* Translation Table Base Control R. */ +#define c2_TTBCR2 (c2_TTBCR + 1)/* Translation Table Base Control R. 2 */ #define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */ #define c5_DFSR (ESR_EL1 * 2)/* Data Fault Status Register */ #define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
arch/arm64/kvm/sys_regs.c +1 -0
@@ -1987,6 +1987,7 @@ static const struct sys_reg_desc cp15_re { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR }, + { Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, c2_TTBCR2 }, { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, c3_DACR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, c5_DFSR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, c5_IFSR },
Greg Kroah-Hartman
maintainerPATCH 598/717 KVM: x86: reinstate vendor-agnostic check on SPEC_CTRL cpuid bits
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 39485ed95d6b83b62fa75c06c2c4d33992e0d971 upstream.
Until commit e7c587da1252 ("x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP"), KVM was testing both Intel and AMD CPUID bits before allowing the guest to write MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD. Testing only Intel bits on VMX processors, or only AMD bits on SVM processors, fails if the guests are created with the "opposite" vendor as the host.
While at it, also tweak the host CPU check to use the vendor-agnostic feature bit X86_FEATURE_IBPB, since we only care about the availability of the MSR on the host here and not about specific CPUID bits.
--- arch/x86/kvm/cpuid.h | 14 ++++++++++++++ arch/x86/kvm/svm/svm.c | 14 ++++---------- arch/x86/kvm/vmx/vmx.c | 8 ++++---- 3 files changed, 22 insertions(+), 14 deletions(-)
arch/x86/kvm/cpuid.h +14 -0
@@ -264,6 +264,20 @@ static inline int guest_cpuid_stepping(sreturn x86_stepping (best->eax); } +static inline bool guest_has_spec_ctrl_msr (struct kvm_vcpu *vcpu) +{ +return (guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL ) || +guest_cpuid_has (vcpu,X86_FEATURE_AMD_STIBP ) || +guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBRS ) || +guest_cpuid_has (vcpu,X86_FEATURE_AMD_SSBD )); +} + +static inline bool guest_has_pred_cmd_msr (struct kvm_vcpu *vcpu) +{ +return (guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL ) || +guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBPB )); +} +static inline bool supports_cpuid_fault (struct kvm_vcpu *vcpu) {return vcpu->arch.msr_platform_info &MSR_PLATFORM_INFO_CPUID_FAULT ;
arch/x86/kvm/svm/svm.c +4 -10
@@ -2543,10 +2543,7 @@ static int svm_get_msr(struct kvm_vcpu *break ;case MSR_IA32_SPEC_CTRL :if (!msr_info->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_STIBP ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBRS ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_SSBD )) + !guest_has_spec_ctrl_msr (vcpu))return 1 ; msr_info->data = svm->spec_ctrl;
@@ -2630,10 +2627,7 @@ static int svm_set_msr(struct kvm_vcpu *break ;case MSR_IA32_SPEC_CTRL :if (!msr->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_STIBP ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBRS ) && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_SSBD )) + !guest_has_spec_ctrl_msr (vcpu))return 1 ;if (kvm_spec_ctrl_test_value (data))
@@ -2658,12 +2652,12 @@ static int svm_set_msr(struct kvm_vcpu *break ;case MSR_IA32_PRED_CMD :if (!msr->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_AMD_IBPB )) + !guest_has_pred_cmd_msr (vcpu))return 1 ;if (data & ~PRED_CMD_IBPB )return 1 ; -if (!boot_cpu_has (X86_FEATURE_AMD_IBPB )) +if (!boot_cpu_has (X86_FEATURE_IBPB ))return 1 ;if (!data)break ;
arch/x86/kvm/vmx/vmx.c +4 -4
@@ -1826,7 +1826,7 @@ static int vmx_get_msr(struct kvm_vcpu *break ;case MSR_IA32_SPEC_CTRL :if (!msr_info->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL )) + !guest_has_spec_ctrl_msr (vcpu))return 1 ; msr_info->data =to_vmx (vcpu)->spec_ctrl;
@@ -2028,7 +2028,7 @@ static int vmx_set_msr(struct kvm_vcpu *break ;case MSR_IA32_SPEC_CTRL :if (!msr_info->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL )) + !guest_has_spec_ctrl_msr (vcpu))return 1 ;if (kvm_spec_ctrl_test_value (data))
@@ -2063,12 +2063,12 @@ static int vmx_set_msr(struct kvm_vcpu * goto find_uret_msr;case MSR_IA32_PRED_CMD :if (!msr_info->host_initiated && - !guest_cpuid_has (vcpu,X86_FEATURE_SPEC_CTRL )) + !guest_has_pred_cmd_msr (vcpu))return 1 ;if (data & ~PRED_CMD_IBPB )return 1 ; -if (!boot_cpu_has (X86_FEATURE_SPEC_CTRL )) +if (!boot_cpu_has (X86_FEATURE_IBPB ))return 1 ;if (!data)break ;
Greg Kroah-Hartman
maintainerPATCH 599/717 KVM: SVM: Remove the call to sev_platform_status() during setup
In reply to Greg Kroah-HartmanFrom: Tom Lendacky <[email protected]>
commit 9d4747d02376aeb8de38afa25430de79129c5799 upstream.
When both KVM support and the CCP driver are built into the kernel instead of as modules, KVM initialization can happen before CCP initialization. As a result, sev_platform_status() will return a failure when it is called from sev_hardware_setup(), when this isn't really an error condition.
Since sev_platform_status() doesn't need to be called at this time anyway, remove the invocation from sev_hardware_setup().
Message-Id: <618380488358b56af558f2682203786f09a49483.1607620209.git.thomas.lendacky@amd.com>
--- arch/x86/kvm/svm/sev.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-)
arch/x86/kvm/svm/sev.c +1 -21
@@ -1127,9 +1127,6 @@ void sev_vm_destroy(struct kvm *kvm)int __init sev_hardware_setup (void ) { -struct sev_user_data_status *status; -int rc; -/* Maximum number of encrypted guests supported simultaneously */ max_sev_asid =cpuid_ecx (0x8000001F );
@@ -1148,26 +1145,9 @@ int __init sev_hardware_setup(void)if (!sev_reclaim_asid_bitmap)return 1 ; - status =kmalloc (sizeof (*status),GFP_KERNEL ); -if (!status) -return 1 ; - -/* -* Check SEV platform status. -* -* PLATFORM_STATUS can be called in any state, if we failed to query -* the PLATFORM status then either PSP firmware does not support SEV -* feature or SEV firmware is dead. -*/ - rc =sev_platform_status (status,NULL ); -if (rc) - goto err; -pr_info ("SEV supported\n" ); -err: -kfree (status); -return rc; +return 0 ; }void sev_hardware_teardown (void )
Greg Kroah-Hartman
maintainerPATCH 600/717 iommu/arm-smmu: Allow implementation specific write_s2cr
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
commit 56b75b51ed6d5e7bffda59440404409bca2dff00 upstream.
The firmware found in some Qualcomm platforms intercepts writes to the S2CR register in order to replace the BYPASS type with FAULT. Further more it treats faults at this level as catastrophic and restarts the device.
Add support for providing implementation specific versions of the S2CR write function, to allow the Qualcomm driver to work around this behavior.
--- drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 ++++++++++--- drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +10 -3
@@ -929,9 +929,16 @@ static void arm_smmu_write_smr(struct arstatic void arm_smmu_write_s2cr (struct arm_smmu_device *smmu,int idx) {struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx; -u32 reg =FIELD_PREP (ARM_SMMU_S2CR_TYPE , s2cr->type) | -FIELD_PREP (ARM_SMMU_S2CR_CBNDX , s2cr->cbndx) | -FIELD_PREP (ARM_SMMU_S2CR_PRIVCFG , s2cr->privcfg); +u32 reg; + +if (smmu->impl && smmu->impl->write_s2cr) { + smmu->impl->write_s2cr (smmu, idx); +return ; + } + + reg =FIELD_PREP (ARM_SMMU_S2CR_TYPE , s2cr->type) | +FIELD_PREP (ARM_SMMU_S2CR_CBNDX , s2cr->cbndx) | +FIELD_PREP (ARM_SMMU_S2CR_PRIVCFG , s2cr->privcfg);if (smmu->features &ARM_SMMU_FEAT_EXIDS && smmu->smrs && smmu->smrs[idx].valid)
drivers/iommu/arm/arm-smmu/arm-smmu.h +1 -0
@@ -436,6 +436,7 @@ struct arm_smmu_impl {int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,struct arm_smmu_device *smmu,struct device *dev,int start); +void (*write_s2cr)(struct arm_smmu_device *smmu,int idx); };#define INVALID_SMENDX -1
Greg Kroah-Hartman
maintainerPATCH 601/717 iommu/arm-smmu-qcom: Read back stream mappings
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
commit 07a7f2caaa5a2619934491bab3c47b261c554fb0 upstream.
The Qualcomm boot loader configures stream mapping for the peripherals that it accesses and in particular it sets up the stream mapping for the display controller to be allowed to scan out a splash screen or EFI framebuffer.
Read back the stream mappings during initialization and make the arm-smmu driver maintain the streams in bypass mode.
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +23 -0
@@ -23,6 +23,28 @@ static const struct of_device_id qcom_sm { } }; +static int qcom_smmu_cfg_probe (struct arm_smmu_device *smmu) +{ +u32 smr; +int i; + +for (i =0 ; i < smmu->num_mapping_groups; i++) { + smr =arm_smmu_gr0_read (smmu,ARM_SMMU_GR0_SMR (i)); + +if (FIELD_GET (ARM_SMMU_SMR_VALID , smr)) { + smmu->smrs[i].id =FIELD_GET (ARM_SMMU_SMR_ID , smr); + smmu->smrs[i].mask =FIELD_GET (ARM_SMMU_SMR_MASK , smr); + smmu->smrs[i].valid = true; + + smmu->s2crs[i].type =S2CR_TYPE_BYPASS ; + smmu->s2crs[i].privcfg =S2CR_PRIVCFG_DEFAULT ; + smmu->s2crs[i].cbndx =0xff ; + } + } + +return 0 ; +} +static int qcom_smmu_def_domain_type (struct device *dev) { const struct of_device_id *match =
@@ -61,6 +83,7 @@ static int qcom_smmu500_reset(struct arm }static const struct arm_smmu_impl qcom_smmu_impl = { + .cfg_probe = qcom_smmu_cfg_probe, .def_domain_type = qcom_smmu_def_domain_type, .reset = qcom_smmu500_reset, };
Greg Kroah-Hartman
maintainerPATCH 602/717 iommu/arm-smmu-qcom: Implement S2CR quirk
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
commit f9081b8ff5934b8d69c748d0200e844cadd2c667 upstream.
The firmware found in some Qualcomm platforms intercepts writes to S2CR in order to replace bypass type streams with fault; and ignore S2CR updates of type fault.
Detect this behavior and implement a custom write_s2cr function in order to trick the firmware into supporting bypass streams by the means of configuring the stream for translation using a reserved and disabled context bank.
Also circumvent the problem of configuring faulting streams by configuring the stream as bypass.
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +67 -0
@@ -10,8 +10,15 @@struct qcom_smmu {struct arm_smmu_device smmu; +bool bypass_quirk; +u8 bypass_cbndx; }; +static struct qcom_smmu *to_qcom_smmu (struct arm_smmu_device *smmu) +{ + return container_of(smmu, struct qcom_smmu, smmu); +} +static const struct of_device_id qcom_smmu_client_of_match[]__maybe_unused = { { .compatible ="qcom,adreno" }, { .compatible ="qcom,mdp4" },
@@ -25,9 +32,33 @@ static const struct of_device_id qcom_smstatic int qcom_smmu_cfg_probe (struct arm_smmu_device *smmu) { +unsigned int last_s2cr =ARM_SMMU_GR0_S2CR (smmu->num_mapping_groups -1 ); +struct qcom_smmu *qsmmu =to_qcom_smmu (smmu); +u32 reg;u32 smr;int i; +/* +* With some firmware versions writes to S2CR of type FAULT are +* ignored, and writing BYPASS will end up written as FAULT in the +* register. Perform a write to S2CR to detect if this is the case and +* if so reserve a context bank to emulate bypass streams. +*/ + reg =FIELD_PREP (ARM_SMMU_S2CR_TYPE ,S2CR_TYPE_BYPASS ) | +FIELD_PREP (ARM_SMMU_S2CR_CBNDX ,0xff ) | +FIELD_PREP (ARM_SMMU_S2CR_PRIVCFG ,S2CR_PRIVCFG_DEFAULT ); +arm_smmu_gr0_write (smmu, last_s2cr, reg); + reg =arm_smmu_gr0_read (smmu, last_s2cr); +if (FIELD_GET (ARM_SMMU_S2CR_TYPE , reg) !=S2CR_TYPE_BYPASS ) { + qsmmu->bypass_quirk = true; + qsmmu->bypass_cbndx = smmu->num_context_banks -1 ; + +set_bit (qsmmu->bypass_cbndx, smmu->context_map); + + reg =FIELD_PREP (ARM_SMMU_CBAR_TYPE ,CBAR_TYPE_S1_TRANS_S2_BYPASS ); +arm_smmu_gr1_write (smmu,ARM_SMMU_GR1_CBAR (qsmmu->bypass_cbndx), reg); + } +for (i =0 ; i < smmu->num_mapping_groups; i++) { smr =arm_smmu_gr0_read (smmu,ARM_SMMU_GR0_SMR (i));
@@ -45,6 +76,41 @@ static int qcom_smmu_cfg_probe(struct arreturn 0 ; } +static void qcom_smmu_write_s2cr (struct arm_smmu_device *smmu,int idx) +{ +struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx; +struct qcom_smmu *qsmmu =to_qcom_smmu (smmu); +u32 cbndx = s2cr->cbndx; +u32 type = s2cr->type; +u32 reg; + +if (qsmmu->bypass_quirk) { +if (type ==S2CR_TYPE_BYPASS ) { +/* +* Firmware with quirky S2CR handling will substitute +* BYPASS writes with FAULT, so point the stream to the +* reserved context bank and ask for translation on the +* stream +*/ + type =S2CR_TYPE_TRANS ; + cbndx = qsmmu->bypass_cbndx; + }else if (type ==S2CR_TYPE_FAULT ) { +/* +* Firmware with quirky S2CR handling will ignore FAULT +* writes, so trick it to write FAULT by asking for a +* BYPASS. +*/ + type =S2CR_TYPE_BYPASS ; + cbndx =0xff ; + } + } + + reg =FIELD_PREP (ARM_SMMU_S2CR_TYPE , type) | +FIELD_PREP (ARM_SMMU_S2CR_CBNDX , cbndx) | +FIELD_PREP (ARM_SMMU_S2CR_PRIVCFG , s2cr->privcfg); +arm_smmu_gr0_write (smmu,ARM_SMMU_GR0_S2CR (idx), reg); +} +static int qcom_smmu_def_domain_type (struct device *dev) { const struct of_device_id *match =
@@ -86,6 +152,7 @@ static const struct arm_smmu_impl qcom_s .cfg_probe = qcom_smmu_cfg_probe, .def_domain_type = qcom_smmu_def_domain_type, .reset = qcom_smmu500_reset, + .write_s2cr = qcom_smmu_write_s2cr, };struct arm_smmu_device *qcom_smmu_impl_init (struct arm_smmu_device *smmu)
Greg Kroah-Hartman
maintainerPATCH 603/717 ARM: dts: pandaboard: fix pinmux for gpio user button of Pandaboard ES
In reply to Greg Kroah-HartmanFrom: H. Nikolaus Schaller <[email protected]>
commit df9dbaf2c415cd94ad520067a1eccfee62f00a33 upstream.
The pinmux control register offset passed to OMAP4_IOPAD is odd.
--- arch/arm/boot/dts/omap4-panda-es.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/omap4-panda-es.dts +1 -1
@@ -46,7 +46,7 @@ button_pins: pinmux_button_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ + OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ >; }; };
Greg Kroah-Hartman
maintainerPATCH 604/717 ARM: dts: at91: sama5d2: fix CAN message ram offset and size
In reply to Greg Kroah-HartmanFrom: Nicolas Ferre <[email protected]>
commit 85b8350ae99d1300eb6dc072459246c2649a8e50 upstream.
CAN0 and CAN1 instances share the same message ram configured at 0x210000 on sama5d2 Linux systems.
According to current configuration of CAN0, we need 0x1c00 bytes so that the CAN1 don't overlap its message ram:
64 x RX FIFO0 elements => 64 x 72 bytes
32 x TXE (TX Event FIFO) elements => 32 x 8 bytes
32 x TXB (TX Buffer) elements => 32 x 72 bytes
So a total of 7168 bytes (0x1C00).
Fix offset to match this needed size.
Make the CAN0 message ram ioremap match exactly this size so that is easily understandable. Adapt CAN1 size accordingly.
--- arch/arm/boot/dts/sama5d2.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/boot/dts/sama5d2.dtsi +3 -3
@@ -725,7 +725,7 @@ can0: can@f8054000 { compatible = "bosch,m_can"; - reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg = <0xf8054000 0x4000>, <0x210000 0x1c00>; reg-names = "m_can", "message_ram"; interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, <64 IRQ_TYPE_LEVEL_HIGH 7>;
@@ -1131,7 +1131,7 @@ can1: can@fc050000 { compatible = "bosch,m_can"; - reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg = <0xfc050000 0x4000>, <0x210000 0x3800>; reg-names = "m_can", "message_ram"; interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, <65 IRQ_TYPE_LEVEL_HIGH 7>;
@@ -1141,7 +1141,7 @@ assigned-clocks = <&pmc PMC_TYPE_GCK 57>; assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>; assigned-clock-rates = <40000000>; - bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + bosch,mram-cfg = <0x1c00 0 0 64 0 0 32 32>; status = "disabled"; };
Greg Kroah-Hartman
maintainerPATCH 605/717 ARM: tegra: Populate OPP table for Tegra20 Ventana
In reply to Greg Kroah-HartmanFrom: Jon Hunter <[email protected]>
commit bd7cd7e05a42491469ca19861da44abc3168cf5f upstream.
Commit 9ce274630495 ("cpufreq: tegra20: Use generic cpufreq-dt driver (Tegra30 supported now)") update the Tegra20 CPUFREQ driver to use the generic CPUFREQ device-tree driver. Since this change CPUFREQ support on the Tegra20 Ventana platform has been broken because the necessary device-tree nodes with the operating point information are not populated for this platform. Fix this by updating device-tree for Venata to include the operating point informration for Tegra20.
--- arch/arm/boot/dts/tegra20-ventana.dts | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/arm/boot/dts/tegra20-ventana.dts +11 -0
@@ -3,6 +3,7 @@ #include <dt-bindings/input/input.h> #include "tegra20.dtsi" +#include "tegra20-cpu-opp.dtsi" / { model = "NVIDIA Tegra20 Ventana evaluation board";
@@ -592,6 +593,16 @@ #clock-cells = <0>; }; + cpus { + cpu0: cpu@0 { + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu@1 { + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + gpio-keys { compatible = "gpio-keys";
Greg Kroah-Hartman
maintainerPATCH 606/717 xprtrdma: Fix XDRBUF_SPARSE_PAGES support
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
commit 15261b9126cd5bb2ad8521da49d8f5c042d904c7 upstream.
Olga K. observed that rpcrdma_marsh_req() allocates sparse pages only when it has determined that a Reply chunk is necessary. There are plenty of cases where no Reply chunk is needed, but the XDRBUF_SPARSE_PAGES flag is set. The result would be a crash in rpcrdma_inline_fixup() when it tries to copy parts of the received Reply into a missing page.
To avoid crashing, handle sparse page allocation up front.
Until XATTR support was added, this issue did not appear often because the only SPARSE_PAGES consumer always expected a reply large enough to always require a Reply chunk.
--- net/sunrpc/xprtrdma/rpc_rdma.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-)
net/sunrpc/xprtrdma/rpc_rdma.c +31 -9
@@ -179,6 +179,31 @@ rpcrdma_nonpayload_inline(const struct r r_xprt->rx_ep->re_max_inline_recv; } +/* ACL likes to be lazy in allocating pages. For TCP, these +* pages can be allocated during receive processing. Not true +* for RDMA, which must always provision receive buffers +* up front. +*/ +static noinline int +rpcrdma_alloc_sparse_pages (struct xdr_buf *buf) +{ +struct page **ppages; +int len; + + len = buf->page_len; + ppages = buf->pages + (buf->page_base >>PAGE_SHIFT ); +while (len >0 ) { +if (!*ppages) + *ppages =alloc_page (GFP_NOWAIT | __GFP_NOWARN); +if (!*ppages) +return -ENOBUFS ; + ppages++; + len -=PAGE_SIZE ; + } + +return 0 ; +} +/* Split @vec on page boundaries into SGEs. FMR registers pages, not * a byte range. Other modes coalesce these SGEs into a single MR * when they can.
@@ -233,15 +258,6 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt ppages = xdrbuf->pages + (xdrbuf->page_base >>PAGE_SHIFT ); page_base =offset_in_page (xdrbuf->page_base);while (len) { -/* ACL likes to be lazy in allocating pages - ACLs -* are small by default but can get huge. -*/ -if (unlikely (xdrbuf->flags &XDRBUF_SPARSE_PAGES )) { -if (!*ppages) - *ppages =alloc_page (GFP_NOWAIT | __GFP_NOWARN); -if (!*ppages) -return -ENOBUFS ; - } seg->mr_page = *ppages; seg->mr_offset = (char *)page_base; seg->mr_len =min_t (u32,PAGE_SIZE - page_base, len);
@@ -867,6 +883,12 @@ rpcrdma_marshal_req(struct rpcrdma_xprt__be32 *p;int ret; +if (unlikely (rqst->rq_rcv_buf.flags &XDRBUF_SPARSE_PAGES )) { + ret =rpcrdma_alloc_sparse_pages (&rqst->rq_rcv_buf); +if (ret) +return ret; + } +rpcrdma_set_xdrlen (&req->rl_hdrbuf,0 );xdr_init_encode (xdr, &req->rl_hdrbuf,rdmab_data (req->rl_rdmabuf), rqst);
Greg Kroah-Hartman
maintainerPATCH 607/717 powerpc/32: Fix vmap stack - Properly set r1 before activating MMU on syscall too
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit d5c243989fb0cb03c74d7340daca3b819f706ee7 upstream.
We need r1 to be properly set before activating MMU, otherwise any new exception taken while saving registers into the stack in syscall prologs will use the user stack, which is wrong and will even lockup or crash when KUAP is selected.
Do that by switching the meaning of r11 and r1 until we have saved r1 to the stack: copy r1 into r11 and setup the new stack pointer in r1. To avoid complicating and impacting all generic and specific prolog code (and more), copy back r1 into r11 once r11 is save onto the stack.
We could get rid of copying r1 back and forth at the cost of rewriting everything to use r1 instead of r11 all the way when CONFIG_VMAP_STACK is set, but the effort is probably not worth it for now.
--- arch/powerpc/kernel/head_32.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
arch/powerpc/kernel/head_32.h +16 -9
@@ -131,18 +131,28 @@#ifdef CONFIG_VMAP_STACK mfspr r11,SPRN_SRR0 mtctr r11 -#endif andi. r11, r9, MSR_PR - lwz r11,TASK_STACK-THREAD(r12) + mr r11, r1 + lwz r1,TASK_STACK-THREAD(r12) beq- 99f - addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE -#ifdef CONFIG_VMAP_STACK + addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ mtmsr r10 isync + tovirt(r12, r12) + stw r11,GPR1(r1) + stw r11,0(r1) + mr r11, r1 +#else + andi. r11, r9, MSR_PR + lwz r11,TASK_STACK-THREAD(r12) + beq- 99f + addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE + tophys(r11, r11) + stw r1,GPR1(r11) + stw r1,0(r11) + tovirt(r1, r11) /* set new kernel sp */ #endif - tovirt_vmstack r12, r12 - tophys_novmstack r11, r11 mflr r10 stw r10, _LINK(r11)#ifdef CONFIG_VMAP_STACK
@@ -150,9 +160,6 @@#else mfspr r10,SPRN_SRR0 #endif - stw r1,GPR1(r11) - stw r1,0(r11) - tovirt_novmstack r1, r11 /* set new kernel sp */ stw r10,_NIP(r11) mfcr r10 rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */
Greg Kroah-Hartman
maintainerPATCH 608/717 powerpc: Fix incorrect stw{, ux, u, x} instructions in __set_pte_at
In reply to Greg Kroah-HartmanFrom: Mathieu Desnoyers <[email protected]>
commit d85be8a49e733dcd23674aa6202870d54bf5600d upstream.
The placeholder for instruction selection should use the second argument's operand, which is %1, not %0. This could generate incorrect assembly code if the memory addressing of operand %0 is a different form from that of operand %1.
Also remove the %Un placeholder because having %Un placeholders for two operands which are based on the same local var (ptep) doesn't make much sense. By the way, it doesn't change the current behaviour because "<>" constraint is missing for the associated "=m".
[chleroy: revised commit log iaw segher's comments and removed %U0]
--- arch/powerpc/include/asm/book3s/32/pgtable.h | 4 ++-- arch/powerpc/include/asm/nohash/pgtable.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/book3s/32/pgtable.h +2 -2
@@ -524,9 +524,9 @@ static inline void __set_pte_at(struct mif (pte_val (*ptep) & _PAGE_HASHPTE)flush_hash_entry (mm, ptep, addr); __asm__ __volatile__("\ -stw%U0%X0 %2,%0\n\ +stw%X0 %2,%0\n\ eieio\n\ -stw%U0%X0 %L2,%1" +stw%X1 %L2,%1" :"=m" (*ptep),"=m" (*((unsigned char *)ptep+4 )) :"r" (pte) :"memory" );
arch/powerpc/include/asm/nohash/pgtable.h +2 -2
@@ -192,9 +192,9 @@ static inline void __set_pte_at(struct m*/ if (IS_ENABLED (CONFIG_PPC32 ) &&IS_ENABLED (CONFIG_PTE_64BIT ) && !percpu) { __asm__ __volatile__("\ -stw%U0%X0 %2,%0\n\ +stw%X0 %2,%0\n\ eieio\n\ -stw%U0%X0 %L2,%1" +stw%X1 %L2,%1" :"=m" (*ptep),"=m" (*((unsigned char *)ptep+4 )) :"r" (pte) :"memory" );return ;
Greg Kroah-Hartman
maintainerPATCH 609/717 powerpc/rtas: Fix typo of ibm,open-errinjct in RTAS filter
In reply to Greg Kroah-HartmanFrom: Tyrel Datwyler <[email protected]>
commit f10881a46f8914428110d110140a455c66bdf27b upstream.
Commit bd59380c5ba4 ("powerpc/rtas: Restrict RTAS requests from userspace") introduced the following error when invoking the errinjct userspace tool:
[root@ltcalpine2-lp5 librtas]# errinjct open
[327884.071171] sys_rtas: RTAS call blocked - exploit attempt? [327884.071186] sys_rtas: token=0x26, nargs=0 (called by errinjct) errinjct: Could not open RTAS error injection facility errinjct: librtas: open: Unexpected I/O error
The entry for ibm,open-errinjct in rtas_filter array has a typo where the "j" is omitted in the rtas call name. After fixing this typo the errinjct tool functions again as expected.
[root@ltcalpine2-lp5 linux]# errinjct open
RTAS error injection facility open, token = 1
--- arch/powerpc/kernel/rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/rtas.c +1 -1
@@ -1030,7 +1030,7 @@ static struct rtas_filter rtas_filters[] { "ibm,display-message", -1, 0, -1, -1, -1 }, { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 }, { "ibm,close-errinjct", -1, -1, -1, -1, -1 }, - { "ibm,open-errinct", -1, -1, -1, -1, -1 }, + { "ibm,open-errinjct", -1, -1, -1, -1, -1 }, { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 }, { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 }, { "ibm,get-indices", -1, 2, 3, -1, -1 },
Greg Kroah-Hartman
maintainerPATCH 610/717 powerpc/bitops: Fix possible undefined behaviour with fls() and fls64()
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 1891ef21d92c4801ea082ee8ed478e304ddc6749 upstream.
fls() and fls64() are using __builtin_ctz() and _builtin_ctzll(). On powerpc, those builtins trivially use ctlzw and ctlzd power instructions.
Allthough those instructions provide the expected result with input argument 0, __builtin_ctz() and __builtin_ctzll() are documented as undefined for value 0.
The easiest fix would be to use fls() and fls64() functions defined in include/asm-generic/bitops/builtin-fls.h and include/asm-generic/bitops/fls64.h, but GCC output is not optimal:
00000388 <testfls>:
388: 2c 03 00 00 cmpwi r3,0 38c: 41 82 00 10 beq 39c <testfls+0x14> 390: 7c 63 00 34 cntlzw r3,r3 394: 20 63 00 20 subfic r3,r3,32 398: 4e 80 00 20 blr 39c: 38 60 00 00 li r3,0 3a0: 4e 80 00 20 blr
000003b0 <testfls64>:
3b0: 2c 03 00 00 cmpwi r3,0 3b4: 40 82 00 1c bne 3d0 <testfls64+0x20> 3b8: 2f 84 00 00 cmpwi cr7,r4,0 3bc: 38 60 00 00 li r3,0 3c0: 4d 9e 00 20 beqlr cr7 3c4: 7c 83 00 34 cntlzw r3,r4 3c8: 20 63 00 20 subfic r3,r3,32 3cc: 4e 80 00 20 blr 3d0: 7c 63 00 34 cntlzw r3,r3 3d4: 20 63 00 40 subfic r3,r3,64 3d8: 4e 80 00 20 blr
When the input of fls(x) is a constant, just check x for nullity and return either 0 or __builtin_clz(x). Otherwise, use cntlzw instruction directly.
For fls64() on PPC64, do the same but with __builtin_clzll() and cntlzd instruction. On PPC32, lets take the generic fls64() which will use our fls(). The result is as expected:
00000388 <testfls>:
388: 7c 63 00 34 cntlzw r3,r3 38c: 20 63 00 20 subfic r3,r3,32 390: 4e 80 00 20 blr
000003a0 <testfls64>:
3a0: 2c 03 00 00 cmpwi r3,0 3a4: 40 82 00 10 bne 3b4 <testfls64+0x14> 3a8: 7c 83 00 34 cntlzw r3,r4 3ac: 20 63 00 20 subfic r3,r3,32 3b0: 4e 80 00 20 blr 3b4: 7c 63 00 34 cntlzw r3,r3 3b8: 20 63 00 40 subfic r3,r3,64 3bc: 4e 80 00 20 blr
--- arch/powerpc/include/asm/bitops.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/bitops.h +21 -2
@@ -216,15 +216,34 @@ static inline void arch___clear_bit_unlo*/ static inline int fls (unsigned int x) { -return 32 -__builtin_clz (x); +int lz; + +if (__builtin_constant_p (x)) +return x ?32 -__builtin_clz (x) :0 ; + asm("cntlzw %0,%1" :"=r" (lz) :"r" (x)); +return 32 - lz; }#include <asm-generic/bitops/builtin-__fls.h> +/* +* 64-bit can do this using one cntlzd (count leading zeroes doubleword) +* instruction; for 32-bit we use the generic version, which does two +* 32-bit fls calls. +*/ +#ifdef CONFIG_PPC64 static inline int fls64 (__u64 x) { -return 64 -__builtin_clzll (x); +int lz; + +if (__builtin_constant_p (x)) +return x ?64 -__builtin_clzll (x) :0 ; + asm("cntlzd %0,%1" :"=r" (lz) :"r" (x)); +return 64 - lz; } +#else +#include <asm-generic/bitops/fls64.h> +#endif #ifdef CONFIG_PPC64 unsigned int __arch_hweight8 (unsigned int w);
Greg Kroah-Hartman
maintainerPATCH 611/717 powerpc/feature: Add CPU_FTR_NOEXECUTE to G2_LE
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 197493af414ee22427be3343637ac290a791925a upstream.
G2_LE has a 603 core, add CPU_FTR_NOEXECUTE.
--- arch/powerpc/include/asm/cputable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/include/asm/cputable.h +1 -1
@@ -369,7 +369,7 @@ static inline void cpu_feature_keys_init CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)#define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE)#define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_MAYBE_CAN_NAP) + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NOEXECUTE)#define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_MAYBE_CAN_NAP | \ CPU_FTR_COMMON | CPU_FTR_NOEXECUTE)
Greg Kroah-Hartman
maintainerPATCH 612/717 powerpc/xmon: Change printk() to pr_cont()
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 7c6c86b36a36dd4a13d30bba07718e767aa2e7a1 upstream.
Since some time now, printk() adds carriage return, leading to unusable xmon output if there is no udbg backend available:
[ 54.288722] sysrq: Entering xmon [ 54.292209] Vector: 0 at [cace3d2c] [ 54.292274] pc: [ 54.292331] c0023650 [ 54.292468] : xmon+0x28/0x58 [ 54.292519] [ 54.292574] lr: [ 54.292630] c0023724 [ 54.292749] : sysrq_handle_xmon+0xa4/0xfc [ 54.292801] [ 54.292867] sp: cace3de8 [ 54.292931] msr: 9032 [ 54.292999] current = 0xc28d0000 [ 54.293072] pid = 377, comm = sh [ 54.293157] Linux version 5.10.0-rc6-s3k-dev-01364-gedf13f0ccd76-dirty ([email protected]) (powerpc64-linux-gcc (GCC) 10.1.0, GNU ld (GNU Binutils) 2.34) #4211 PREEMPT Fri Dec 4 09:32:11 UTC 2020 [ 54.293287] enter ? for help [ 54.293470] [cace3de8] [ 54.293532] c0023724 [ 54.293654] sysrq_handle_xmon+0xa4/0xfc [ 54.293711] (unreliable) ... [ 54.296002] [ 54.296159] --- Exception: c01 (System Call) at [ 54.296217] 0fd4e784 [ 54.296303] [ 54.296375] SP (7fca6ff0) is in userspace [ 54.296431] mon> [ 54.296484] <no input ...>
Use pr_cont() instead.
--- arch/powerpc/xmon/nonstdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/xmon/nonstdio.c +1 -1
@@ -178,7 +178,7 @@ void xmon_printf(const char *format, ...if (n && rc ==0 ) {/* No udbg hooks, fallback to printk() - dangerous */ -printk ("%s" , xmon_outbuf); +pr_cont ("%s" , xmon_outbuf); } }
Greg Kroah-Hartman
maintainerPATCH 613/717 powerpc/8xx: Fix early debug when SMC1 is relocated
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 1e78f723d6a52966bfe3804209dbf404fdc9d3bb upstream.
When SMC1 is relocated and early debug is selected, the board hangs is ppc_md.setup_arch(). This is because ones the microcode has been loaded and SMC1 relocated, early debug writes in the weed.
To allow smooth continuation, the SMC1 parameter RAM set up by the bootloader have to be copied into the new location.
--- arch/powerpc/include/asm/cpm1.h | 1 + arch/powerpc/platforms/8xx/micropatch.c | 11 +++++++++++ 2 files changed, 12 insertions(+)
arch/powerpc/include/asm/cpm1.h +1 -0
@@ -68,6 +68,7 @@ extern void cpm_reset(void);#define PROFF_SPI ((uint)0x0180)#define PROFF_SCC3 ((uint)0x0200)#define PROFF_SMC1 ((uint)0x0280) +#define PROFF_DSP1 ((uint)0x02c0)#define PROFF_SCC4 ((uint)0x0300)#define PROFF_SMC2 ((uint)0x0380)
arch/powerpc/platforms/8xx/micropatch.c +11 -0
@@ -360,6 +360,17 @@ void __init cpm_load_patch(cpm8xx_t *cp)if (IS_ENABLED (CONFIG_SMC_UCODE_PATCH )) {smc_uart_t *smp; +if (IS_ENABLED (CONFIG_PPC_EARLY_DEBUG_CPM )) { +int i; + +for (i =0 ; i <sizeof (*smp); i +=4 ) { +u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i]; +u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i]; + +out_be32 (dst,in_be32 (src)); + } + } + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1 ];out_be16 (&smp->smc_rpbase,0x1ec0 ); smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2 ];
Greg Kroah-Hartman
maintainerPATCH 614/717 powerpc/mm: Fix verification of MMU_FTR_TYPE_44x
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 17179aeb9d34cc81e1a4ae3f85e5b12b13a1f8d0 upstream.
MMU_FTR_TYPE_44x cannot be checked by cpu_has_feature()
Use mmu_has_feature() instead
--- arch/powerpc/mm/mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/mem.c +1 -1
@@ -532,7 +532,7 @@ void __flush_dcache_icache(void *p)* space occurs, before returning to user space. */ -if (cpu_has_feature (MMU_FTR_TYPE_44x)) +if (mmu_has_feature (MMU_FTR_TYPE_44x))return ;invalidate_icache_range (addr, addr +PAGE_SIZE );
Greg Kroah-Hartman
maintainerPATCH 615/717 powerpc/powernv/npu: Do not attempt NPU2 setup on POWER8NVL NPU
In reply to Greg Kroah-HartmanFrom: Alexey Kardashevskiy <[email protected]>
commit b1198a88230f2ce50c271e22b82a8b8610b2eea9 upstream.
We execute certain NPU2 setup code (such as mapping an LPID to a device in NPU2) unconditionally if an Nvlink bridge is detected. However this cannot succeed on POWER8NVL machines and errors appear in dmesg. This is harmless as skiboot returns an error and the only place we check it is vfio-pci but that code does not get called on P8+ either.
This adds a check if pnv_npu2_xxx helpers are called on a machine with NPU2 which initializes pnv_phb::npu in pnv_npu2_init(); pnv_phb::npu==NULL on POWER8/NVL (Naples).
While at this, fix NULL derefencing in pnv_npu_peers_take_ownership/ pnv_npu_peers_release_ownership which occurs when GPUs on mentioned P8s cause EEH which happens if "vfio-pci" disables devices using the D3 power state; the vfio-pci's disable_idle_d3 module parameter controls this and must be set on Naples. The EEH handling clears the entire pnv_ioda_pe struct in pnv_ioda_free_pe() hence the NULL derefencing. We cannot recover from that but at least we stop crashing.
Tested on
- POWER9 pvr=004e1201, Ubuntu 19.04 host, Ubuntu 18.04 vm, NVIDIA GV100 10de:1db1 driver 418.39
- POWER8 pvr=004c0100, RHEL 7.6 host, Ubuntu 16.10 vm, NVIDIA P100 10de:15f9 driver 396.47
--- arch/powerpc/platforms/powernv/npu-dma.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/powerpc/platforms/powernv/npu-dma.c +14 -2
@@ -385,7 +385,8 @@ static void pnv_npu_peers_take_ownershipfor (i =0 ; i < npucomp->pe_num; ++i) {struct pnv_ioda_pe *pe = npucomp->pe[i]; -if (!pe->table_group.ops->take_ownership) +if (!pe->table_group.ops || + !pe->table_group.ops->take_ownership)continue ; pe->table_group.ops->take_ownership (&pe->table_group); }
@@ -401,7 +402,8 @@ static void pnv_npu_peers_release_ownersfor (i =0 ; i < npucomp->pe_num; ++i) {struct pnv_ioda_pe *pe = npucomp->pe[i]; -if (!pe->table_group.ops->release_ownership) +if (!pe->table_group.ops || + !pe->table_group.ops->release_ownership)continue ; pe->table_group.ops->release_ownership (&pe->table_group); }
@@ -623,6 +625,11 @@ int pnv_npu2_map_lpar_dev(struct pci_devreturn -ENODEV ; hose =pci_bus_to_host (npdev->bus); +if (hose->npu ==NULL ) { +dev_info_once (&npdev->dev,"Nvlink1 does not support contexts" ); +return 0 ; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n",
@@ -670,6 +677,11 @@ int pnv_npu2_unmap_lpar_dev(struct pci_dreturn -ENODEV ; hose =pci_bus_to_host (npdev->bus); +if (hose->npu ==NULL ) { +dev_info_once (&npdev->dev,"Nvlink1 does not support contexts" ); +return 0 ; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n",
Greg Kroah-Hartman
maintainerPATCH 616/717 powerpc/powernv/memtrace: Dont leak kernel memory to user space
In reply to Greg Kroah-HartmanFrom: David Hildenbrand <[email protected]>
commit c74cf7a3d59a21b290fe0468f5b470d0b8ee37df upstream.
We currently leak kernel memory to user space, because memory offlining doesn't do any implicit clearing of memory and we are missing explicit clearing of memory.
Let's keep it simple and clear pages before removing the linear mapping.
Reproduced in QEMU/TCG with 10 GiB of main memory:
[root@localhost ~]# dd obs=9G if=/dev/urandom of=/dev/null
[... wait until "free -m" used counter no longer changes and cancel] 19665802+0 records in
1+0 records out
9663676416 bytes (9.7 GB, 9.0 GiB) copied, 135.548 s, 71.3 MB/s [root@localhost ~]# cat /sys/devices/system/memory/block_size_bytes 40000000
[root@localhost ~]# echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
[ 402.978663][ T1086] page:000000001bc4bc74 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x24900 [ 402.980063][ T1086] flags: 0x7ffff000001000(reserved) [ 402.980415][ T1086] raw: 007ffff000001000 c00c000000924008 c00c000000924008 0000000000000000 [ 402.980627][ T1086] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 402.980845][ T1086] page dumped because: unmovable page [ 402.989608][ T1086] Offlined Pages 16384 [ 403.324155][ T1086] memtrace: Allocated trace memory on node 0 at 0x0000000200000000
Before this patch:
[root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head
00000000 c8 25 72 51 4d 26 36 c5 5c c2 56 15 d5 1a cd 10 |.%rQM&6.\.V.....|
00000010 19 b9 50 b2 cb e3 60 b8 ec 0a f3 ec 4b 3c 39 f0 |..P...`.....K<9.|$
00000020 4e 5a 4c cf bd 26 19 ff 37 79 13 67 24 b7 b8 57 |NZL..&..7y.g$..W|$
00000030 98 3e f5 be 6f 14 6a bd a4 52 bc 6e e9 e0 c1 5d |.>..o.j..R.n...]|$
00000040 76 b3 ae b5 88 d7 da e3 64 23 85 2c 10 88 07 b6 |v.......d#.,....|$
00000050 9a d8 91 de f7 50 27 69 2e 64 9c 6f d3 19 45 79 |.....P'i.d.o..Ey|$
00000060 6a 6f 8a 61 71 19 1f c7 f1 df 28 26 ca 0f 84 55 |jo.aq.....(&...U|$
00000070 01 3f be e4 e2 e1 da ff 7b 8c 8e 32 37 b4 24 53 |.?......{..27.$S|$
00000080 1b 70 30 45 56 e6 8c c4 0e b5 4c fb 9f dd 88 06 |.p0EV.....L.....|$
00000090 ef c4 18 79 f1 60 b1 5c 79 59 4d f4 36 d7 4a 5c |...y.`.\yYM.6.J\|$After this patch:
[root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| *
40000000
--- arch/powerpc/platforms/powernv/memtrace.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/powerpc/platforms/powernv/memtrace.c +22 -0
@@ -67,6 +67,23 @@ static int change_memblock_state(structreturn 0 ; } +static void memtrace_clear_range (unsigned long start_pfn, +unsigned long nr_pages) +{ +unsigned long pfn; + +/* +* As pages are offline, we cannot trust the memmap anymore. As HIGHMEM +* does not apply, avoid passing around "struct page" and use +* clear_page() instead directly. +*/ +for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { +if (IS_ALIGNED (pfn,PAGES_PER_SECTION )) +cond_resched (); +clear_page (__va (PFN_PHYS (pfn))); + } +} +/* called with device_hotplug_lock held */ static bool memtrace_offline_pages (u32 nid,u64 start_pfn,u64 nr_pages) {
@@ -112,6 +129,11 @@ static u64 memtrace_alloc_node(u32 nid,for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) {if (memtrace_offline_pages (nid, base_pfn, nr_pages) == true) {/* +* Clear the range while we still have a linear +* mapping. +*/ +memtrace_clear_range (base_pfn, nr_pages); +/* * Remove memory in memory block size chunks so that * iomem resources are always split to the same size and * we never try to remove memory that spans two iomem
Greg Kroah-Hartman
maintainerPATCH 617/717 powerpc/powernv/memtrace: Fix crashing the kernel when enabling concurrently
In reply to Greg Kroah-HartmanFrom: David Hildenbrand <[email protected]>
commit d6718941a2767fb383e105d257d2105fe4f15f0e upstream.
It's very easy to crash the kernel right now by simply trying to enable memtrace concurrently, hammering on the "enable" interface
loop.sh:
#!/bin/bash
dmesg --console-off
while true; do
echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
done
[root@localhost ~]# loop.sh &
[root@localhost ~]# loop.sh &
Resulting quickly in a kernel crash. Let's properly protect using a mutex.
--- arch/powerpc/platforms/powernv/memtrace.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
arch/powerpc/platforms/powernv/memtrace.c +15 -7
@@ -30,6 +30,7 @@ struct memtrace_entry {char name[16 ]; }; +static DEFINE_MUTEX (memtrace_mutex);static u64 memtrace_size;static struct memtrace_entry *memtrace_array;
@@ -279,6 +280,7 @@ static int memtrace_online(void)static int memtrace_enable_set (void *data,u64 val) { +int rc = -EAGAIN ;u64 bytes;/*
@@ -291,25 +293,31 @@ static int memtrace_enable_set(void *datreturn -EINVAL ; } +mutex_lock (&memtrace_mutex); +/* Re-add/online previously removed/offlined memory */ if (memtrace_size) {if (memtrace_online ()) -return -EAGAIN ; + goto out_unlock; } -if (!val) -return 0 ; +if (!val) { + rc =0 ; + goto out_unlock; + }/* Offline and remove memory */ if (memtrace_init_regions_runtime (val)) -return -EINVAL ; + goto out_unlock;if (memtrace_init_debugfs ()) -return -EINVAL ; + goto out_unlock; memtrace_size = val; - -return 0 ; + rc =0 ; +out_unlock: +mutex_unlock (&memtrace_mutex); +return rc; }static int memtrace_enable_get (void *data,u64 *val)
Greg Kroah-Hartman
maintainerPATCH 618/717 ovl: make ioctl() safe
In reply to Greg Kroah-HartmanFrom: Miklos Szeredi <[email protected]>
commit 89bdfaf93d9157499c3a0d61f489df66f2dead7f upstream.
ovl_ioctl_set_flags() does a capability check using flags, but then the real ioctl double-fetches flags and uses potentially different value.
The "Check the capability before cred override" comment misleading: user can skip this check by presenting benign flags first and then overwriting them to non-benign flags.
Just remove the cred override for now, hoping this doesn't cause a regression.
The proper solution is to create a new setxflags i_op (patches are in the works).
Xfstests don't show a regression.
--- fs/overlayfs/file.c | 87 +++++++++------------------------------------------- 1 file changed, 16 insertions(+), 71 deletions(-)
fs/overlayfs/file.c +16 -71
@@ -541,46 +541,31 @@ static long ovl_real_ioctl(struct file * unsigned long arg) {struct fd real; -const struct cred *old_cred;long ret; ret =ovl_real_fdget (file, &real);if (ret)return ret; - old_cred =ovl_override_creds (file_inode (file)->i_sb); ret =security_file_ioctl (real.file, cmd, arg); -if (!ret) +if (!ret) { +/* +* Don't override creds, since we currently can't safely check +* permissions before doing so. +*/ ret =vfs_ioctl (real.file, cmd, arg); -revert_creds (old_cred); + }fdput (real);return ret; } -static unsigned int ovl_iflags_to_fsflags (unsigned int iflags) -{ -unsigned int flags =0 ; - -if (iflags &S_SYNC ) - flags |=FS_SYNC_FL ; -if (iflags &S_APPEND ) - flags |=FS_APPEND_FL ; -if (iflags &S_IMMUTABLE ) - flags |=FS_IMMUTABLE_FL ; -if (iflags &S_NOATIME ) - flags |=FS_NOATIME_FL ; - -return flags; -} -static long ovl_ioctl_set_flags (struct file *file,unsigned int cmd, -unsigned long arg,unsigned int flags) +unsigned long arg) {long ret;struct inode *inode =file_inode (file); -unsigned int oldflags;if (!inode_owner_or_capable (inode))return -EACCES ;
@@ -591,10 +576,13 @@ static long ovl_ioctl_set_flags(struct finode_lock (inode); -/* Check the capability before cred override */ - oldflags =ovl_iflags_to_fsflags (READ_ONCE (inode->i_flags)); - ret =vfs_ioc_setflags_prepare (inode, oldflags, flags); -if (ret) +/* +* Prevent copy up if immutable and has no CAP_LINUX_IMMUTABLE +* capability. +*/ + ret = -EPERM ; +if (!ovl_has_upperdata (inode) &&IS_IMMUTABLE (inode) && + !capable (CAP_LINUX_IMMUTABLE )) goto unlock; ret =ovl_maybe_copy_up (file_dentry (file),O_WRONLY );
@@ -613,46 +601,6 @@ unlock: } -static long ovl_ioctl_set_fsflags (struct file *file,unsigned int cmd, -unsigned long arg) -{ -unsigned int flags; - -if (get_user (flags, (int __user *) arg)) -return -EFAULT ; - -return ovl_ioctl_set_flags (file, cmd, arg, flags); -} - -static unsigned int ovl_fsxflags_to_fsflags (unsigned int xflags) -{ -unsigned int flags =0 ; - -if (xflags &FS_XFLAG_SYNC ) - flags |=FS_SYNC_FL ; -if (xflags &FS_XFLAG_APPEND ) - flags |=FS_APPEND_FL ; -if (xflags &FS_XFLAG_IMMUTABLE ) - flags |=FS_IMMUTABLE_FL ; -if (xflags &FS_XFLAG_NOATIME ) - flags |=FS_NOATIME_FL ; - -return flags; -} - -static long ovl_ioctl_set_fsxflags (struct file *file,unsigned int cmd, -unsigned long arg) -{ -struct fsxattr fa; - -memset (&fa,0 ,sizeof (fa)); -if (copy_from_user (&fa, (void __user *) arg,sizeof (fa))) -return -EFAULT ; - -return ovl_ioctl_set_flags (file, cmd, arg, -ovl_fsxflags_to_fsflags (fa.fsx_xflags)); -} -long ovl_ioctl (struct file *file,unsigned int cmd,unsigned long arg) {long ret;
@@ -663,12 +611,9 @@ long ovl_ioctl(struct file *file, unsign ret =ovl_real_ioctl (file, cmd, arg);break ; -case FS_IOC_SETFLAGS : - ret =ovl_ioctl_set_fsflags (file, cmd, arg); -break ; -case FS_IOC_FSSETXATTR : - ret =ovl_ioctl_set_fsxflags (file, cmd, arg); +case FS_IOC_SETFLAGS : + ret =ovl_ioctl_set_flags (file, cmd, arg);break ;default :
Greg Kroah-Hartman
maintainerPATCH 619/717 ima: Dont modify file descriptor mode on the fly
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit 207cdd565dfc95a0a5185263a567817b7ebf5467 upstream.
Commit a408e4a86b36b ("ima: open a new file instance if no read permissions") already introduced a second open to measure a file when the original file descriptor does not allow it. However, it didn't remove the existing method of changing the mode of the original file descriptor, which is still necessary if the current process does not have enough privileges to open a new one.
Changing the mode isn't really an option, as the filesystem might need to do preliminary steps to make the read possible. Thus, this patch removes the code and keeps the second open as the only option to measure a file when it is unreadable with the original file descriptor.
--- security/integrity/ima/ima_crypto.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
security/integrity/ima/ima_crypto.c +5 -15
@@ -537,7 +537,7 @@ int ima_calc_file_hash(struct file *fileloff_t i_size;int rc;struct file *f = file; -bool new_file_instance = false, modified_mode = false; +bool new_file_instance = false;/* * For consistency, fail file's opened with the O_DIRECT flag on
@@ -555,18 +555,10 @@ int ima_calc_file_hash(struct file *file O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL); flags |=O_RDONLY ; f =dentry_open (&file->f_path, flags, file->f_cred); -if (IS_ERR (f)) { -/* -* Cannot open the file again, lets modify f_mode -* of original and continue -*/ -pr_info_ratelimited ("Unable to reopen file for reading.\n" ); - f = file; - f->f_mode |=FMODE_READ ; - modified_mode = true; - }else { - new_file_instance = true; - } +if (IS_ERR (f)) +return PTR_ERR (f); + + new_file_instance = true; } i_size =i_size_read (file_inode (f));
@@ -581,8 +573,6 @@ int ima_calc_file_hash(struct file *file out:if (new_file_instance)fput (f); -else if (modified_mode) - f->f_mode &= ~FMODE_READ ;return rc; }
Greg Kroah-Hartman
maintainerPATCH 620/717 um: Remove use of asprinf in umid.c
In reply to Greg Kroah-HartmanFrom: Anton Ivanov <[email protected]>
commit 97be7ceaf7fea68104824b6aa874cff235333ac1 upstream.
asprintf is not compatible with the existing uml memory allocation mechanism. Its use on the "user" side of UML results in a corrupt slab state.
--- arch/um/os-Linux/umid.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
arch/um/os-Linux/umid.c +5 -12
@@ -137,20 +137,13 @@ static inline int is_umdir_used(char *di {char pid[sizeof ("nnnnnnnnn" )], *end, *file;int dead, fd, p, n, err; -size_t filelen; +size_t filelen =strlen (dir) +sizeof ("/pid" ) +1 ; - err =asprintf (&file,"%s/pid" , dir); -if (err <0 ) -return 0 ; + file =malloc (filelen); +if (!file) +return -ENOMEM ; - filelen =strlen (file); - - n =snprintf (file, filelen,"%s/pid" , dir); -if (n >= filelen) { -printk (UM_KERN_ERR "is_umdir_used - pid filename too long\n" ); - err = -E2BIG ; - goto out; - } +snprintf (file, filelen,"%s/pid" , dir); dead =0 ; fd =open (file,O_RDONLY );
Greg Kroah-Hartman
maintainerPATCH 621/717 um: Fix time-travel mode
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit ff9632d2a66512436d616ef4c380a0e73f748db1 upstream.
Since the time-travel rework, basic time-travel mode hasn't worked properly, but there's no longer a need for this WARN_ON() so just remove it and thereby fix things.
--- arch/um/kernel/time.c | 5 ----- 1 file changed, 5 deletions(-)
arch/um/kernel/time.c +0 -5
@@ -260,11 +260,6 @@ static void __time_travel_add_event(strustruct time_travel_event *tmp;bool inserted = false; -if (WARN (time_travel_mode ==TT_MODE_BASIC && - e != &time_travel_timer_event, -"only timer events can be handled in basic mode" )) -return ; -if (e->pending)return ;
Greg Kroah-Hartman
maintainerPATCH 622/717 ceph: fix race in concurrent __ceph_remove_cap invocations
In reply to Greg Kroah-HartmanFrom: Luis Henriques <[email protected]>
commit e5cafce3ad0f8652d6849314d951459c2bff7233 upstream.
A NULL pointer dereference may occur in __ceph_remove_cap with some of the callbacks used in ceph_iterate_session_caps, namely trim_caps_cb and remove_session_caps_cb. Those callers hold the session->s_mutex, so they are prevented from concurrent execution, but ceph_evict_inode does not.
Since the callers of this function hold the i_ceph_lock, the fix is simply a matter of returning immediately if caps->ci is NULL.
Cc: [email protected]
URL: https://tracker.ceph.com/issues/43272
--- fs/ceph/caps.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
fs/ceph/caps.c +9 -2
@@ -1140,12 +1140,19 @@ void __ceph_remove_cap(struct ceph_cap * {struct ceph_mds_session *session = cap->session;struct ceph_inode_info *ci = cap->ci; -struct ceph_mds_client *mdsc = -ceph_sb_to_client (ci->vfs_inode.i_sb)->mdsc; +struct ceph_mds_client *mdsc;int removed =0 ; +/* 'ci' being NULL means the remove have already occurred */ +if (!ci) { +dout ("%s: cap inode is NULL\n" , __func__); +return ; + } +dout ("__ceph_remove_cap %p from %p\n" , cap, &ci->vfs_inode); + mdsc =ceph_inode_to_client (&ci->vfs_inode)->mdsc; +/* remove from inode's cap rbtree, and clear auth cap */ rb_erase (&cap->ci_node, &ci->i_caps);if (ci->i_auth_cap == cap) {
Greg Kroah-Hartman
maintainerPATCH 623/717 SMB3: avoid confusing warning message on mount to Azure
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit ebcd6de98754d9b6a5f89d7835864b1c365d432f upstream.
Mounts to Azure cause an unneeded warning message in dmesg
"CIFS: VFS: parse_server_interfaces: incomplete interface info"
Azure rounds up the size (by 8 additional bytes, to a 16 byte boundary) of the structure returned on the query of the server interfaces at mount time. This is permissible even though different than other servers so do not log a warning if query network interfaces response is only rounded up by 8 bytes or fewer.
--- fs/cifs/smb2ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/cifs/smb2ops.c +2 -1
@@ -477,7 +477,8 @@ parse_server_interfaces(struct network_i goto out; } -if (bytes_left || p->Next) +/* Azure rounds the buffer size up 8, to a 16 byte boundary */ +if ((bytes_left >8 ) || p->Next)cifs_dbg (VFS ,"%s: incomplete interface info\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 624/717 SMB3.1.1: remove confusing mount warning when no SPNEGO info on negprot rsp
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit bc7c4129d4cdc56d1b5477c1714246f27df914dd upstream.
Azure does not send an SPNEGO blob in the negotiate protocol response, so we shouldn't assume that it is there when validating the location of the first negotiate context. This avoids the potential confusing mount warning:
CIFS: Invalid negotiate context offset
--- fs/cifs/smb2misc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
fs/cifs/smb2misc.c +12 -4
@@ -94,6 +94,8 @@ static const __le16 smb2_rsp_struct_size /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24) }; +#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_sync_hdr) + sizeof(struct smb2_negotiate_rsp)) +static __u32 get_neg_ctxt_len (struct smb2_sync_hdr *hdr,__u32 len,__u32 non_ctxlen) {
@@ -109,11 +111,17 @@ static __u32 get_neg_ctxt_len(struct smb/* Make sure that negotiate contexts start after gss security blob */ nc_offset =le32_to_cpu (pneg_rsp->NegotiateContextOffset); -if (nc_offset < non_ctxlen) { -pr_warn_once ("Invalid negotiate context offset\n" ); +if (nc_offset +1 < non_ctxlen) { +pr_warn_once ("Invalid negotiate context offset %d\n" , nc_offset);return 0 ; - } - size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen; + }else if (nc_offset +1 == non_ctxlen) { +cifs_dbg (FYI ,"no SPNEGO security blob in negprot rsp\n" ); + size_of_pad_before_neg_ctxts =0 ; + }else if (non_ctxlen ==SMB311_NEGPROT_BASE_SIZE ) +/* has padding, but no SPNEGO blob */ + size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen +1 ; +else + size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen;/* Verify that at least minimal negotiate contexts fit within frame */ if (len < nc_offset + (neg_count *sizeof (struct smb2_neg_context ))) {
Greg Kroah-Hartman
maintainerPATCH 625/717 SMB3.1.1: do not log warning message if server doesnt populate salt
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 7955f105afb6034af344038d663bc98809483cdd upstream.
In the negotiate protocol preauth context, the server is not required to populate the salt (although it is done by most servers) so do not warn on mount.
We retain the checks (warn) that the preauth context is the minimum size and that the salt does not exceed DataLength of the SMB response. Although we use the defaults in the case that the preauth context response is invalid, these checks may be useful in the future as servers add support for additional mechanisms.
--- fs/cifs/smb2pdu.c | 7 +++++-- fs/cifs/smb2pdu.h | 14 +++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-)
fs/cifs/smb2pdu.c +5 -2
@@ -427,8 +427,8 @@ build_preauth_ctxt(struct smb2_preauth_n pneg_ctxt->ContextType =SMB2_PREAUTH_INTEGRITY_CAPABILITIES ; pneg_ctxt->DataLength =cpu_to_le16 (38 ); pneg_ctxt->HashAlgorithmCount =cpu_to_le16 (1 ); - pneg_ctxt->SaltLength =cpu_to_le16 (SMB311_SALT_SIZE ); -get_random_bytes (pneg_ctxt->Salt,SMB311_SALT_SIZE ); + pneg_ctxt->SaltLength =cpu_to_le16 (SMB311_LINUX_CLIENT_SALT_SIZE ); +get_random_bytes (pneg_ctxt->Salt,SMB311_LINUX_CLIENT_SALT_SIZE ); pneg_ctxt->HashAlgorithms =SMB2_PREAUTH_INTEGRITY_SHA512 ; }
@@ -566,6 +566,9 @@ static void decode_preauth_context(strucif (len <MIN_PREAUTH_CTXT_DATA_LEN ) {pr_warn_once ("server sent bad preauth context\n" );return ; + }else if (len <MIN_PREAUTH_CTXT_DATA_LEN +le16_to_cpu (ctxt->SaltLength)) { +pr_warn_once ("server sent invalid SaltLength\n" ); +return ; }if (le16_to_cpu (ctxt->HashAlgorithmCount) !=1 )pr_warn_once ("Invalid SMB3 hash algorithm count\n" );
fs/cifs/smb2pdu.h +11 -3
@@ -333,12 +333,20 @@ struct smb2_neg_context {/* Followed by array of data */ } __packed; -#define SMB311_SALT_SIZE 32 +#define SMB311_LINUX_CLIENT_SALT_SIZE 32/* Hash Algorithm Types */ #define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001)#define SMB2_PREAUTH_HASH_SIZE 64 -#define MIN_PREAUTH_CTXT_DATA_LEN (SMB311_SALT_SIZE + 6) +/* +* SaltLength that the server send can be zero, so the only three required +* fields (all __le16) end up six bytes total, so the minimum context data len +* in the response is six bytes which accounts for +* +* HashAlgorithmCount, SaltLength, and 1 HashAlgorithm. +*/ +#define MIN_PREAUTH_CTXT_DATA_LEN 6 +struct smb2_preauth_neg_context {__le16 ContextType;/* 1 */ __le16 DataLength;
@@ -346,7 +354,7 @@ struct smb2_preauth_neg_context {__le16 HashAlgorithmCount;/* 1 */ __le16 SaltLength;__le16 HashAlgorithms;/* HashAlgorithms[0] since only one defined */ -__u8 Salt[SMB311_SALT_SIZE ]; +__u8 Salt[SMB311_LINUX_CLIENT_SALT_SIZE ]; } __packed;/* Encryption Algorithms Ciphers */