env_dpdk: fix check for AMD iommu
Update code for read the virtual address width to use glob to locate the Intel and AMD iommu capability registers. This code should work for all AMD numa configurations. Fixes issue 2730 Signed-off-by: Michael Piszczek <mpiszczek@ddn.com> Change-Id: Ibf5789087b7e372d892b53101e4c0231809053f0 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14961 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Community-CI: Mellanox Build Bot
This commit is contained in:
parent
0d0de8e7d9
commit
1473d3b8c2
@ -37,6 +37,7 @@ extern "C" {
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <glob.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
@ -157,96 +157,43 @@ push_arg(char *args[], int *argcount, char *arg)
|
|||||||
#define RD_AMD_CAP_VASIZE_SHIFT 15
|
#define RD_AMD_CAP_VASIZE_SHIFT 15
|
||||||
#define RD_AMD_CAP_VASIZE_MASK (0x7F << RD_AMD_CAP_VASIZE_SHIFT)
|
#define RD_AMD_CAP_VASIZE_MASK (0x7F << RD_AMD_CAP_VASIZE_SHIFT)
|
||||||
|
|
||||||
static int
|
|
||||||
get_amd_iommu_width(void)
|
|
||||||
{
|
|
||||||
FILE *file;
|
|
||||||
char buf[64];
|
|
||||||
char *end;
|
|
||||||
long long int amd_cap;
|
|
||||||
|
|
||||||
file = fopen("/sys/class/iommu/ivhd2/amd-iommu/cap", "r");
|
|
||||||
if (file == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), file) == NULL) {
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
amd_cap = strtoll(buf, &end, 16);
|
|
||||||
if (amd_cap == LLONG_MIN || amd_cap == LLONG_MAX) {
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
return (amd_cap & RD_AMD_CAP_VASIZE_MASK) >> RD_AMD_CAP_VASIZE_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_iommu_width(void)
|
get_iommu_width(void)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
int width = 0;
|
||||||
FILE *file;
|
glob_t glob_results = {};
|
||||||
struct dirent *entry;
|
|
||||||
char mgaw_path[64];
|
|
||||||
char buf[64];
|
|
||||||
char *end;
|
|
||||||
long long int val;
|
|
||||||
int width, tmp;
|
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
if (stat("/sys/class/iommu/ivhd2/amd-iommu", &s) == 0) {
|
/* Break * and / into separate strings to appease check_format.sh comment style check. */
|
||||||
return get_amd_iommu_width();
|
glob("/sys/devices/virtual/iommu/dmar*" "/intel-iommu/cap", 0, NULL, &glob_results);
|
||||||
|
glob("/sys/class/iommu/ivhd*" "/amd-iommu/cap", GLOB_APPEND, NULL, &glob_results);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < glob_results.gl_pathc; i++) {
|
||||||
|
const char *filename = glob_results.gl_pathv[0];
|
||||||
|
FILE *file = fopen(filename, "r");
|
||||||
|
uint64_t cap_reg = 0;
|
||||||
|
|
||||||
|
if (file != NULL && fscanf(file, "%" PRIx64, &cap_reg) == 1) {
|
||||||
|
if (strstr(filename, "intel-iommu") != NULL) {
|
||||||
|
/* We have an Intel IOMMU */
|
||||||
|
int mgaw = ((cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1;
|
||||||
|
|
||||||
|
if (width == 0 || (mgaw > 0 && mgaw < width)) {
|
||||||
|
width = mgaw;
|
||||||
}
|
}
|
||||||
|
} else if (strstr(filename, "amd-iommu") != NULL) {
|
||||||
|
/* We have an AMD IOMMU */
|
||||||
|
int mgaw = ((cap_reg & RD_AMD_CAP_VASIZE_MASK) >> RD_AMD_CAP_VASIZE_SHIFT) + 1;
|
||||||
|
|
||||||
dir = opendir("/sys/devices/virtual/iommu/");
|
if (width == 0 || (mgaw > 0 && mgaw < width)) {
|
||||||
if (dir == NULL) {
|
width = mgaw;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
width = 0;
|
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
|
||||||
/* Find directories named "dmar0", "dmar1", etc */
|
|
||||||
if (strncmp(entry->d_name, "dmar", sizeof("dmar") - 1) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = snprintf(mgaw_path, sizeof(mgaw_path), "/sys/devices/virtual/iommu/%s/intel-iommu/cap",
|
|
||||||
entry->d_name);
|
|
||||||
if ((unsigned)tmp >= sizeof(mgaw_path)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = fopen(mgaw_path, "r");
|
|
||||||
if (file == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), file) == NULL) {
|
|
||||||
fclose(file);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = strtoll(buf, &end, 16);
|
|
||||||
if (val == LLONG_MIN || val == LLONG_MAX) {
|
|
||||||
fclose(file);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = ((val & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1;
|
|
||||||
if (width == 0 || tmp < width) {
|
|
||||||
width = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
globfree(&glob_results);
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user