Commit 0c8c77d35582c3f7989f1316368da5ae7f14ad4b
Committed by
Greg Kroah-Hartman
1 parent
b44b214026
Exists in
master
and in
13 other branches
s390/ccwgroup: Fix memory corruption
commit 0b60f9ead5d4816e7e3d6e28f4a0d22d4a1b2513 (s390: use device_remove_file_self() instead of device_schedule_callback()) caused random memory corruption on my s390 box. Turns out that the last element of the ccwgroup structure is of dynamic size, so we must move the newly introduced work structure _before_ the zero length array. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> CC: Tejun Heo <tj@kernel.org> CC: Martin Schwidefsky <schwidefsky@de.ibm.com> CC: Heiko Carstens <heiko.carstens@de.ibm.com> CC: Sebastian Ott <sebott@linux.vnet.ibm.com> CC: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 1 additions and 1 deletions Inline Diff
arch/s390/include/asm/ccwgroup.h
1 | #ifndef S390_CCWGROUP_H | 1 | #ifndef S390_CCWGROUP_H |
2 | #define S390_CCWGROUP_H | 2 | #define S390_CCWGROUP_H |
3 | 3 | ||
4 | struct ccw_device; | 4 | struct ccw_device; |
5 | struct ccw_driver; | 5 | struct ccw_driver; |
6 | 6 | ||
7 | /** | 7 | /** |
8 | * struct ccwgroup_device - ccw group device | 8 | * struct ccwgroup_device - ccw group device |
9 | * @state: online/offline state | 9 | * @state: online/offline state |
10 | * @count: number of attached slave devices | 10 | * @count: number of attached slave devices |
11 | * @dev: embedded device structure | 11 | * @dev: embedded device structure |
12 | * @cdev: variable number of slave devices, allocated as needed | 12 | * @cdev: variable number of slave devices, allocated as needed |
13 | */ | 13 | */ |
14 | struct ccwgroup_device { | 14 | struct ccwgroup_device { |
15 | enum { | 15 | enum { |
16 | CCWGROUP_OFFLINE, | 16 | CCWGROUP_OFFLINE, |
17 | CCWGROUP_ONLINE, | 17 | CCWGROUP_ONLINE, |
18 | } state; | 18 | } state; |
19 | /* private: */ | 19 | /* private: */ |
20 | atomic_t onoff; | 20 | atomic_t onoff; |
21 | struct mutex reg_mutex; | 21 | struct mutex reg_mutex; |
22 | /* public: */ | 22 | /* public: */ |
23 | unsigned int count; | 23 | unsigned int count; |
24 | struct device dev; | 24 | struct device dev; |
25 | struct ccw_device *cdev[0]; | ||
26 | struct work_struct ungroup_work; | 25 | struct work_struct ungroup_work; |
26 | struct ccw_device *cdev[0]; | ||
27 | }; | 27 | }; |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * struct ccwgroup_driver - driver for ccw group devices | 30 | * struct ccwgroup_driver - driver for ccw group devices |
31 | * @setup: function called during device creation to setup the device | 31 | * @setup: function called during device creation to setup the device |
32 | * @remove: function called on remove | 32 | * @remove: function called on remove |
33 | * @set_online: function called when device is set online | 33 | * @set_online: function called when device is set online |
34 | * @set_offline: function called when device is set offline | 34 | * @set_offline: function called when device is set offline |
35 | * @shutdown: function called when device is shut down | 35 | * @shutdown: function called when device is shut down |
36 | * @prepare: prepare for pm state transition | 36 | * @prepare: prepare for pm state transition |
37 | * @complete: undo work done in @prepare | 37 | * @complete: undo work done in @prepare |
38 | * @freeze: callback for freezing during hibernation snapshotting | 38 | * @freeze: callback for freezing during hibernation snapshotting |
39 | * @thaw: undo work done in @freeze | 39 | * @thaw: undo work done in @freeze |
40 | * @restore: callback for restoring after hibernation | 40 | * @restore: callback for restoring after hibernation |
41 | * @driver: embedded driver structure | 41 | * @driver: embedded driver structure |
42 | */ | 42 | */ |
43 | struct ccwgroup_driver { | 43 | struct ccwgroup_driver { |
44 | int (*setup) (struct ccwgroup_device *); | 44 | int (*setup) (struct ccwgroup_device *); |
45 | void (*remove) (struct ccwgroup_device *); | 45 | void (*remove) (struct ccwgroup_device *); |
46 | int (*set_online) (struct ccwgroup_device *); | 46 | int (*set_online) (struct ccwgroup_device *); |
47 | int (*set_offline) (struct ccwgroup_device *); | 47 | int (*set_offline) (struct ccwgroup_device *); |
48 | void (*shutdown)(struct ccwgroup_device *); | 48 | void (*shutdown)(struct ccwgroup_device *); |
49 | int (*prepare) (struct ccwgroup_device *); | 49 | int (*prepare) (struct ccwgroup_device *); |
50 | void (*complete) (struct ccwgroup_device *); | 50 | void (*complete) (struct ccwgroup_device *); |
51 | int (*freeze)(struct ccwgroup_device *); | 51 | int (*freeze)(struct ccwgroup_device *); |
52 | int (*thaw) (struct ccwgroup_device *); | 52 | int (*thaw) (struct ccwgroup_device *); |
53 | int (*restore)(struct ccwgroup_device *); | 53 | int (*restore)(struct ccwgroup_device *); |
54 | 54 | ||
55 | struct device_driver driver; | 55 | struct device_driver driver; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); | 58 | extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); |
59 | extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); | 59 | extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); |
60 | int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv, | 60 | int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv, |
61 | int num_devices, const char *buf); | 61 | int num_devices, const char *buf); |
62 | 62 | ||
63 | extern int ccwgroup_set_online(struct ccwgroup_device *gdev); | 63 | extern int ccwgroup_set_online(struct ccwgroup_device *gdev); |
64 | extern int ccwgroup_set_offline(struct ccwgroup_device *gdev); | 64 | extern int ccwgroup_set_offline(struct ccwgroup_device *gdev); |
65 | 65 | ||
66 | extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); | 66 | extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); |
67 | extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); | 67 | extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); |
68 | 68 | ||
69 | #define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev) | 69 | #define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev) |
70 | #define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver) | 70 | #define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver) |
71 | #endif | 71 | #endif |