From nobody Mon Feb 9 14:37:04 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1660903610163192.36237471013033; Fri, 19 Aug 2022 03:06:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.390217.627542 (Exim 4.92) (envelope-from ) id 1oOytL-0002sD-00; Fri, 19 Aug 2022 10:06:15 +0000 Received: by outflank-mailman (output) from mailman id 390217.627542; Fri, 19 Aug 2022 10:06:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oOytK-0002s6-SB; Fri, 19 Aug 2022 10:06:14 +0000 Received: by outflank-mailman (input) for mailman id 390217; Fri, 19 Aug 2022 10:06:13 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oOytJ-0002G7-EC for xen-devel@lists.xenproject.org; Fri, 19 Aug 2022 10:06:13 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 8d9f2eed-1fa6-11ed-bd2e-47488cf2e6aa; Fri, 19 Aug 2022 12:06:12 +0200 (CEST) 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 3CFF71042; Fri, 19 Aug 2022 03:06:13 -0700 (PDT) Received: from e109506.cambridge.arm.com (e109506.cambridge.arm.com [10.1.199.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 879A43F70D; Fri, 19 Aug 2022 03:06:10 -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" X-Inumbo-ID: 8d9f2eed-1fa6-11ed-bd2e-47488cf2e6aa From: Rahul Singh To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, rahul.singh@arm.com, Stefano Stabellini , Julien Grall , Volodymyr Babchuk Subject: [PATCH v2 6/7] xen: introduce xen-evtchn dom0less property Date: Fri, 19 Aug 2022 11:02:43 +0100 Message-Id: <02993cf398573adf9e9bad62aa8d6e753b2c6ab9.1660902588.git.rahul.singh@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1660903610569100005 Content-Type: text/plain; charset="utf-8" Introduce a new sub-node under /chosen node to establish static event channel communication between domains on dom0less systems. An event channel will be created beforehand to allow the domains to send notifications to each other. Signed-off-by: Rahul Singh --- Changes in v2: - no change --- --- docs/misc/arm/device-tree/booting.txt | 63 +++++++++++- xen/arch/arm/domain_build.c | 136 ++++++++++++++++++++++++++ xen/arch/arm/include/asm/domain.h | 1 + xen/arch/arm/include/asm/setup.h | 1 + xen/arch/arm/setup.c | 2 + 5 files changed, 202 insertions(+), 1 deletion(-) diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-t= ree/booting.txt index 98253414b8..ec7dbcaf8f 100644 --- a/docs/misc/arm/device-tree/booting.txt +++ b/docs/misc/arm/device-tree/booting.txt @@ -212,7 +212,7 @@ with the following properties: enable only selected interfaces. =20 Under the "xen,domain" compatible node, one or more sub-nodes are present -for the DomU kernel and ramdisk. +for the DomU kernel, ramdisk and static event channel. =20 The kernel sub-node has the following properties: =20 @@ -254,11 +254,43 @@ The ramdisk sub-node has the following properties: property because it will be created by the UEFI stub on boot. This option is needed only when UEFI boot is used. =20 +The static event channel sub-node has the following properties: + +- compatible + + "xen,evtchn" + +- xen,evtchn + + The property is tuples of two numbers + (local-evtchn link-to-foreign-evtchn) where: + + local-evtchn is an integer value that will be used to allocate local p= ort + for a domain to send and receive event notifications to/from the remote + domain. Maximum supported value is 2^17 for FIFO ABI and 4096 for 2L A= BI. + It is recommended to use low event channel ID. + + link-to-foreign-evtchn is a single phandle to a remote evtchn to which + local-evtchn will be connected. =20 Example =3D=3D=3D=3D=3D=3D=3D =20 chosen { + + module@0 { + compatible =3D "multiboot,kernel", "multiboot,module"; + xen,uefi-binary =3D "..."; + bootargs =3D "..."; + + /* one sub-node per local event channel */ + ec1: evtchn@1 { + compatible =3D "xen,evtchn-v1"; + /* local-evtchn link-to-foreign-evtchn */ + xen,evtchn =3D <0xa &ec2>; + }; + }; + domU1 { compatible =3D "xen,domain"; #address-cells =3D <0x2>; @@ -277,6 +309,23 @@ chosen { compatible =3D "multiboot,ramdisk", "multiboot,module"; reg =3D <0x0 0x4b000000 0xffffff>; }; + + /* one sub-node per local event channel */ + ec2: evtchn@2 { + compatible =3D "xen,evtchn-v1"; + /* local-evtchn link-to-foreign-evtchn */ + xen,evtchn =3D <0xa &ec1>; + }; + + ec3: evtchn@3 { + compatible =3D "xen,evtchn-v1"; + xen,evtchn =3D <0xb &ec5>; + }; + + ec4: evtchn@4 { + compatible =3D "xen,evtchn-v1"; + xen,evtchn =3D <0xc &ec6>; + }; }; =20 domU2 { @@ -296,6 +345,18 @@ chosen { compatible =3D "multiboot,ramdisk", "multiboot,module"; reg =3D <0x0 0x4d000000 0xffffff>; }; + + /* one sub-node per local event channel */ + ec5: evtchn@5 { + compatible =3D "xen,evtchn-v1"; + /* local-evtchn link-to-foreign-evtchn */ + xen,evtchn =3D <0xb &ec3>; + }; + + ec6: evtchn@6 { + compatible =3D "xen,evtchn-v1"; + xen,evtchn =3D <0xd &ec4>; + }; }; }; =20 diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 11a8c6b8b5..5101bca979 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -3052,6 +3052,141 @@ void __init evtchn_allocate(struct domain *d) d->arch.hvm.params[HVM_PARAM_CALLBACK_IRQ] =3D val; } =20 +static const void *__init get_evtchn_dt_property( + const struct dt_device_node *np) +{ + const void *prop =3D NULL; + uint32_t len; + + prop =3D dt_get_property(np, "xen,evtchn", &len); + if ( !prop ) + return NULL; + + if ( !len ) + { + printk(XENLOG_ERR "xen,evtchn property cannot be empty.\n"); + return ERR_PTR(-EINVAL); + } + + return prop; +} + +static int __init allocate_domain_evtchn(const struct dt_device_node *node) +{ + const void *prop =3D NULL; + const __be32 *cell; + uint32_t domU1_port, domU2_port, remote_phandle; + const struct dt_device_node *evtchn_node, *remote_node; + struct evtchn_alloc_unbound alloc_unbound; + struct evtchn_bind_interdomain bind_interdomain; + int rc; + + dt_for_each_child_node(node, evtchn_node) + { + struct domain *d, *d1 =3D NULL, *d2 =3D NULL; + + if ( !dt_device_is_compatible(evtchn_node, "xen,evtchn-v1") ) + continue; + + prop =3D get_evtchn_dt_property(evtchn_node); + /* If the property is not found, return without errors */ + if ( !prop || IS_ERR(prop) ) + return IS_ERR(prop) ? PTR_ERR(prop) : 0; + + cell =3D (const __be32 *)prop; + domU1_port =3D dt_next_cell(1, &cell); + remote_phandle =3D dt_next_cell(1, &cell); + + remote_node =3D dt_find_node_by_phandle(remote_phandle); + if ( !remote_node ) + { + printk(XENLOG_ERR + "evtchn: could not find remote evtchn phandle\n"); + return -EINVAL; + } + + prop =3D get_evtchn_dt_property(remote_node); + /* If the property is not found, return without errors */ + if ( !prop || IS_ERR(prop) ) + return IS_ERR(prop) ? PTR_ERR(prop) : 0; + + cell =3D (const __be32 *)prop; + domU2_port =3D dt_next_cell(1, &cell); + remote_phandle =3D dt_next_cell(1, &cell); + + if ( evtchn_node->phandle !=3D remote_phandle ) + { + printk(XENLOG_ERR "xen,evtchn property is not setup correctly.= \n"); + return -EINVAL; + } + + for_each_domain ( d ) + { + if ( d->arch.node =3D=3D node ) + { + d1 =3D d; + continue; + } + if ( d->arch.node =3D=3D dt_get_parent(remote_node) ) + d2 =3D d; + } + + if ( !d1 && dt_device_is_compatible(node, "multiboot,kernel") ) + d1 =3D hardware_domain; + + if ( !d2 && dt_device_is_compatible(dt_get_parent(remote_node), + "multiboot,kernel") ) + d2 =3D hardware_domain; + + if ( !d1 || !d2 ) + { + printk(XENLOG_ERR "evtchn: could not find domains\n" ); + return -EINVAL; + } + + alloc_unbound.dom =3D d1->domain_id; + alloc_unbound.remote_dom =3D d2->domain_id; + + rc =3D evtchn_alloc_unbound(&alloc_unbound, domU1_port); + if ( rc < 0 && rc !=3D -EBUSY ) + { + printk(XENLOG_ERR + "evtchn_alloc_unbound() failure (Error %d) \n", rc); + return rc; + } + + bind_interdomain.remote_dom =3D d1->domain_id; + bind_interdomain.remote_port =3D domU1_port; + + rc =3D evtchn_bind_interdomain(&bind_interdomain, d2, domU2_port); + if ( rc < 0 && rc !=3D -EBUSY ) + { + printk(XENLOG_ERR + "evtchn_bind_interdomain() failure (Error %d) \n", rc); + return rc; + } + } + + return 0; +} + +void __init allocate_static_evtchn(void) +{ + struct dt_device_node *node; + const struct dt_device_node *chosen =3D dt_find_node_by_path("/chosen"= ); + + BUG_ON(chosen =3D=3D NULL); + dt_for_each_child_node(chosen, node) + { + if ( dt_device_is_compatible(node, "xen,domain") || + dt_device_is_compatible(node, "multiboot,kernel") ) + { + if ( allocate_domain_evtchn(node) !=3D 0 ) + panic("Could not set up domains evtchn\n"); + } + } +} + static void __init find_gnttab_region(struct domain *d, struct kernel_info *kinfo) { @@ -3358,6 +3493,7 @@ void __init create_domUs(void) panic("Error creating domain %s\n", dt_node_name(node)); =20 d->is_console =3D true; + d->arch.node =3D node; =20 if ( construct_domU(d, node) !=3D 0 ) panic("Could not set up domain %s\n", dt_node_name(node)); diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/d= omain.h index cd9ce19b4b..51192b28ee 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -105,6 +105,7 @@ struct arch_domain #endif =20 bool directmap; + struct dt_device_node *node; } __cacheline_aligned; =20 struct arch_vcpu diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/se= tup.h index 2bb01ecfa8..bac876e68e 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -106,6 +106,7 @@ int acpi_make_efi_nodes(void *fdt, struct membank tbl_a= dd[]); =20 void create_domUs(void); void create_dom0(void); +void allocate_static_evtchn(void); =20 void discard_initial_modules(void); void fw_unreserved_regions(paddr_t s, paddr_t e, diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 500307edc0..8eead619ae 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -1063,6 +1063,8 @@ void __init start_xen(unsigned long boot_phys_offset, if ( acpi_disabled ) create_domUs(); =20 + allocate_static_evtchn(); + /* * This needs to be called **before** heap_init_late() so modules * will be scrubbed (unless suppressed). --=20 2.25.1