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 --- |