From nobody Tue Aug 25 10:47:43 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1783353571; cv=none; d=zohomail.com; s=zohoarc; b=UfKKzAVRR9/45J0TfZVrGqUZGOy5j2a7FmGqu2kCIkNhFtfJoVD+aQvoHzgwVVlJ4HA4uQOiRrKtR3JNJMlLmFmU/DKnvR6pjYB0FfiIflJez4a3K9ddULOIOvuowVL8HztrXNAnZbkGfMRtnXU1Iq79x4XqDoTVG7pSI7oBnlY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783353571; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VOtrWkaPQqlfPd6Df6usWjHZMbCEmGeH2VRC7YlQb7M=; b=e4Sq1WXnjt7PhMQtaWPaGWC8HX/b+W+PplHxmfnTjHZhn8qmMnLHrpQqh8pY0IcCHR2OW3Z7KMR4wojZJySCqgjVNgAxogUA6J1hh+7p+qaWf5c3Xz6RxTSokgJuKdlTPSlAzYPOMEiyecNEwjjDOEvxJmWTrg4LRiYf5jaK9OM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1783353571002622.590945976329; Mon, 6 Jul 2026 08:59:31 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1355539.1610431 (Exim 4.92) (envelope-from ) id 1wglif-0004G2-Nf; Mon, 06 Jul 2026 15:58:53 +0000 Received: by outflank-mailman (output) from mailman id 1355539.1610431; Mon, 06 Jul 2026 15:58:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wglie-0004B7-Rv; Mon, 06 Jul 2026 15:58:52 +0000 Received: by outflank-mailman (input) for mailman id 1355539; Mon, 06 Jul 2026 15:58:47 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) id 1wgliY-0002t5-LK for xen-devel@lists.xenproject.org; Mon, 06 Jul 2026 15:58:46 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wgliY-00AcZM-0V for xen-devel@lists.xenproject.org; Mon, 06 Jul 2026 17:58:46 +0200 Received: from [10.42.69.10] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a4bd081-5cb7-0a2a0a5109dd-0a2a450a953e-44 for ; Mon, 06 Jul 2026 17:58:45 +0200 Received: from [209.85.128.53] (helo=mail-wm1-f53.google.com) by tlsNG-4011c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a4bd0b5-e40e-0a2a450a0019-d1558035e498-3 for ; Mon, 06 Jul 2026 17:58:45 +0200 Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-493bc8fda98so35471125e9.0 for ; Mon, 06 Jul 2026 08:58:45 -0700 (PDT) Received: from fedora (user-109-243-144-234.play-internet.pl. [109.243.144.234]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-493cce03fa1sm284910325e9.11.2026.07.06.08.58.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 08:58:44 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783353525; x=1783958325; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VOtrWkaPQqlfPd6Df6usWjHZMbCEmGeH2VRC7YlQb7M=; b=bOE7Vr3TTWY/vqIt2ENCpd/P1jLCX8jCOt5vwl0XaQjxkyWgXZHWS4DaphEeTY4IWr WH0/ZAjMECpmyySFadbEBonqdMNRv4a68smFV7d7U813W9mY6t9aOAJk2BEtrnzrijCO R3cSzrZZ1yMPBTMBlyhWinDnDnqYrEmNX4J0sRSK3CG076qfyqh66lQFHjIRaQVGAmBB Chzcz+eXWKBA39NFnD0MZd/yG/UbioeLRLdgDjS5rbmHq1rVBmCi8ueM5CJkS3ills5z IafVQxHCr9M2eDDyTXEs1/LsHToTM9StBZfkjGM6HD/8iIe+leX3DuWM8bKjF2PY14Hq uclw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783353525; x=1783958325; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VOtrWkaPQqlfPd6Df6usWjHZMbCEmGeH2VRC7YlQb7M=; b=GlMxcgNHGtn8PP95VtsfzLRjjIjoCOZjZ5+Y9K+0A/tVjTTJMdnCaeoUmNLGhBqDq8 7YQqWMOZ4fCBAGZGuAsAQBqX8ndNIvP2C4ItHtSlY4MiC80qQ09w3hVYInUY1nxRG1O7 zlW+tMRfek51FmOTGT62Ti65gXYsg+0cyX9oNN5Rvgy+ZccQepsmdMe+CDcIEbNH5O4E Lsv+STwpAQPi7AD/wrMcDdaBQkOO/QJxJCt4+amCwMhjHMzFyVjNTfGiKHgm0pd8WVX6 Bt/UM9J2ZCQnVVW7W7O8Gc7XfbfaAqQTn2ykOwzAw4as6+S3MEuXH8+Mq+LfUDSJf4aU 8mUw== X-Gm-Message-State: AOJu0YyIjiun6UzFg5jcNBhGOka2Q+0zUaRXjTitwKSN+xxyyhc8E38I cxBqWjUGNNlRoHEECLlo/G5vjRDoXtR+PZIXFnlN6kIkS3j43AKjJwSKJWfvOg== X-Gm-Gg: AfdE7cnjo1kPvPNc/2IMcUwk1kBPmraP0nn+OtLkBEV/J0jPnCpF+eLnXDE1UcnyWkp dN4mSPp/Y0R0QgmsdfGLTmQp2RoLl/aozlvtzMJSjFAGbbjPlvRv6Y9wa4xEC+MHOY0JhQsgWIG GvdBEw18mvkf5CquVZqFGEJCWTEKc95bG/RVK8aqkN+DdvQA02cwMtb0g7pppeyiwmsCUxK7Dqv 4x16gndsbQU3vNeYBhZDLvQa6ppyKoJUDEzVSJbyHtBFszde0AGylcrhDixcCDt7JHAm0rDkheD AUFzWP+1ETT589hPHx8zkKctDMcEKCxLqSa0jK/UjT/W+FS8ECRh91AkRJei3WPytZjGF6Tr844 zh+c2tEzEFf5zJrWzw3depQK+8mTmmgsTsLxpUuwxD8L7Qv7WcuDIoqNA0yU8DbSpJxUbB7+Y/v vmtCjghzoUKxtdSfz3rnFn/t/44THUVITFzGwhp+BVg13Xz7H6CMkpNhl+eA== X-Received: by 2002:a05:600c:3d8b:b0:493:bba7:e9f4 with SMTP id 5b1f17b1804b1-493df065f50mr14196265e9.18.1783353525265; Mon, 06 Jul 2026 08:58:45 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Romain Caritey , Baptiste Le Duc , Oleksii Kurochko , Alistair Francis , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini Subject: [PATCH v5 20/26] xen/riscv: create APLIC DT node for guest domains Date: Mon, 6 Jul 2026 17:58:01 +0200 Message-ID: X-Mailer: git-send-email 2.54.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-4011c0/1783353525-3D470DDE-DB34833C/10/73395122804 X-purgate-type: spam X-purgate-size: 8543 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1783353573045158500 Content-Type: text/plain; charset="utf-8" Guests require a Device Tree description of the interrupt controller topology. Add support for creating an APLIC node when building the guest DT. Provide stub for imsic_make_dt_node() it will be introduced properly in follow-up patch. The value chosen for GUEST_APLIC_S_BASE is based on QEMU one. DT-building functions are marked __init because domain creation happens at boot time, before the init sections are freed. In a typical deployment libxl creates the interrupt controller node in userspace and hands the complete FDT to Xen, so these functions are only called during early domain construction. Co-developed-by: Romain Caritey Signed-off-by: Oleksii Kurochko --- Changes in v5: - Drop pointless initializer for local variable res in vaplic_make_domu_dt_node(). - Limit guest_num_sources in the similar way to IMSIC. - Rename VAPLIC_NUM_SOURCES to GUEST_APLIC_MAX_SOURCES to be aligned with the similar place in vIMSIC related code. --- Changes in v4: - Drop spurious and includes from aplic.c (mistakenly added, they belong to vaplic.c). - Reduce vaplic_name[] from 128 to 32 bytes in vaplic_make_domu_dt_node(). - Use __initconstrel (with const) for init_ops instead of __initdata. - s/__ULL/_UL for defintion of GUEST_APLIC_S_BASE. --- Changes in v3: - Fix rebase conflicts becuase of this patch is reordered after IMSIC DT node creation is intoduced. - Update the commit message. - Move initialization of domaincfg with APLIC_DOMAINCFG_RO80 from this patch to earlier. - Change paddr_t aplic_size to unsigned int in vaplic_make_domu_dt_node() and replace the UB (after it started to be uint) aplic_size >> 32 with an explicit 0 in the DT reg property. - Add BUILD_BUG_ON() to be sure that aplic size isn't bigger then UINT32_MAX. --- Changes in v2: - Avoid as max as possible of host properties inheritance. Only number of APLIC's irqs are checked what leads to an introduction of get_aplic_irqs_num(). - Move this patch earlier what leads to an introduction of vimsic_make_domu_dt_node() stub. - s/vimsic_make_domu_dt_node/imsic_make_domu_dt_node. - Refactor vimsic_make_domu_dt_node() to avoid re-usage of APLIC host properties. - Drop next_phandle as it is now in common code. - Drop const for kinfo argument of vimsic_make_domu_dt_node() is is going to be updated inside vimsic_make_domu_dt_node(). - Use introduced before vintc->num_irqs. --- --- xen/arch/riscv/aplic-priv.h | 14 +++++ xen/arch/riscv/aplic.c | 2 + xen/arch/riscv/include/asm/aplic.h | 8 +++ xen/arch/riscv/include/asm/guest-layout.h | 6 ++ xen/arch/riscv/vaplic.c | 77 +++++++++++++++++++++++ 5 files changed, 107 insertions(+) diff --git a/xen/arch/riscv/aplic-priv.h b/xen/arch/riscv/aplic-priv.h index 85e0d028d1ae..ac971f34add3 100644 --- a/xen/arch/riscv/aplic-priv.h +++ b/xen/arch/riscv/aplic-priv.h @@ -34,4 +34,18 @@ struct aplic_priv { const struct imsic_config *imsic_cfg; }; =20 +/* + * Value is inspired by what QEMU is using for riscv,num-sources property = for + * APLIC node. + */ +#define GUEST_APLIC_MAX_SOURCES 96 + +/* + * Specifies the number of wired interrupt sources supported by guest APLIC + * domain. + * Could be limited by host interrupt controller and is identical for every + * domain. + */ +extern unsigned int guest_num_sources; + #endif /* ASM_RISCV_APLIC_PRIV_H */ diff --git a/xen/arch/riscv/aplic.c b/xen/arch/riscv/aplic.c index 126d56fb7ea8..5f8ae4d97b87 100644 --- a/xen/arch/riscv/aplic.c +++ b/xen/arch/riscv/aplic.c @@ -92,6 +92,8 @@ static int __init cf_check aplic_init(void) panic("%s: failed to get number of interrupt sources\n", node->full_name); =20 + guest_num_sources =3D min(GUEST_APLIC_MAX_SOURCES + 0U, aplic_info.num= _irqs); + if ( aplic_info.num_irqs > ARRAY_SIZE(aplic.regs->sourcecfg) ) aplic_info.num_irqs =3D ARRAY_SIZE(aplic.regs->sourcecfg); =20 diff --git a/xen/arch/riscv/include/asm/aplic.h b/xen/arch/riscv/include/as= m/aplic.h index 31264e2e683a..5a1ab85353e1 100644 --- a/xen/arch/riscv/include/asm/aplic.h +++ b/xen/arch/riscv/include/asm/aplic.h @@ -29,6 +29,14 @@ =20 #define APLIC_TARGET_HART_IDX_SHIFT 18 =20 +#define APLIC_IDC_SIZE 32 + +#define APLIC_MIN_SIZE 0x4000 +#define APLIC_SIZE_ALIGN(x) ROUNDUP(x, APLIC_MIN_SIZE) + +#define APLIC_SIZE(nr_cpus) (APLIC_MIN_SIZE + \ + APLIC_SIZE_ALIGN(APLIC_IDC_SIZE * (nr_cpu= s))) + struct aplic_regs { uint32_t domaincfg; /* 0x0000 */ uint32_t sourcecfg[1023]; /* 0x0004 */ diff --git a/xen/arch/riscv/include/asm/guest-layout.h b/xen/arch/riscv/inc= lude/asm/guest-layout.h index 5e566450bdfa..90603f06bb91 100644 --- a/xen/arch/riscv/include/asm/guest-layout.h +++ b/xen/arch/riscv/include/asm/guest-layout.h @@ -3,6 +3,12 @@ =20 #include =20 +/* + * Base address of the guest's supervisor-mode APLIC. The value is the add= ress + * typically used for APLIC by QEMU. + */ +#define GUEST_APLIC_S_BASE _UL(0xd000000) + /* * Base address of the guest's supervisor-mode IMSIC. The value is the add= ress * typically used for IMSIC by QEMU. diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c index 6562b25f0abb..719c439e48d9 100644 --- a/xen/arch/riscv/vaplic.c +++ b/xen/arch/riscv/vaplic.c @@ -9,6 +9,8 @@ */ =20 #include +#include +#include #include #include =20 @@ -19,6 +21,12 @@ =20 #include "aplic-priv.h" =20 +unsigned int __ro_after_init guest_num_sources; + +#define VAPLIC_COMPATIBLE "riscv,aplic" + +#define FDT_VAPLIC_INT_CELLS 2 + static int cf_check vaplic_init(struct vcpu *v) { return vcpu_imsic_init(v); @@ -29,6 +37,74 @@ static void cf_check vaplic_deinit(struct vcpu *v) return vcpu_imsic_deinit(v); } =20 +static int __init cf_check vaplic_make_domu_dt_node(struct kernel_info *ki= nfo) +{ + struct domain *d =3D kinfo->bd.d; + int res; + void *fdt =3D kinfo->fdt; + unsigned int msi_parent_phandle; + char vaplic_name[32]; + unsigned int aplic_size =3D APLIC_SIZE(d->max_vcpus); + const __be32 reg[] =3D { + cpu_to_be32(GUEST_APLIC_S_BASE >> 32), + cpu_to_be32(GUEST_APLIC_S_BASE), + cpu_to_be32(0), + cpu_to_be32(aplic_size), + }; + + BUILD_BUG_ON(APLIC_SIZE(MAX_VIRT_CPUS) > UINT_MAX); + + res =3D snprintf(vaplic_name, sizeof(vaplic_name), "/soc/aplic@%lx", + GUEST_APLIC_S_BASE); + if ( res >=3D sizeof(vaplic_name) ) + { + dprintk(XENLOG_DEBUG, "vaplic name is truncated\n"); + return -ENOBUFS; + } + + res =3D vimsic_make_domu_dt_node(kinfo, &msi_parent_phandle); + if ( res ) + return res; + + res =3D fdt_begin_node(fdt, vaplic_name); + if ( res ) + return res; + + res =3D fdt_property_cell(fdt, "#interrupt-cells", FDT_VAPLIC_INT_CELL= S); + if ( res ) + return res; + + res =3D fdt_property(fdt, "reg", reg, sizeof(reg)); + if ( res ) + return res; + + res =3D fdt_property_cell(fdt, "riscv,num-sources", guest_num_sources); + if ( res ) + return res; + + res =3D fdt_property(fdt, "interrupt-controller", NULL, 0); + if ( res ) + return res; + + res =3D fdt_property_string(fdt, "compatible", VAPLIC_COMPATIBLE); + if ( res ) + return res; + + res =3D fdt_property_cell(fdt, "msi-parent", msi_parent_phandle); + if ( res ) + return res; + + res =3D fdt_property_cell(fdt, "phandle", kinfo->phandle_intc); + if ( res ) + return res; + + return fdt_end_node(fdt); +} + +static const struct vintc_init_ops __initconstrel init_ops =3D { + .make_domu_dt_node =3D vaplic_make_domu_dt_node, +}; + static const struct vintc_ops vintc_ops =3D { .vcpu_init =3D vaplic_init, .vcpu_deinit =3D vaplic_deinit, @@ -43,6 +119,7 @@ int domain_vaplic_init(struct domain *d) =20 d->arch.vintc =3D &vaplic->vintc; d->arch.vintc->ops =3D &vintc_ops; + d->arch.vintc->init_ops =3D &init_ops; =20 vaplic->regs.domaincfg =3D APLIC_DOMAINCFG_IE | APLIC_DOMAINCFG_DM | APLIC_DOMAINCFG_RO; --=20 2.54.0