]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/intel-ipsec-mb/LibPerfApp/msr.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / intel-ipsec-mb / LibPerfApp / msr.c
1 /**********************************************************************
2 Copyright(c) 2018 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29
30 /**
31 * @brief Provides access to MSR read & write operations
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #ifndef _WIN32
38 #include <unistd.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #endif
43
44 #include "msr.h"
45
46 static int *m_msr_fd = NULL; /**< MSR driver file descriptors table */
47 static unsigned m_maxcores = 0; /**< max number of cores (size of the
48 table above too) */
49
50 int
51 machine_init(const unsigned max_core_id)
52 {
53 #ifndef _WIN32
54 unsigned i;
55
56 if (max_core_id == 0)
57 return MACHINE_RETVAL_PARAM;
58
59 m_maxcores = max_core_id + 1;
60
61 /**
62 * Allocate table to hold MSR driver file descriptors
63 * Each file descriptor is for a different core.
64 * Core id is an index to the table.
65 */
66 m_msr_fd = (int *)malloc(m_maxcores * sizeof(m_msr_fd[0]));
67 if (m_msr_fd == NULL) {
68 m_maxcores = 0;
69 return MACHINE_RETVAL_ERROR;
70 }
71
72 for (i = 0; i < m_maxcores; i++)
73 m_msr_fd[i] = -1;
74 #endif /* _WIN32 */
75 return MACHINE_RETVAL_OK;
76 }
77
78 int
79 machine_fini(void)
80 {
81 #ifndef _WIN32
82 unsigned i;
83
84 ASSERT(m_msr_fd != NULL);
85 if (m_msr_fd == NULL)
86 return MACHINE_RETVAL_ERROR;
87
88 /**
89 * Close open file descriptors and free up table memory.
90 */
91 for (i = 0; i < m_maxcores; i++)
92 if (m_msr_fd[i] != -1) {
93 close(m_msr_fd[i]);
94 m_msr_fd[i] = -1;
95 }
96
97 free(m_msr_fd);
98 m_msr_fd = NULL;
99 m_maxcores = 0;
100 #endif /* _WIN32 */
101 return MACHINE_RETVAL_OK;
102 }
103
104 #ifndef _WIN32
105 /**
106 * @brief Returns MSR driver file descriptor for given core id
107 *
108 * File descriptor could be previously open and comes from
109 * m_msr_fd table or is open (& cached) during the call.
110 *
111 * @param lcore logical core id
112 *
113 * @return MSR driver file descriptor corresponding \a lcore
114 */
115 static int
116 msr_file_open(const unsigned lcore)
117 {
118 ASSERT(lcore < m_maxcores);
119 ASSERT(m_msr_fd != NULL);
120
121 int fd = m_msr_fd[lcore];
122
123 if (fd < 0) {
124 char fname[32];
125
126 memset(fname, 0, sizeof(fname));
127 snprintf(fname, sizeof(fname)-1,
128 "/dev/cpu/%u/msr", lcore);
129 fd = open(fname, O_RDWR);
130 if (fd < 0)
131 fprintf(stderr, "Error opening file '%s'!\n", fname);
132 else
133 m_msr_fd[lcore] = fd;
134 }
135
136 return fd;
137 }
138 #endif /* _WIN32 */
139
140 int
141 msr_read(const unsigned lcore,
142 const uint32_t reg,
143 uint64_t *value)
144 {
145 int ret = MACHINE_RETVAL_OK;
146 #ifndef _WIN32
147 int fd = -1;
148 ssize_t read_ret = 0;
149
150 ASSERT(value != NULL);
151 if (value == NULL)
152 return MACHINE_RETVAL_PARAM;
153
154 ASSERT(lcore < m_maxcores);
155 if (lcore >= m_maxcores)
156 return MACHINE_RETVAL_PARAM;
157
158 ASSERT(m_msr_fd != NULL);
159 if (m_msr_fd == NULL)
160 return MACHINE_RETVAL_ERROR;
161
162 fd = msr_file_open(lcore);
163 if (fd < 0)
164 return MACHINE_RETVAL_ERROR;
165
166 read_ret = pread(fd, value, sizeof(value[0]), (off_t)reg);
167
168 if (read_ret != sizeof(value[0])) {
169 fprintf(stderr, "RDMSR failed for reg[0x%x] on lcore %u\n",
170 (unsigned)reg, lcore);
171 ret = MACHINE_RETVAL_ERROR;
172 }
173 #endif /* _WIN32 */
174 return ret;
175 }
176
177 int
178 msr_write(const unsigned lcore,
179 const uint32_t reg,
180 const uint64_t value)
181 {
182 int ret = MACHINE_RETVAL_OK;
183 #ifndef _WIN32
184 int fd = -1;
185 ssize_t write_ret = 0;
186
187 ASSERT(lcore < m_maxcores);
188 if (lcore >= m_maxcores)
189 return MACHINE_RETVAL_PARAM;
190
191 ASSERT(m_msr_fd != NULL);
192 if (m_msr_fd == NULL)
193 return MACHINE_RETVAL_ERROR;
194
195 fd = msr_file_open(lcore);
196 if (fd < 0)
197 return MACHINE_RETVAL_ERROR;
198
199 write_ret = pwrite(fd, &value, sizeof(value), (off_t)reg);
200
201 if (write_ret != sizeof(value)) {
202 fprintf(stderr, "WRMSR failed for reg[0x%x] "
203 "<- value[0x%llx] on lcore %u\n",
204 (unsigned)reg, (unsigned long long)value, lcore);
205 ret = MACHINE_RETVAL_ERROR;
206 }
207 #endif /* _WIN32 */
208 return ret;
209 }