Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

Fixes: 654ba4cc0f3e ("fpga manager: ensure lifetime with of_fpga_mgr_get")
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Suggested-by: Xu Yilun <yilun.xu@intel.com>
Signed-off-by: Marco Pagani <marpagan@redhat.com>
Acked-by: Xu Yilun <yilun.xu@intel.com>
Link: https://lore.kernel.org/r/20240305192926.84886-1-marpagan@redhat.com
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>

authored by

Marco Pagani and committed by
Xu Yilun
4d4d2d43 4cece764

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