Beispiel #1
0
zx_status_t mtrace_cpuperf_control(uint32_t action, uint32_t options,
                                   user_inout_ptr<void> arg, size_t size) {
    LTRACEF("action %u, options 0x%x, arg %p, size 0x%zx\n",
            action, options, arg.get(), size);

    switch (action) {
    case MTRACE_CPUPERF_GET_PROPERTIES: {
        zx_arch_pmu_properties_t props;
        if (size != sizeof(props))
            return ZX_ERR_INVALID_ARGS;
        if (options != 0)
            return ZX_ERR_INVALID_ARGS;
        auto status = arch_perfmon_get_properties(&props);
        if (status != ZX_OK)
            return status;
        status = arg.reinterpret<zx_arch_pmu_properties_t>().copy_to_user(props);
        if (status != ZX_OK)
            return status;
        return ZX_OK;
    }

    case MTRACE_CPUPERF_INIT:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_init();

    case MTRACE_CPUPERF_ASSIGN_BUFFER: {
        zx_arch_pmu_buffer_t buffer;
        if (size != sizeof(buffer))
            return ZX_ERR_INVALID_ARGS;
        zx_status_t status = arg.reinterpret<zx_arch_pmu_buffer_t>().copy_from_user(&buffer);
        if (status != ZX_OK)
            return status;

        // TODO(dje): Later need to rework to assign buffers to things
        // like threads.
        uint32_t cpu = MTRACE_CPUPERF_OPTIONS_CPU(options);
        if ((options & ~MTRACE_CPUPERF_OPTIONS_CPU_MASK) != 0)
            return ZX_ERR_INVALID_ARGS;

        // lookup the VMO dispatcher from handle
        // TODO(dje): Passing in a vmo from userspace, even from a device
        // driver we control, to which we will write from kernel space, feels
        // dodgey. Perhaps we should allocate the vmo here, but that put more
        // of this driver in kernel space. Revisit.
        auto up = ProcessDispatcher::GetCurrent();
        fbl::RefPtr<VmObjectDispatcher> vmo;
        zx_rights_t vmo_rights;
        zx_rights_t needed_rights =
            ZX_RIGHT_MAP | ZX_RIGHT_READ | ZX_RIGHT_WRITE;
        status = up->GetDispatcherWithRights(buffer.vmo, needed_rights,
                                             &vmo, &vmo_rights);
        if (status != ZX_OK)
            return status;

        return arch_perfmon_assign_buffer(cpu, ktl::move(vmo->vmo()));
    }

    case MTRACE_CPUPERF_STAGE_CONFIG: {
        zx_arch_pmu_config_t config;
        if (size != sizeof(config))
            return ZX_ERR_INVALID_ARGS;
        zx_status_t status = arg.reinterpret<zx_arch_pmu_config_t>().copy_from_user(&config);
        if (status != ZX_OK)
            return status;
        if (options != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_stage_config(&config);
    }

    case MTRACE_CPUPERF_START:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_start();

    case MTRACE_CPUPERF_STOP:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_stop();

    case MTRACE_CPUPERF_FINI:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_fini();

    default:
        return ZX_ERR_INVALID_ARGS;
    }
}
Beispiel #2
0
static int __init nmi_init(void)
{
	__u8 vendor = current_cpu_data.x86_vendor;
	__u8 family = current_cpu_data.x86;
	__u8 _model = current_cpu_data.x86_model;

	if (!cpu_has_apic) {
		printk("xenoprof: Initialization failed. No APIC\n");
		return -ENODEV;
	}

	switch (vendor) {
		case X86_VENDOR_AMD:
			/* Needs to be at least an Athlon (or hammer in 32bit mode) */

			switch (family) {
			default:
				printk("xenoprof: Initialization failed. "
				       "AMD processor family %d is not "
				       "supported\n", family);
				return -ENODEV;
			case 0xf:
				model = &op_athlon_spec;
				cpu_type = "x86-64/hammer";
				break;
			case 0x10:
				model = &op_athlon_spec;
				cpu_type = "x86-64/family10";
				ibs_init();
				break;
			case 0x11:
				model = &op_athlon_spec;
				cpu_type = "x86-64/family11h";
				break;
                        case 0x12:
				model = &op_athlon_spec;
				cpu_type = "x86-64/family12h";
				break;
			case 0x14:
                                model = &op_athlon_spec;
                                cpu_type = "x86-64/family14h";
                                break;
                        case 0x15:
                                model = &op_amd_fam15h_spec;
                                cpu_type = "x86-64/family15h";
                                break;
			case 0x16:
				model = &op_athlon_spec;
				cpu_type = "x86-64/family16h";
				break;
			}
			break;

		case X86_VENDOR_INTEL:
			switch (family) {
				/* Pentium IV */
				case 0xf:
					p4_init(&cpu_type);
					break;

				/* A P6-class processor */
				case 6:
					ppro_init(&cpu_type);
					break;

				default:
				break;
			}
			if (!cpu_type && !arch_perfmon_init(&cpu_type)) {
				printk("xenoprof: Initialization failed. "
				       "Intel processor family %d model %d"
				       "is not supported\n", family, _model);
				return -ENODEV;
			}
			break;

		default:
			printk("xenoprof: Initialization failed. "
			       "Unsupported processor. Unknown vendor %d\n",
				vendor);
			return -ENODEV;
	}

	return 0;
}