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

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


  • To: Julien Grall <julien@xxxxxxx>
  • From: Rahul Singh <Rahul.Singh@xxxxxxx>
  • Date: Fri, 2 Sep 2022 15:07:50 +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=Y8kAxI9yYXnG9M/rGlqs/+IrCPTUSvtUMwzDZT9EbMM=; b=OO07l2JySI0vocipTzYQhn8s5MD6rroUp0gC5Tdkw3vTw4JA3K354aBTj6rO0em6Q8kdt2DDTIqUGv1sB1EVFQfjsNawf4NBqizN31qapA+In5BORZlg9mpWTGWqYXnu83W3Jmu85x19ThvUoO0ISdrmQrNDZP8fDRzZrpBzIR1j0mM8n52JWDew7ICFmUZPCikuf0pTgrcQL8JOak6GH67/aYidw19Fp8LvZAbZoNCP3HHHv8DVn3AbF87II7nX4Rwc7w/gqdm96eP8Km9kq+n0bk/3762VYOb3KGsv/zrrLnvuyyaa1Uf9Ku1ugkSV7SITjF9OXTqE6cTvHOrpSw==
  • 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=Y8kAxI9yYXnG9M/rGlqs/+IrCPTUSvtUMwzDZT9EbMM=; b=Xgpc9oJvqesHV1Y4G7S0UDu/A/EZ9k7stQyDWdPF8YMOgGW5z/mol7a5QNhioBlZWViSH3gb6tsEEX8QHkikKiTFHLgDSbaQLsOs+NI2omI0m5CBwC0qpm2EUI6/YpAe34DIPFDbIHnz/Zk9EQ6+LKxbcJe7WjlIe1Xm0AhrVTLq0hIYk43F3tvpbYfueu9m+ui5gXip03O16ZKbFgClgZYTbq7n03MbadDHPkIhVFxBAMDY8uej1fC60XEyQJ5jFHvuYjzzwMTavlkeGtPOo1RWI6xbU0qnmgtXAK+NUuJ3R8Nf9NtugRfwCdcSx9Mn+o4DRCx3//eBlcIaToF6tg==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=g496igFT6X0p70NDgdUFejH/bOTTg44oArLKJ7SbLXmr+us3zcH+HSEbT028EtHg8DsR0Ewc6rxwh9lL3KVMuXxgX7L8Eg35nTaaqKW9OxgYWP5sr+4IxGFEygCaZ5zXEhr9SiXS4vyayV1VT712WpDt74FyNUKAeg8LgqmdqX79bPsiS1Q1uaqWL2REFZEbHFrYQalU+Ibp95zIZnZ0GkVdZNI14FgoxR4CdDVLqTaCOnqkWNDwzPmXjLRcrqKClKcnHajx6X3oRqBPhyncT4MQRGar9uyp09AwySUi1AQSB2JU+ipQVlg+aq2EHEUDR1RtSCpH2ExTiv7/+KPfcA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=L/MFkneOz2I1K9UDPGNzALTnWMrfeZ6P8kZXILj3zmgTFOZKOBIJlr92rfrU4wotn88eSeY0yo8HfhCnaPwKK0WrQblGXX1907IRPw4IKe5vsqJ3XeWn90rbkx0VpC2phnclI3JpNwZYy1Fp7Pmso+gc35rIXqEqu52GBpDy7oCkn3DC3Mi3+tQvurKRZN4P0xhk+wIQiN7tONLLwcuuV4fcYfEbb73Xeq1o1SLKbhpv5cOlbofpoL5INem5WFpCA2M4IEszHFbll+KxNbSD/E+dFc3kpNymBnzHrd7DGQK8CY9gzhWMDfSCgFKJeLcnqo3CvffnNru2bfJij9XC+Q==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Fri, 02 Sep 2022 15:08:12 +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: AQHYveNwxlXXcvK6NkiecVIaY62Ipq3K34wAgAFgNQA=
  • Thread-topic: [PATCH v3 6/7] xen/arm: introduce xen-evtchn dom0less property

Hi Julien,

> On 1 Sep 2022, at 7:07 pm, Julien Grall <julien@xxxxxxx> wrote:
> 
> Hi Rahul,
> 
> On 01/09/2022 10:13, 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 v3:
>>  - use device-tree used_by to find the domain id of the evtchn node.
>>  - add new static_evtchn_create variable in struct dt_device_node to
>>    hold the information if evtchn is already created.
>>  - fix minor comments
>> Changes in v2:
>>  - no change
>> ---
>>  docs/misc/arm/device-tree/booting.txt |  64 ++++++++++++-
>>  xen/arch/arm/domain_build.c           | 128 ++++++++++++++++++++++++++
>>  xen/arch/arm/include/asm/setup.h      |   1 +
>>  xen/arch/arm/setup.c                  |   2 +
>>  xen/include/xen/device_tree.h         |  13 +++
>>  5 files changed, 207 insertions(+), 1 deletion(-)
>> diff --git a/docs/misc/arm/device-tree/booting.txt 
>> b/docs/misc/arm/device-tree/booting.txt
>> index 98253414b8..edef98e6d1 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,44 @@ 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 IDs.
>> +
>> +    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 = "...";
>> +
>> +    };
> 
> NIT: Describing this node in the example seems unnecessary.

Ack. I will remove this.
> 
>> +
>> +    /* one sub-node per local event channel */
>> +    ec1: evtchn@1 {
>> +         compatible = "xen,evtchn-v1";
>> +         /* local-evtchn link-to-foreign-evtchn */
>> +         xen,evtchn = <0xa &ec2>;
>> +    };
>> +
> 
> Here you provide an example for dom0. But the position where you describe the 
> binding suggests this binding only exists for domUs.
> 
> Either we duplicate the binding or we re-order the documentation to have 
> common binding in a single place. My preference would be the latter.
> 

Ack. 
>>      domU1 {
>>          compatible = "xen,domain";
>>          #address-cells = <0x2>;
>> @@ -277,6 +310,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 +346,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 707e247f6a..4b24261825 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -33,6 +33,8 @@
>>  #include <xen/grant_table.h>
>>  #include <xen/serial.h>
>>  +#define STATIC_EVTCHN_NODE_SIZE_CELLS 2
>> +
>>  static unsigned int __initdata opt_dom0_max_vcpus;
>>  integer_param("dom0_max_vcpus", opt_dom0_max_vcpus);
>>  @@ -3052,6 +3054,131 @@ void __init evtchn_allocate(struct domain *d)
>>      d->arch.hvm.params[HVM_PARAM_CALLBACK_IRQ] = val;
>>  }
>>  +static int __init get_evtchn_dt_property(const struct dt_device_node *np,
>> +                                         uint32_t *port, uint32_t *phandle)
>> +{
>> +    const __be32 *prop = NULL;
>> +    uint32_t len;
>> +
>> +    prop = dt_get_property(np, "xen,evtchn", &len);
>> +    if ( !prop )
>> +    {
>> +        printk(XENLOG_ERR "xen,evtchn property should not be empty.\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    if ( !len || len < dt_cells_to_size(STATIC_EVTCHN_NODE_SIZE_CELLS) )
>> +    {
>> +        printk(XENLOG_ERR "xen,evtchn property value is not valid.\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    *port = dt_next_cell(1, &prop);
>> +    *phandle = dt_next_cell(1, &prop);
>> +
>> +    return 0;
>> +}
>> +
>> +static int __init alloc_domain_evtchn(struct dt_device_node *node)
>> +{
>> +    int rc;
>> +    uint32_t domU1_port, domU2_port, remote_phandle;
>> +    struct dt_device_node *remote_node;
>> +    struct evtchn_alloc_unbound alloc_unbound;
>> +    struct evtchn_bind_interdomain bind_interdomain;
>> +    struct domain *d1 = NULL, *d2 = NULL;
>> +
>> +    if ( dt_device_static_evtchn_created(node) )
> 
> I think this deserve a comment explain why the node would be created. I.e it 
> would happen if the other side was created first. I will comment about 
> dt_device_static_evtchn_created() futher down.

I will modify as below:

 /*                                                                          
  * Event channel is already created while parsing the other side of         
  * evtchn node.                                                             
  */                                                                         
   if ( dt_device_static_evtchn_created(node) )                                
       return 0;
> 
>> +        return 0;
>> +
>> +    rc = get_evtchn_dt_property(node, &domU1_port, &remote_phandle);
>> +    if ( rc )
>> +        return rc;
>> +
>> +    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;
>> +    }
>> +
>> +    rc = get_evtchn_dt_property(remote_node, &domU2_port, &remote_phandle);
>> +    if ( rc )
>> +        return rc;
>> +
>> +    if ( node->phandle != remote_phandle )
>> +    {
>> +        printk(XENLOG_ERR "xen,evtchn property is not setup correctly.\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    d1 = get_domain_by_id(dt_get_parent(node)->used_by);
>> +    d2 = get_domain_by_id(dt_get_parent(remote_node)->used_by);
> 
> I think dt_get_parent() could return NULL (i.e. for the root). So I think you 
> want to check that at least remote_node() has a parent. For convenience, this 
> check could be done in

Ack. 
> 
>> +
>> +    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 )
>> +    {
>> +        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 )
>> +    {
>> +        printk(XENLOG_ERR
>> +                "evtchn_bind_interdomain() failure (Error %d) \n", rc);
>> +        return rc;
>> +    }
>> +
>> +    dt_device_set_static_evtchn_created(node);
>> +    dt_device_set_static_evtchn_created(remote_node);
>> +
>> +    return 0;
>> +}
>> +
>> +void __init process_static_evtchn_node(struct dt_device_node *node)
> 
> This is missing a prototype. So I guess this wants to be static?
> 
> That said, I think it would make more sense to fold 
> process_static_evtchn_node() in alloc_domain_evtchn() or 
> alloc_static-evtchn().

Ack. 
> 
>> +{
>> +    if ( dt_device_is_compatible(node, "xen,evtchn-v1") )
>> +    {
>> +        if ( alloc_domain_evtchn(node) != 0 )
>> +            panic("Could not set up domains evtchn\n");
>> +    }
>> +}
>> +
>> +void __init alloc_static_evtchn(void)
>> +{
>> +    struct dt_device_node *node, *evtchn_node;
>> +    struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
>> +
>> +    BUG_ON(chosen == NULL);
>> +
>> +    if ( hardware_domain )
>> +        dt_device_set_used_by(chosen, hardware_domain->domain_id);
>> +
>> +    dt_for_each_child_node(chosen, node)
>> +    {
>> +        if ( hardware_domain )
>> +            process_static_evtchn_node(node);
>> +
>> +        dt_for_each_child_node(node, evtchn_node)
>> +            process_static_evtchn_node(evtchn_node);
>> +    }
>> +}
>> +
>>  static void __init find_gnttab_region(struct domain *d,
>>                                        struct kernel_info *kinfo)
>>  {
>> @@ -3364,6 +3491,7 @@ void __init create_domUs(void)
>>              panic("Error creating domain %s\n", dt_node_name(node));
>>            d->is_console = true;
>> +        dt_device_set_used_by(node, d->domain_id);
>>            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/setup.h 
>> b/xen/arch/arm/include/asm/setup.h
>> index 5815ccf8c5..5ee28b270f 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_add[]);
>>    void create_domUs(void);
>>  void create_dom0(void);
>> +void alloc_static_evtchn(void);
>>    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 6e0398f3f6..cf15d359d2 100644
>> --- a/xen/arch/arm/setup.c
>> +++ b/xen/arch/arm/setup.c
>> @@ -1077,6 +1077,8 @@ void __init start_xen(unsigned long boot_phys_offset,
>>      if ( acpi_disabled )
>>          create_domUs();
>>  +    alloc_static_evtchn();
>> +
>>      /*
>>       * This needs to be called **before** heap_init_late() so modules
>>       * will be scrubbed (unless suppressed).
>> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
>> index 430a1ef445..5579c875d2 100644
>> --- a/xen/include/xen/device_tree.h
>> +++ b/xen/include/xen/device_tree.h
>> @@ -82,6 +82,7 @@ struct dt_device_node {
>>      dt_phandle phandle;
>>      char *full_name;
>>      domid_t used_by; /* By default it's used by dom0 */
>> +    bool_t static_evtchn_created;
> 
> I can see why you want to add the boolean in dt_device_node. However, I 
> dislike this approach because this feels an abuse of dt_device_node and the 
> field is only used at boot.
> 
> So this seems to be a bit of a waste to include it in the structure (even if 
> we are re-using padding today).
> 
> I don't have a solution that is has trivial as this approach. However, at 
> minimum we should document this is a HACK and should be remove if we need 
> space in the structure.
 
Ok. I will add the comment that this is HACK.

….
     /* IOMMU specific fields */
     bool is_protected;
+
+    /* HACK: Remove this if there is a need of space */
+    bool_t static_evtchn_created;
+
     /*
      * The main purpose of this list is to link the structure in the list
      * of devices assigned to domain.
….

Regards,
Rahul

 


Rackspace

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