CFL was missing from intel_early_ids[]. The PCI ID needs to be there to
allow the memory region to be stolen, otherwise we could have RAM being
arbitrarily overwritten if for example we keep using the UEFI framebuffer,
depending on how BIOS has set up the e820 map.
Fixes: b056f8f3d6b9 ("drm/i915/cfl: Add Coffee Lake PCI IDs for S Skus.")
Signed-off-by: Lucas De Marchi <lucas.demarchi(a)intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi(a)intel.com>
Cc: Anusha Srivatsa <anusha.srivatsa(a)intel.com>
Cc: Jani Nikula <jani.nikula(a)linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen(a)linux.intel.com>
Cc: David Airlie <airlied(a)linux.ie>
Cc: intel-gfx(a)lists.freedesktop.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: Ingo Molnar <mingo(a)kernel.org>
Cc: H. Peter Anvin <hpa(a)zytor.com>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: x86(a)kernel.org
Cc: <stable(a)vger.kernel.org> # v4.13+ 0890540e21cf drm/i915: add GT number to intel_device_info
Cc: <stable(a)vger.kernel.org> # v4.13+ 41693fd52373 drm/i915/kbl: Change a KBL pci id to GT2 from GT1.5
Cc: <stable(a)vger.kernel.org> # v4.13+
Reviewed-by: Rodrigo Vivi <rodrigo.vivi(a)intel.com>
---
v2: improve commit message, add Fixes tag and CC stable
arch/x86/kernel/early-quirks.c | 1 +
include/drm/i915_pciids.h | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 3cbb2c78a9df..bae0d32e327b 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -528,6 +528,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_SKL_IDS(&gen9_early_ops),
INTEL_BXT_IDS(&gen9_early_ops),
INTEL_KBL_IDS(&gen9_early_ops),
+ INTEL_CFL_IDS(&gen9_early_ops),
INTEL_GLK_IDS(&gen9_early_ops),
INTEL_CNL_IDS(&gen9_early_ops),
};
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h
index 972a25633525..c65e4489006d 100644
--- a/include/drm/i915_pciids.h
+++ b/include/drm/i915_pciids.h
@@ -392,6 +392,12 @@
INTEL_VGA_DEVICE(0x3EA8, info), /* ULT GT3 */ \
INTEL_VGA_DEVICE(0x3EA5, info) /* ULT GT3 */
+#define INTEL_CFL_IDS(info) \
+ INTEL_CFL_S_GT1_IDS(info), \
+ INTEL_CFL_S_GT2_IDS(info), \
+ INTEL_CFL_H_GT2_IDS(info), \
+ INTEL_CFL_U_GT3_IDS(info)
+
/* CNL U 2+2 */
#define INTEL_CNL_U_GT2_IDS(info) \
INTEL_VGA_DEVICE(0x5A52, info), \
--
2.14.3
Quoting Hans:
If we return 1 from our post_reset handler, then our disconnect handler
will be called immediately afterwards. Since pre_reset blocks all scsi
requests our disconnect handler will then hang in the scsi_remove_host
call.
This is esp. bad because our disconnect handler hanging for ever also
stops the USB subsys from enumerating any new USB devices, causes commands
like lsusb to hang, etc.
In practice this happens when unplugging some uas devices because the hub
code may see the device as needing a warm-reset and calls usb_reset_device
before seeing the disconnect. In this case uas_configure_endpoints fails
with -ENODEV. We do not want to print an error for this, so this commit
also silences the shost_printk for -ENODEV.
ENDQUOTE
However, if we do that we better drop any unconditional execution
and report to the SCSI subsystem that we have undergone a reset
but we are not operational now.
Signed-off-by: Oliver Neukum <oneukum(a)suse.com>
Reported-by: Hans de Goede <hdegoede(a)redhat.com>
CC: stable(a)vger.kernel.org
---
drivers/usb/storage/uas.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 5d04c40ee40a..3b1b9695177a 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1076,20 +1076,19 @@ static int uas_post_reset(struct usb_interface *intf)
return 0;
err = uas_configure_endpoints(devinfo);
- if (err) {
+ if (err && err != ENODEV)
shost_printk(KERN_ERR, shost,
"%s: alloc streams error %d after reset",
__func__, err);
- return 1;
- }
+ /* we must unblock the host in every case lest we deadlock */
spin_lock_irqsave(shost->host_lock, flags);
scsi_report_bus_reset(shost, 0);
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_unblock_requests(shost);
- return 0;
+ return err ? 1 : 0;
}
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
--
2.13.6
Quoting Hans:
If we return 1 from our post_reset handler, then our disconnect handler
will be called immediately afterwards. Since pre_reset blocks all scsi
requests our disconnect handler will then hang in the scsi_remove_host
call.
This is esp. bad because our disconnect handler hanging for ever also
stops the USB subsys from enumerating any new USB devices, causes commands
like lsusb to hang, etc.
In practice this happens when unplugging some uas devices because the hub
code may see the device as needing a warm-reset and calls usb_reset_device
before seeing the disconnect. In this case uas_configure_endpoints fails
with -ENODEV. We do not want to print an error for this, so this commit
also silences the shost_printk for -ENODEV.
ENDQUOTE
However, if we do that we better drop any unconditional execution
and report to the SCSI subsystem that we have undergone a reset
but we are not operational now.
Signed-off-by: Oliver Neukum <oneukum(a)suse.com>
Reported-by: Hans de Goede <hdegoede(a)redhat.com>
CC: stable(a)vger.kernel.org
---
Makefile | 2 +-
drivers/usb/storage/uas.c | 7 +++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 7e02f951b284..5025bac05cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
VERSION = 4
PATCHLEVEL = 15
SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc4bs0108a
NAME = Fearless Coyote
# *DOCUMENTATION*
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 5d04c40ee40a..3b1b9695177a 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1076,20 +1076,19 @@ static int uas_post_reset(struct usb_interface *intf)
return 0;
err = uas_configure_endpoints(devinfo);
- if (err) {
+ if (err && err != ENODEV)
shost_printk(KERN_ERR, shost,
"%s: alloc streams error %d after reset",
__func__, err);
- return 1;
- }
+ /* we must unblock the host in every case lest we deadlock */
spin_lock_irqsave(shost->host_lock, flags);
scsi_report_bus_reset(shost, 0);
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_unblock_requests(shost);
- return 0;
+ return err ? 1 : 0;
}
static int uas_suspend(struct usb_interface *intf, pm_message_t message)
--
2.13.6
On 11/01/18 11:31, Felipe Balbi wrote:
>
> Hi,
>
> Roger Quadros <rogerq(a)ti.com> writes:
>>> Roger Quadros <rogerq(a)ti.com> writes:
>>>>>>> - ret = dwc3_core_soft_reset(dwc);
>>>>>>> + ret = dwc3_core_get_phy(dwc);
>>>>>>
>>>>>> we can get_phy in dwc3_core_init() as it will get called on resume().
>>>>>> This was the $subject of this patch.
>>>>>
>>>>> indeed. thanks :-)
>>>>>
>>>>
>>>> oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). :P
>>>
>>> bit of a chicken-and-egg problem. We need to setup the PHY interface
>>> before getting the PHYs, but can't get PHY during resume. Maybe the best
>>> way here would be to check for the pointers being valid. Something like:
>>>
>>> if (!phy)
>>> get_phy();
>>>
>>
>> OK that should take care of not calling get_phy() on suspend.
>> However there is one more issue with the approach
>>
>>> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>>> dwc->maximum_speed = USB_SPEED_HIGH;
>>> }
>>>
>>> - ret = dwc3_core_get_phy(dwc);
>>> + ret = dwc3_phy_setup(dwc);
>>> if (ret)
>>> goto err0;
>>
>> here we configure PHY related bits and register the ulpi interface.
>>
>>>
>>> - ret = dwc3_core_soft_reset(dwc);
>>> + ret = dwc3_core_get_phy(dwc);
>>> if (ret)
>>> goto err0;
>>>
>>
>> we got the PHYs. all OK here.
>>
>>> - ret = dwc3_phy_setup(dwc);
>>> + ret = dwc3_core_soft_reset(dwc);
>>> if (ret)
>>> goto err0;
>>
>> Now we do a soft reset. This means we loose the PHY configuration bits that we did
>> in dwc3_phy_setup. So we need to call dwc3_phy_setup again but not re-register the ulpi interface.
>> I can use a flag there so that dwc3_ulpi_init() is done only once.
>
> sounds like it's better to extract out a smaller function that just
> checks if we need ULPI bus and registers it, something akin to:
>
> @@ -482,6 +482,21 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
> parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
> }
>
> +static int dwc3_ulpi_init(struct dwc3 *dwc)
> +{
> + int intf;
> +
> + intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
> +
> + if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
> + (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
> + dwc->hsphy_interface &&
> + !strncmp(dwc->hsphy_interface, "ulpi", 4)))
> + return dwc3_ulpi_init(dwc);
> +
> + return 0;
> +}
> +
> /**
> * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
> * @dwc: Pointer to our controller context structure
> @@ -563,11 +578,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
> break;
> }
> /* FALLTHROUGH */
> - case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
> - ret = dwc3_ulpi_init(dwc);
> - if (ret)
> - return ret;
> - /* FALLTHROUGH */
> default:
> break;
> }
>
> Then we just call that outside of any functions that get called during PM.
>
Right. Seems like we've covered everything. I'll send a patch in a while.
--
cheers,
-roger
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
+Heikki
On 11/01/18 10:25, Felipe Balbi wrote:
>
> Hi,
>
> Roger Quadros <rogerq(a)ti.com> writes:
>>>>> - ret = dwc3_core_soft_reset(dwc);
>>>>> + ret = dwc3_core_get_phy(dwc);
>>>>
>>>> we can get_phy in dwc3_core_init() as it will get called on resume().
>>>> This was the $subject of this patch.
>>>
>>> indeed. thanks :-)
>>>
>>
>> oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). :P
>
> bit of a chicken-and-egg problem. We need to setup the PHY interface
> before getting the PHYs, but can't get PHY during resume. Maybe the best
> way here would be to check for the pointers being valid. Something like:
>
> if (!phy)
> get_phy();
>
OK that should take care of not calling get_phy() on suspend.
However there is one more issue with the approach
> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
> dwc->maximum_speed = USB_SPEED_HIGH;
> }
>
> - ret = dwc3_core_get_phy(dwc);
> + ret = dwc3_phy_setup(dwc);
> if (ret)
> goto err0;
here we configure PHY related bits and register the ulpi interface.
>
> - ret = dwc3_core_soft_reset(dwc);
> + ret = dwc3_core_get_phy(dwc);
> if (ret)
> goto err0;
>
we got the PHYs. all OK here.
> - ret = dwc3_phy_setup(dwc);
> + ret = dwc3_core_soft_reset(dwc);
> if (ret)
> goto err0;
Now we do a soft reset. This means we loose the PHY configuration bits that we did
in dwc3_phy_setup. So we need to call dwc3_phy_setup again but not re-register the ulpi interface.
I can use a flag there so that dwc3_ulpi_init() is done only once.
--
cheers,
-roger
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
This is a note to let you know that I've just added the patch titled
[PATCH] nvmem: add i.MX7 support to snvs-lpgpr
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
nvmem-add-i.mx7-support-to-snvs-lpgpr.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From yurovsky(a)gmail.com Thu Jan 11 07:36:10 2018
From: Andrey Yurovsky <yurovsky(a)gmail.com>
Date: Wed, 10 Jan 2018 15:47:34 -0800
Subject: [PATCH] nvmem: add i.MX7 support to snvs-lpgpr
To: srinivas.kandagatla(a)linaro.org
Cc: Andrey Yurovsky <yurovsky(a)gmail.com>, o.rempel(a)pengutronix.de, gregkh(a)linuxfoundation.org
Message-ID: <20180110234734.26213-1-yurovsky(a)gmail.com>
The i.MX7 family has similar SNVS hardware so make the snvs-lpgpr
support it along with the i.MX6 family. The register interface is the
same except for the number and offset of the general purpose registers.
Signed-off-by: Andrey Yurovsky <yurovsky(a)gmail.com>
---
.../devicetree/bindings/nvmem/snvs-lpgpr.txt | 3 ++-
drivers/nvmem/Kconfig | 4 ++--
drivers/nvmem/snvs_lpgpr.c | 27 +++++++++++++++++-----
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt b/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
index 20bc49b49799..3cb170896658 100644
--- a/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
+++ b/Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt
@@ -1,5 +1,5 @@
Device tree bindings for Low Power General Purpose Register found in i.MX6Q/D
-Secure Non-Volatile Storage.
+and i.MX7 Secure Non-Volatile Storage.
This DT node should be represented as a sub-node of a "syscon",
"simple-mfd" node.
@@ -8,6 +8,7 @@ Required properties:
- compatible: should be one of the fallowing variants:
"fsl,imx6q-snvs-lpgpr" for Freescale i.MX6Q/D/DL/S
"fsl,imx6ul-snvs-lpgpr" for Freescale i.MX6UL
+ "fsl,imx7d-snvs-lpgpr" for Freescale i.MX7D/S
Example:
snvs: snvs@020cc000 {
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index ff505af064ba..5f9bc787d634 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -167,10 +167,10 @@ config MESON_MX_EFUSE
config NVMEM_SNVS_LPGPR
tristate "Support for Low Power General Purpose Register"
- depends on SOC_IMX6 || COMPILE_TEST
+ depends on SOC_IMX6 || SOC_IMX7D || COMPILE_TEST
help
This is a driver for Low Power General Purpose Register (LPGPR) available on
- i.MX6 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
+ i.MX6 and i.MX7 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
This driver can also be built as a module. If so, the module
will be called nvmem-snvs-lpgpr.
diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index e5c2a4a17f03..3ed617a16db0 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -14,15 +14,21 @@
#include <linux/regmap.h>
#define IMX6Q_SNVS_HPLR 0x00
-#define IMX6Q_GPR_SL BIT(5)
#define IMX6Q_SNVS_LPLR 0x34
-#define IMX6Q_GPR_HL BIT(5)
#define IMX6Q_SNVS_LPGPR 0x68
+#define IMX7D_SNVS_HPLR 0x00
+#define IMX7D_SNVS_LPLR 0x34
+#define IMX7D_SNVS_LPGPR 0x90
+
+#define IMX_GPR_SL BIT(5)
+#define IMX_GPR_HL BIT(5)
+
struct snvs_lpgpr_cfg {
int offset;
int offset_hplr;
int offset_lplr;
+ int size;
};
struct snvs_lpgpr_priv {
@@ -36,6 +42,14 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx6q = {
.offset = IMX6Q_SNVS_LPGPR,
.offset_hplr = IMX6Q_SNVS_HPLR,
.offset_lplr = IMX6Q_SNVS_LPLR,
+ .size = 4,
+};
+
+static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
+ .offset = IMX7D_SNVS_LPGPR,
+ .offset_hplr = IMX7D_SNVS_HPLR,
+ .offset_lplr = IMX7D_SNVS_LPLR,
+ .size = 16,
};
static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
@@ -50,14 +64,14 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
if (ret < 0)
return ret;
- if (lock_reg & IMX6Q_GPR_SL)
+ if (lock_reg & IMX_GPR_SL)
return -EPERM;
ret = regmap_read(priv->regmap, dcfg->offset_lplr, &lock_reg);
if (ret < 0)
return ret;
- if (lock_reg & IMX6Q_GPR_HL)
+ if (lock_reg & IMX_GPR_HL)
return -EPERM;
return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
@@ -112,7 +126,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
cfg->dev = dev;
cfg->stride = 4,
cfg->word_size = 4,
- cfg->size = 4,
+ cfg->size = dcfg->size,
cfg->owner = THIS_MODULE,
cfg->reg_read = snvs_lpgpr_read,
cfg->reg_write = snvs_lpgpr_write,
@@ -137,6 +151,7 @@ static const struct of_device_id snvs_lpgpr_dt_ids[] = {
{ .compatible = "fsl,imx6q-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx6q },
{ .compatible = "fsl,imx6ul-snvs-lpgpr",
.data = &snvs_lpgpr_cfg_imx6q },
+ { .compatible = "fsl,imx7d-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx7d },
{ },
};
MODULE_DEVICE_TABLE(of, snvs_lpgpr_dt_ids);
@@ -152,5 +167,5 @@ static struct platform_driver snvs_lpgpr_driver = {
module_platform_driver(snvs_lpgpr_driver);
MODULE_AUTHOR("Oleksij Rempel <o.rempel(a)pengutronix.de>");
-MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 Secure Non-Volatile Storage");
+MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 and i.MX7 Secure Non-Volatile Storage");
MODULE_LICENSE("GPL v2");
--
2.14.3
Patches currently in stable-queue which might be from yurovsky(a)gmail.com are
queue-4.4/nvmem-add-i.mx7-support-to-snvs-lpgpr.patch
This is a note to let you know that I've just added the patch titled
x86/acpi: Reduce code duplication in mp_override_legacy_irq()
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 4ee2ec1b122599f7b10c849fa7915cebb37b7edb Mon Sep 17 00:00:00 2001
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Date: Thu, 16 Nov 2017 21:43:45 +0530
Subject: x86/acpi: Reduce code duplication in mp_override_legacy_irq()
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
commit 4ee2ec1b122599f7b10c849fa7915cebb37b7edb upstream.
The new function mp_register_ioapic_irq() is a subset of the code in
mp_override_legacy_irq().
Replace the code duplication by invoking mp_register_ioapic_irq() from
mp_override_legacy_irq().
Signed-off-by: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Reviewed-by: Thomas Gleixner <tglx(a)linutronix.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Cc: linux-pm(a)vger.kernel.org
Cc: kkamagui(a)gmail.com
Cc: linux-acpi(a)vger.kernel.org
Link: https://lkml.kernel.org/r/1510848825-21965-3-git-send-email-vikas.cha.sajja…
Cc: Jean Delvare <jdelvare(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/acpi/boot.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -321,13 +321,12 @@ acpi_parse_lapic_nmi(struct acpi_subtabl
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0
+static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
+ u8 trigger, u32 gsi);
+
static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi)
{
- int ioapic;
- int pin;
- struct mpc_intsrc mp_irq;
-
/*
* Check bus_irq boundary.
*/
@@ -337,14 +336,6 @@ static void __init mp_override_legacy_ir
}
/*
- * Convert 'gsi' to 'ioapic.pin'.
- */
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- return;
- pin = mp_find_ioapic_pin(ioapic, gsi);
-
- /*
* TBD: This check is for faulty timer entries, where the override
* erroneously sets the trigger to level, resulting in a HUGE
* increase of timer interrupts!
@@ -352,16 +343,8 @@ static void __init mp_override_legacy_ir
if ((bus_irq == 0) && (trigger == 3))
trigger = 1;
- mp_irq.type = MP_INTSRC;
- mp_irq.irqtype = mp_INT;
- mp_irq.irqflag = (trigger << 2) | polarity;
- mp_irq.srcbus = MP_ISA_BUS;
- mp_irq.srcbusirq = bus_irq; /* IRQ */
- mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
- mp_irq.dstirq = pin; /* INTIN# */
-
- mp_save_irq(&mp_irq);
-
+ if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
+ return;
/*
* Reset default identity mapping if gsi is also an legacy IRQ,
* otherwise there will be more than one entry with the same GSI
Patches currently in stable-queue which might be from vikas.cha.sajjan(a)hpe.com are
queue-4.4/x86-acpi-handle-sci-interrupts-above-legacy-space-gracefully.patch
queue-4.4/x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
This is a note to let you know that I've just added the patch titled
x86/acpi: Reduce code duplication in mp_override_legacy_irq()
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 4ee2ec1b122599f7b10c849fa7915cebb37b7edb Mon Sep 17 00:00:00 2001
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Date: Thu, 16 Nov 2017 21:43:45 +0530
Subject: x86/acpi: Reduce code duplication in mp_override_legacy_irq()
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
commit 4ee2ec1b122599f7b10c849fa7915cebb37b7edb upstream.
The new function mp_register_ioapic_irq() is a subset of the code in
mp_override_legacy_irq().
Replace the code duplication by invoking mp_register_ioapic_irq() from
mp_override_legacy_irq().
Signed-off-by: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Reviewed-by: Thomas Gleixner <tglx(a)linutronix.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Cc: linux-pm(a)vger.kernel.org
Cc: kkamagui(a)gmail.com
Cc: linux-acpi(a)vger.kernel.org
Link: https://lkml.kernel.org/r/1510848825-21965-3-git-send-email-vikas.cha.sajja…
Cc: Jean Delvare <jdelvare(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/acpi/boot.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -342,13 +342,12 @@ acpi_parse_lapic_nmi(struct acpi_subtabl
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0
+static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
+ u8 trigger, u32 gsi);
+
static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi)
{
- int ioapic;
- int pin;
- struct mpc_intsrc mp_irq;
-
/*
* Check bus_irq boundary.
*/
@@ -358,14 +357,6 @@ static void __init mp_override_legacy_ir
}
/*
- * Convert 'gsi' to 'ioapic.pin'.
- */
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- return;
- pin = mp_find_ioapic_pin(ioapic, gsi);
-
- /*
* TBD: This check is for faulty timer entries, where the override
* erroneously sets the trigger to level, resulting in a HUGE
* increase of timer interrupts!
@@ -373,16 +364,8 @@ static void __init mp_override_legacy_ir
if ((bus_irq == 0) && (trigger == 3))
trigger = 1;
- mp_irq.type = MP_INTSRC;
- mp_irq.irqtype = mp_INT;
- mp_irq.irqflag = (trigger << 2) | polarity;
- mp_irq.srcbus = MP_ISA_BUS;
- mp_irq.srcbusirq = bus_irq; /* IRQ */
- mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
- mp_irq.dstirq = pin; /* INTIN# */
-
- mp_save_irq(&mp_irq);
-
+ if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
+ return;
/*
* Reset default identity mapping if gsi is also an legacy IRQ,
* otherwise there will be more than one entry with the same GSI
Patches currently in stable-queue which might be from vikas.cha.sajjan(a)hpe.com are
queue-4.14/x86-acpi-handle-sci-interrupts-above-legacy-space-gracefully.patch
queue-4.14/x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
This is a note to let you know that I've just added the patch titled
x86/acpi: Reduce code duplication in mp_override_legacy_irq()
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 4ee2ec1b122599f7b10c849fa7915cebb37b7edb Mon Sep 17 00:00:00 2001
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Date: Thu, 16 Nov 2017 21:43:45 +0530
Subject: x86/acpi: Reduce code duplication in mp_override_legacy_irq()
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
commit 4ee2ec1b122599f7b10c849fa7915cebb37b7edb upstream.
The new function mp_register_ioapic_irq() is a subset of the code in
mp_override_legacy_irq().
Replace the code duplication by invoking mp_register_ioapic_irq() from
mp_override_legacy_irq().
Signed-off-by: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Reviewed-by: Thomas Gleixner <tglx(a)linutronix.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Cc: linux-pm(a)vger.kernel.org
Cc: kkamagui(a)gmail.com
Cc: linux-acpi(a)vger.kernel.org
Link: https://lkml.kernel.org/r/1510848825-21965-3-git-send-email-vikas.cha.sajja…
Cc: Jean Delvare <jdelvare(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/acpi/boot.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -308,13 +308,12 @@ acpi_parse_lapic_nmi(struct acpi_subtabl
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0
+static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
+ u8 trigger, u32 gsi);
+
static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi)
{
- int ioapic;
- int pin;
- struct mpc_intsrc mp_irq;
-
/*
* Check bus_irq boundary.
*/
@@ -324,14 +323,6 @@ static void __init mp_override_legacy_ir
}
/*
- * Convert 'gsi' to 'ioapic.pin'.
- */
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- return;
- pin = mp_find_ioapic_pin(ioapic, gsi);
-
- /*
* TBD: This check is for faulty timer entries, where the override
* erroneously sets the trigger to level, resulting in a HUGE
* increase of timer interrupts!
@@ -339,16 +330,8 @@ static void __init mp_override_legacy_ir
if ((bus_irq == 0) && (trigger == 3))
trigger = 1;
- mp_irq.type = MP_INTSRC;
- mp_irq.irqtype = mp_INT;
- mp_irq.irqflag = (trigger << 2) | polarity;
- mp_irq.srcbus = MP_ISA_BUS;
- mp_irq.srcbusirq = bus_irq; /* IRQ */
- mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
- mp_irq.dstirq = pin; /* INTIN# */
-
- mp_save_irq(&mp_irq);
-
+ if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
+ return;
/*
* Reset default identity mapping if gsi is also an legacy IRQ,
* otherwise there will be more than one entry with the same GSI
Patches currently in stable-queue which might be from vikas.cha.sajjan(a)hpe.com are
queue-3.18/x86-acpi-handle-sci-interrupts-above-legacy-space-gracefully.patch
queue-3.18/x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
Hi all,
Commit dad5ab0db8de ("x86/acpi: Prevent out of bound access caused by
broken ACPI tables") was tagged for stable and merged in various stable
kernel trees (at least 3.2, 3.16, 3.18, 4.1, 4.4, 4.9 and 4.12.)
However it turns out that this commit introduced a regression on some
systems (in particular HPE Superdome 2, but possibly others.) The fix
for this breakage is:
commit 252714155f04c5d16989cb3aadb85fd1b5772f99
Author: Vikas C Sajjan
Date: Thu Nov 16 21:43:44 2017 +0530
x86/acpi: Handle SCI interrupts above legacy space gracefully
(and follow-up cleanup 4ee2ec1b1225 "x86/acpi: Reduce code duplication
in mp_override_legacy_irq()".) Unfortunately the fix-up patch was NOT
tagged for stable and also lacks a Fixes tag referring to the faulty
commit. As a consequence nobody realized they fix a regression, and this
regression is still present in all the aforementioned stable branches.
So I invite the maintainers of these stable kernel branches to backport
commits 252714155f04 and possibly 4ee2ec1b1225 to solve this issue.
Thanks,
--
Jean Delvare
SUSE L3 Support
This is a note to let you know that I've just added the patch titled
x86/acpi: Reduce code duplication in mp_override_legacy_irq()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 4ee2ec1b122599f7b10c849fa7915cebb37b7edb Mon Sep 17 00:00:00 2001
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Date: Thu, 16 Nov 2017 21:43:45 +0530
Subject: x86/acpi: Reduce code duplication in mp_override_legacy_irq()
From: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
commit 4ee2ec1b122599f7b10c849fa7915cebb37b7edb upstream.
The new function mp_register_ioapic_irq() is a subset of the code in
mp_override_legacy_irq().
Replace the code duplication by invoking mp_register_ioapic_irq() from
mp_override_legacy_irq().
Signed-off-by: Vikas C Sajjan <vikas.cha.sajjan(a)hpe.com>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Reviewed-by: Thomas Gleixner <tglx(a)linutronix.de>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Cc: linux-pm(a)vger.kernel.org
Cc: kkamagui(a)gmail.com
Cc: linux-acpi(a)vger.kernel.org
Link: https://lkml.kernel.org/r/1510848825-21965-3-git-send-email-vikas.cha.sajja…
Cc: Jean Delvare <jdelvare(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
arch/x86/kernel/acpi/boot.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -335,13 +335,12 @@ acpi_parse_lapic_nmi(struct acpi_subtabl
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0
+static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
+ u8 trigger, u32 gsi);
+
static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi)
{
- int ioapic;
- int pin;
- struct mpc_intsrc mp_irq;
-
/*
* Check bus_irq boundary.
*/
@@ -351,14 +350,6 @@ static void __init mp_override_legacy_ir
}
/*
- * Convert 'gsi' to 'ioapic.pin'.
- */
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- return;
- pin = mp_find_ioapic_pin(ioapic, gsi);
-
- /*
* TBD: This check is for faulty timer entries, where the override
* erroneously sets the trigger to level, resulting in a HUGE
* increase of timer interrupts!
@@ -366,16 +357,8 @@ static void __init mp_override_legacy_ir
if ((bus_irq == 0) && (trigger == 3))
trigger = 1;
- mp_irq.type = MP_INTSRC;
- mp_irq.irqtype = mp_INT;
- mp_irq.irqflag = (trigger << 2) | polarity;
- mp_irq.srcbus = MP_ISA_BUS;
- mp_irq.srcbusirq = bus_irq; /* IRQ */
- mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
- mp_irq.dstirq = pin; /* INTIN# */
-
- mp_save_irq(&mp_irq);
-
+ if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
+ return;
/*
* Reset default identity mapping if gsi is also an legacy IRQ,
* otherwise there will be more than one entry with the same GSI
Patches currently in stable-queue which might be from vikas.cha.sajjan(a)hpe.com are
queue-4.9/x86-acpi-handle-sci-interrupts-above-legacy-space-gracefully.patch
queue-4.9/x86-acpi-reduce-code-duplication-in-mp_override_legacy_irq.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Remove incorrect snd_BUG_ON() usages
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From fe08f34d066f4404934a509b6806db1a4f700c86 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 1 Jan 2018 09:50:50 +0100
Subject: ALSA: pcm: Remove incorrect snd_BUG_ON() usages
From: Takashi Iwai <tiwai(a)suse.de>
commit fe08f34d066f4404934a509b6806db1a4f700c86 upstream.
syzkaller triggered kernel warnings through PCM OSS emulation at
closing a stream:
WARNING: CPU: 0 PID: 3502 at sound/core/pcm_lib.c:1635
snd_pcm_hw_param_first+0x289/0x690 sound/core/pcm_lib.c:1635
Call Trace:
....
snd_pcm_hw_param_near.constprop.27+0x78d/0x9a0 sound/core/oss/pcm_oss.c:457
snd_pcm_oss_change_params+0x17d3/0x3720 sound/core/oss/pcm_oss.c:969
snd_pcm_oss_make_ready+0xaa/0x130 sound/core/oss/pcm_oss.c:1128
snd_pcm_oss_sync+0x257/0x830 sound/core/oss/pcm_oss.c:1638
snd_pcm_oss_release+0x20b/0x280 sound/core/oss/pcm_oss.c:2431
__fput+0x327/0x7e0 fs/file_table.c:210
....
This happens while it tries to open and set up the aloop device
concurrently. The warning above (invoked from snd_BUG_ON() macro) is
to detect the unexpected logical error where snd_pcm_hw_refine() call
shouldn't fail. The theory is true for the case where the hw_params
config rules are static. But for an aloop device, the hw_params rule
condition does vary dynamically depending on the connected target;
when another device is opened and changes the parameters, the device
connected in another side is also affected, and it caused the error
from snd_pcm_hw_refine().
That is, the simplest "solution" for this is to remove the incorrect
assumption of static rules, and treat such an error as a normal error
path. As there are a couple of other places using snd_BUG_ON()
incorrectly, this patch removes these spurious snd_BUG_ON() calls.
Reported-by: syzbot+6f11c7e2a1b91d466432(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 1 -
sound/core/pcm_lib.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -466,7 +466,6 @@ static int snd_pcm_hw_param_near(struct
v = snd_pcm_hw_param_last(pcm, params, var, dir);
else
v = snd_pcm_hw_param_first(pcm, params, var, dir);
- snd_BUG_ON(v < 0);
return v;
}
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1664,7 +1664,7 @@ int snd_pcm_hw_param_first(struct snd_pc
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
@@ -1711,7 +1711,7 @@ int snd_pcm_hw_param_last(struct snd_pcm
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 900498a34a3ac9c611e9b425094c8106bdd7dc1c Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 14:03:53 +0100
Subject: ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.
PCM OSS read/write loops keep taking the mutex lock for the whole
read/write, and this might take very long when the exceptionally high
amount of data is given. Also, since it invokes with mutex_lock(),
the concurrent read/write becomes unbreakable.
This patch tries to address these issues by replacing mutex_lock()
with mutex_lock_interruptible(), and also splits / re-takes the lock
at each read/write period chunk, so that it can switch the context
more finely if requested.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1369,8 +1369,11 @@ static ssize_t snd_pcm_oss_write1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
tmp = bytes;
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1414,18 +1417,18 @@ static ssize_t snd_pcm_oss_write1(struct
xfer += tmp;
if ((substream->f_flags & O_NONBLOCK) != 0 &&
tmp != runtime->oss.period_bytes)
- break;
+ tmp = -EAGAIN;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
@@ -1473,8 +1476,11 @@ static ssize_t snd_pcm_oss_read1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
if (runtime->oss.buffer_used == 0) {
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1505,16 +1511,16 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Add missing error checks in OSS emulation plugin builder
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 6708913750344a900f2e73bfe4a4d6dbbce4fe8d Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 16:39:27 +0100
Subject: ALSA: pcm: Add missing error checks in OSS emulation plugin builder
From: Takashi Iwai <tiwai(a)suse.de>
commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream.
In the OSS emulation plugin builder where the frame size is parsed in
the plugin chain, some places miss the possible errors returned from
the plugin src_ or dst_frames callback.
This patch papers over such places.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_plugin.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -591,18 +591,26 @@ snd_pcm_sframes_t snd_pcm_plug_write_tra
snd_pcm_sframes_t frames = size;
plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
+ while (plugin) {
+ if (frames <= 0)
+ return frames;
if ((next = plugin->next) != NULL) {
snd_pcm_sframes_t frames1 = frames;
- if (plugin->dst_frames)
+ if (plugin->dst_frames) {
frames1 = plugin->dst_frames(plugin, frames);
+ if (frames1 <= 0)
+ return frames1;
+ }
if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
return err;
}
if (err != frames1) {
frames = err;
- if (plugin->src_frames)
+ if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames1);
+ if (frames <= 0)
+ return frames;
+ }
}
} else
dst_channels = NULL;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Abort properly at pending signal in OSS read/write loops
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 13:58:31 +0100
Subject: ALSA: pcm: Abort properly at pending signal in OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream.
The loops for read and write in PCM OSS emulation have no proper check
of pending signals, and they keep processing even after user tries to
break. This results in a very long delay, often seen as RCU stall
when a huge unprocessed bytes remain queued. The bug could be easily
triggered by syzkaller.
As a simple workaround, this patch adds the proper check of pending
signals and aborts the loop appropriately.
Reported-by: syzbot+993cb4cfcbbff3947c21(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1416,6 +1416,10 @@ static ssize_t snd_pcm_oss_write1(struct
tmp != runtime->oss.period_bytes)
break;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
@@ -1501,6 +1505,10 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Release cable upon open error path
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-release-cable-upon-open-error-path.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 9685347aa0a5c2869058ca6ab79fd8e93084a67f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:09:47 +0100
Subject: ALSA: aloop: Release cable upon open error path
From: Takashi Iwai <tiwai(a)suse.de>
commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream.
The aloop runtime object and its assignment in the cable are left even
when opening a substream fails. This doesn't mean any memory leak,
but it still keeps the invalid pointer that may be referred by the
another side of the cable spontaneously, which is a potential Oops
cause.
Clean up the cable assignment and the empty cable upon the error path
properly.
Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -658,12 +658,31 @@ static int rule_channels(struct snd_pcm_
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
+static void free_cable(struct snd_pcm_substream *substream)
+{
+ struct loopback *loopback = substream->private_data;
+ int dev = get_cable_index(substream);
+ struct loopback_cable *cable;
+
+ cable = loopback->cables[substream->number][dev];
+ if (!cable)
+ return;
+ if (cable->streams[!substream->stream]) {
+ /* other stream is still alive */
+ cable->streams[substream->stream] = NULL;
+ } else {
+ /* free the cable */
+ loopback->cables[substream->number][dev] = NULL;
+ kfree(cable);
+ }
+}
+
static int loopback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
+ struct loopback_cable *cable = NULL;
int err = 0;
int dev = get_cable_index(substream);
@@ -682,7 +701,6 @@ static int loopback_open(struct snd_pcm_
if (!cable) {
cable = kzalloc(sizeof(*cable), GFP_KERNEL);
if (!cable) {
- kfree(dpcm);
err = -ENOMEM;
goto unlock;
}
@@ -724,6 +742,10 @@ static int loopback_open(struct snd_pcm_
else
runtime->hw = cable->hw;
unlock:
+ if (err < 0) {
+ free_cable(substream);
+ kfree(dpcm);
+ }
mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -732,20 +754,10 @@ static int loopback_close(struct snd_pcm
{
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
loopback_timer_stop(dpcm);
mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
+ free_cable(substream);
mutex_unlock(&loopback->cable_lock);
return 0;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix racy hw constraints adjustment
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-racy-hw-constraints-adjustment.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 898dfe4687f460ba337a01c11549f87269a13fa2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 17:38:54 +0100
Subject: ALSA: aloop: Fix racy hw constraints adjustment
From: Takashi Iwai <tiwai(a)suse.de>
commit 898dfe4687f460ba337a01c11549f87269a13fa2 upstream.
The aloop driver tries to update the hw constraints of the connected
target on the cable of the opened PCM substream. This is done by
adding the extra hw constraints rules referring to the substream
runtime->hw fields, while the other substream may update the runtime
hw of another side on the fly.
This is, however, racy and may result in the inconsistent values when
both PCM streams perform the prepare concurrently. One of the reason
is that it overwrites the other's runtime->hw field; which is not only
racy but also broken when it's called before the open of another side
finishes. And, since the reference to runtime->hw isn't protected,
the concurrent write may give the partial value update and become
inconsistent.
This patch is an attempt to fix and clean up:
- The prepare doesn't change the runtime->hw of other side any longer,
but only update the cable->hw that is referred commonly.
- The extra rules refer to the loopback_pcm object instead of the
runtime->hw. The actual hw is deduced from cable->hw.
- The extra rules take the cable_lock to protect against the race.
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 51 ++++++++++++++++++++------------------------------
1 file changed, 21 insertions(+), 30 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -306,19 +306,6 @@ static int loopback_trigger(struct snd_p
return 0;
}
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
static void params_change(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -330,10 +317,6 @@ static void params_change(struct snd_pcm
cable->hw.rate_max = runtime->rate;
cable->hw.channels_min = runtime->channels;
cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
}
static int loopback_prepare(struct snd_pcm_substream *substream)
@@ -621,24 +604,29 @@ static unsigned int get_cable_index(stru
static int rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
-
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_mask m;
snd_mask_none(&m);
- m.bits[0] = (u_int32_t)hw->formats;
- m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ mutex_lock(&dpcm->loopback->cable_lock);
+ m.bits[0] = (u_int32_t)cable->hw.formats;
+ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
+ mutex_unlock(&dpcm->loopback->cable_lock);
return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->rate_min;
- t.max = hw->rate_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.rate_min;
+ t.max = cable->hw.rate_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -647,11 +635,14 @@ static int rule_rate(struct snd_pcm_hw_p
static int rule_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->channels_min;
- t.max = hw->channels_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.channels_min;
+ t.max = cable->hw.channels_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -717,19 +708,19 @@ static int loopback_open(struct snd_pcm_
/* are cached -> they do not reflect the actual state */
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
+ rule_format, dpcm,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
+ rule_rate, dpcm,
SNDRV_PCM_HW_PARAM_RATE, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
+ rule_channels, dpcm,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (err < 0)
goto unlock;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix inconsistent format due to incomplete rule
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:15:33 +0100
Subject: ALSA: aloop: Fix inconsistent format due to incomplete rule
From: Takashi Iwai <tiwai(a)suse.de>
commit b088b53e20c7d09b5ab84c5688e609f478e5c417 upstream.
The extra hw constraint rule for the formats the aloop driver
introduced has a slight flaw, where it doesn't return a positive value
when the mask got changed. It came from the fact that it's basically
a copy&paste from snd_hw_constraint_mask64(). The original code is
supposed to be a single-shot and it modifies the mask bits only once
and never after, while what we need for aloop is the dynamic hw rule
that limits the mask bits.
This difference results in the inconsistent state, as the hw_refine
doesn't apply the dependencies fully. The worse and surprisingly
result is that it causes a crash in OSS emulation when multiple
full-duplex reads/writes are performed concurrently (I leave why it
triggers Oops to readers as a homework).
For fixing this, replace a few open-codes with the standard
snd_mask_*() macros.
Reported-by: syzbot+3902b5220e8ca27889ca(a)syzkaller.appspotmail.com
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -39,6 +39,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
@@ -622,14 +623,12 @@ static int rule_format(struct snd_pcm_hw
{
struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
+ struct snd_mask m;
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
+ snd_mask_none(&m);
+ m.bits[0] = (u_int32_t)hw->formats;
+ m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.9/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.9/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.9/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.9/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.9/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.9/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.9/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Remove incorrect snd_BUG_ON() usages
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From fe08f34d066f4404934a509b6806db1a4f700c86 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 1 Jan 2018 09:50:50 +0100
Subject: ALSA: pcm: Remove incorrect snd_BUG_ON() usages
From: Takashi Iwai <tiwai(a)suse.de>
commit fe08f34d066f4404934a509b6806db1a4f700c86 upstream.
syzkaller triggered kernel warnings through PCM OSS emulation at
closing a stream:
WARNING: CPU: 0 PID: 3502 at sound/core/pcm_lib.c:1635
snd_pcm_hw_param_first+0x289/0x690 sound/core/pcm_lib.c:1635
Call Trace:
....
snd_pcm_hw_param_near.constprop.27+0x78d/0x9a0 sound/core/oss/pcm_oss.c:457
snd_pcm_oss_change_params+0x17d3/0x3720 sound/core/oss/pcm_oss.c:969
snd_pcm_oss_make_ready+0xaa/0x130 sound/core/oss/pcm_oss.c:1128
snd_pcm_oss_sync+0x257/0x830 sound/core/oss/pcm_oss.c:1638
snd_pcm_oss_release+0x20b/0x280 sound/core/oss/pcm_oss.c:2431
__fput+0x327/0x7e0 fs/file_table.c:210
....
This happens while it tries to open and set up the aloop device
concurrently. The warning above (invoked from snd_BUG_ON() macro) is
to detect the unexpected logical error where snd_pcm_hw_refine() call
shouldn't fail. The theory is true for the case where the hw_params
config rules are static. But for an aloop device, the hw_params rule
condition does vary dynamically depending on the connected target;
when another device is opened and changes the parameters, the device
connected in another side is also affected, and it caused the error
from snd_pcm_hw_refine().
That is, the simplest "solution" for this is to remove the incorrect
assumption of static rules, and treat such an error as a normal error
path. As there are a couple of other places using snd_BUG_ON()
incorrectly, this patch removes these spurious snd_BUG_ON() calls.
Reported-by: syzbot+6f11c7e2a1b91d466432(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 1 -
sound/core/pcm_lib.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -465,7 +465,6 @@ static int snd_pcm_hw_param_near(struct
v = snd_pcm_hw_param_last(pcm, params, var, dir);
else
v = snd_pcm_hw_param_first(pcm, params, var, dir);
- snd_BUG_ON(v < 0);
return v;
}
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1664,7 +1664,7 @@ int snd_pcm_hw_param_first(struct snd_pc
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
@@ -1711,7 +1711,7 @@ int snd_pcm_hw_param_last(struct snd_pcm
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 900498a34a3ac9c611e9b425094c8106bdd7dc1c Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 14:03:53 +0100
Subject: ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.
PCM OSS read/write loops keep taking the mutex lock for the whole
read/write, and this might take very long when the exceptionally high
amount of data is given. Also, since it invokes with mutex_lock(),
the concurrent read/write becomes unbreakable.
This patch tries to address these issues by replacing mutex_lock()
with mutex_lock_interruptible(), and also splits / re-takes the lock
at each read/write period chunk, so that it can switch the context
more finely if requested.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1369,8 +1369,11 @@ static ssize_t snd_pcm_oss_write1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
tmp = bytes;
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1414,18 +1417,18 @@ static ssize_t snd_pcm_oss_write1(struct
xfer += tmp;
if ((substream->f_flags & O_NONBLOCK) != 0 &&
tmp != runtime->oss.period_bytes)
- break;
+ tmp = -EAGAIN;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
@@ -1473,8 +1476,11 @@ static ssize_t snd_pcm_oss_read1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
if (runtime->oss.buffer_used == 0) {
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1505,16 +1511,16 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Release cable upon open error path
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-release-cable-upon-open-error-path.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 9685347aa0a5c2869058ca6ab79fd8e93084a67f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:09:47 +0100
Subject: ALSA: aloop: Release cable upon open error path
From: Takashi Iwai <tiwai(a)suse.de>
commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream.
The aloop runtime object and its assignment in the cable are left even
when opening a substream fails. This doesn't mean any memory leak,
but it still keeps the invalid pointer that may be referred by the
another side of the cable spontaneously, which is a potential Oops
cause.
Clean up the cable assignment and the empty cable upon the error path
properly.
Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -658,12 +658,31 @@ static int rule_channels(struct snd_pcm_
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
+static void free_cable(struct snd_pcm_substream *substream)
+{
+ struct loopback *loopback = substream->private_data;
+ int dev = get_cable_index(substream);
+ struct loopback_cable *cable;
+
+ cable = loopback->cables[substream->number][dev];
+ if (!cable)
+ return;
+ if (cable->streams[!substream->stream]) {
+ /* other stream is still alive */
+ cable->streams[substream->stream] = NULL;
+ } else {
+ /* free the cable */
+ loopback->cables[substream->number][dev] = NULL;
+ kfree(cable);
+ }
+}
+
static int loopback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
+ struct loopback_cable *cable = NULL;
int err = 0;
int dev = get_cable_index(substream);
@@ -682,7 +701,6 @@ static int loopback_open(struct snd_pcm_
if (!cable) {
cable = kzalloc(sizeof(*cable), GFP_KERNEL);
if (!cable) {
- kfree(dpcm);
err = -ENOMEM;
goto unlock;
}
@@ -724,6 +742,10 @@ static int loopback_open(struct snd_pcm_
else
runtime->hw = cable->hw;
unlock:
+ if (err < 0) {
+ free_cable(substream);
+ kfree(dpcm);
+ }
mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -732,20 +754,10 @@ static int loopback_close(struct snd_pcm
{
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
loopback_timer_stop(dpcm);
mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
+ free_cable(substream);
mutex_unlock(&loopback->cable_lock);
return 0;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Add missing error checks in OSS emulation plugin builder
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 6708913750344a900f2e73bfe4a4d6dbbce4fe8d Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 16:39:27 +0100
Subject: ALSA: pcm: Add missing error checks in OSS emulation plugin builder
From: Takashi Iwai <tiwai(a)suse.de>
commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream.
In the OSS emulation plugin builder where the frame size is parsed in
the plugin chain, some places miss the possible errors returned from
the plugin src_ or dst_frames callback.
This patch papers over such places.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_plugin.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -591,18 +591,26 @@ snd_pcm_sframes_t snd_pcm_plug_write_tra
snd_pcm_sframes_t frames = size;
plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
+ while (plugin) {
+ if (frames <= 0)
+ return frames;
if ((next = plugin->next) != NULL) {
snd_pcm_sframes_t frames1 = frames;
- if (plugin->dst_frames)
+ if (plugin->dst_frames) {
frames1 = plugin->dst_frames(plugin, frames);
+ if (frames1 <= 0)
+ return frames1;
+ }
if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
return err;
}
if (err != frames1) {
frames = err;
- if (plugin->src_frames)
+ if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames1);
+ if (frames <= 0)
+ return frames;
+ }
}
} else
dst_channels = NULL;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Abort properly at pending signal in OSS read/write loops
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 13:58:31 +0100
Subject: ALSA: pcm: Abort properly at pending signal in OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream.
The loops for read and write in PCM OSS emulation have no proper check
of pending signals, and they keep processing even after user tries to
break. This results in a very long delay, often seen as RCU stall
when a huge unprocessed bytes remain queued. The bug could be easily
triggered by syzkaller.
As a simple workaround, this patch adds the proper check of pending
signals and aborts the loop appropriately.
Reported-by: syzbot+993cb4cfcbbff3947c21(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1416,6 +1416,10 @@ static ssize_t snd_pcm_oss_write1(struct
tmp != runtime->oss.period_bytes)
break;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
@@ -1501,6 +1505,10 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix racy hw constraints adjustment
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-racy-hw-constraints-adjustment.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 898dfe4687f460ba337a01c11549f87269a13fa2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 17:38:54 +0100
Subject: ALSA: aloop: Fix racy hw constraints adjustment
From: Takashi Iwai <tiwai(a)suse.de>
commit 898dfe4687f460ba337a01c11549f87269a13fa2 upstream.
The aloop driver tries to update the hw constraints of the connected
target on the cable of the opened PCM substream. This is done by
adding the extra hw constraints rules referring to the substream
runtime->hw fields, while the other substream may update the runtime
hw of another side on the fly.
This is, however, racy and may result in the inconsistent values when
both PCM streams perform the prepare concurrently. One of the reason
is that it overwrites the other's runtime->hw field; which is not only
racy but also broken when it's called before the open of another side
finishes. And, since the reference to runtime->hw isn't protected,
the concurrent write may give the partial value update and become
inconsistent.
This patch is an attempt to fix and clean up:
- The prepare doesn't change the runtime->hw of other side any longer,
but only update the cable->hw that is referred commonly.
- The extra rules refer to the loopback_pcm object instead of the
runtime->hw. The actual hw is deduced from cable->hw.
- The extra rules take the cable_lock to protect against the race.
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 51 ++++++++++++++++++++------------------------------
1 file changed, 21 insertions(+), 30 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -306,19 +306,6 @@ static int loopback_trigger(struct snd_p
return 0;
}
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
static void params_change(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -330,10 +317,6 @@ static void params_change(struct snd_pcm
cable->hw.rate_max = runtime->rate;
cable->hw.channels_min = runtime->channels;
cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
}
static int loopback_prepare(struct snd_pcm_substream *substream)
@@ -621,24 +604,29 @@ static unsigned int get_cable_index(stru
static int rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
-
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_mask m;
snd_mask_none(&m);
- m.bits[0] = (u_int32_t)hw->formats;
- m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ mutex_lock(&dpcm->loopback->cable_lock);
+ m.bits[0] = (u_int32_t)cable->hw.formats;
+ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
+ mutex_unlock(&dpcm->loopback->cable_lock);
return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->rate_min;
- t.max = hw->rate_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.rate_min;
+ t.max = cable->hw.rate_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -647,11 +635,14 @@ static int rule_rate(struct snd_pcm_hw_p
static int rule_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->channels_min;
- t.max = hw->channels_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.channels_min;
+ t.max = cable->hw.channels_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -717,19 +708,19 @@ static int loopback_open(struct snd_pcm_
/* are cached -> they do not reflect the actual state */
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
+ rule_format, dpcm,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
+ rule_rate, dpcm,
SNDRV_PCM_HW_PARAM_RATE, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
+ rule_channels, dpcm,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (err < 0)
goto unlock;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix inconsistent format due to incomplete rule
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:15:33 +0100
Subject: ALSA: aloop: Fix inconsistent format due to incomplete rule
From: Takashi Iwai <tiwai(a)suse.de>
commit b088b53e20c7d09b5ab84c5688e609f478e5c417 upstream.
The extra hw constraint rule for the formats the aloop driver
introduced has a slight flaw, where it doesn't return a positive value
when the mask got changed. It came from the fact that it's basically
a copy&paste from snd_hw_constraint_mask64(). The original code is
supposed to be a single-shot and it modifies the mask bits only once
and never after, while what we need for aloop is the dynamic hw rule
that limits the mask bits.
This difference results in the inconsistent state, as the hw_refine
doesn't apply the dependencies fully. The worse and surprisingly
result is that it causes a crash in OSS emulation when multiple
full-duplex reads/writes are performed concurrently (I leave why it
triggers Oops to readers as a homework).
For fixing this, replace a few open-codes with the standard
snd_mask_*() macros.
Reported-by: syzbot+3902b5220e8ca27889ca(a)syzkaller.appspotmail.com
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -39,6 +39,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
@@ -622,14 +623,12 @@ static int rule_format(struct snd_pcm_hw
{
struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
+ struct snd_mask m;
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
+ snd_mask_none(&m);
+ m.bits[0] = (u_int32_t)hw->formats;
+ m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.4/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.4/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.4/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.4/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.4/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.4/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.4/alsa-aloop-release-cable-upon-open-error-path.patch