static int arm_spe_pmu_device_probe()

in arm_spe_pmu.c [1175:1220]


static int arm_spe_pmu_device_probe(struct platform_device *pdev)
{
	int ret;
	struct arm_spe_pmu *spe_pmu;
	struct device *dev = &pdev->dev;

	/*
	 * If kernelspace is unmapped when running at EL0, then the SPE
	 * buffer will fault and prematurely terminate the AUX session.
	 */
	if (arm64_kernel_unmapped_at_el0()) {
		dev_warn_once(dev, "profiling buffer inaccessible. Try passing \"kpti=off\" on the kernel command line\n");
		return -EPERM;
	}

	spe_pmu = devm_kzalloc(dev, sizeof(*spe_pmu), GFP_KERNEL);
	if (!spe_pmu)
		return -ENOMEM;

	spe_pmu->handle = alloc_percpu(typeof(*spe_pmu->handle));
	if (!spe_pmu->handle)
		return -ENOMEM;

	spe_pmu->pdev = pdev;
	platform_set_drvdata(pdev, spe_pmu);

	ret = arm_spe_pmu_irq_probe(spe_pmu);
	if (ret)
		goto out_free_handle;

	ret = arm_spe_pmu_dev_init(spe_pmu);
	if (ret)
		goto out_free_handle;

	ret = arm_spe_pmu_perf_init(spe_pmu);
	if (ret)
		goto out_teardown_dev;

	return 0;

out_teardown_dev:
	arm_spe_pmu_dev_teardown(spe_pmu);
out_free_handle:
	free_percpu(spe_pmu->handle);
	return ret;
}