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

Re: [PATCH v2 6/7] xen: introduce xen-evtchn dom0less property


  • To: Julien Grall <julien@xxxxxxx>
  • From: Rahul Singh <Rahul.Singh@xxxxxxx>
  • Date: Wed, 24 Aug 2022 14:52:07 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=fkIUcqbjCVYCOAy3IWm5Zxq0DUuSXQLG5q/JJnWDQek=; b=hxvXghiG19KlUIxbzXm7vgN0bJBLy44ydtTjT7nWj3SVhWmnjWYDSXc0A6Hyj5MW0atQ7yojkwaVGtGbTwY8gRArNmkWuYsWP1gs/VZtgJ0YyqLxr8kLz7PdF/dYeB/m7dSUwa8bHTlS/EZoaxFKpz88FlDjnnfzki6fKouw4OSlMuUTDBggTpPU6dFnKdvBC2U+rL9dgZTJzckLOg+EOEioa0+LZV+nbg0RVuI2xflxxFORUq6Ry3yAWrG9mL8ckLnWwRaGuJUHrnFglVzsHVwj4Wk37blYdffBQA9mdla670Q1ZVBECJjKgI1F/MSAxpKHi1VVv5mq2PiQJU0foQ==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=fkIUcqbjCVYCOAy3IWm5Zxq0DUuSXQLG5q/JJnWDQek=; b=QxFzAY/bx/CpaGxCAZJ3rPbn3wL/sjkHqk4iB/aVYBjRnyjkRVpKZuWDbU0W6TbtNajQ4QmrsD8bJqX+f04nIiP4GEYenh989cujFNr0wkh5G0oelP2KeBcV3RwrU6dKLv4t7ye5yA/arwo2pBxnTG/rzQpsUDQj3CE3gSMTKr6soL+/5nmhHVECPwv9EHtl5ZJs91wxYq7F2lKGCQMYJTMgDG2kUulxE5RaA+1mkALR2sWvSMyH9ZURx9b8AvTYxbuNT1I+XeHOMHUUs2acJCvbDe0XRCetkuu5mXG4ERhYDovDh8NzAVK4VB//O9f9Ij4eT0mFHD5LkSMdjgzRSQ==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=eUzTYZjzLNdK69KA3irg9qAvUheINscadPK7dosoPpTt6JjKOJXfKiEOly761TRe87um7R9v1hod0Qeimv978ZIDXNmWTTvZ+XFGr4DuA9I0q930SEIsx7wgdCrD2C3e1x1AaqnNt2TyG1cpfFUk+7hWMSfU5E7JVg464Fqs/DDuZ5jKOt1LpV+YoAORAS8hShJxBNur0L5kqlP58xSEQu8M7Ex5CUPPptUF3fZ3sjwW7Tnc9fVEAVv1Bz1uzJTZf9Gr81dPW8lzgcFnY6rL+jHfRVm05QhbzfGG6g8v2Fl78DSW6sSvSRO4ZVsRKRGLnhyq2cnNANqiQaHswsMDoA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FNkrQ68juaByQo6Mb6X291EZ80eSgLuay1DURc6PA6v3MGnUv6qnFOuRk5vmAaR9aPT17nNib1+5IUV5rbjewLTiTsw1EwJzp4b5I1sIwSXEGUJZwPuWBZDvjm+Uc7cJrmSbC3eLKI0XJd26JrJHIMJWmwGw60uLNWlbeBjYu0rl7j8XuejUmH6C81TDcjC5XjYsrf3xr22GHp+VmCsfVbYsKbIn/N5eNHbPnKTgGnBCemk0I+wNmIL3YDbbELYWZH4F7lyjgOB3aR8LXcoNKs9VTusx6S3fnSgzlCuJo0zRoqaZZYmgPQ0JMLj5ovbOW8iNmwdKBI75afd2CYIdIQ==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Wed, 24 Aug 2022 14:52:37 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHYs7NW3+Fahvka9EWQJqDFDZ/aKq28Pz0AgAHrhYA=
  • Thread-topic: [PATCH v2 6/7] xen: introduce xen-evtchn dom0less property

Hi Julien,

> On 23 Aug 2022, at 10:32 am, Julien Grall <julien@xxxxxxx> wrote:
> 
> Hi Rahul,
> 
> On 19/08/2022 11:02, Rahul Singh wrote:
>> 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 <rahul.singh@xxxxxxx>
>> ---
>> 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-tree/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.
>>    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.
>>    The kernel sub-node has the following properties:
>>  @@ -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.
>>  +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 
>> port
>> +    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 
>> ABI.
>> +    It is recommended to use low event channel ID.
> 
> I think you are either missing a 'a' or 'ID' should be 'IDs'

Ack. 
> 
>> +
>> +    link-to-foreign-evtchn is a single phandle to a remote evtchn to which
>> +    local-evtchn will be connected.
>>    Example
>>  =======
>>    chosen {
>> +
>> +    module@0 {
>> +        compatible = "multiboot,kernel", "multiboot,module";
>> +        xen,uefi-binary = "...";
>> +        bootargs = "...";
>> +
>> +        /* one sub-node per local event channel */
>> +        ec1: evtchn@1 {
>> +            compatible = "xen,evtchn-v1";
>> +            /* local-evtchn link-to-foreign-evtchn */
>> +            xen,evtchn = <0xa &ec2>;
>> +        };
> 
> AFAIU, this is meant to describe the static event channels for dom0. I can't 
> find the documentation for it. Do they always need to be a subnode the node 
> "multiboot,kernel"?
> 
> The reason I am asking is it feels strange to define them below that subnode 
> when for domUs, both nodes have the same parent. So I think it would make 
> more sense to define them in chosen.

Ok. I will move the dom0 evtchn node under chosen done.
> 
>> +    };
>> +
>>      domU1 {
>>          compatible = "xen,domain";
>>          #address-cells = <0x2>;
>> @@ -277,6 +309,23 @@ chosen {
>>              compatible = "multiboot,ramdisk", "multiboot,module";
>>              reg = <0x0 0x4b000000 0xffffff>;
>>          };
>> +
>> +        /* one sub-node per local event channel */
>> +        ec2: evtchn@2 {
>> +            compatible = "xen,evtchn-v1";
>> +            /* local-evtchn link-to-foreign-evtchn */
>> +            xen,evtchn = <0xa &ec1>;
>> +        };
>> +
>> +        ec3: evtchn@3 {
>> +            compatible = "xen,evtchn-v1";
>> +            xen,evtchn = <0xb &ec5>;
>> +        };
>> +
>> +        ec4: evtchn@4 {
>> +            compatible = "xen,evtchn-v1";
>> +            xen,evtchn = <0xc &ec6>;
>> +        };
>>      };
>>        domU2 {
>> @@ -296,6 +345,18 @@ chosen {
>>              compatible = "multiboot,ramdisk", "multiboot,module";
>>              reg = <0x0 0x4d000000 0xffffff>;
>>          };
>> +
>> +        /* one sub-node per local event channel */
>> +        ec5: evtchn@5 {
>> +            compatible = "xen,evtchn-v1";
>> +            /* local-evtchn link-to-foreign-evtchn */
>> +            xen,evtchn = <0xb &ec3>;
>> +        };
>> +
>> +        ec6: evtchn@6 {
>> +            compatible = "xen,evtchn-v1";
>> +            xen,evtchn = <0xd &ec4>;
>> +        };
>>      };
>>  };
>>  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] = val;
>>  }
>>  +static const void *__init get_evtchn_dt_property(
>> +        const struct dt_device_node *np)
>> +{
>> +    const void *prop = NULL;
>> +    uint32_t len;
>> +
>> +    prop = dt_get_property(np, "xen,evtchn", &len);
>> +    if ( !prop )
>> +        return NULL;
>> +
>> +    if ( !len )
>> +    {
>> +        printk(XENLOG_ERR "xen,evtchn property cannot be empty.\n")
> 
> Looking at the callers, they all assume that there is enough cells in the 
> property. So I think you should check the size as well.

Ack, 
> 
>> +        return ERR_PTR(-EINVAL);
>> +    }
>> +
>> +    return prop;
>> +}
>> +
>> +static int __init allocate_domain_evtchn(const struct dt_device_node *node)
>> +{
>> +    const void *prop = 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 = NULL, *d2 = NULL;
>> +
>> +        if ( !dt_device_is_compatible(evtchn_node, "xen,evtchn-v1") )
>> +            continue;
>> +
>> +        prop = get_evtchn_dt_property(evtchn_node);
>> +        /* If the property is not found, return without errors */
> 
> From the binding description, the property is not optional. So do we want to 
> ignore the error? If you treat it as an error, then ...

Ok. I will treat it as en error.
> 
>> +        if ( !prop || IS_ERR(prop) )
>> +            return IS_ERR(prop) ? PTR_ERR(prop) : 0;
> 
> ... you could return ERR_PTR(-ENOMEM) instead of NULL and then simplify this 
> code with:

Ack. 
> 
>> +
>> +        cell = (const __be32 *)prop;
> 
> prop is a void pointer. So the cast is unnecessary.

Ack. 
> 
>> +        domU1_port = dt_next_cell(1, &cell);
>> +        remote_phandle = dt_next_cell(1, &cell);
> The code is also duplicated below for the remote port. I think it would be 
> better if this is part of your helper get_evtchn_dt_property().

Ack .
> 
>> +
>> +        remote_node = dt_find_node_by_phandle(remote_phandle);
>> +        if ( !remote_node )
>> +        {
>> +            printk(XENLOG_ERR
>> +                   "evtchn: could not find remote evtchn phandle\n");
>> +            return -EINVAL;
>> +        }
>> +
>> +        prop = 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 = (const __be32 *)prop;
>> +        domU2_port = dt_next_cell(1, &cell);
>> +        remote_phandle = dt_next_cell(1, &cell);
>> +
>> +        if ( evtchn_node->phandle != remote_phandle )
>> +        {
>> +            printk(XENLOG_ERR "xen,evtchn property is not setup 
>> correctly.\n");
>> +            return -EINVAL;
>> +        }
>> +
>> +        for_each_domain ( d )
>> +        {
>> +            if ( d->arch.node == node )
>> +            {
>> +                d1 = d;
>> +                continue;
>> +            }
>> +            if ( d->arch.node == dt_get_parent(remote_node) )
>> +                d2 = d;
>> +        }
> 
> The loop could be avoided if you stash the domid in the field 'used_by' of 
> the device-tree node when the domain is created.

Ok. I will used the “used_by” to store the domid.
> 
>> +
>> +        if ( !d1 && dt_device_is_compatible(node, "multiboot,kernel") )
>> +            d1 = hardware_domain;
>> +
>> +        if ( !d2 && dt_device_is_compatible(dt_get_parent(remote_node),
>> +                                            "multiboot,kernel") )
>> +            d2 = hardware_domain;
> 
> Any particular reason to handle the hardware domain differently?

As I have not set the "d->arch.node” for hwdom that why there is differently 
handling for hwdom.
I will try to use the “used_by” and will avoid this handling.

> 
>> +
>> +        if ( !d1 || !d2 )
>> +        {
>> +            printk(XENLOG_ERR "evtchn: could not find domains\n" );
>> +            return -EINVAL;
>> +        }
>> +
>> +        alloc_unbound.dom = d1->domain_id;
>> +        alloc_unbound.remote_dom = d2->domain_id;
>> +
>> +        rc = evtchn_alloc_unbound(&alloc_unbound, domU1_port);
>> +        if ( rc < 0 && rc != -EBUSY )
> 
> Please explain in a comment why you want to handle -EBUSY differently.

-EBUSY is used to check if evtchn is not already created while we scanning
the evtchn dt nodes.

> 
>> +        {
>> +            printk(XENLOG_ERR
>> +                   "evtchn_alloc_unbound() failure (Error %d) \n", rc);
>> +            return rc;
>> +        }
>> +
>> +        bind_interdomain.remote_dom  = d1->domain_id;
>> +        bind_interdomain.remote_port = domU1_port;
>> +
>> +        rc = evtchn_bind_interdomain(&bind_interdomain, d2, domU2_port);
>> +        if ( rc < 0 && rc != -EBUSY )
> 
> AFAIU, EBUSY only tells you the port is been used. It doesn't tell you the 
> link is the same. So I think you want to also confirm that to avoid to 
> continuing with the wrong setup.

Ack. 
> 
>> +        {
>> +            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;
> 
> AFAICT, all the users below can deal with constisfied node. So I think you 
> want to add 'const' here.

Ack.
> 
>> +    const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
>> +
>> +    BUG_ON(chosen == 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) != 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));
>>            d->is_console = true;
>> +        d->arch.node = node;
> 
> If you follow my suggestion above, this should not be necessary. However, if 
> this is still needed for some reason, then I think we should also set 
> d->arch.node for the Hardware Domain and ...

Ack. 
> 
>>            if ( construct_domU(d, node) != 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/domain.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
>>        bool directmap;
>> +    struct dt_device_node *node;
> 
> ... this should be const as the node shouldn't be modifiable.

Ack. 

Regards,
Rahul

 


Rackspace

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