[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 3/4] xen/arm: its: refactor ITS quirk matching


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Mykola Kvach <mykola_kvach@xxxxxxxx>
  • Date: Tue, 22 Sep 2026 18:58:41 +0300
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=y0CNFQ6w0OoFMTVo9GGVwFDr1Sg2IGBlLPPygPrJC/Y=; b=uG1/Gi81Z5n0fRfO65ju8ZQlAaCsNm3rkzStvRIfFBYM28L1+wkuV636ZEJV8zKZ+Be4K2zzWUBg+RchRTCAJetzGQUbxDUYZXso66YK6sQhVbB58bQAGeO02ogOhqFgxHf1AT/dRgZobPZE5r/2T0e/NPh4SV15Qkaef7ziU9mC7xAj9gokmjl13tF0zKk2bFIw2UamRFFB5LEJ4X1HK1Auzo7j2lhdzQitjKe87mi88OuehZfGXK/kdw30BAVUMVEYxos51Tj/k2Qxb0Bfb2NgQmJHcGxX502l6vVL67P4q7jX5dvmeSn4ulQhq+1W7LJKSFiD0mY64REgRbvqzQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=oLgtyVh4ZP5JqViUaVZV3+F7q04fMyUlbh3lMICdp3WpBeDjWsuXCUvW+mDtme4orTB2PKMg20Db82MX4GW8PrkSbvlrBqviRDIsVeGl5NzoZgX44mb3UK4TwTCpyW2i5Ibo/Wt0m++6/0vF3XzwxBYoyRA0Mzi/BOULjXXUBYA6++MHCaYs5MEBNLc1eV+/n1PUcYHiRaAMesNEdeTAkMzaANvoLY8cHJJ+X2FQ/NaL5p/ot98CiMk5qDEGMQazeGXSQI+xzMx3eUs99pf6yBFE/WS3LRlqGMgreCabQoM1d+/xAR3DJ2rLr9GgbsCOtkgVrrALm0VdJbg/uVW+Sw==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=epam.com header.i="@epam.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Tue, 22 Sep 2026 15:59:11 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

ITS quirks are matched only by IIDR and mask fields stored in each table
entry. That is too coarse when the same GIC IP block appears on several
platforms but a workaround is valid only for some of them.

Replace the fixed IIDR fields with a generic match(hw_its, data)
callback and an opaque data pointer. Add an IIDR matcher as a reusable
building block and use it from the R-Car Gen4 matcher after checking the
Renesas machine compatibles.

This intentionally narrows the R-Car Gen4 quirk. Previously every ITS
with IIDR 0x0201743b matched. Now it matches only a DT-discovered ITS on
an r8a779f0 or r8a779g0 machine. ACPI-discovered ITSes and the same IIDR
on other platforms no longer match.

Keep first-match semantics explicit. Assert that non-sentinel entries
provide a matcher and that IIDR matching receives match data. Retain
runtime guards so malformed entries cannot cause a NULL function call
or data dereference in non-debug builds. Place the matcher data and
table in init-only read-only sections.

The matched entry still supplies separate ITS and LPI flags; this patch
only changes how the entry is selected.

Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
---
Changes in v3:
- Document the intentional narrowing of the R-Car Gen4 match.
- Add the non-debug NULL-data guard.
- Put the matcher data and table in init-only read-only sections.

Changes in v2:
- Replace v1's optional platform callback plus fixed IIDR/mask fields
  with a single generic match(hw_its, data) selector.
- Add a reusable IIDR matcher and use it after the R-Car Gen4
  machine-compatible checks.
- Document that the R-Car Gen4 quirk remains DT-only.
- Keep the split ITS and host LPI quirk scopes when applying the matched
  entry.
- Document first-match ordering in the lookup path and guard against
  entries without a match callback or IIDR match data.
---
 xen/arch/arm/gic-v3-its.c | 73 +++++++++++++++++++++++++++++++--------
 1 file changed, 58 insertions(+), 15 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index 454fd0e0ef..f52232ca40 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -54,8 +54,8 @@ struct its_device {
 
 struct its_quirk {
     const char *desc;
-    uint32_t iidr;
-    uint32_t mask;
+    bool (*match)(const struct host_its *hw_its, const void *data);
+    const void *data;
     uint32_t its_flags;
     /*
      * lpi_flags are ORed into the global host LPI policy and must only
@@ -65,11 +65,52 @@ struct its_quirk {
     uint32_t lpi_flags;
 };
 
-static const struct its_quirk its_quirks[] = {
+struct its_quirk_match_iidr {
+    uint32_t iidr;
+    uint32_t mask;
+};
+
+static bool __init gicv3_its_match_iidr(const struct host_its *hw_its,
+                                        const void *data)
+{
+    const struct its_quirk_match_iidr *match;
+    uint32_t iidr;
+
+    ASSERT(data);
+
+    if ( !data )
+        return false;
+
+    match = data;
+    iidr = readl_relaxed(hw_its->its_base + GITS_IIDR);
+
+    return (iidr & match->mask) == match->iidr;
+}
+
+static bool __init gicv3_its_match_quirk_gen4(const struct host_its *hw_its,
+                                              const void *data)
+{
+    if ( !hw_its->dt_node )
+        return false;
+
+    if ( !dt_machine_is_compatible("renesas,r8a779f0") &&
+         !dt_machine_is_compatible("renesas,r8a779g0") )
+        return false;
+
+    return gicv3_its_match_iidr(hw_its, data);
+}
+
+static const struct its_quirk_match_iidr rcar_gen4_iidr __initconst = {
+    /* Implementer 0x43b identifies Arm Ltd. */
+    .iidr = 0x0201743b,
+    .mask = 0xffffffffU,
+};
+
+static const struct its_quirk its_quirks[] __initconstrel = {
     {
-        .desc  = "R-Car Gen4",
-        .iidr  = 0x0201743b,
-        .mask  = 0xffffffffU,
+        .desc = "R-Car Gen4",
+        .match = gicv3_its_match_quirk_gen4,
+        .data = &rcar_gen4_iidr,
         .its_flags = GICV3_QUIRK_MEM_NC_NS | GICV3_QUIRK_MEM_32BIT_ADDR,
         .lpi_flags = GICV3_QUIRK_MEM_NC_NS | GICV3_QUIRK_MEM_32BIT_ADDR,
     },
@@ -78,18 +119,21 @@ static const struct its_quirk its_quirks[] = {
     }
 };
 
-static const struct its_quirk *__init gicv3_its_find_quirk(uint32_t iidr)
+static const struct its_quirk *__init gicv3_its_find_quirk(
+    const struct host_its *hw_its)
 {
-    const struct its_quirk *quirks = its_quirks;
+    const struct its_quirk *quirk;
 
     /*
-     * The first matching quirk wins. More specific quirks must be listed
-     * before broader IIDR-only entries.
+     * The first matching quirk wins. Entries that match a specific platform
+     * must be listed before broader IIDR-only entries.
      */
-    for ( ; quirks->desc; quirks++ )
+    for ( quirk = its_quirks; quirk->desc; quirk++ )
     {
-        if ( quirks->iidr == (quirks->mask & iidr) )
-            return quirks;
+        ASSERT(quirk->match);
+
+        if ( quirk->match && quirk->match(hw_its, quirk->data) )
+            return quirk;
     }
 
     return NULL;
@@ -97,8 +141,7 @@ static const struct its_quirk *__init 
gicv3_its_find_quirk(uint32_t iidr)
 
 static void __init gicv3_its_collect_quirks(struct host_its *hw_its)
 {
-    uint32_t iidr = readl_relaxed(hw_its->its_base + GITS_IIDR);
-    const struct its_quirk *quirk = gicv3_its_find_quirk(iidr);
+    const struct its_quirk *quirk = gicv3_its_find_quirk(hw_its);
 
     if ( quirk )
     {
-- 
2.53.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.