Deleted Added
full compact
cpuctl.c (300424) cpuctl.c (301962)
1/*-
2 * Copyright (c) 2006-2008 Stanislav Sedov <stas@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006-2008 Stanislav Sedov <stas@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/cpuctl/cpuctl.c 300424 2016-05-22 15:22:45Z ache $");
29__FBSDID("$FreeBSD: head/sys/dev/cpuctl/cpuctl.c 301962 2016-06-16 12:07:40Z kib $");
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/conf.h>
34#include <sys/fcntl.h>
35#include <sys/ioccom.h>
36#include <sys/malloc.h>
37#include <sys/module.h>

--- 24 unchanged lines hidden (view full) ---

62#else
63# define DPRINTF(...)
64#endif
65
66#define UCODE_SIZE_MAX (32 * 1024)
67
68static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
69 struct thread *td);
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/conf.h>
34#include <sys/fcntl.h>
35#include <sys/ioccom.h>
36#include <sys/malloc.h>
37#include <sys/module.h>

--- 24 unchanged lines hidden (view full) ---

62#else
63# define DPRINTF(...)
64#endif
65
66#define UCODE_SIZE_MAX (32 * 1024)
67
68static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
69 struct thread *td);
70static void cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
70static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
71 struct thread *td);
71 struct thread *td);
72static void cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
72static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
73 struct thread *td);
74static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
75 struct thread *td);
76static int update_intel(int cpu, cpuctl_update_args_t *args,
77 struct thread *td);
78static int update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td);
79static int update_via(int cpu, cpuctl_update_args_t *args,
80 struct thread *td);

--- 85 unchanged lines hidden (view full) ---

166 case CPUCTL_MSRCBIT:
167 case CPUCTL_WRMSR:
168 ret = priv_check(td, PRIV_CPUCTL_WRMSR);
169 if (ret != 0)
170 goto fail;
171 ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
172 break;
173 case CPUCTL_CPUID:
73 struct thread *td);
74static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
75 struct thread *td);
76static int update_intel(int cpu, cpuctl_update_args_t *args,
77 struct thread *td);
78static int update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td);
79static int update_via(int cpu, cpuctl_update_args_t *args,
80 struct thread *td);

--- 85 unchanged lines hidden (view full) ---

166 case CPUCTL_MSRCBIT:
167 case CPUCTL_WRMSR:
168 ret = priv_check(td, PRIV_CPUCTL_WRMSR);
169 if (ret != 0)
170 goto fail;
171 ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
172 break;
173 case CPUCTL_CPUID:
174 cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
175 ret = 0;
174 ret = cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
176 break;
177 case CPUCTL_UPDATE:
178 ret = priv_check(td, PRIV_CPUCTL_UPDATE);
179 if (ret != 0)
180 goto fail;
181 ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
182 break;
183 case CPUCTL_CPUID_COUNT:
175 break;
176 case CPUCTL_UPDATE:
177 ret = priv_check(td, PRIV_CPUCTL_UPDATE);
178 if (ret != 0)
179 goto fail;
180 ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
181 break;
182 case CPUCTL_CPUID_COUNT:
184 cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_count_args_t *)data,
185 td);
186 ret = 0;
183 ret = cpuctl_do_cpuid_count(cpu,
184 (cpuctl_cpuid_count_args_t *)data, td);
187 break;
188 default:
189 ret = EINVAL;
190 break;
191 }
192fail:
193 return (ret);
194}
195
196/*
197 * Actually perform cpuid operation.
198 */
185 break;
186 default:
187 ret = EINVAL;
188 break;
189 }
190fail:
191 return (ret);
192}
193
194/*
195 * Actually perform cpuid operation.
196 */
199static void
197static int
200cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
201 struct thread *td)
202{
203 int is_bound = 0;
204 int oldcpu;
205
206 KASSERT(cpu >= 0 && cpu < mp_ncpus,
207 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
208
209 /* Explicitly clear cpuid data to avoid returning stale info. */
210 bzero(data->data, sizeof(data->data));
211 DPRINTF("[cpuctl,%d]: retrieving cpuid lev %#0x type %#0x for %d cpu\n",
212 __LINE__, data->level, data->level_type, cpu);
198cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
199 struct thread *td)
200{
201 int is_bound = 0;
202 int oldcpu;
203
204 KASSERT(cpu >= 0 && cpu < mp_ncpus,
205 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
206
207 /* Explicitly clear cpuid data to avoid returning stale info. */
208 bzero(data->data, sizeof(data->data));
209 DPRINTF("[cpuctl,%d]: retrieving cpuid lev %#0x type %#0x for %d cpu\n",
210 __LINE__, data->level, data->level_type, cpu);
211#ifdef __i386__
212 if (cpu_id == 0)
213 return (ENODEV);
214#endif
213 oldcpu = td->td_oncpu;
214 is_bound = cpu_sched_is_bound(td);
215 set_cpu(cpu, td);
216 cpuid_count(data->level, data->level_type, data->data);
217 restore_cpu(oldcpu, is_bound, td);
215 oldcpu = td->td_oncpu;
216 is_bound = cpu_sched_is_bound(td);
217 set_cpu(cpu, td);
218 cpuid_count(data->level, data->level_type, data->data);
219 restore_cpu(oldcpu, is_bound, td);
220 return (0);
218}
219
221}
222
220static void
223static int
221cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
222{
223 cpuctl_cpuid_count_args_t cdata;
224cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
225{
226 cpuctl_cpuid_count_args_t cdata;
227 int error;
224
225 cdata.level = data->level;
226 /* Override the level type. */
227 cdata.level_type = 0;
228
229 cdata.level = data->level;
230 /* Override the level type. */
231 cdata.level_type = 0;
228 cpuctl_do_cpuid_count(cpu, &cdata, td);
232 error = cpuctl_do_cpuid_count(cpu, &cdata, td);
229 bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
233 bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
234 return (error);
230}
231
232/*
233 * Actually perform MSR operations.
234 */
235static int
236cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td)
237{

--- 6 unchanged lines hidden (view full) ---

244 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
245
246 /*
247 * Explicitly clear cpuid data to avoid returning stale
248 * info
249 */
250 DPRINTF("[cpuctl,%d]: operating on MSR %#0x for %d cpu\n", __LINE__,
251 data->msr, cpu);
235}
236
237/*
238 * Actually perform MSR operations.
239 */
240static int
241cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td)
242{

--- 6 unchanged lines hidden (view full) ---

249 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
250
251 /*
252 * Explicitly clear cpuid data to avoid returning stale
253 * info
254 */
255 DPRINTF("[cpuctl,%d]: operating on MSR %#0x for %d cpu\n", __LINE__,
256 data->msr, cpu);
257#ifdef __i386__
258 if ((cpu_feature & CPUID_MSR) == 0)
259 return (ENODEV);
260#endif
252 oldcpu = td->td_oncpu;
253 is_bound = cpu_sched_is_bound(td);
254 set_cpu(cpu, td);
255 if (cmd == CPUCTL_RDMSR) {
256 data->data = 0;
257 ret = rdmsr_safe(data->msr, &data->data);
258 } else if (cmd == CPUCTL_WRMSR) {
259 ret = wrmsr_safe(data->msr, data->data);

--- 26 unchanged lines hidden (view full) ---

286 };
287 char vendor[13];
288 int ret;
289
290 KASSERT(cpu >= 0 && cpu < mp_ncpus,
291 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
292 DPRINTF("[cpuctl,%d]: XXX %d", __LINE__, cpu);
293
261 oldcpu = td->td_oncpu;
262 is_bound = cpu_sched_is_bound(td);
263 set_cpu(cpu, td);
264 if (cmd == CPUCTL_RDMSR) {
265 data->data = 0;
266 ret = rdmsr_safe(data->msr, &data->data);
267 } else if (cmd == CPUCTL_WRMSR) {
268 ret = wrmsr_safe(data->msr, data->data);

--- 26 unchanged lines hidden (view full) ---

295 };
296 char vendor[13];
297 int ret;
298
299 KASSERT(cpu >= 0 && cpu < mp_ncpus,
300 ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
301 DPRINTF("[cpuctl,%d]: XXX %d", __LINE__, cpu);
302
294 cpuctl_do_cpuid(cpu, &args, td);
303 ret = cpuctl_do_cpuid(cpu, &args, td);
304 if (ret != 0)
305 return (ret);
295 ((uint32_t *)vendor)[0] = args.data[1];
296 ((uint32_t *)vendor)[1] = args.data[3];
297 ((uint32_t *)vendor)[2] = args.data[2];
298 vendor[12] = '\0';
299 if (strncmp(vendor, INTEL_VENDOR_ID, sizeof(INTEL_VENDOR_ID)) == 0)
300 ret = update_intel(cpu, data, td);
301 else if(strncmp(vendor, AMD_VENDOR_ID, sizeof(AMD_VENDOR_ID)) == 0)
302 ret = update_amd(cpu, data, td);

--- 210 unchanged lines hidden (view full) ---

513
514static int
515cpuctl_modevent(module_t mod __unused, int type, void *data __unused)
516{
517 int cpu;
518
519 switch(type) {
520 case MOD_LOAD:
306 ((uint32_t *)vendor)[0] = args.data[1];
307 ((uint32_t *)vendor)[1] = args.data[3];
308 ((uint32_t *)vendor)[2] = args.data[2];
309 vendor[12] = '\0';
310 if (strncmp(vendor, INTEL_VENDOR_ID, sizeof(INTEL_VENDOR_ID)) == 0)
311 ret = update_intel(cpu, data, td);
312 else if(strncmp(vendor, AMD_VENDOR_ID, sizeof(AMD_VENDOR_ID)) == 0)
313 ret = update_amd(cpu, data, td);

--- 210 unchanged lines hidden (view full) ---

524
525static int
526cpuctl_modevent(module_t mod __unused, int type, void *data __unused)
527{
528 int cpu;
529
530 switch(type) {
531 case MOD_LOAD:
521 if ((cpu_feature & CPUID_MSR) == 0) {
522 if (bootverbose)
523 printf("cpuctl: not available.\n");
524 return (ENODEV);
525 }
526 if (bootverbose)
527 printf("cpuctl: access to MSR registers/cpuid info.\n");
528 cpuctl_devs = malloc(sizeof(*cpuctl_devs) * mp_ncpus, M_CPUCTL,
529 M_WAITOK | M_ZERO);
530 for (cpu = 0; cpu < mp_ncpus; cpu++)
531 if (cpu_enabled(cpu))
532 cpuctl_devs[cpu] = make_dev(&cpuctl_cdevsw, cpu,
533 UID_ROOT, GID_KMEM, 0640, "cpuctl%d", cpu);

--- 18 unchanged lines hidden ---
532 if (bootverbose)
533 printf("cpuctl: access to MSR registers/cpuid info.\n");
534 cpuctl_devs = malloc(sizeof(*cpuctl_devs) * mp_ncpus, M_CPUCTL,
535 M_WAITOK | M_ZERO);
536 for (cpu = 0; cpu < mp_ncpus; cpu++)
537 if (cpu_enabled(cpu))
538 cpuctl_devs[cpu] = make_dev(&cpuctl_cdevsw, cpu,
539 UID_ROOT, GID_KMEM, 0640, "cpuctl%d", cpu);

--- 18 unchanged lines hidden ---