dpdk/lib/librte_eal/linux/eal_cpuflags.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright 2018 Red Hat, Inc.
   3 */
   4
   5#include <elf.h>
   6#include <fcntl.h>
   7#include <string.h>
   8#include <sys/stat.h>
   9#include <sys/types.h>
  10#include <unistd.h>
  11
  12#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
  13#if __GLIBC_PREREQ(2, 16)
  14#include <sys/auxv.h>
  15#define HAS_AUXV 1
  16#endif
  17#endif
  18
  19#include <rte_cpuflags.h>
  20
  21#ifndef HAS_AUXV
  22static unsigned long
  23getauxval(unsigned long type __rte_unused)
  24{
  25        errno = ENOTSUP;
  26        return 0;
  27}
  28#endif
  29
  30#ifdef RTE_ARCH_64
  31typedef Elf64_auxv_t Internal_Elfx_auxv_t;
  32#else
  33typedef Elf32_auxv_t Internal_Elfx_auxv_t;
  34#endif
  35
  36/**
  37 * Provides a method for retrieving values from the auxiliary vector and
  38 * possibly running a string comparison.
  39 *
  40 * @return Always returns a result.  When the result is 0, check errno
  41 * to see if an error occurred during processing.
  42 */
  43static unsigned long
  44_rte_cpu_getauxval(unsigned long type, const char *str)
  45{
  46        unsigned long val;
  47
  48        errno = 0;
  49        val = getauxval(type);
  50
  51        if (!val && (errno == ENOTSUP || errno == ENOENT)) {
  52                int auxv_fd = open("/proc/self/auxv", O_RDONLY);
  53                Internal_Elfx_auxv_t auxv;
  54
  55                if (auxv_fd == -1)
  56                        return 0;
  57
  58                errno = ENOENT;
  59                while (read(auxv_fd, &auxv, sizeof(auxv)) == sizeof(auxv)) {
  60                        if (auxv.a_type == type) {
  61                                errno = 0;
  62                                val = auxv.a_un.a_val;
  63                                if (str)
  64                                        val = strcmp((const char *)val, str);
  65                                break;
  66                        }
  67                }
  68                close(auxv_fd);
  69        }
  70
  71        return val;
  72}
  73
  74unsigned long
  75rte_cpu_getauxval(unsigned long type)
  76{
  77        return _rte_cpu_getauxval(type, NULL);
  78}
  79
  80int
  81rte_cpu_strcmp_auxval(unsigned long type, const char *str)
  82{
  83        return _rte_cpu_getauxval(type, str);
  84}
  85