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