diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index b1c8585e09ae8d..3e8c2ba07c95db 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -355,11 +355,18 @@ typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_pa
 
 void verbs_register_driver(const struct verbs_device_ops *ops);
 
-/* Macro for providers to use to supply verbs_device_ops to the core code */
-#define PROVIDER_DRIVER(drv)                                                   \
+/*
+ * Macro for providers to use to supply verbs_device_ops to the core code.
+ * This creates a global symbol for the provider structure to be used by the
+ * ibv_static_providers() machinery, and a global constructor for the dlopen
+ * machinery.
+ */
+#define PROVIDER_DRIVER(provider_name, drv_struct)                             \
+	extern const struct verbs_device_ops verbs_provider_##provider_name    \
+		__attribute__((alias(stringify(drv_struct))));                 \
 	static __attribute__((constructor)) void drv##__register_driver(void)  \
 	{                                                                      \
-		verbs_register_driver(&drv);                                   \
+		verbs_register_driver(&drv_struct);                            \
 	}
 
 void *_verbs_init_and_alloc_context(struct ibv_device *device, int cmd_fd,
diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h
index 80b8414236683a..e5327eee48564d 100644
--- a/libibverbs/verbs.h
+++ b/libibverbs/verbs.h
@@ -1880,6 +1880,25 @@ static inline struct verbs_context *verbs_get_ctx(struct ibv_context *ctx)
  */
 struct ibv_device **ibv_get_device_list(int *num_devices);
 
+#ifdef RDMA_STATIC_PROVIDERS
+struct verbs_devices_ops;
+extern const struct verbs_device_ops verbs_provider_bnxt_re;
+extern const struct verbs_device_ops verbs_provider_cxgb3;
+extern const struct verbs_device_ops verbs_provider_cxgb4;
+extern const struct verbs_device_ops verbs_provider_hfi1verbs;
+extern const struct verbs_device_ops verbs_provider_hns;
+extern const struct verbs_device_ops verbs_provider_i40iw;
+extern const struct verbs_device_ops verbs_provider_ipathverbs;
+extern const struct verbs_device_ops verbs_provider_mlx4;
+extern const struct verbs_device_ops verbs_provider_mlx5;
+extern const struct verbs_device_ops verbs_provider_mthca;
+extern const struct verbs_device_ops verbs_provider_nes;
+extern const struct verbs_device_ops verbs_provider_ocrdma;
+extern const struct verbs_device_ops verbs_provider_qedr;
+extern const struct verbs_device_ops verbs_provider_rxe;
+extern const struct verbs_device_ops verbs_provider_vmw_pvrdma;
+#endif
+
 /**
  * ibv_free_device_list - Free list from ibv_get_device_list()
  *
diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
index 8fe5819f305add..1cd4d880412878 100644
--- a/providers/bnxt_re/main.c
+++ b/providers/bnxt_re/main.c
@@ -197,4 +197,4 @@ static const struct verbs_device_ops bnxt_re_dev_ops = {
 	.alloc_context = bnxt_re_alloc_context,
 	.free_context = bnxt_re_free_context,
 };
-PROVIDER_DRIVER(bnxt_re_dev_ops);
+PROVIDER_DRIVER(bnxt_re, bnxt_re_dev_ops);
diff --git a/providers/cxgb3/iwch.c b/providers/cxgb3/iwch.c
index cf82a662fdd846..0c6c15be0fa54a 100644
--- a/providers/cxgb3/iwch.c
+++ b/providers/cxgb3/iwch.c
@@ -267,4 +267,4 @@ static const struct verbs_device_ops iwch_dev_ops = {
 	.alloc_context = iwch_alloc_context,
 	.free_context = iwch_free_context,
 };
-PROVIDER_DRIVER(iwch_dev_ops);
+PROVIDER_DRIVER(cxgb3, iwch_dev_ops);
diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
index 9d8b6d0166f8d9..aba007f0b0ca33 100644
--- a/providers/cxgb4/dev.c
+++ b/providers/cxgb4/dev.c
@@ -504,7 +504,7 @@ static const struct verbs_device_ops c4iw_dev_ops = {
 	.alloc_context = c4iw_alloc_context,
 	.free_context = c4iw_free_context,
 };
-PROVIDER_DRIVER(c4iw_dev_ops);
+PROVIDER_DRIVER(cxgb4, c4iw_dev_ops);
 
 #ifdef STATS
 void __attribute__ ((destructor)) cs_fini(void);
diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
index bb7c5498a93000..feb4faea306e16 100644
--- a/providers/hfi1verbs/hfiverbs.c
+++ b/providers/hfi1verbs/hfiverbs.c
@@ -206,4 +206,4 @@ static const struct verbs_device_ops hfi1_dev_ops = {
 	.alloc_context = hfi1_alloc_context,
 	.free_context = hfi1_free_context,
 };
-PROVIDER_DRIVER(hfi1_dev_ops);
+PROVIDER_DRIVER(hfi1verbs, hfi1_dev_ops);
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index 3597e9add10a97..108e2090e4e929 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -205,4 +205,4 @@ static const struct verbs_device_ops hns_roce_dev_ops = {
 	.alloc_context = hns_roce_alloc_context,
 	.free_context = hns_roce_free_context,
 };
-PROVIDER_DRIVER(hns_roce_dev_ops);
+PROVIDER_DRIVER(hns, hns_roce_dev_ops);
diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
index afe54d914ac217..b620e720125d40 100644
--- a/providers/i40iw/i40iw_umain.c
+++ b/providers/i40iw/i40iw_umain.c
@@ -226,4 +226,4 @@ static const struct verbs_device_ops i40iw_udev_ops = {
 	.alloc_context = i40iw_ualloc_context,
 	.free_context = i40iw_ufree_context,
 };
-PROVIDER_DRIVER(i40iw_udev_ops);
+PROVIDER_DRIVER(i40iw, i40iw_udev_ops);
diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
index c54729773b90f9..ab3ccd14fa18b1 100644
--- a/providers/ipathverbs/ipathverbs.c
+++ b/providers/ipathverbs/ipathverbs.c
@@ -204,4 +204,4 @@ static const struct verbs_device_ops ipath_dev_ops = {
 	.alloc_context = ipath_alloc_context,
 	.free_context = ipath_free_context,
 };
-PROVIDER_DRIVER(ipath_dev_ops);
+PROVIDER_DRIVER(ipathverbs, ipath_dev_ops);
diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
index 1847e2d09d7719..42bff4d212c451 100644
--- a/providers/mlx4/mlx4.c
+++ b/providers/mlx4/mlx4.c
@@ -302,7 +302,7 @@ static const struct verbs_device_ops mlx4_dev_ops = {
 	.alloc_context = mlx4_alloc_context,
 	.free_context = mlx4_free_context,
 };
-PROVIDER_DRIVER(mlx4_dev_ops);
+PROVIDER_DRIVER(mlx4, mlx4_dev_ops);
 
 static int mlx4dv_get_qp(struct ibv_qp *qp_in,
 			 struct mlx4dv_qp *qp_out)
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index 22b27fdb78ccc0..3eedf34f81ed75 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -1324,4 +1324,4 @@ static const struct verbs_device_ops mlx5_dev_ops = {
 	.alloc_context = mlx5_alloc_context,
 	.free_context = mlx5_free_context,
 };
-PROVIDER_DRIVER(mlx5_dev_ops);
+PROVIDER_DRIVER(mlx5, mlx5_dev_ops);
diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
index e893b4dff617a2..c3293d8dff2494 100644
--- a/providers/mthca/mthca.c
+++ b/providers/mthca/mthca.c
@@ -239,4 +239,4 @@ static const struct verbs_device_ops mthca_dev_ops = {
 	.alloc_context = mthca_alloc_context,
 	.free_context = mthca_free_context,
 };
-PROVIDER_DRIVER(mthca_dev_ops);
+PROVIDER_DRIVER(mthca, mthca_dev_ops);
diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
index 006c3e9675cfcd..deb0be6a9fd1cf 100644
--- a/providers/nes/nes_umain.c
+++ b/providers/nes/nes_umain.c
@@ -218,4 +218,4 @@ static const struct verbs_device_ops nes_udev_ops = {
 	.alloc_context = nes_ualloc_context,
 	.free_context = nes_ufree_context,
 };
-PROVIDER_DRIVER(nes_udev_ops);
+PROVIDER_DRIVER(nes, nes_udev_ops);
diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
index 022625d6be8ef1..f71ec8a8e231da 100644
--- a/providers/ocrdma/ocrdma_main.c
+++ b/providers/ocrdma/ocrdma_main.c
@@ -195,4 +195,4 @@ static const struct verbs_device_ops ocrdma_dev_ops = {
 	.alloc_context = ocrdma_alloc_context,
 	.free_context = ocrdma_free_context,
 };
-PROVIDER_DRIVER(ocrdma_dev_ops);
+PROVIDER_DRIVER(ocrdma, ocrdma_dev_ops);
diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
index ce36e07c5c5779..650e846e8f1e58 100644
--- a/providers/qedr/qelr_main.c
+++ b/providers/qedr/qelr_main.c
@@ -250,4 +250,4 @@ static const struct verbs_device_ops qelr_dev_ops = {
 	.alloc_context = qelr_alloc_context,
 	.free_context = qelr_free_context,
 };
-PROVIDER_DRIVER(qelr_dev_ops);
+PROVIDER_DRIVER(qedr, qelr_dev_ops);
diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c
index c8fa600921d297..857ea0981321e9 100644
--- a/providers/rxe/rxe.c
+++ b/providers/rxe/rxe.c
@@ -923,4 +923,4 @@ static const struct verbs_device_ops rxe_dev_ops = {
 	.alloc_context = rxe_alloc_context,
 	.free_context = rxe_free_context,
 };
-PROVIDER_DRIVER(rxe_dev_ops);
+PROVIDER_DRIVER(rxe, rxe_dev_ops);
diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
index 3168edb3b148c1..52a2de22d44cb2 100644
--- a/providers/vmw_pvrdma/pvrdma_main.c
+++ b/providers/vmw_pvrdma/pvrdma_main.c
@@ -209,4 +209,4 @@ static const struct verbs_device_ops pvrdma_dev_ops = {
 	.alloc_context = pvrdma_alloc_context,
 	.free_context  = pvrdma_free_context,
 };
-PROVIDER_DRIVER(pvrdma_dev_ops);
+PROVIDER_DRIVER(vmw_pvrdma, pvrdma_dev_ops);
