Fwd: platform driver (musb/davinci.ko) and resource.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

   I'm forwarding this mail to linux-usb and the MUSB maintainer.

WBR, Sergei

-------- Original Message --------
Subject: 	platform driver (musb/davinci.ko) and resource.c
Date: 	Tue, 24 Jan 2012 23:02:59 +0200
From: 	Nam Nequam <maxdw.ml@xxxxxxxxx>
To: 	davinci-linux-open-source@xxxxxxxxxxxxxxxxxxxx



Hello,

In the recent kernel versions usb/musb/davinci has been promoted to a module
(platform driver) instead of being part of musb_hdrc.

There is a little bug if davinci.ko is compiled as loadable module. davinci.ko
can be inserted (modprobe) once only.
After removal, it cannot be inserted again, due to "musb_hdrc: failed to claim
resource 0" error in platform.c:platform_device_add() or crash.
It happens because upon davinci.ko:davinci_probe(),
resource.c:__insert_resource() modifies the global
mach-davinci/usb.c:usb_dev.resource variable.
After davinci.ko removal, the global usb.c:usb_dev.resource.parent points to
freed memory.
So, at the next modprobe davinci.ko, if, luckily, davinci.ko allocates memory
platfrom_device_add_resources():kmemdup at the same location,
it gives the above error ("claim resource"), otherwise - crash (since
resource->parent pointer is not valid)

It may be a common problem for platform devices that use global resource
array, and their loadable platform drivers.

BTW: Why does resource.c build a tree from overlapping resources at multiple
insertions, and then silently drops the whole sub-tree upon removal of the
current root.
Where the root is just the most recently added resource.


Here is the exact sequence:
1. Upon boot /mach-davinci/usb:davinci_setup_usb registers a usb_dev
1.1 platform.c:platform_device_add inserts a usb_dev.resource[0] (defaulting
its parent to iomem_resource)
1.2 resource.c:__insert_resource places usb_dev.resource[0] under iomem_resource

2. Upon modprobe davinci.ko:
2.1 davinci.c:davinci_probe kmemdup(platform_device_add_resources) the
resource from usb_dev.resource[0]  (where sb_dev.resource[0].parent ==
iomem_resource from 1.1)
2.2 davinci.c:davinci_probe    calls platform.c:platform_device_add, which
calls resource.c:insert_resource
2.3 resource.c:__insert_resource:
2.3.1 finds a registered (at 1.2) usb_dev.resource[0]
2.3.2 replaces it by musb->resource[0] and makes usb_dev.resource[0] child of
musb->resource[0]
2.3.3 so, now, the global usb_dev.resource[0].parent == musb->resource[0]
(usb_dev.resource[0].parent->musb->resource[0].parent->iomem_resource)

3. Upon rmmod davinci.ko
2.1 resource.c:release_resource drops both musb->resource[0] and
usb_dev.resource[0] (usb_dev.resource[0].parent->musb->resource[0].parent)
2.2 davinci.c:davinci_removes platform device
2.3 the global usb_dev.resource[0].parent now points to kfreed
parent->musb->resource[0]

4. Upon the second modprobe davinci.ko: resource.c:__insert_resource
4.1 davinci.c:davinci_probe kmemdup(platform_device_add_resources) the
resource from usb_dev.resource[0]  (where usb_dev.resource[0].parent ==
deleted  musb->resource[0] from 2.3.3)
4.2 if kmemdup allocated musb->resource[0] at the same place:
     __insert_resource will reject it, because its parent points to itself
(the same memory location from the previous reincarantion),
     otherwise
     __insert_resource will crash trying to insert musb->resource[0] under
[usb_dev/musb].parent which points to invalid memory location (released at 2.2)
_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@xxxxxxxxxxxxxxxxxxxx
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux