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

Re: [Xen-devel] [RFC PATCH v1 02/10] xen/arm: register mmio handler at runtime



Hi,

On Thu, Mar 20, 2014 at 3:18 PM, Julien Grall <julien.grall@xxxxxxxxxx> wrote:
> Hello Vijay,
>
> (Adding Andrii who is working on a similar patch).
>

Thank you for pointing me to this thread. Some time ago I posted the
idea of this solution, but my work with it is a bit postponed now.
Hope to resume it asap.
The reason why I started working with this - is a proper OMAP IOMMU
handling, which needs runtime IO traps for sure.
vgic and vuart as standalone modules do not need this - they need boot
time IO mem configuration only. But if you add OMAP IOMMU (hope I'll
post it asap), you'll need to update vgic and vuart too.

> Thanks you for the patch.
>
> On 03/19/2014 02:17 PM, vijay.kilari@xxxxxxxxx wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
>>
>> mmio handlers are registers at compile time
>> for drivers like vuart and vgic.
>> Make mmio handler registered at runtime by
>> creating linked list of mmio handlers
>>
>> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
>> ---
>>  xen/arch/arm/io.c    |   32 +++++++++++++++++---------
>>  xen/arch/arm/io.h    |   16 +++++--------
>>  xen/arch/arm/vgic.c  |   61 
>> ++++++++++++++++++++++++++------------------------
>>  xen/arch/arm/vuart.c |   39 ++++++++++++++++----------------
>>  4 files changed, 79 insertions(+), 69 deletions(-)
>>
>> diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
>> index a6db00b..d140b29 100644
>> --- a/xen/arch/arm/io.c
>> +++ b/xen/arch/arm/io.c
>> @@ -17,31 +17,41 @@
>>   */
>>
>>  #include <xen/config.h>
>> +#include <xen/init.h>
>> +#include <xen/kernel.h>
>>  #include <xen/lib.h>
>> +#include <xen/spinlock.h>
>>  #include <asm/current.h>
>>
>>  #include "io.h"
>>
>> -static const struct mmio_handler *const mmio_handlers[] =
>> -{
>> -    &vgic_distr_mmio_handler,
>> -    &vuart_mmio_handler,
>> -};
>> -#define MMIO_HANDLER_NR ARRAY_SIZE(mmio_handlers)
>> +LIST_HEAD(handle_head);

static LIST_HEAD

>> +static DEFINE_SPINLOCK(handler_lock);
>
> As you change the code, I would prefer a per domain list IO handler. So
> we can easily handle GICv2 guest on GICv3 host.
>
> This list would only contains handlers that will be effectively used for
> the domain.
>
>>  int handle_mmio(mmio_info_t *info)
>>  {
>>      struct vcpu *v = current;
>> -    int i;
>> +    struct list_head *pos;
>> +    struct mmio_handler *mmio_handle;
>>
>> -    for ( i = 0; i < MMIO_HANDLER_NR; i++ )
>> -        if ( mmio_handlers[i]->check_handler(v, info->gpa) )

Must be locked with irqsave lock.

>> +    list_for_each(pos, &handle_head) {
>> +        mmio_handle = list_entry(pos, struct mmio_handler, handle_list);
>
> You can use list_for_each_entry here.
>

Right. Should be list_for_each_entry

>> +        if ( mmio_handle->check_handler(v, info->gpa) )
>>              return info->dabt.write ?
>> -                mmio_handlers[i]->write_handler(v, info) :
>> -                mmio_handlers[i]->read_handler(v, info);
>> +                mmio_handle->write_handler(v, info) :
>> +                mmio_handle->read_handler(v, info);
>> +    }
>>
>>      return 0;
>>  }
>> +
>> +void register_mmio_handler(struct mmio_handler * handle)
>> +{
>> +    spin_lock(&handler_lock);
>
> Why do you take the lock here and not in handle_mmio?
>

I planned that these functions will be used at runtime and not only
boot time. So spinlocking here is needed for sure. From IOMMU point of
view (which I working with) - this code may be called at any time at
any CPU simultaneously. The only issue here - lock should be irqsave.

>> +    list_add(&handle->handle_list, &handle_head);
>> +    spin_unlock(&handler_lock);
>> +}
>> +
>>  /*
>>   * Local variables:
>>   * mode: C
>> diff --git a/xen/arch/arm/io.h b/xen/arch/arm/io.h
>> index 8d252c0..99cd7c3 100644
>> --- a/xen/arch/arm/io.h
>> +++ b/xen/arch/arm/io.h
>> @@ -22,6 +22,7 @@
>>  #include <xen/lib.h>
>>  #include <asm/processor.h>
>>  #include <asm/regs.h>
>> +#include <xen/list.h>
>>
>>  typedef struct
>>  {
>> @@ -30,20 +31,15 @@ typedef struct
>>      paddr_t gpa;
>>  } mmio_info_t;
>>
>> -typedef int (*mmio_read_t)(struct vcpu *v, mmio_info_t *info);
>> -typedef int (*mmio_write_t)(struct vcpu *v, mmio_info_t *info);
>> -typedef int (*mmio_check_t)(struct vcpu *v, paddr_t addr);
>> -
>
> Why did you remove the typedef? It was useful for the code comprehension.
>
>>  struct mmio_handler {
>> -    mmio_check_t check_handler;
>> -    mmio_read_t read_handler;
>> -    mmio_write_t write_handler;
>> +    int (*read_handler)(struct vcpu *v, mmio_info_t *info);
>> +    int (*write_handler)(struct vcpu *v, mmio_info_t *info);
>> +    int (*check_handler)(struct vcpu *v, paddr_t addr);
>
> If we are going to a per domain list IO, I would remove check_handler
> and replacing by:
>
> paddr_t addr;
> paddr_t size;
>
>> +    struct list_head handle_list;
>
> On a previous mail (see
> http://www.gossamer-threads.com/lists/xen/devel/317457#317457) I said
> that a list would be better ... but after thinking we can define a fixed
> array of 16 cells. It would be enough for now.
>
> You can see an example in arch/x86/hvm/intercept.c
>
>>  };
>>
>> -extern const struct mmio_handler vgic_distr_mmio_handler;
>> -extern const struct mmio_handler vuart_mmio_handler;
>> -
>>  extern int handle_mmio(mmio_info_t *info);
>> +void register_mmio_handler(struct mmio_handler * handle);
>>
>>  #endif
>>
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index 553411d..d2a13fb 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -73,34 +73,6 @@ static struct vgic_irq_rank *vgic_irq_rank(struct vcpu 
>> *v, int b, int n)
>>          return NULL;
>>  }
>>
>> -int domain_vgic_init(struct domain *d)
>> -{
>> -    int i;
>> -
>> -    d->arch.vgic.ctlr = 0;
>> -
>> -    /* Currently nr_lines in vgic and gic doesn't have the same meanings
>> -     * Here nr_lines = number of SPIs
>> -     */
>> -    if ( d->domain_id == 0 )
>> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
>> -    else
>> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
>> -
>> -    d->arch.vgic.shared_irqs =
>> -        xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
>> -    d->arch.vgic.pending_irqs =
>> -        xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
>> -    for (i=0; i<d->arch.vgic.nr_lines; i++)
>> -    {
>> -        INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
>> -        INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
>> -    }
>> -    for (i=0; i<DOMAIN_NR_RANKS(d); i++)
>> -        spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
>> -    return 0;
>> -}
>> -
>
> I would predefine vgic_distr_mmio_handler early rather moving the whole
> function. It's easier to understand the modification in this patch.
>
> [..]
>
>>  struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
>>  {
>>      struct pending_irq *n;
>> diff --git a/xen/arch/arm/vuart.c b/xen/arch/arm/vuart.c
>> index b9d3ced..c237d71 100644
>> --- a/xen/arch/arm/vuart.c
>> +++ b/xen/arch/arm/vuart.c
>> @@ -44,24 +44,6 @@
>>
>>  #define domain_has_vuart(d) ((d)->arch.vuart.info != NULL)
>>
>> -int domain_vuart_init(struct domain *d)
>> -{
>> -    ASSERT( !d->domain_id );
>> -
>> -    d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
>> -    if ( !d->arch.vuart.info )
>> -        return 0;
>> -
>> -    spin_lock_init(&d->arch.vuart.lock);
>> -    d->arch.vuart.idx = 0;
>> -
>> -    d->arch.vuart.buf = xzalloc_array(char, VUART_BUF_SIZE);
>> -    if ( !d->arch.vuart.buf )
>> -        return -ENOMEM;
>> -
>> -    return 0;
>> -}
>> -
>
> Same remark as domain_vgic_init.
>
> Regards,
>
> --
> Julien Grall


Regards,
Andrii


-- 

Andrii Tseglytskyi | Embedded Dev
GlobalLogic
www.globallogic.com

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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