From nobody Tue Feb 10 02:50:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9BEF41547F0 for ; Sat, 21 Dec 2024 16:59:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734800387; cv=none; b=KuKLooal6rButRhbTb5/21AZCgfMa5s1GWkeWUXiDcI6kVq7Ks5kicaTU2Aw68lNMuRxCTLgNsqyu/1AoNTkH33WirXixexqyranlB6YLGLmrzFKhTjRekZY8pjn0hMgR3dKZEnCY+W4xgp9CI4t14ausAF81HStlRuJ+Xx8od0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734800387; c=relaxed/simple; bh=RCGjO9DyzTOgkT4KOVmO3BHDzii6/5YRlyDAbapwIT0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uFN+7kCE5e8aLBeSSM3mMFFk3zLaILbHJedbrkivD5EjxfHuFCHqDf3YKbc31nkqM05/nTUUxFt7paXqLV0SQvLeYmxRtHeRizXbJdGdaPK8K0y12iJLtVrrPsgt8vjSMxLBdb6+OWiNI+2fwc+kQmNpaM1HD/bRX4XnO0M8lbA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 279021477; Sat, 21 Dec 2024 09:00:07 -0800 (PST) Received: from e129823.cambridge.arm.com (e129823.arm.com [10.1.197.6]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C53ED3F528; Sat, 21 Dec 2024 08:59:37 -0800 (PST) From: Yeoreum Yun To: suzuki.poulose@arm.com, mike.leach@linaro.org, james.clark@linaro.org, alexander.shishkin@linux.intel.com Cc: coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Yeoreum Yun Subject: [PATCH 1/4] coresight/etm4x: disallow altering config via sysfs while enabled Date: Sat, 21 Dec 2024 16:59:31 +0000 Message-Id: <20241221165934.1161856-2-yeoreum.yun@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241221165934.1161856-1-yeoreum.yun@arm.com> References: <20241221165934.1161856-1-yeoreum.yun@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When etm4x configuration is modified via sysfs while etm4x is being enabled via perf, enabled etm4x could run with different configuration from perf_event. To address this, disallow altering config via sysfs while csdev is enabled. Signed-off-by: Yeoreum Yun --- .../coresight/coresight-etm4x-sysfs.c | 132 +++++++++++++++++- 1 file changed, 128 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/= hwtracing/coresight/coresight-etm4x-sysfs.c index 11e865b8e824..cc1f112921d7 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -174,6 +174,9 @@ static ssize_t reset_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); if (val) config->mode =3D 0x0; @@ -300,6 +303,9 @@ static ssize_t mode_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); config->mode =3D val & ETMv4_MODE_ALL; =20 @@ -466,6 +472,9 @@ static ssize_t pe_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); if (val > drvdata->nr_pe) { raw_spin_unlock(&drvdata->spinlock); @@ -501,6 +510,9 @@ static ssize_t event_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); switch (drvdata->nr_event) { case 0x0: @@ -550,6 +562,9 @@ static ssize_t event_instren_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); /* start by clearing all instruction event enable bits */ config->eventctrl1 &=3D ~TRCEVENTCTL1R_INSTEN_MASK; @@ -608,6 +623,9 @@ static ssize_t event_ts_store(struct device *dev, if (!drvdata->ts_size) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + config->ts_ctrl =3D val & ETMv4_EVENT_MASK; return size; } @@ -638,6 +656,9 @@ static ssize_t syncfreq_store(struct device *dev, if (drvdata->syncpr =3D=3D true) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + config->syncfreq =3D val & ETMv4_SYNC_MASK; return size; } @@ -666,6 +687,9 @@ static ssize_t cyc_threshold_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* mask off max threshold before checking min value */ val &=3D ETM_CYC_THRESHOLD_MASK; if (val < drvdata->ccitmin) @@ -703,6 +727,9 @@ static ssize_t bb_ctrl_store(struct device *dev, if (!drvdata->nr_addr_cmp) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Bit[8] controls include(1) / exclude(0), bits[0-7] select * individual range comparators. If include then at least 1 @@ -739,6 +766,9 @@ static ssize_t event_vinst_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); val &=3D TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK); config->vinst_ctrl &=3D ~TRCVICTLR_EVENT_MASK; @@ -771,6 +801,9 @@ static ssize_t s_exlevel_vinst_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); /* clear all EXLEVEL_S bits */ config->vinst_ctrl &=3D ~TRCVICTLR_EXLEVEL_S_MASK; @@ -806,6 +839,9 @@ static ssize_t ns_exlevel_vinst_store(struct device *de= v, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); /* clear EXLEVEL_NS bits */ config->vinst_ctrl &=3D ~TRCVICTLR_EXLEVEL_NS_MASK; @@ -842,6 +878,9 @@ static ssize_t addr_idx_store(struct device *dev, if (val >=3D drvdata->nr_addr_cmp * 2) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Use spinlock to ensure index doesn't change while it gets * dereferenced multiple times within a spinlock block elsewhere. @@ -888,6 +927,9 @@ static ssize_t addr_instdatatype_store(struct device *d= ev, if (sscanf(buf, "%s", str) !=3D 1) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (!strcmp(str, "instr")) @@ -913,7 +955,7 @@ static ssize_t addr_single_show(struct device *dev, if (!(config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_NONE || config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_SINGLE)) { raw_spin_unlock(&drvdata->spinlock); - return -EPERM; + return -EBUSY; } val =3D (unsigned long)config->addr_val[idx]; raw_spin_unlock(&drvdata->spinlock); @@ -932,12 +974,15 @@ static ssize_t addr_single_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (!(config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_NONE || config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_SINGLE)) { raw_spin_unlock(&drvdata->spinlock); - return -EPERM; + return -EBUSY; } =20 config->addr_val[idx] =3D (u64)val; @@ -960,14 +1005,14 @@ static ssize_t addr_range_show(struct device *dev, idx =3D config->addr_idx; if (idx % 2 !=3D 0) { raw_spin_unlock(&drvdata->spinlock); - return -EPERM; + return -EBUSY; } if (!((config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_NONE && config->addr_type[idx + 1] =3D=3D ETM_ADDR_TYPE_NONE) || (config->addr_type[idx] =3D=3D ETM_ADDR_TYPE_RANGE && config->addr_type[idx + 1] =3D=3D ETM_ADDR_TYPE_RANGE))) { raw_spin_unlock(&drvdata->spinlock); - return -EPERM; + return -EBUSY; } =20 val1 =3D (unsigned long)config->addr_val[idx]; @@ -995,6 +1040,9 @@ static ssize_t addr_range_store(struct device *dev, if (val1 > val2) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (idx % 2 !=3D 0) { @@ -1063,6 +1111,9 @@ static ssize_t addr_start_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (!drvdata->nr_addr_cmp) { @@ -1118,6 +1169,9 @@ static ssize_t addr_stop_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (!drvdata->nr_addr_cmp) { @@ -1172,6 +1226,9 @@ static ssize_t addr_ctxtype_store(struct device *dev, if (sscanf(buf, "%s", str) !=3D 1) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; if (!strcmp(str, "none")) @@ -1238,6 +1295,9 @@ static ssize_t addr_context_store(struct device *dev, drvdata->numcidc : drvdata->numvmidc)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->addr_idx; /* clear context ID comparator bits[6:4] */ @@ -1276,6 +1336,9 @@ static ssize_t addr_exlevel_s_ns_store(struct device = *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK))) return -EINVAL; =20 @@ -1366,6 +1429,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct d= evice *dev, if (!drvdata->nr_pe_cmp) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); config->vipcssctlr =3D val; raw_spin_unlock(&drvdata->spinlock); @@ -1398,6 +1464,9 @@ static ssize_t seq_idx_store(struct device *dev, if (val >=3D drvdata->nrseqstate - 1) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Use spinlock to ensure index doesn't change while it gets * dereferenced multiple times within a spinlock block elsewhere. @@ -1434,6 +1503,9 @@ static ssize_t seq_state_store(struct device *dev, if (val >=3D drvdata->nrseqstate) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + config->seq_state =3D val; return size; } @@ -1467,6 +1539,9 @@ static ssize_t seq_event_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->seq_idx; /* Seq control has two masks B[15:8] F[7:0] */ @@ -1501,6 +1576,9 @@ static ssize_t seq_reset_event_store(struct device *d= ev, if (!(drvdata->nrseqstate)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + config->seq_rst =3D val & ETMv4_EVENT_MASK; return size; } @@ -1531,6 +1609,9 @@ static ssize_t cntr_idx_store(struct device *dev, if (val >=3D drvdata->nr_cntr) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Use spinlock to ensure index doesn't change while it gets * dereferenced multiple times within a spinlock block elsewhere. @@ -1572,6 +1653,9 @@ static ssize_t cntrldvr_store(struct device *dev, if (val > ETM_CNTR_MAX_VAL) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->cntr_idx; config->cntrldvr[idx] =3D val; @@ -1610,6 +1694,9 @@ static ssize_t cntr_val_store(struct device *dev, if (val > ETM_CNTR_MAX_VAL) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->cntr_idx; config->cntr_val[idx] =3D val; @@ -1646,6 +1733,9 @@ static ssize_t cntr_ctrl_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->cntr_idx; config->cntr_ctrl[idx] =3D val; @@ -1676,6 +1766,10 @@ static ssize_t res_idx_store(struct device *dev, =20 if (kstrtoul(buf, 16, &val)) return -EINVAL; + + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Resource selector pair 0 is always implemented and reserved, * namely an idx with 0 and 1 is illegal. @@ -1722,6 +1816,9 @@ static ssize_t res_ctrl_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->res_idx; /* For odd idx pair inversal bit is RES0 */ @@ -1761,6 +1858,9 @@ static ssize_t sshot_idx_store(struct device *dev, if (val >=3D drvdata->nr_ss_cmp) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); config->ss_idx =3D val; raw_spin_unlock(&drvdata->spinlock); @@ -1794,6 +1894,9 @@ static ssize_t sshot_ctrl_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->ss_idx; config->ss_ctrl[idx] =3D FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val); @@ -1844,6 +1947,9 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->ss_idx; config->ss_pe_cmp[idx] =3D FIELD_PREP(TRCSSPCICRn_PC_MASK, val); @@ -1879,6 +1985,9 @@ static ssize_t ctxid_idx_store(struct device *dev, if (val >=3D drvdata->numcidc) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Use spinlock to ensure index doesn't change while it gets * dereferenced multiple times within a spinlock block elsewhere. @@ -1944,6 +2053,9 @@ static ssize_t ctxid_pid_store(struct device *dev, if (kstrtoul(buf, 16, &pid)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); idx =3D config->ctxid_idx; config->ctxid_pid[idx] =3D (u64)pid; @@ -2003,6 +2115,9 @@ static ssize_t ctxid_masks_store(struct device *dev, if ((drvdata->numcidc > 4) && (nr_inputs !=3D 2)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); /* * each byte[0..3] controls mask value applied to ctxid @@ -2105,6 +2220,9 @@ static ssize_t vmid_idx_store(struct device *dev, if (val >=3D drvdata->numvmidc) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + /* * Use spinlock to ensure index doesn't change while it gets * dereferenced multiple times within a spinlock block elsewhere. @@ -2161,6 +2279,9 @@ static ssize_t vmid_val_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); config->vmid_val[config->vmid_idx] =3D (u64)val; raw_spin_unlock(&drvdata->spinlock); @@ -2217,6 +2338,9 @@ static ssize_t vmid_masks_store(struct device *dev, if ((drvdata->numvmidc > 4) && (nr_inputs !=3D 2)) return -EINVAL; =20 + if (coresight_get_mode(drvdata->csdev)) + return -EBUSY; + raw_spin_lock(&drvdata->spinlock); =20 /* --=20 LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}