From 021d935a038495f8db02be48b6683d92b3401501 Mon Sep 17 00:00:00 2001 From: Michael Qiu Date: Wed, 10 Dec 2014 19:46:17 +0800 Subject: [PATCH] vfio: avoid enabling while the module is not loaded When vfio module is not loaded when kernel support vfio feature, the routine still try to open the container to get file description. This action is not safe, and of course got error messages: EAL: Detected 40 lcore(s) EAL: unsupported IOMMU type! EAL: VFIO support could not be initialized EAL: Setting up memory... This may make user confuse, this patch make it reasonable and much more smooth to user. Signed-off-by: Michael Qiu Acked-by: Anatoly Burakov --- lib/librte_eal/common/eal_private.h | 14 +++++++++++ lib/librte_eal/linuxapp/eal/eal.c | 27 ++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 24 +++++++++++++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 232fceccc7..159cd669a2 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -203,4 +203,18 @@ int rte_eal_alarm_init(void); */ int rte_eal_dev_init(void); +/** + * Function is to check if the kernel module(like, vfio, vfio_iommu_type1, + * etc.) loaded. + * + * @param module_name + * The module's name which need to be checked + * + * @return + * -1 means some error happens(NULL pointer or open failure) + * 0 means the module not loaded + * 1 means the module loaded + */ +int rte_eal_check_module(const char *module_name); + #endif /* _EAL_PRIVATE_H_ */ diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 2fb1acc201..648ef81401 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -859,3 +859,30 @@ int rte_eal_has_hugepages(void) { return ! internal_config.no_hugetlbfs; } + +int +rte_eal_check_module(const char *module_name) +{ + char mod_name[30]; /* Any module names can be longer than 30 bytes? */ + int ret = 0; + + if (NULL == module_name) + return -1; + + FILE *fd = fopen("/proc/modules", "r"); + if (NULL == fd) { + RTE_LOG(ERR, EAL, "Open /proc/modules failed!" + " error %i (%s)\n", errno, strerror(errno)); + return -1; + } + while (!feof(fd)) { + fscanf(fd, "%29s %*[^\n]", mod_name); + if (!strcmp(mod_name, module_name)) { + ret = 1; + break; + } + } + fclose(fd); + + return ret; +} diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c index c1246e8dab..20e097727f 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "eal_filesystem.h" #include "eal_pci_init.h" @@ -340,9 +341,11 @@ pci_vfio_get_container_fd(void) if (ret != 1) { if (ret < 0) RTE_LOG(ERR, EAL, " could not get IOMMU type, " - "error %i (%s)\n", errno, strerror(errno)); + "error %i (%s)\n", errno, + strerror(errno)); else - RTE_LOG(ERR, EAL, " unsupported IOMMU type!\n"); + RTE_LOG(ERR, EAL, " unsupported IOMMU type " + "detected in VFIO\n"); close(vfio_container_fd); return -1; } @@ -783,11 +786,28 @@ pci_vfio_enable(void) { /* initialize group list */ int i; + int module_vfio_type1; for (i = 0; i < VFIO_MAX_GROUPS; i++) { vfio_cfg.vfio_groups[i].fd = -1; vfio_cfg.vfio_groups[i].group_no = -1; } + + module_vfio_type1 = rte_eal_check_module("vfio_iommu_type1"); + + /* return error directly */ + if (module_vfio_type1 == -1) { + RTE_LOG(INFO, EAL, "Could not get loaded module details!\n"); + return -1; + } + + /* return 0 if VFIO modules not loaded */ + if (module_vfio_type1 == 0) { + RTE_LOG(INFO, EAL, "VFIO modules not all loaded, " + "skip VFIO support...\n"); + return 0; + } + vfio_cfg.vfio_container_fd = pci_vfio_get_container_fd(); /* check if we have VFIO driver enabled */ -- 2.20.1