mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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;
|
ci13xxx_imx_platdata.phy = data->phy;
|
||||||
|
|
||||||
if (!pdev->dev.dma_mask) {
|
if (!pdev->dev.dma_mask)
|
||||||
pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
|
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||||
sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
|
if (!pdev->dev.coherent_dma_mask)
|
||||||
if (!pdev->dev.dma_mask) {
|
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||||
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 (usbmisc_ops && usbmisc_ops->init) {
|
if (usbmisc_ops && usbmisc_ops->init) {
|
||||||
ret = usbmisc_ops->init(&pdev->dev);
|
ret = usbmisc_ops->init(&pdev->dev);
|
||||||
|
@ -95,8 +95,6 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
|
|
||||||
|
|
||||||
static int dwc3_exynos_probe(struct platform_device *pdev)
|
static int dwc3_exynos_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dwc3_exynos *exynos;
|
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.
|
* Once we move to full device tree support this will vanish off.
|
||||||
*/
|
*/
|
||||||
if (!dev->dma_mask)
|
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);
|
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)
|
static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct usb_hcd *hcd;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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));
|
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
|
||||||
if (!hcd) {
|
if (!hcd) {
|
||||||
|
@ -90,8 +90,6 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = {
|
|||||||
.extra_priv_size = sizeof(struct omap_hcd),
|
.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
|
* 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.
|
* Since shared usb code relies on it, set it here for now.
|
||||||
* Once we have dma capability bindings this can go away.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
if (!dev->dma_mask)
|
||||||
pdev->dev.dma_mask = &omap_ehci_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,
|
hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,
|
||||||
dev_name(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)
|
static int ehci_orion_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct orion_ehci_data *pd = pdev->dev.platform_data;
|
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.
|
* now. Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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),
|
if (!request_mem_region(res->start, resource_size(res),
|
||||||
ehci_orion_hc_driver.description)) {
|
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);
|
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)
|
static int s5p_ehci_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
|
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.
|
* Once we move to full device tree support this will vanish off.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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)
|
if (!pdev->dev.coherent_dma_mask)
|
||||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
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,
|
static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
|
||||||
ehci_spear_drv_resume);
|
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)
|
static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct usb_hcd *hcd ;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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);
|
usbh_clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(usbh_clk)) {
|
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);
|
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)
|
static int tegra_ehci_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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);
|
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);
|
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)
|
static int ohci_at91_of_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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);
|
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||||
if (!pdata)
|
if (!pdata)
|
||||||
|
@ -98,8 +98,6 @@ static const struct hc_driver exynos_ohci_hc_driver = {
|
|||||||
.start_port_reset = ohci_start_port_reset,
|
.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)
|
static int exynos_ohci_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
|
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.
|
* Once we move to full device tree support this will vanish off.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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)
|
if (!pdev->dev.coherent_dma_mask)
|
||||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
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
|
* configure so an HC device and id are always provided
|
||||||
* always called with process context; sleeping is OK
|
* 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.
|
* Since shared usb code relies on it, set it here for now.
|
||||||
* Once we have dma capability bindings this can go away.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
if (!dev->dma_mask)
|
||||||
pdev->dev.dma_mask = &omap_ohci_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,
|
hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,
|
||||||
dev_name(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);
|
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)
|
static int ohci_pxa_of_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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);
|
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||||
if (!pdata)
|
if (!pdata)
|
||||||
|
@ -91,8 +91,6 @@ static const struct hc_driver ohci_spear_hc_driver = {
|
|||||||
.start_port_reset = ohci_start_port_reset,
|
.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)
|
static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
const struct hc_driver *driver = &ohci_spear_hc_driver;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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);
|
usbh_clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(usbh_clk)) {
|
if (IS_ERR(usbh_clk)) {
|
||||||
|
@ -60,8 +60,6 @@ static const struct hc_driver uhci_platform_hc_driver = {
|
|||||||
.hub_control = uhci_hub_control,
|
.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)
|
static int uhci_hcd_platform_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct usb_hcd *hcd;
|
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.
|
* Once we have dma capability bindings this can go away.
|
||||||
*/
|
*/
|
||||||
if (!pdev->dev.dma_mask)
|
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,
|
hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
|
||||||
pdev->name);
|
pdev->name);
|
||||||
|
Loading…
Reference in New Issue
Block a user