Always allow loading of cpuctl(4). When a CPU feature is not
supported, e.g. CPUID or MSR, return ENODEV from the ioctl which needs that feature. Sponsored by: The FreeBSD Foundation MFC after: 1 week Approved by: re (hrs)
This commit is contained in:
parent
5c2cf81845
commit
f1143962a5
@ -67,9 +67,9 @@ static d_ioctl_t cpuctl_ioctl;
|
||||
|
||||
static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
|
||||
struct thread *td);
|
||||
static void cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
|
||||
static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
|
||||
struct thread *td);
|
||||
static void cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
struct thread *td);
|
||||
static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
|
||||
struct thread *td);
|
||||
@ -171,8 +171,7 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
|
||||
break;
|
||||
case CPUCTL_CPUID:
|
||||
cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
|
||||
ret = 0;
|
||||
ret = cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
|
||||
break;
|
||||
case CPUCTL_UPDATE:
|
||||
ret = priv_check(td, PRIV_CPUCTL_UPDATE);
|
||||
@ -181,9 +180,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
|
||||
break;
|
||||
case CPUCTL_CPUID_COUNT:
|
||||
cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_count_args_t *)data,
|
||||
td);
|
||||
ret = 0;
|
||||
ret = cpuctl_do_cpuid_count(cpu,
|
||||
(cpuctl_cpuid_count_args_t *)data, td);
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
@ -196,7 +194,7 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
/*
|
||||
* Actually perform cpuid operation.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
struct thread *td)
|
||||
{
|
||||
@ -210,23 +208,30 @@ cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
bzero(data->data, sizeof(data->data));
|
||||
DPRINTF("[cpuctl,%d]: retrieving cpuid lev %#0x type %#0x for %d cpu\n",
|
||||
__LINE__, data->level, data->level_type, cpu);
|
||||
#ifdef __i386__
|
||||
if (cpu_id == 0)
|
||||
return (ENODEV);
|
||||
#endif
|
||||
oldcpu = td->td_oncpu;
|
||||
is_bound = cpu_sched_is_bound(td);
|
||||
set_cpu(cpu, td);
|
||||
cpuid_count(data->level, data->level_type, data->data);
|
||||
restore_cpu(oldcpu, is_bound, td);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
|
||||
{
|
||||
cpuctl_cpuid_count_args_t cdata;
|
||||
int error;
|
||||
|
||||
cdata.level = data->level;
|
||||
/* Override the level type. */
|
||||
cdata.level_type = 0;
|
||||
cpuctl_do_cpuid_count(cpu, &cdata, td);
|
||||
error = cpuctl_do_cpuid_count(cpu, &cdata, td);
|
||||
bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -249,6 +254,10 @@ cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td)
|
||||
*/
|
||||
DPRINTF("[cpuctl,%d]: operating on MSR %#0x for %d cpu\n", __LINE__,
|
||||
data->msr, cpu);
|
||||
#ifdef __i386__
|
||||
if ((cpu_feature & CPUID_MSR) == 0)
|
||||
return (ENODEV);
|
||||
#endif
|
||||
oldcpu = td->td_oncpu;
|
||||
is_bound = cpu_sched_is_bound(td);
|
||||
set_cpu(cpu, td);
|
||||
@ -291,7 +300,9 @@ cpuctl_do_update(int cpu, cpuctl_update_args_t *data, struct thread *td)
|
||||
("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
|
||||
DPRINTF("[cpuctl,%d]: XXX %d", __LINE__, cpu);
|
||||
|
||||
cpuctl_do_cpuid(cpu, &args, td);
|
||||
ret = cpuctl_do_cpuid(cpu, &args, td);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
((uint32_t *)vendor)[0] = args.data[1];
|
||||
((uint32_t *)vendor)[1] = args.data[3];
|
||||
((uint32_t *)vendor)[2] = args.data[2];
|
||||
@ -518,11 +529,6 @@ cpuctl_modevent(module_t mod __unused, int type, void *data __unused)
|
||||
|
||||
switch(type) {
|
||||
case MOD_LOAD:
|
||||
if ((cpu_feature & CPUID_MSR) == 0) {
|
||||
if (bootverbose)
|
||||
printf("cpuctl: not available.\n");
|
||||
return (ENODEV);
|
||||
}
|
||||
if (bootverbose)
|
||||
printf("cpuctl: access to MSR registers/cpuid info.\n");
|
||||
cpuctl_devs = malloc(sizeof(*cpuctl_devs) * mp_ncpus, M_CPUCTL,
|
||||
|
Loading…
Reference in New Issue
Block a user