USB: set device dma_mask without reference to global data
Many USB host drivers contain code such as:
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &tegra_ehci_dma_mask;
... where tegra_ehci_dma_mask is a global. I suspect this code originated
in commit 4a53f4e
"USB: ehci-tegra: add probing through device tree" and
was simply copied everywhere else.
This works fine when the code is built-in, but can cause a crash when the
code is in a module. The first module load sets up the dma_mask pointer,
but if the module is removed and re-inserted, the value is now non-NULL,
and hence is not updated to point at the new location, and hence points
at a stale location within the previous module load address, which in
turn causes a crash if the pointer is de-referenced.
The simplest way of solving this seems to be to copy the code from
ehci-platform.c, which uses the coherent_dma_mask as the target for the
dma_mask pointer.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Tony Prisk <linux@prisktech.co.nz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8ff10bdb14
commit
3b9561e9d9
|
@ -173,17 +173,10 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
|
|||
|
||||
ci13xxx_imx_platdata.phy = data->phy;
|
||||
|
||||
if (!pdev->dev.dma_mask) {
|
||||
pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
|
||||
if (!pdev->dev.dma_mask) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
|
||||
goto err;
|
||||
}
|
||||
*pdev->dev.dma_mask = DMA_BIT_MASK(32);
|
||||
dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);
|
||||
}
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (usbmisc_ops && usbmisc_ops->init) {
|
||||
ret = usbmisc_ops->init(&pdev->dev);
|
||||
|
|
|
@ -95,8 +95,6 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int dwc3_exynos_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct dwc3_exynos *exynos;
|
||||
|
@ -118,7 +116,9 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
|
|||
* Once we move to full device tree support this will vanish off.
|
||||
*/
|
||||
if (!dev->dma_mask)
|
||||
dev->dma_mask = &dwc3_exynos_dma_mask;
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
if (!dev->coherent_dma_mask)
|
||||
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
platform_set_drvdata(pdev, exynos);
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ static void atmel_stop_ehci(struct platform_device *pdev)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
|
@ -93,7 +91,9 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &at91_ehci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
|
||||
if (!hcd) {
|
||||
|
|
|
@ -90,8 +90,6 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = {
|
|||
.extra_priv_size = sizeof(struct omap_hcd),
|
||||
};
|
||||
|
||||
static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
/**
|
||||
* ehci_hcd_omap_probe - initialize TI-based HCDs
|
||||
*
|
||||
|
@ -146,8 +144,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
|||
* Since shared usb code relies on it, set it here for now.
|
||||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &omap_ehci_dma_mask;
|
||||
if (!dev->dma_mask)
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
if (!dev->coherent_dma_mask)
|
||||
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,
|
||||
dev_name(dev));
|
||||
|
|
|
@ -137,8 +137,6 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
|
|||
}
|
||||
}
|
||||
|
||||
static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int ehci_orion_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct orion_ehci_data *pd = pdev->dev.platform_data;
|
||||
|
@ -183,7 +181,9 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
|
|||
* now. Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &ehci_orion_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (!request_mem_region(res->start, resource_size(res),
|
||||
ehci_orion_hc_driver.description)) {
|
||||
|
|
|
@ -71,8 +71,6 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
|
|||
dev_err(dev, "can't request ehci vbus gpio %d", gpio);
|
||||
}
|
||||
|
||||
static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int s5p_ehci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
|
||||
|
@ -90,7 +88,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
|
|||
* Once we move to full device tree support this will vanish off.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &ehci_s5p_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
|
|
|
@ -58,8 +58,6 @@ static int ehci_spear_drv_resume(struct device *dev)
|
|||
static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
|
||||
ehci_spear_drv_resume);
|
||||
|
||||
static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd ;
|
||||
|
@ -84,7 +82,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &spear_ehci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
usbh_clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(usbh_clk)) {
|
||||
|
|
|
@ -637,8 +637,6 @@ static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
|
|||
writel(val, base + TEGRA_USB_PORTSC1);
|
||||
}
|
||||
|
||||
static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int tegra_ehci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
|
@ -661,7 +659,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &tegra_ehci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
setup_vbus_gpio(pdev, pdata);
|
||||
|
||||
|
|
|
@ -504,8 +504,6 @@ static const struct of_device_id at91_ohci_dt_ids[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
|
||||
|
||||
static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int ohci_at91_of_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
@ -522,7 +520,9 @@ static int ohci_at91_of_init(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &at91_ohci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
|
|
|
@ -98,8 +98,6 @@ static const struct hc_driver exynos_ohci_hc_driver = {
|
|||
.start_port_reset = ohci_start_port_reset,
|
||||
};
|
||||
|
||||
static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int exynos_ohci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
|
||||
|
@ -117,7 +115,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
|
|||
* Once we move to full device tree support this will vanish off.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &ohci_exynos_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
|
|
|
@ -114,8 +114,6 @@ static const struct hc_driver ohci_omap3_hc_driver = {
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
/*
|
||||
* configure so an HC device and id are always provided
|
||||
* always called with process context; sleeping is OK
|
||||
|
@ -168,8 +166,10 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
|
|||
* Since shared usb code relies on it, set it here for now.
|
||||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &omap_ohci_dma_mask;
|
||||
if (!dev->dma_mask)
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
if (!dev->coherent_dma_mask)
|
||||
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,
|
||||
dev_name(dev));
|
||||
|
|
|
@ -282,8 +282,6 @@ static const struct of_device_id pxa_ohci_dt_ids[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids);
|
||||
|
||||
static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int ohci_pxa_of_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
@ -298,7 +296,9 @@ static int ohci_pxa_of_init(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &pxa_ohci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
|
|
|
@ -91,8 +91,6 @@ static const struct hc_driver ohci_spear_hc_driver = {
|
|||
.start_port_reset = ohci_start_port_reset,
|
||||
};
|
||||
|
||||
static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct hc_driver *driver = &ohci_spear_hc_driver;
|
||||
|
@ -114,7 +112,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &spear_ohci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
usbh_clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(usbh_clk)) {
|
||||
|
|
|
@ -60,8 +60,6 @@ static const struct hc_driver uhci_platform_hc_driver = {
|
|||
.hub_control = uhci_hub_control,
|
||||
};
|
||||
|
||||
static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int uhci_hcd_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
|
@ -78,7 +76,9 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
|
|||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &platform_uhci_dma_mask;
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
if (!pdev->dev.coherent_dma_mask)
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
|
||||
pdev->name);
|
||||
|
|
Loading…
Reference in a new issue