Ejemplo n.º 1
0
int
cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
    int flags, struct thread *td)
{
	int cpu, ret;

	cpu = dev2unit(dev);
	if (cpu > mp_maxid || !cpu_enabled(cpu)) {
		DPRINTF("[cpuctl,%d]: bad cpu number %d\n", __LINE__, cpu);
		return (ENXIO);
	}
	/* Require write flag for "write" requests. */
	if ((cmd == CPUCTL_MSRCBIT || cmd == CPUCTL_MSRSBIT ||
	    cmd == CPUCTL_UPDATE || cmd == CPUCTL_WRMSR ||
	    cmd == CPUCTL_EVAL_CPU_FEATURES) &&
	    (flags & FWRITE) == 0)
		return (EPERM);
	switch (cmd) {
	case CPUCTL_RDMSR:
		ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
		break;
	case CPUCTL_MSRSBIT:
	case CPUCTL_MSRCBIT:
	case CPUCTL_WRMSR:
		ret = priv_check(td, PRIV_CPUCTL_WRMSR);
		if (ret != 0)
			goto fail;
		ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
		break;
	case CPUCTL_CPUID:
		ret = cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
		break;
	case CPUCTL_UPDATE:
		ret = priv_check(td, PRIV_CPUCTL_UPDATE);
		if (ret != 0)
			goto fail;
		ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
		break;
	case CPUCTL_CPUID_COUNT:
		ret = cpuctl_do_cpuid_count(cpu,
		    (cpuctl_cpuid_count_args_t *)data, td);
		break;
	case CPUCTL_EVAL_CPU_FEATURES:
		ret = cpuctl_do_eval_cpu_features(cpu, td);
		break;
	default:
		ret = EINVAL;
		break;
	}
fail:
	return (ret);
}
Ejemplo n.º 2
0
 * Actually perform microcode update.
 */
static int
cpuctl_do_update(int cpu, cpuctl_update_args_t *data, struct thread *td)
{
	cpuctl_cpuid_args_t args = {
		.level = 0,
	};
	char vendor[13];
	int ret;

	KASSERT(cpu >= 0 && cpu < mp_ncpus,
	    ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
	DPRINTF("[cpuctl,%d]: XXX %d", __LINE__, cpu);

	ret = cpuctl_do_cpuid(cpu, &args, td);
	if (ret != 0) {
		DPRINTF("[cpuctl,%d]: cannot retrive cpuid info for cpu %d",
		    __LINE__, cpu);
		return (ENXIO);
	}
	((uint32_t *)vendor)[0] = args.data[1];
	((uint32_t *)vendor)[1] = args.data[3];
	((uint32_t *)vendor)[2] = args.data[2];
	vendor[12] = '\0';
	if (strncmp(vendor, INTEL_VENDOR_ID, sizeof(INTEL_VENDOR_ID)) == 0)
		ret = update_intel(cpu, data, td);
	else if(strncmp(vendor, AMD_VENDOR_ID, sizeof(AMD_VENDOR_ID)) == 0)
		ret = update_amd(cpu, data, td);
	else if(strncmp(vendor, CENTAUR_VENDOR_ID, sizeof(CENTAUR_VENDOR_ID)) == 0)
		ret = update_via(cpu, data, td);