Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/1]  coresight: fix issue with insufficient claim tags
@ 2026-06-19 16:01 Mike Leach
  2026-06-19 16:01 ` [PATCH v3 1/1] coresight: fix issue where coresight component has no claimtags Mike Leach
  0 siblings, 1 reply; 3+ messages in thread
From: Mike Leach @ 2026-06-19 16:01 UTC (permalink / raw)
  To: coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, leo.yan, james.clark, Mike Leach

All CoreSight compliant components have an implementation defined number
of 0 to 8 claim tag bits in the claim tag registers.

These are used to claim the CoreSight resources by system agents.

ARM recommends implementions have 4 claim tag bits, though a valid
implementation can have 0 claim tags bits.

The CoreSight drivers implement a 2 claim tag bit protocol to allow
self hosted and external debug agents to manage access to the hardware.

However, if there are less than 2 claim tags available the protocol
incorrectly returns an error on device claim, as no checks are made.

If insufficient claim tags are present in a component then the protocol
must return success on claim / disclaim to allow components to be used
normally.

Add initialisation to read the CLAIMSET bits to establish the number of
available claim tag bits, and adjust the claim returns accordingly.

Cache the claimtag protocol availablity in the coresight_device to reduce
reads for the main claim/disclaim api.

changes since v2:
1) consolidated API to remove the API calls using just cs_access, which were
used purely to clear down stale self claim tags, replace with a normal
coresight_device API for initialisation, to match the claim/disclaim API.
This does both the check on availability and the stale tag clearance.
Updated all drivers to use the new init functionality

2) Added option for drivers to skip claim tag checking completely for devices
with no-compliant hardware, that do not implement registers at the claim tag
location, or do not operate correctly to indicate the correct number of
claim tags for the device.

changes since v1:
1) Added claim tag availability cache into coresight_device when using the
main coresight_claim_device() / coresight_disclaim_device() API.

Applies to coresight/next

Mike Leach (1):
  coresight: fix issue where coresight component has no claimtags

 drivers/hwtracing/coresight/coresight-catu.c  |   6 +-
 drivers/hwtracing/coresight/coresight-core.c  | 139 ++++++++++++++++--
 .../hwtracing/coresight/coresight-cti-core.c  |   7 +-
 drivers/hwtracing/coresight/coresight-etb10.c |   9 +-
 .../coresight/coresight-etm3x-core.c          |   8 +-
 .../coresight/coresight-etm4x-core.c          |   8 +-
 .../hwtracing/coresight/coresight-funnel.c    |   7 +-
 drivers/hwtracing/coresight/coresight-priv.h  |   7 +
 .../coresight/coresight-replicator.c          |   9 +-
 .../hwtracing/coresight/coresight-tmc-core.c  |   7 +-
 include/linux/coresight.h                     |  23 ++-
 11 files changed, 205 insertions(+), 25 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v3 1/1] coresight: fix issue where coresight component has no claimtags
  2026-06-19 16:01 [PATCH v3 0/1] coresight: fix issue with insufficient claim tags Mike Leach
@ 2026-06-19 16:01 ` Mike Leach
  2026-06-22 10:26   ` Leo Yan
  0 siblings, 1 reply; 3+ messages in thread
From: Mike Leach @ 2026-06-19 16:01 UTC (permalink / raw)
  To: coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, leo.yan, james.clark, Mike Leach

Coresight components have 0 to 8 claim tag bits. ARM recommends 4 and
the implemented claim tag protocol uses two of these.

If a component has insufficient claim tags then the protocol incorrectly
returns an error when attempting to claim a component.

Fix by introducing a claim tag init function that will read CLAIMSET
to establish then actual number of claim tags and save a claim tag info
flag to indicate the level of support in the device.

Additionally this init routine will also clear down any stale self claim
tag bits that are present in the hardware - removing the need for the
additional interface that was added to accomplish this during device probe.

Any device which is not verified to support claim tags, will now get a
success return from the claim/disclaim calls.

Device drivers can also force skipping of claim tag support checks where
hardware does not support any readable registers at the claim tag
location.

Signed-off-by: Mike Leach <mike.leach@arm.com>
---
 drivers/hwtracing/coresight/coresight-catu.c  |   6 +-
 drivers/hwtracing/coresight/coresight-core.c  | 139 ++++++++++++++++--
 .../hwtracing/coresight/coresight-cti-core.c  |   7 +-
 drivers/hwtracing/coresight/coresight-etb10.c |   9 +-
 .../coresight/coresight-etm3x-core.c          |   8 +-
 .../coresight/coresight-etm4x-core.c          |   8 +-
 .../hwtracing/coresight/coresight-funnel.c    |   7 +-
 drivers/hwtracing/coresight/coresight-priv.h  |   7 +
 .../coresight/coresight-replicator.c          |   9 +-
 .../hwtracing/coresight/coresight-tmc-core.c  |   7 +-
 include/linux/coresight.h                     |  23 ++-
 11 files changed, 205 insertions(+), 25 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 43abe13995cf..d8a0ecc502af 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -574,10 +574,14 @@ static int __catu_probe(struct device *dev, struct resource *res)
 	catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
 	catu_desc.ops = &catu_ops;
 
-	coresight_clear_self_claim_tag(&catu_desc.access);
 	drvdata->csdev = coresight_register(&catu_desc);
 	if (IS_ERR(drvdata->csdev))
 		ret = PTR_ERR(drvdata->csdev);
+
+	ret = coresight_init_claim_tags(drvdata->csdev);
+	if (ret)
+		coresight_unregister(drvdata->csdev);
+
 out:
 	return ret;
 }
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index f7b1308a759c..b110d1b977d1 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -232,6 +232,34 @@ coresight_find_out_connection(struct coresight_device *csdev,
 	return ERR_PTR(-ENODEV);
 }
 
+/*
+ * Reading CLAIMSET returns a bitfield representing the number of claim tags
+ * implemented from bit 0 to bit nTag-1, valid bits set to 1.
+ *
+ * Claim protocol requires 2 bits so test for MS bit required,
+ * bit 1 -  CORESIGHT_CLAIM_SELF_HOSTED
+ *
+ * return true if sufficient claim tags implemented for protocol
+ */
+static bool coresight_claim_tags_implemented_unlocked(struct csdev_access *csa)
+{
+	u32 claim_bits_impl = FIELD_GET(CORESIGHT_CLAIM_BITS_MAX_MASK,
+			 csdev_access_relaxed_read32(csa, CORESIGHT_CLAIMSET));
+	return ((claim_bits_impl & CORESIGHT_CLAIM_SELF_HOSTED) != 0);
+}
+
+/* helper for checking if claim tag protocol in use */
+static bool coresight_using_claim_tag_protocol(struct coresight_device *csdev)
+{
+	return (bool)(csdev->claim_tag_info == CS_CLAIM_TAG_STD_PROTOCOL);
+}
+
+/* helper to check initialised */
+static bool coresight_claim_tag_noinit(struct coresight_device *csdev)
+{
+	return (bool)(csdev->claim_tag_info == CS_CLAIM_TAG_UNKNOWN);
+}
+
 static u32 coresight_read_claim_tags_unlocked(struct coresight_device *csdev)
 {
 	return FIELD_GET(CORESIGHT_CLAIM_MASK,
@@ -245,23 +273,97 @@ static void coresight_set_self_claim_tag_unlocked(struct coresight_device *csdev
 	isb();
 }
 
-void coresight_clear_self_claim_tag(struct csdev_access *csa)
+static void coresight_clear_self_claim_tag_unlocked(struct csdev_access *csa)
+{
+	csdev_access_relaxed_write32(csa, CORESIGHT_CLAIM_SELF_HOSTED,
+				     CORESIGHT_CLAIMCLR);
+	isb();
+}
+
+/*
+ * Initialise claim tag protocol.
+ *
+ * Check for existence of claim tags and clear down any stale
+ * existing self claim tag.
+ *
+ * Set claim tag protocol usage flag.
+ *
+ * Automatically unlocks/relocks memory mapped devices.
+ *
+ * Call during device probe.
+ */
+int coresight_init_claim_tags(struct coresight_device *csdev)
 {
+	struct csdev_access *csa;
+
+	if (WARN_ON(!csdev))
+		return -EINVAL;
+
+	/* if previous init or forced ignore claim tag,  no checks needed */
+	if (csdev->claim_tag_info != CS_CLAIM_TAG_UNKNOWN) {
+		if (csdev->claim_tag_info == CS_CLAIM_TAG_IGNORE)
+			dev_dbg(&csdev->dev,
+				"Device set to ignore claim tag protocols\n");
+		return 0;
+	}
+
+	/* get the access method */
+	csa = &csdev->access;
+
+	/* unlock if memory access */
 	if (csa->io_mem)
 		CS_UNLOCK(csa->base);
-	coresight_clear_self_claim_tag_unlocked(csa);
+
+	/* check claim tag validity */
+	if (coresight_claim_tags_implemented_unlocked(csa)) {
+		csdev->claim_tag_info = CS_CLAIM_TAG_STD_PROTOCOL;
+		dev_dbg(&csdev->dev, "Device using standard claim tag protocol\n");
+
+		/* using claim tags so clear down any stale self claim tag */
+		coresight_clear_self_claim_tag_unlocked(csa);
+	} else {
+		csdev->claim_tag_info = CS_CLAIM_TAG_NOT_IMPL;
+		dev_dbg(&csdev->dev, "Device claim tag hardware not implemented\n");
+	}
+
+	/* relock if memory access */
 	if (csa->io_mem)
 		CS_LOCK(csa->base);
+
+	/* return success - caller can check claim_tag_info for state */
+	return 0;
 }
-EXPORT_SYMBOL_GPL(coresight_clear_self_claim_tag);
+EXPORT_SYMBOL_GPL(coresight_init_claim_tags);
+
+struct cs_claim_tag_init_arg {
+	struct coresight_device *csdev;
+	int rc;
+};
 
-void coresight_clear_self_claim_tag_unlocked(struct csdev_access *csa)
+static void coresight_init_claim_tags_smp_call(void *info)
 {
-	csdev_access_relaxed_write32(csa, CORESIGHT_CLAIM_SELF_HOSTED,
-				     CORESIGHT_CLAIMCLR);
-	isb();
+	struct cs_claim_tag_init_arg *arg = info;
+
+	arg->rc = coresight_init_claim_tags(arg->csdev);
 }
-EXPORT_SYMBOL_GPL(coresight_clear_self_claim_tag_unlocked);
+
+/* cpu bound devices (etms) may need to run on bound cpu */
+int coresight_init_claim_tags_cpu_smp(struct coresight_device *csdev, int cpu)
+{
+	int ret = 0;
+	struct cs_claim_tag_init_arg arg = { };
+
+	arg.csdev = csdev;
+	ret = smp_call_function_single(cpu,
+				       coresight_init_claim_tags_smp_call,
+				       &arg, 1);
+
+	if (!ret)
+		ret = arg.rc;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(coresight_init_claim_tags_cpu_smp);
 
 /*
  * coresight_claim_device_unlocked : Claim the device for self-hosted usage
@@ -276,12 +378,18 @@ EXPORT_SYMBOL_GPL(coresight_clear_self_claim_tag_unlocked);
 int coresight_claim_device_unlocked(struct coresight_device *csdev)
 {
 	int tag;
-	struct csdev_access *csa;
 
 	if (WARN_ON(!csdev))
 		return -EINVAL;
 
-	csa = &csdev->access;
+	/* check init complete */
+	if (WARN_ON(coresight_claim_tag_noinit(csdev)))
+		return -EPERM;
+
+	/* check if we are using claim tags on this device */
+	if (!coresight_using_claim_tag_protocol(csdev))
+		return 0;
+
 	tag = coresight_read_claim_tags_unlocked(csdev);
 
 	switch (tag) {
@@ -291,7 +399,7 @@ int coresight_claim_device_unlocked(struct coresight_device *csdev)
 			return 0;
 
 		/* There was a race setting the tag, clean up and fail */
-		coresight_clear_self_claim_tag_unlocked(csa);
+		coresight_clear_self_claim_tag_unlocked(&csdev->access);
 		dev_dbg(&csdev->dev, "Busy: Couldn't set self claim tag");
 		return -EBUSY;
 
@@ -338,6 +446,14 @@ void coresight_disclaim_device_unlocked(struct coresight_device *csdev)
 	if (WARN_ON(!csdev))
 		return;
 
+	/* check init complete */
+	if (WARN_ON(coresight_claim_tag_noinit(csdev)))
+		return;
+
+	/* check if we are using claim tags on this device */
+	if (!coresight_using_claim_tag_protocol(csdev))
+		return;
+
 	if (coresight_read_claim_tags_unlocked(csdev) == CORESIGHT_CLAIM_SELF_HOSTED)
 		coresight_clear_self_claim_tag_unlocked(&csdev->access);
 	else
@@ -1543,6 +1659,7 @@ coresight_init_device(struct coresight_desc *desc)
 	csdev->ops = desc->ops;
 	csdev->access = desc->access;
 	csdev->orphan = true;
+	csdev->claim_tag_info = CS_CLAIM_TAG_UNKNOWN;
 
 	if (desc->flags & CORESIGHT_DESC_CPU_BOUND) {
 		csdev->cpu = desc->cpu;
diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index b2c9a4db13b4..436ae2d8a7b9 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -729,11 +729,16 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	cti_desc.groups = drvdata->ctidev.con_groups;
 	cti_desc.dev = dev;
 
-	coresight_clear_self_claim_tag(&cti_desc.access);
 	drvdata->csdev = coresight_register(&cti_desc);
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	ret = coresight_init_claim_tags(drvdata->csdev);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		return ret;
+	}
+
 	/* add to list of CTI devices */
 	mutex_lock(&ect_mutex);
 	list_add(&drvdata->node, &ect_net);
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index a827f76b8144..339d902ce88a 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -769,22 +769,25 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 	desc.dev = dev;
 	desc.groups = coresight_etb_groups;
 
-	coresight_clear_self_claim_tag(&desc.access);
 	drvdata->csdev = coresight_register(&desc);
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	ret = coresight_init_claim_tags(drvdata->csdev);
+	if (ret)
+		goto err_unregister_csdev;
+
 	drvdata->miscdev.name = desc.name;
 	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
 	drvdata->miscdev.fops = &etb_fops;
 	ret = misc_register(&drvdata->miscdev);
 	if (ret)
-		goto err_misc_register;
+		goto err_unregister_csdev;
 
 	pm_runtime_put(&adev->dev);
 	return 0;
 
-err_misc_register:
+err_unregister_csdev:
 	coresight_unregister(drvdata->csdev);
 	return ret;
 }
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 862ad0786699..3d24bcac14ec 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -756,7 +756,6 @@ static void etm_init_arch_data(void *info)
 	drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
 	drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
 
-	coresight_clear_self_claim_tag_unlocked(&drvdata->csa);
 	etm_set_pwrdwn(drvdata);
 	etm_clr_pwrup(drvdata);
 	CS_LOCK(drvdata->csa.base);
@@ -852,6 +851,13 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	/* init the claim tag protocol - ensure run on correct cpu */
+	ret = coresight_init_claim_tags_cpu_smp(drvdata->csdev, drvdata->cpu);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		return ret;
+	}
+
 	ret = etm_perf_symlink(drvdata->csdev, true);
 	if (ret) {
 		coresight_unregister(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 14bb31bd6a0b..b053ba7cf021 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1511,7 +1511,6 @@ static void etm4_init_arch_data(void *info)
 	/* NUMCNTR, bits[30:28] number of counters available for tracing */
 	drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
 
-	coresight_clear_self_claim_tag_unlocked(csa);
 	etm4_cs_lock(drvdata, csa);
 	cpu_detect_trace_filtering(drvdata);
 }
@@ -2195,6 +2194,13 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	/* init the claim tag protocol - ensure run on correct cpu */
+	ret = coresight_init_claim_tags_cpu_smp(drvdata->csdev, drvdata->cpu);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		return ret;
+	}
+
 	ret = etm_perf_symlink(drvdata->csdev, true);
 	if (ret) {
 		coresight_unregister(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3f56ceccd8c9..72f87284219a 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -244,7 +244,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
 		drvdata->base = base;
 		desc.groups = coresight_funnel_groups;
 		desc.access = CSDEV_ACCESS_IOMEM(base);
-		coresight_clear_self_claim_tag(&desc.access);
 	}
 
 	dev_set_drvdata(dev, drvdata);
@@ -265,6 +264,12 @@ static int funnel_probe(struct device *dev, struct resource *res)
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	if (res) {
+		ret = coresight_init_claim_tags(drvdata->csdev);
+		if (ret)
+			coresight_unregister(drvdata->csdev);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index dddac946659f..fada0e49ed28 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -41,6 +41,13 @@ extern const struct device_type coresight_dev_type[];
 #define CORESIGHT_CLAIM_SELF_HOSTED	2
 #define CORESIGHT_CLAIM_INVALID		3
 
+/*
+ * Coresight specification defines a maximum of 8 claim tag bits.
+ * The precise number is implementation defined, and may be obtained by
+ * reading the CLAIMSET register.
+ */
+#define CORESIGHT_CLAIM_BITS_MAX_MASK	GENMASK(7, 0)
+
 #define TIMEOUT_US		100
 #define BMVAL(val, lsb, msb)	((val & GENMASK(msb, lsb)) >> lsb)
 
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 07fc04f53b88..0ef87715fa2a 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -251,7 +251,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
 		drvdata->base = base;
 		desc.groups = replicator_groups;
 		desc.access = CSDEV_ACCESS_IOMEM(base);
-		coresight_clear_self_claim_tag(&desc.access);
 	}
 
 	if (fwnode_property_present(dev_fwnode(dev),
@@ -276,6 +275,14 @@ static int replicator_probe(struct device *dev, struct resource *res)
 	if (IS_ERR(drvdata->csdev))
 		return PTR_ERR(drvdata->csdev);
 
+	if (res) {
+		ret = coresight_init_claim_tags(drvdata->csdev);
+		if (ret) {
+			coresight_unregister(drvdata->csdev);
+			return ret;
+		}
+	}
+
 	replicator_reset(drvdata);
 	return 0;
 }
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index c89fe996af23..45241c934ee6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -864,13 +864,18 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 	dev->platform_data = pdata;
 	desc.pdata = pdata;
 
-	coresight_clear_self_claim_tag(&desc.access);
 	drvdata->csdev = coresight_register(&desc);
 	if (IS_ERR(drvdata->csdev)) {
 		ret = PTR_ERR(drvdata->csdev);
 		goto out;
 	}
 
+	ret = coresight_init_claim_tags(drvdata->csdev);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		goto out;
+	}
+
 	drvdata->miscdev.name = desc.name;
 	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
 	drvdata->miscdev.fops = &tmc_fops;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index add0579cad88..126e0e867e16 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -248,6 +248,20 @@ struct coresight_trace_id_map {
 	raw_spinlock_t lock;
 };
 
+/*
+ * Coresight claim tag info:
+ * CS_CLAIM_TAG_UNKNOWN      - not yet checked.
+ * CS_CLAIM_TAG_STD_PROTOCOL - using standard claim/release protocol.
+ * CS_CLAIM_TAG_NOT_IMPL     - no claim tags available.
+ * CS_CLAIM_TAG_IGNORE	     - force skip of claim tags protocol
+ */
+enum coresight_claim_tag_info {
+	CS_CLAIM_TAG_UNKNOWN,
+	CS_CLAIM_TAG_STD_PROTOCOL,
+	CS_CLAIM_TAG_NOT_IMPL,
+	CS_CLAIM_TAG_IGNORE,
+};
+
 /**
  * struct coresight_device - representation of a device as used by the framework
  * @pdata:	Platform data with device connections associated to this device.
@@ -269,6 +283,7 @@ struct coresight_trace_id_map {
  *		spinlock.
  * @cpu:	The CPU this component is affined to (-1 for not CPU bound).
  * @orphan:	true if the component has connections that haven't been linked.
+ * @claim_tag_info: how the device is using claim tags.
  * @sysfs_sink_activated: 'true' when a sink has been selected for use via sysfs
  *		by writing a 1 to the 'enable_sink' file.  A sink can be
  *		activated but not yet enabled.  Enabling for a _sink_ happens
@@ -297,6 +312,7 @@ struct coresight_device {
 	int refcnt;
 	int cpu;
 	bool orphan;
+	enum coresight_claim_tag_info claim_tag_info;
 	/* sink specific fields */
 	bool sysfs_sink_activated;
 	struct dev_ext_attribute *ea;
@@ -664,15 +680,14 @@ int coresight_timeout(struct csdev_access *csa, u32 offset, int position, int va
 typedef void (*coresight_timeout_cb_t) (struct csdev_access *, u32, int, int);
 int coresight_timeout_action(struct csdev_access *csa, u32 offset, int position, int value,
 			     coresight_timeout_cb_t cb);
-int coresight_claim_device(struct coresight_device *csdev);
-int coresight_claim_device_unlocked(struct coresight_device *csdev);
 
 int coresight_claim_device(struct coresight_device *csdev);
 int coresight_claim_device_unlocked(struct coresight_device *csdev);
-void coresight_clear_self_claim_tag(struct csdev_access *csa);
-void coresight_clear_self_claim_tag_unlocked(struct csdev_access *csa);
 void coresight_disclaim_device(struct coresight_device *csdev);
 void coresight_disclaim_device_unlocked(struct coresight_device *csdev);
+int coresight_init_claim_tags(struct coresight_device *csdev);
+int coresight_init_claim_tags_cpu_smp(struct coresight_device *csdev, int cpu);
+
 char *coresight_alloc_device_name(const char *prefix, struct device *dev);
 
 bool coresight_loses_context_with_cpu(struct device *dev);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3 1/1] coresight: fix issue where coresight component has no claimtags
  2026-06-19 16:01 ` [PATCH v3 1/1] coresight: fix issue where coresight component has no claimtags Mike Leach
@ 2026-06-22 10:26   ` Leo Yan
  0 siblings, 0 replies; 3+ messages in thread
From: Leo Yan @ 2026-06-22 10:26 UTC (permalink / raw)
  To: Mike Leach
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	james.clark

Hi Mike,

On Fri, Jun 19, 2026 at 05:01:48PM +0100, Mike Leach wrote:

[...]

> Any device which is not verified to support claim tags, will now get a
> success return from the claim/disclaim calls.

Do we really want to relax this?

AFAIK, all Arm standard modules should follow the claim tag protocol.
SoC specific modules that do not support claim tags should not enable
claim tag handling in the first place. In that case, they would not
need any claim tag-related operations.

The tricky part is that if a module provides CORESIGHT_CLAIMSET, it
likely supports claim tags. Conversely, if a module does not provide
CORESIGHT_CLAIMSET, validating claim tags using that offset seems
pointless.

As a result, can we constraint to only two cases as below?

  enum coresight_claim_tag_info {
       CS_CLAIM_TAG_STD_PROTOCOL,
       CS_CLAIM_TAG_IGNORE,
  };

For CS_CLAIM_TAG_STD_PROTOCOL type, it must pass the validation.
Otherwise, the claim tag operations will be totally ignored.

[...]

> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> index 43abe13995cf..d8a0ecc502af 100644
> --- a/drivers/hwtracing/coresight/coresight-catu.c
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -574,10 +574,14 @@ static int __catu_probe(struct device *dev, struct resource *res)
>  	catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
>  	catu_desc.ops = &catu_ops;
>  
> -	coresight_clear_self_claim_tag(&catu_desc.access);
>  	drvdata->csdev = coresight_register(&catu_desc);
>  	if (IS_ERR(drvdata->csdev))
>  		ret = PTR_ERR(drvdata->csdev);
> +
> +	ret = coresight_init_claim_tags(drvdata->csdev);
> +	if (ret)
> +		coresight_unregister(drvdata->csdev);
> +

coresight_init_claim_tags() is much simpler than coresight_register(),
this is why we can put coresight_init_claim_tags() before
coresight_register() to avoid complex rollback operations for claim init
failure.

I have no strong opinion for this, as the sequence in this patch should
can work as well.

> +/* helper for checking if claim tag protocol in use */
> +static bool coresight_using_claim_tag_protocol(struct coresight_device *csdev)
> +{
> +	return (bool)(csdev->claim_tag_info == CS_CLAIM_TAG_STD_PROTOCOL);
> +}

Redundant for bool cast?

> +
> +/* helper to check initialised */
> +static bool coresight_claim_tag_noinit(struct coresight_device *csdev)
> +{
> +	return (bool)(csdev->claim_tag_info == CS_CLAIM_TAG_UNKNOWN);

Ditto.

> +/* cpu bound devices (etms) may need to run on bound cpu */
> +int coresight_init_claim_tags_cpu_smp(struct coresight_device *csdev, int cpu)
> +{
> +	int ret = 0;
> +	struct cs_claim_tag_init_arg arg = { };
> +
> +	arg.csdev = csdev;
> +	ret = smp_call_function_single(cpu,
> +				       coresight_init_claim_tags_smp_call,
> +				       &arg, 1);
> +
> +	if (!ret)
> +		ret = arg.rc;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(coresight_init_claim_tags_cpu_smp);

Do we really need a specific SMP call for this? I understand this will
be used by ETMv3/v4 drivers, can we simply init claim tags in the local
functions (e.g., etm4_init_arch_data() for ETMv4), same as the current
implemenation?

Thanks,
Leo


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-22 10:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-19 16:01 [PATCH v3 0/1] coresight: fix issue with insufficient claim tags Mike Leach
2026-06-19 16:01 ` [PATCH v3 1/1] coresight: fix issue where coresight component has no claimtags Mike Leach
2026-06-22 10:26   ` Leo Yan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox