]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/lib/librte_eal/linux/eal_cpuflags.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / lib / librte_eal / linux / eal_cpuflags.c
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
22 static unsigned long
23 getauxval(unsigned long type __rte_unused)
24 {
25 errno = ENOTSUP;
26 return 0;
27 }
28 #endif
29
30 #ifdef RTE_ARCH_64
31 typedef Elf64_auxv_t Internal_Elfx_auxv_t;
32 #else
33 typedef 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 */
43 static 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
74 unsigned long
75 rte_cpu_getauxval(unsigned long type)
76 {
77 return _rte_cpu_getauxval(type, NULL);
78 }
79
80 int
81 rte_cpu_strcmp_auxval(unsigned long type, const char *str)
82 {
83 return _rte_cpu_getauxval(type, str);
84 }