diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 04f76a63f..a89ea2353 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -409,6 +409,10 @@ vdev_scan(void)
 
 	if (rte_mp_action_register(VDEV_MP_KEY, vdev_action) < 0 &&
 	    rte_errno != EEXIST) {
+		/* for primary, unsupported IPC is not an error */
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+				rte_errno == ENOTSUP)
+			goto scan;
 		VDEV_LOG(ERR, "Failed to add vdev mp action");
 		return -1;
 	}
@@ -436,6 +440,7 @@ vdev_scan(void)
 		/* Fall through to allow private vdevs in secondary process */
 	}
 
+scan:
 	/* call custom scan callbacks if any */
 	rte_spinlock_lock(&vdev_custom_scan_lock);
 	TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 17dfcd5a3..3cfa07de3 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -693,6 +693,7 @@ mlx4_init_once(void)
 {
 	struct mlx4_shared_data *sd;
 	struct mlx4_local_data *ld = &mlx4_local_data;
+	int ret = 0;
 
 	if (mlx4_init_shared_data())
 		return -rte_errno;
@@ -707,21 +708,26 @@ mlx4_init_once(void)
 		rte_rwlock_init(&sd->mem_event_rwlock);
 		rte_mem_event_callback_register("MLX4_MEM_EVENT_CB",
 						mlx4_mr_mem_event_cb, NULL);
-		mlx4_mp_init_primary();
+		ret = mlx4_mp_init_primary();
+		if (ret)
+			goto out;
 		sd->init_done = true;
 		break;
 	case RTE_PROC_SECONDARY:
 		if (ld->init_done)
 			break;
-		mlx4_mp_init_secondary();
+		ret = mlx4_mp_init_secondary();
+		if (ret)
+			goto out;
 		++sd->secondary_cnt;
 		ld->init_done = true;
 		break;
 	default:
 		break;
 	}
+out:
 	rte_spinlock_unlock(&sd->lock);
-	return 0;
+	return ret;
 }
 
 /**
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 6224b3be1..d0769bbc9 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -239,9 +239,9 @@ void mlx4_mp_req_start_rxtx(struct rte_eth_dev *dev);
 void mlx4_mp_req_stop_rxtx(struct rte_eth_dev *dev);
 int mlx4_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);
 int mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
-void mlx4_mp_init_primary(void);
+int mlx4_mp_init_primary(void);
 void mlx4_mp_uninit_primary(void);
-void mlx4_mp_init_secondary(void);
+int mlx4_mp_init_secondary(void);
 void mlx4_mp_uninit_secondary(void);
 
 #endif /* RTE_PMD_MLX4_H_ */
diff --git a/drivers/net/mlx4/mlx4_mp.c b/drivers/net/mlx4/mlx4_mp.c
index 183622453..ebc57a99e 100644
--- a/drivers/net/mlx4/mlx4_mp.c
+++ b/drivers/net/mlx4/mlx4_mp.c
@@ -316,11 +316,18 @@ mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
 /**
  * Initialize by primary process.
  */
-void
+int
 mlx4_mp_init_primary(void)
 {
+	int ret;
+
 	assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
-	rte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);
+
+	/* primary is allowed to not support IPC */
+	ret = rte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);
+	if (ret && rte_errno != ENOTSUP)
+		return -1;
+	return 0;
 }
 
 /**
@@ -336,11 +343,11 @@ mlx4_mp_uninit_primary(void)
 /**
  * Initialize by secondary process.
  */
-void
+int
 mlx4_mp_init_secondary(void)
 {
 	assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
-	rte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);
+	return rte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 46ca08a4d..271d79d8f 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -990,6 +990,7 @@ mlx5_init_once(void)
 {
 	struct mlx5_shared_data *sd;
 	struct mlx5_local_data *ld = &mlx5_local_data;
+	int ret = 0;
 
 	if (mlx5_init_shared_data())
 		return -rte_errno;
@@ -1004,21 +1005,26 @@ mlx5_init_once(void)
 		rte_rwlock_init(&sd->mem_event_rwlock);
 		rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
 						mlx5_mr_mem_event_cb, NULL);
-		mlx5_mp_init_primary();
+		ret = mlx5_mp_init_primary();
+		if (ret)
+			goto out;
 		sd->init_done = true;
 		break;
 	case RTE_PROC_SECONDARY:
 		if (ld->init_done)
 			break;
-		mlx5_mp_init_secondary();
+		ret = mlx5_mp_init_secondary();
+		if (ret)
+			goto out;
 		++sd->secondary_cnt;
 		ld->init_done = true;
 		break;
 	default:
 		break;
 	}
+out:
 	rte_spinlock_unlock(&sd->lock);
-	return 0;
+	return ret;
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 0a6d7f1d5..0b3418b4a 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -540,9 +540,9 @@ void mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev);
 void mlx5_mp_req_stop_rxtx(struct rte_eth_dev *dev);
 int mlx5_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);
 int mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);
-void mlx5_mp_init_primary(void);
+int mlx5_mp_init_primary(void);
 void mlx5_mp_uninit_primary(void);
-void mlx5_mp_init_secondary(void);
+int mlx5_mp_init_secondary(void);
 void mlx5_mp_uninit_secondary(void);
 
 /* mlx5_nl.c */
diff --git a/drivers/net/mlx5/mlx5_mp.c b/drivers/net/mlx5/mlx5_mp.c
index cea74adb6..dc99231fe 100644
--- a/drivers/net/mlx5/mlx5_mp.c
+++ b/drivers/net/mlx5/mlx5_mp.c
@@ -320,11 +320,18 @@ mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
 /**
  * Initialize by primary process.
  */
-void
+int
 mlx5_mp_init_primary(void)
 {
+	int ret;
+
 	assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
-	rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
+
+	/* primary is allowed to not support IPC */
+	ret = rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
+	if (ret && rte_errno != ENOTSUP)
+		return -1;
+	return 0;
 }
 
 /**
@@ -340,11 +347,11 @@ mlx5_mp_uninit_primary(void)
 /**
  * Initialize by secondary process.
  */
-void
+int
 mlx5_mp_init_secondary(void)
 {
 	assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
-	rte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);
+	return rte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);
 }
 
 /**
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 7f74b5dc9..3e82f5138 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -2273,7 +2273,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
 	/* Register IPC feed callback */
 	if (!tap_devices_count) {
 		ret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues);
-		if (ret < 0) {
+		if (ret < 0 && rte_errno != ENOTSUP) {
 			TAP_LOG(ERR, "tap: Failed to register IPC callback: %s",
 				strerror(rte_errno));
 			goto leave;
diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index a4581e3b4..a40aa2c1b 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -205,6 +205,12 @@ rte_mp_action_register(const char *name, rte_mp_t action)
 	if (validate_action_name(name))
 		return -1;
 
+	if (internal_config.no_shconf) {
+		RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+		rte_errno = ENOTSUP;
+		return -1;
+	}
+
 	entry = malloc(sizeof(struct action_entry));
 	if (entry == NULL) {
 		rte_errno = ENOMEM;
diff --git a/lib/librte_eal/common/hotplug_mp.c b/lib/librte_eal/common/hotplug_mp.c
index 4052a5c7f..60cd1402d 100644
--- a/lib/librte_eal/common/hotplug_mp.c
+++ b/lib/librte_eal/common/hotplug_mp.c
@@ -4,6 +4,7 @@
 #include <string.h>
 
 #include <rte_eal.h>
+#include <rte_errno.h>
 #include <rte_alarm.h>
 #include <rte_string_fns.h>
 #include <rte_devargs.h>
@@ -440,7 +441,8 @@ int rte_mp_dev_hotplug_init(void)
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
 		ret = rte_mp_action_register(EAL_DEV_MP_ACTION_REQUEST,
 					handle_secondary_request);
-		if (ret != 0) {
+		/* primary is allowed to not support IPC */
+		if (ret != 0 && rte_errno != ENOTSUP) {
 			RTE_LOG(ERR, EAL, "Couldn't register '%s' action\n",
 				EAL_DEV_MP_ACTION_REQUEST);
 			return ret;
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index f9288666e..7f807aa8e 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -248,6 +248,9 @@ typedef int (*rte_mp_async_reply_t)(const struct rte_mp_msg *request,
  * to response the messages from the corresponding component in its primary
  * process or secondary processes.
  *
+ * @note IPC may be unsupported in certain circumstances, so caller should check
+ *    for ENOTSUP error.
+ *
  * @param name
  *   The name argument plays as the nonredundant key to find the action.
  *
diff --git a/lib/librte_eal/common/malloc_mp.c b/lib/librte_eal/common/malloc_mp.c
index b470565e0..1374eabc2 100644
--- a/lib/librte_eal/common/malloc_mp.c
+++ b/lib/librte_eal/common/malloc_mp.c
@@ -722,7 +722,9 @@ int
 register_mp_requests(void)
 {
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		if (rte_mp_action_register(MP_ACTION_REQUEST, handle_request)) {
+		/* it's OK for primary to not support IPC */
+		if (rte_mp_action_register(MP_ACTION_REQUEST, handle_request) &&
+				rte_errno != ENOTSUP) {
 			RTE_LOG(ERR, EAL, "Couldn't register '%s' action\n",
 				MP_ACTION_REQUEST);
 			return -1;
diff --git a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c
index 2a47f29d5..5f2a5fc1d 100644
--- a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c
@@ -6,6 +6,7 @@
 #include <string.h>
 
 #include <rte_compat.h>
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_vfio.h>
 #include <rte_eal.h>
@@ -110,8 +111,11 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer)
 int
 vfio_mp_sync_setup(void)
 {
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		return rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		int ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
+		if (ret && rte_errno != ENOTSUP)
+			return -1;
+	}
 
 	return 0;
 }
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 14744b9ff..cd24dd010 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -408,7 +408,10 @@ pdump_server(const struct rte_mp_msg *mp_msg, const void *peer)
 int
 rte_pdump_init(void)
 {
-	return rte_mp_action_register(PDUMP_MP, pdump_server);
+	int ret = rte_mp_action_register(PDUMP_MP, pdump_server);
+	if (ret && rte_errno != ENOTSUP)
+		return -1;
+	return 0;
 }
 
 int
