History

fpga: manager: add owner module and take its refcount

The current implementation of the fpga manager assumes that the low-level module registers a driver for the parent device and uses its owner pointer to take the module's refcount. This approach is problematic since it can lead to a null pointer dereference while attempting to get the manager if the parent device does not have a driver. To address this problem, add a module owner pointer to the fpga_manager struct and use it to take the module's refcount. Modify the functions for registering the manager to take an additional owner module parameter and rename them to avoid conflicts. Use the old function names for helper macros that automatically set the module that registers the manager as the owner. This ensures compatibility with existing low-level control modules and reduces the chances of registering a manager without setting the owner. Also, update the documentation to keep it consistent with the new interface for registering an fpga manager. Other changes: opportunistically move put_device() from __fpga_mgr_get() to fpga_mgr_get() and of_fpga_mgr_get() to improve code clarity since the manager device is taken in these functions.

Marco Pagani committed 2 years ago

Commit 4d4d2d41 parent 4cece763 files · +89 −53Browse files

Unified · Split

3 files
  1. Documentation/driver-api/fpga/fpga-mgr.rst +20 −14
  2. drivers/fpga/fpga-mgr.c +49 −33
  3. include/linux/fpga/fpga-mgr.h +20 −6
Documentation/driver-api/fpga/fpga-mgr.rst+20−14
@@ -24,7 +24,8 @@ How to support a new FPGA device · 23 unmodified lines
24--------------------------------24--------------------------------
25 25
26To add another FPGA manager, write a driver that implements a set of ops. The26To add another FPGA manager, write a driver that implements a set of ops. The
27probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as::27probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``,
28such as::
28 29
29 static const struct fpga_manager_ops socfpga_fpga_ops = {30 static const struct fpga_manager_ops socfpga_fpga_ops = {
30 .write_init = socfpga_fpga_ops_configure_init,31 .write_init = socfpga_fpga_ops_configure_init,
@@ -69,10 +70,11 @@ probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as:: · 38 unmodified lines
69 }70 }
70 71
71Alternatively, the probe function could call one of the resource managed72Alternatively, the probe function could call one of the resource managed
72register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full().73register functions, ``devm_fpga_mgr_register()`` or
73When these functions are used, the parameter syntax is the same, but the call74``devm_fpga_mgr_register_full()``. When these functions are used, the
74to fpga_mgr_unregister() should be removed. In the above example, the75parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be
75socfpga_fpga_remove() function would not be required.76removed. In the above example, the ``socfpga_fpga_remove()`` function would not be
77required.
76 78
77The ops will implement whatever device specific register writes are needed to79The ops will implement whatever device specific register writes are needed to
78do the programming sequence for this particular FPGA. These ops return 0 for80do the programming sequence for this particular FPGA. These ops return 0 for
@@ -125,15 +127,19 @@ API for implementing a new FPGA Manager driver · 46 unmodified lines
125* struct fpga_manager - the FPGA manager struct127* struct fpga_manager - the FPGA manager struct
126* struct fpga_manager_ops - Low level FPGA manager driver ops128* struct fpga_manager_ops - Low level FPGA manager driver ops
127* struct fpga_manager_info - Parameter structure for fpga_mgr_register_full()129* struct fpga_manager_info - Parameter structure for fpga_mgr_register_full()
128* fpga_mgr_register_full() - Create and register an FPGA manager using the130* __fpga_mgr_register_full() - Create and register an FPGA manager using the
129 fpga_mgr_info structure to provide the full flexibility of options131 fpga_mgr_info structure to provide the full flexibility of options
130* fpga_mgr_register() - Create and register an FPGA manager using standard132* __fpga_mgr_register() - Create and register an FPGA manager using standard
131 arguments133 arguments
132* devm_fpga_mgr_register_full() - Resource managed version of134* __devm_fpga_mgr_register_full() - Resource managed version of
133 fpga_mgr_register_full()135 __fpga_mgr_register_full()
134* devm_fpga_mgr_register() - Resource managed version of fpga_mgr_register()136* __devm_fpga_mgr_register() - Resource managed version of __fpga_mgr_register()
135* fpga_mgr_unregister() - Unregister an FPGA manager137* fpga_mgr_unregister() - Unregister an FPGA manager
136 138
139Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``,
140``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available
141to ease the registration.
142
137.. kernel-doc:: include/linux/fpga/fpga-mgr.h143.. kernel-doc:: include/linux/fpga/fpga-mgr.h
138 :functions: fpga_mgr_states144 :functions: fpga_mgr_states
139 145
@@ -147,16 +153,16 @@ API for implementing a new FPGA Manager driver · 7 unmodified lines
147 :functions: fpga_manager_info153 :functions: fpga_manager_info
148 154
149.. kernel-doc:: drivers/fpga/fpga-mgr.c155.. kernel-doc:: drivers/fpga/fpga-mgr.c
150 :functions: fpga_mgr_register_full156 :functions: __fpga_mgr_register_full
151 157
152.. kernel-doc:: drivers/fpga/fpga-mgr.c158.. kernel-doc:: drivers/fpga/fpga-mgr.c
153 :functions: fpga_mgr_register159 :functions: __fpga_mgr_register
154 160
155.. kernel-doc:: drivers/fpga/fpga-mgr.c161.. kernel-doc:: drivers/fpga/fpga-mgr.c
156 :functions: devm_fpga_mgr_register_full162 :functions: __devm_fpga_mgr_register_full
157 163
158.. kernel-doc:: drivers/fpga/fpga-mgr.c164.. kernel-doc:: drivers/fpga/fpga-mgr.c
159 :functions: devm_fpga_mgr_register165 :functions: __devm_fpga_mgr_register
160 166
161.. kernel-doc:: drivers/fpga/fpga-mgr.c167.. kernel-doc:: drivers/fpga/fpga-mgr.c
162 :functions: fpga_mgr_unregister168 :functions: fpga_mgr_unregister
drivers/fpga/fpga-mgr.c+49−33
@@ -664,20 +664,16 @@ static struct attribute *fpga_mgr_attrs[] = { · 663 unmodified lines
664};664};
665ATTRIBUTE_GROUPS(fpga_mgr);665ATTRIBUTE_GROUPS(fpga_mgr);
666 666
667static struct fpga_manager *__fpga_mgr_get(struct device *dev)667static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)
668{668{
669 struct fpga_manager *mgr;669 struct fpga_manager *mgr;
670 670
671 mgr = to_fpga_manager(dev);671 mgr = to_fpga_manager(mgr_dev);
672 672
673 if (!try_module_get(dev->parent->driver->owner))673 if (!try_module_get(mgr->mops_owner))
674 goto err_dev;674 mgr = ERR_PTR(-ENODEV);
675 675
676 return mgr;676 return mgr;
677
678err_dev:
679 put_device(dev);
680 return ERR_PTR(-ENODEV);
681}677}
682 678
683static int fpga_mgr_dev_match(struct device *dev, const void *data)679static int fpga_mgr_dev_match(struct device *dev, const void *data)
@@ -693,12 +689,18 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data) · 9 unmodified lines
693 */689 */
694struct fpga_manager *fpga_mgr_get(struct device *dev)690struct fpga_manager *fpga_mgr_get(struct device *dev)
695{691{
696 struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev,692 struct fpga_manager *mgr;
697 fpga_mgr_dev_match);693 struct device *mgr_dev;
694
695 mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match);
698 if (!mgr_dev)696 if (!mgr_dev)
699 return ERR_PTR(-ENODEV);697 return ERR_PTR(-ENODEV);
700 698
701 return __fpga_mgr_get(mgr_dev);699 mgr = __fpga_mgr_get(mgr_dev);
700 if (IS_ERR(mgr))
701 put_device(mgr_dev);
702
703 return mgr;
702}704}
703EXPORT_SYMBOL_GPL(fpga_mgr_get);705EXPORT_SYMBOL_GPL(fpga_mgr_get);
704 706
@@ -711,13 +713,18 @@ EXPORT_SYMBOL_GPL(fpga_mgr_get); · 6 unmodified lines
711 */713 */
712struct fpga_manager *of_fpga_mgr_get(struct device_node *node)714struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
713{715{
714 struct device *dev;716 struct fpga_manager *mgr;
717 struct device *mgr_dev;
715 718
716 dev = class_find_device_by_of_node(&fpga_mgr_class, node);719 mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node);
717 if (!dev)720 if (!mgr_dev)
718 return ERR_PTR(-ENODEV);721 return ERR_PTR(-ENODEV);
719 722
720 return __fpga_mgr_get(dev);723 mgr = __fpga_mgr_get(mgr_dev);
724 if (IS_ERR(mgr))
725 put_device(mgr_dev);
726
727 return mgr;
721}728}
722EXPORT_SYMBOL_GPL(of_fpga_mgr_get);729EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
723 730
@@ -727,7 +734,7 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get); · 3 unmodified lines
727 */734 */
728void fpga_mgr_put(struct fpga_manager *mgr)735void fpga_mgr_put(struct fpga_manager *mgr)
729{736{
730 module_put(mgr->dev.parent->driver->owner);737 module_put(mgr->mops_owner);
731 put_device(&mgr->dev);738 put_device(&mgr->dev);
732}739}
733EXPORT_SYMBOL_GPL(fpga_mgr_put);740EXPORT_SYMBOL_GPL(fpga_mgr_put);
@@ -766,9 +773,10 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) · 32 unmodified lines
766EXPORT_SYMBOL_GPL(fpga_mgr_unlock);773EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
767 774
768/**775/**
769 * fpga_mgr_register_full - create and register an FPGA Manager device776 * __fpga_mgr_register_full - create and register an FPGA Manager device
770 * @parent: fpga manager device from pdev777 * @parent: fpga manager device from pdev
771 * @info: parameters for fpga manager778 * @info: parameters for fpga manager
779 * @owner: owner module containing the ops
772 *780 *
773 * The caller of this function is responsible for calling fpga_mgr_unregister().781 * The caller of this function is responsible for calling fpga_mgr_unregister().
774 * Using devm_fpga_mgr_register_full() instead is recommended.782 * Using devm_fpga_mgr_register_full() instead is recommended.
@@ -776,7 +784,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock); · 1 unmodified line
776 * Return: pointer to struct fpga_manager pointer or ERR_PTR()784 * Return: pointer to struct fpga_manager pointer or ERR_PTR()
777 */785 */
778struct fpga_manager *786struct fpga_manager *
779fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)787__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
788 struct module *owner)
780{789{
781 const struct fpga_manager_ops *mops = info->mops;790 const struct fpga_manager_ops *mops = info->mops;
782 struct fpga_manager *mgr;791 struct fpga_manager *mgr;
@@ -804,6 +813,8 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in · 21 unmodified lines
804 813
805 mutex_init(&mgr->ref_mutex);814 mutex_init(&mgr->ref_mutex);
806 815
816 mgr->mops_owner = owner;
817
807 mgr->name = info->name;818 mgr->name = info->name;
808 mgr->mops = info->mops;819 mgr->mops = info->mops;
809 mgr->priv = info->priv;820 mgr->priv = info->priv;
@@ -841,14 +852,15 @@ error_kfree: · 31 unmodified lines
841 852
842 return ERR_PTR(ret);853 return ERR_PTR(ret);
843}854}
844EXPORT_SYMBOL_GPL(fpga_mgr_register_full);855EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);
845 856
846/**857/**
847 * fpga_mgr_register - create and register an FPGA Manager device858 * __fpga_mgr_register - create and register an FPGA Manager device
848 * @parent: fpga manager device from pdev859 * @parent: fpga manager device from pdev
849 * @name: fpga manager name860 * @name: fpga manager name
850 * @mops: pointer to structure of fpga manager ops861 * @mops: pointer to structure of fpga manager ops
851 * @priv: fpga manager private data862 * @priv: fpga manager private data
863 * @owner: owner module containing the ops
852 *864 *
853 * The caller of this function is responsible for calling fpga_mgr_unregister().865 * The caller of this function is responsible for calling fpga_mgr_unregister().
854 * Using devm_fpga_mgr_register() instead is recommended. This simple866 * Using devm_fpga_mgr_register() instead is recommended. This simple
@@ -859,8 +871,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_register_full); · 4 unmodified lines
859 * Return: pointer to struct fpga_manager pointer or ERR_PTR()871 * Return: pointer to struct fpga_manager pointer or ERR_PTR()
860 */872 */
861struct fpga_manager *873struct fpga_manager *
862fpga_mgr_register(struct device *parent, const char *name,874__fpga_mgr_register(struct device *parent, const char *name,
863 const struct fpga_manager_ops *mops, void *priv)875 const struct fpga_manager_ops *mops, void *priv, struct module *owner)
864{876{
865 struct fpga_manager_info info = { 0 };877 struct fpga_manager_info info = { 0 };
866 878
@@ -868,9 +880,9 @@ fpga_mgr_register(struct device *parent, const char *name, · 1 unmodified line
868 info.mops = mops;880 info.mops = mops;
869 info.priv = priv;881 info.priv = priv;
870 882
871 return fpga_mgr_register_full(parent, &info);883 return __fpga_mgr_register_full(parent, &info, owner);
872}884}
873EXPORT_SYMBOL_GPL(fpga_mgr_register);885EXPORT_SYMBOL_GPL(__fpga_mgr_register);
874 886
875/**887/**
876 * fpga_mgr_unregister - unregister an FPGA manager888 * fpga_mgr_unregister - unregister an FPGA manager
@@ -900,9 +912,10 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res) · 23 unmodified lines
900}912}
901 913
902/**914/**
903 * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()915 * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
904 * @parent: fpga manager device from pdev916 * @parent: fpga manager device from pdev
905 * @info: parameters for fpga manager917 * @info: parameters for fpga manager
918 * @owner: owner module containing the ops
906 *919 *
907 * Return: fpga manager pointer on success, negative error code otherwise.920 * Return: fpga manager pointer on success, negative error code otherwise.
908 *921 *
@@ -910,7 +923,8 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res) · 1 unmodified line
910 * function will be called automatically when the managing device is detached.923 * function will be called automatically when the managing device is detached.
911 */924 */
912struct fpga_manager *925struct fpga_manager *
913devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)926__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
927 struct module *owner)
914{928{
915 struct fpga_mgr_devres *dr;929 struct fpga_mgr_devres *dr;
916 struct fpga_manager *mgr;930 struct fpga_manager *mgr;
@@ -919,7 +933,7 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf · 2 unmodified lines
919 if (!dr)933 if (!dr)
920 return ERR_PTR(-ENOMEM);934 return ERR_PTR(-ENOMEM);
921 935
922 mgr = fpga_mgr_register_full(parent, info);936 mgr = __fpga_mgr_register_full(parent, info, owner);
923 if (IS_ERR(mgr)) {937 if (IS_ERR(mgr)) {
924 devres_free(dr);938 devres_free(dr);
925 return mgr;939 return mgr;
@@ -930,14 +944,15 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf · 4 unmodified lines
930 944
931 return mgr;945 return mgr;
932}946}
933EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full);947EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);
934 948
935/**949/**
936 * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()950 * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
937 * @parent: fpga manager device from pdev951 * @parent: fpga manager device from pdev
938 * @name: fpga manager name952 * @name: fpga manager name
939 * @mops: pointer to structure of fpga manager ops953 * @mops: pointer to structure of fpga manager ops
940 * @priv: fpga manager private data954 * @priv: fpga manager private data
955 * @owner: owner module containing the ops
941 *956 *
942 * Return: fpga manager pointer on success, negative error code otherwise.957 * Return: fpga manager pointer on success, negative error code otherwise.
943 *958 *
@@ -946,8 +961,9 @@ EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); · 2 unmodified lines
946 * device is detached.961 * device is detached.
947 */962 */
948struct fpga_manager *963struct fpga_manager *
949devm_fpga_mgr_register(struct device *parent, const char *name,964__devm_fpga_mgr_register(struct device *parent, const char *name,
950 const struct fpga_manager_ops *mops, void *priv)965 const struct fpga_manager_ops *mops, void *priv,
966 struct module *owner)
951{967{
952 struct fpga_manager_info info = { 0 };968 struct fpga_manager_info info = { 0 };
953 969
@@ -955,9 +971,9 @@ devm_fpga_mgr_register(struct device *parent, const char *name, · 1 unmodified line
955 info.mops = mops;971 info.mops = mops;
956 info.priv = priv;972 info.priv = priv;
957 973
958 return devm_fpga_mgr_register_full(parent, &info);974 return __devm_fpga_mgr_register_full(parent, &info, owner);
959}975}
960EXPORT_SYMBOL_GPL(devm_fpga_mgr_register);976EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);
961 977
962static void fpga_mgr_dev_release(struct device *dev)978static void fpga_mgr_dev_release(struct device *dev)
963{979{
include/linux/fpga/fpga-mgr.h+20−6
@@ -201,6 +201,7 @@ struct fpga_manager_ops { · 200 unmodified lines
201 * @state: state of fpga manager201 * @state: state of fpga manager
202 * @compat_id: FPGA manager id for compatibility check.202 * @compat_id: FPGA manager id for compatibility check.
203 * @mops: pointer to struct of fpga manager ops203 * @mops: pointer to struct of fpga manager ops
204 * @mops_owner: module containing the mops
204 * @priv: low level driver private date205 * @priv: low level driver private date
205 */206 */
206struct fpga_manager {207struct fpga_manager {
@@ -210,6 +211,7 @@ struct fpga_manager { · 3 unmodified lines
210 enum fpga_mgr_states state;211 enum fpga_mgr_states state;
211 struct fpga_compat_id *compat_id;212 struct fpga_compat_id *compat_id;
212 const struct fpga_manager_ops *mops;213 const struct fpga_manager_ops *mops;
214 struct module *mops_owner;
213 void *priv;215 void *priv;
214};216};
215 217
@@ -230,18 +232,30 @@ struct fpga_manager *fpga_mgr_get(struct device *dev); · 14 unmodified lines
230 232
231void fpga_mgr_put(struct fpga_manager *mgr);233void fpga_mgr_put(struct fpga_manager *mgr);
232 234
235#define fpga_mgr_register_full(parent, info) \
236 __fpga_mgr_register_full(parent, info, THIS_MODULE)
233struct fpga_manager *237struct fpga_manager *
234fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info);238__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
239 struct module *owner);
235 240
241#define fpga_mgr_register(parent, name, mops, priv) \
242 __fpga_mgr_register(parent, name, mops, priv, THIS_MODULE)
236struct fpga_manager *243struct fpga_manager *
237fpga_mgr_register(struct device *parent, const char *name,244__fpga_mgr_register(struct device *parent, const char *name,
238 const struct fpga_manager_ops *mops, void *priv);245 const struct fpga_manager_ops *mops, void *priv, struct module *owner);
246
239void fpga_mgr_unregister(struct fpga_manager *mgr);247void fpga_mgr_unregister(struct fpga_manager *mgr);
240 248
249#define devm_fpga_mgr_register_full(parent, info) \
250 __devm_fpga_mgr_register_full(parent, info, THIS_MODULE)
241struct fpga_manager *251struct fpga_manager *
242devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info);252__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
253 struct module *owner);
254#define devm_fpga_mgr_register(parent, name, mops, priv) \
255 __devm_fpga_mgr_register(parent, name, mops, priv, THIS_MODULE)
243struct fpga_manager *256struct fpga_manager *
244devm_fpga_mgr_register(struct device *parent, const char *name,257__devm_fpga_mgr_register(struct device *parent, const char *name,
245 const struct fpga_manager_ops *mops, void *priv);258 const struct fpga_manager_ops *mops, void *priv,
259 struct module *owner);
246 260
247#endif /*_LINUX_FPGA_MGR_H */261#endif /*_LINUX_FPGA_MGR_H */