From: Chengwen Feng <[email protected]>
Add a dma_check_vchan_conf() helper to validate rte_dma_vchan_conf
fields that do not depend on device capabilities: direction enum,
port_type enum, domain type enum, and all reserved[] arrays.
In rte_dma_configure(), reject undefined flag bits and non-zero
priority when the device lacks priority scheduling support.
Fixes: b36970f2e13e ("dmadev: introduce DMA device library")
Cc: [email protected]
Signed-off-by: Chengwen Feng <[email protected]>
---
lib/dmadev/rte_dmadev.c | 156 ++++++++++++++++++++++++++++------------
1 file changed, 109 insertions(+), 47 deletions(-)
diff --git a/lib/dmadev/rte_dmadev.c b/lib/dmadev/rte_dmadev.c
index 822bb7c89f..2311f01906 100644
--- a/lib/dmadev/rte_dmadev.c
+++ b/lib/dmadev/rte_dmadev.c
@@ -480,6 +480,7 @@ RTE_EXPORT_SYMBOL(rte_dma_configure)
int
rte_dma_configure(int16_t dev_id, const struct rte_dma_conf *dev_conf)
{
+ const uint64_t valid_flags = RTE_DMA_CFG_FLAG_SILENT |
RTE_DMA_CFG_FLAG_ENQ_DEQ;
struct rte_dma_info dev_info;
struct rte_dma_dev *dev;
int ret;
@@ -510,18 +511,28 @@ rte_dma_configure(int16_t dev_id, const struct
rte_dma_conf *dev_conf)
"Device %d configure too many vchans", dev_id);
return -EINVAL;
}
+
+ if (dev_info.dev_capa & RTE_DMA_CAPA_PRI_POLICY_SP) {
+ if (dev_conf->priority >= dev_info.nb_priorities) {
+ RTE_DMA_LOG(ERR, "Device %d configure invalid
priority", dev_id);
+ return -EINVAL;
+ }
+ } else {
+ if (dev_conf->priority != 0) {
+ RTE_DMA_LOG(ERR, "Device %d should not configure
priority", dev_id);
+ return -EINVAL;
+ }
+ }
+
+ if ((dev_conf->flags & ~valid_flags) != 0) {
+ RTE_DMA_LOG(ERR, "Device %d configure invalid flags", dev_id);
+ return -EINVAL;
+ }
if ((dev_conf->flags & RTE_DMA_CFG_FLAG_SILENT) &&
!(dev_info.dev_capa & RTE_DMA_CAPA_SILENT)) {
RTE_DMA_LOG(ERR, "Device %d don't support silent", dev_id);
return -EINVAL;
}
-
- if ((dev_info.dev_capa & RTE_DMA_CAPA_PRI_POLICY_SP) &&
- (dev_conf->priority >= dev_info.nb_priorities)) {
- RTE_DMA_LOG(ERR, "Device %d configure invalid priority",
dev_id);
- return -EINVAL;
- }
-
if ((dev_conf->flags & RTE_DMA_CFG_FLAG_ENQ_DEQ) &&
!(dev_info.dev_capa & RTE_DMA_CAPA_OPS_ENQ_DEQ)) {
RTE_DMA_LOG(ERR, "Device %d don't support enqueue/dequeue",
dev_id);
@@ -632,13 +643,85 @@ rte_dma_close(int16_t dev_id)
return ret;
}
+/* Perform verification on rte_dma_vchan_conf only. */
+static int
+dma_check_vchan_conf(int16_t dev_id, const struct rte_dma_vchan_conf *conf)
+{
+ bool src_is_dev, dst_is_dev;
+
+ if (conf->direction != RTE_DMA_DIR_MEM_TO_MEM &&
+ conf->direction != RTE_DMA_DIR_MEM_TO_DEV &&
+ conf->direction != RTE_DMA_DIR_DEV_TO_MEM &&
+ conf->direction != RTE_DMA_DIR_DEV_TO_DEV) {
+ RTE_DMA_LOG(ERR, "Device %d direction invalid!", dev_id);
+ return -EINVAL;
+ }
+
+ if (conf->src_port.port_type != RTE_DMA_PORT_NONE &&
+ conf->src_port.port_type != RTE_DMA_PORT_PCIE) {
+ RTE_DMA_LOG(ERR, "Device %d source port type unsupported",
dev_id);
+ return -EINVAL;
+ }
+ if (conf->src_port.reserved[0] != 0 || conf->src_port.reserved[1] != 0)
{
+ RTE_DMA_LOG(ERR, "Device %d src_port has non-zero reserved
fields", dev_id);
+ return -EINVAL;
+ }
+ src_is_dev = conf->direction == RTE_DMA_DIR_DEV_TO_MEM ||
+ conf->direction == RTE_DMA_DIR_DEV_TO_DEV;
+ if ((conf->src_port.port_type == RTE_DMA_PORT_NONE && src_is_dev) ||
+ (conf->src_port.port_type != RTE_DMA_PORT_NONE && !src_is_dev)) {
+ RTE_DMA_LOG(ERR, "Device %d source port type invalid", dev_id);
+ return -EINVAL;
+ }
+
+ if (conf->dst_port.port_type != RTE_DMA_PORT_NONE &&
+ conf->dst_port.port_type != RTE_DMA_PORT_PCIE) {
+ RTE_DMA_LOG(ERR, "Device %d destination port type unsupported",
dev_id);
+ return -EINVAL;
+ }
+ if (conf->dst_port.reserved[0] != 0 || conf->dst_port.reserved[1] != 0)
{
+ RTE_DMA_LOG(ERR, "Device %d dst_port has non-zero reserved
fields", dev_id);
+ return -EINVAL;
+ }
+ dst_is_dev = conf->direction == RTE_DMA_DIR_MEM_TO_DEV ||
+ conf->direction == RTE_DMA_DIR_DEV_TO_DEV;
+ if ((conf->dst_port.port_type == RTE_DMA_PORT_NONE && dst_is_dev) ||
+ (conf->dst_port.port_type != RTE_DMA_PORT_NONE && !dst_is_dev)) {
+ RTE_DMA_LOG(ERR,
+ "Device %d destination port type invalid", dev_id);
+ return -EINVAL;
+ }
+
+ if (conf->auto_free.reserved[0] != 0 || conf->auto_free.reserved[1] !=
0) {
+ RTE_DMA_LOG(ERR, "Device %d auto_free has non-zero reserved
fields", dev_id);
+ return -EINVAL;
+ }
+
+ if (conf->domain.type != RTE_DMA_INTER_DOMAIN_NONE &&
+ conf->domain.type != RTE_DMA_INTER_PROCESS_DOMAIN &&
+ conf->domain.type != RTE_DMA_INTER_OS_DOMAIN) {
+ RTE_DMA_LOG(ERR, "Device %d domain type invalid!", dev_id);
+ return -EINVAL;
+ }
+ if (conf->domain.reserved[0] != 0 || conf->domain.reserved[1] != 0) {
+ RTE_DMA_LOG(ERR, "Device %d domain has non-zero reserved
fields", dev_id);
+ return -EINVAL;
+ }
+ if (conf->domain.type != RTE_DMA_INTER_DOMAIN_NONE &&
+ conf->direction != RTE_DMA_DIR_MEM_TO_MEM) {
+ RTE_DMA_LOG(ERR, "Device %d inter domain only support
mem-to-mem transfer", dev_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
RTE_EXPORT_SYMBOL(rte_dma_vchan_setup)
int
rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,
const struct rte_dma_vchan_conf *conf)
{
struct rte_dma_info dev_info;
- bool src_is_dev, dst_is_dev;
struct rte_dma_dev *dev;
int ret;
@@ -653,6 +736,10 @@ rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,
return -EBUSY;
}
+ ret = dma_check_vchan_conf(dev_id, conf);
+ if (ret != 0)
+ return ret;
+
ret = rte_dma_info_get(dev_id, &dev_info);
if (ret != 0) {
RTE_DMA_LOG(ERR, "Device %d get device info fail", dev_id);
@@ -666,34 +753,7 @@ rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,
RTE_DMA_LOG(ERR, "Device %d vchan out range!", dev_id);
return -EINVAL;
}
- if (conf->domain.type != RTE_DMA_INTER_DOMAIN_NONE &&
- conf->direction != RTE_DMA_DIR_MEM_TO_MEM) {
- RTE_DMA_LOG(ERR, "Device %d inter domain only support
mem-to-mem transfer", dev_id);
- return -EINVAL;
- }
- if (conf->domain.type == RTE_DMA_INTER_OS_DOMAIN &&
- !(dev_info.dev_capa & RTE_DMA_CAPA_INTER_OS_DOMAIN)) {
- RTE_DMA_LOG(ERR, "Device %d does not support inter os domain",
dev_id);
- return -EINVAL;
- }
- if (conf->domain.type == RTE_DMA_INTER_PROCESS_DOMAIN &&
- !(dev_info.dev_capa & RTE_DMA_CAPA_INTER_PROCESS_DOMAIN)) {
- RTE_DMA_LOG(ERR, "Device %d does not support inter process
domain", dev_id);
- return -EINVAL;
- }
- if ((conf->domain.type == RTE_DMA_INTER_PROCESS_DOMAIN ||
- conf->domain.type == RTE_DMA_INTER_OS_DOMAIN) &&
- (conf->domain.reserved[0] != 0 || conf->domain.reserved[1] != 0)) {
- RTE_DMA_LOG(ERR, "Device %d does not support non-zero reserved
fields", dev_id);
- return -EINVAL;
- }
- if (conf->direction != RTE_DMA_DIR_MEM_TO_MEM &&
- conf->direction != RTE_DMA_DIR_MEM_TO_DEV &&
- conf->direction != RTE_DMA_DIR_DEV_TO_MEM &&
- conf->direction != RTE_DMA_DIR_DEV_TO_DEV) {
- RTE_DMA_LOG(ERR, "Device %d direction invalid!", dev_id);
- return -EINVAL;
- }
+
if (conf->direction == RTE_DMA_DIR_MEM_TO_MEM &&
!(dev_info.dev_capa & RTE_DMA_CAPA_MEM_TO_MEM)) {
RTE_DMA_LOG(ERR,
@@ -724,19 +784,21 @@ rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan,
"Device %d number of descriptors invalid", dev_id);
return -EINVAL;
}
- src_is_dev = conf->direction == RTE_DMA_DIR_DEV_TO_MEM ||
- conf->direction == RTE_DMA_DIR_DEV_TO_DEV;
- if ((conf->src_port.port_type == RTE_DMA_PORT_NONE && src_is_dev) ||
- (conf->src_port.port_type != RTE_DMA_PORT_NONE && !src_is_dev)) {
- RTE_DMA_LOG(ERR, "Device %d source port type invalid", dev_id);
+
+ if (conf->auto_free.m2d.pool != NULL &&
+ !(dev_info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE)) {
+ RTE_DMA_LOG(ERR, "Device %d does not support m2d auto free",
dev_id);
return -EINVAL;
}
- dst_is_dev = conf->direction == RTE_DMA_DIR_MEM_TO_DEV ||
- conf->direction == RTE_DMA_DIR_DEV_TO_DEV;
- if ((conf->dst_port.port_type == RTE_DMA_PORT_NONE && dst_is_dev) ||
- (conf->dst_port.port_type != RTE_DMA_PORT_NONE && !dst_is_dev)) {
- RTE_DMA_LOG(ERR,
- "Device %d destination port type invalid", dev_id);
+
+ if (conf->domain.type == RTE_DMA_INTER_OS_DOMAIN &&
+ !(dev_info.dev_capa & RTE_DMA_CAPA_INTER_OS_DOMAIN)) {
+ RTE_DMA_LOG(ERR, "Device %d does not support inter os domain",
dev_id);
+ return -EINVAL;
+ }
+ if (conf->domain.type == RTE_DMA_INTER_PROCESS_DOMAIN &&
+ !(dev_info.dev_capa & RTE_DMA_CAPA_INTER_PROCESS_DOMAIN)) {
+ RTE_DMA_LOG(ERR, "Device %d does not support inter process
domain", dev_id);
return -EINVAL;
}
--
2.54.0