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

Re: [Xen-devel] [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS



>>> On 29.03.17 at 16:47, <roger.pau@xxxxxxxxxx> wrote:
> +static unsigned int base_gsi(const struct domain *d,
> +                             const struct hvm_vioapic *vioapic)
> +{
> +    const struct hvm_vioapic *tmp;
> +    unsigned int base_gsi = 0, nr_vioapics = d->arch.hvm_domain.nr_vioapics;
> +
> +    for ( tmp = domain_vioapic(d, 0); --nr_vioapics && tmp != vioapic; tmp++ 
> )

I don't think tmp++ is correct here - you need to use
domain_vioapic(d, i) on every iteration.

> @@ -361,64 +416,71 @@ static void vioapic_deliver(struct hvm_vioapic 
> *vioapic, int irq)
>  
>  void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
> +    unsigned int pin;
> +    struct hvm_vioapic *vioapic = gsi_vioapic(d, irq, &pin);
>      union vioapic_redir_entry *ent;
>  
>      ASSERT(has_vioapic(d));

Perhaps better make this ASSERT(vioapic) now? Or even bail if this
ends up being NULL? The ASSERT() above comes too late now in
any event.

>  void vioapic_update_EOI(struct domain *d, u8 vector)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
>      struct hvm_irq *hvm_irq = hvm_domain_irq(d);
>      union vioapic_redir_entry *ent;
> -    int gsi;
> +    unsigned int i, base_gsi = 0;
>  
>      ASSERT(has_vioapic(d));
> 
>      spin_lock(&d->arch.hvm_domain.irq_lock);
>  
> -    for ( gsi = 0; gsi < vioapic->nr_pins; gsi++ )
> +    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
>      {
> -        ent = &vioapic->redirtbl[gsi];
> -        if ( ent->fields.vector != vector )
> -            continue;
> -
> -        ent->fields.remote_irr = 0;
> +        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
> +        unsigned int j;
>  
> -        if ( iommu_enabled )
> +        for ( j = 0; j < vioapic->nr_pins; j++ )

Please use pin instead of j.

> @@ -426,12 +488,13 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
>  
>  static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
>  {
> -    struct hvm_vioapic *s = domain_vioapic(d);
> +    struct hvm_vioapic *s = domain_vioapic(d, 0);
>  
>      if ( !has_vioapic(d) )
>          return 0;

This check needs to be ahead of domain_vioapic() use - I'd expect
d->vioapic to be NULL in such a case, and the macro dereferences
it. Please double check other uses.

> @@ -454,32 +518,68 @@ HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, 
> ioapic_load, 1, HVMSR_PER_DOM);
>  
>  void vioapic_reset(struct domain *d)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
> -    uint32_t nr_pins = vioapic->nr_pins;
> -    int i;
> +    unsigned int i;
>  
>      if ( !has_vioapic(d) )
> +    {
> +        ASSERT(!d->arch.hvm_domain.nr_vioapics);
>          return;
> +    }
>  
> -    memset(vioapic, 0, hvm_vioapic_size(nr_pins));
> -    vioapic->domain = d;
> -    vioapic->nr_pins = nr_pins;
> -    for ( i = 0; i < nr_pins; i++ )
> -        vioapic->redirtbl[i].fields.mask = 1;
> -    vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
> +    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
> +    {
> +        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
> +        unsigned int j, nr_pins = vioapic->nr_pins;
> +
> +        memset(vioapic, 0, hvm_vioapic_size(nr_pins));
> +        for ( j = 0; j < nr_pins; j++ )
> +            vioapic->redirtbl[j].fields.mask = 1;

It's not as relevant here, but s/j/pin/ would again be better imo.

> +        ASSERT(!i);
> +        vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
> +                                VIOAPIC_MEM_LENGTH * i;

With the ASSERT() above, please drop the (wrong, as pointed out
before) dependency on i of this expression.

> @@ -91,13 +92,22 @@ static int pt_irq_vector(struct periodic_time *pt, enum 
> hvm_intsrc src)
>                  + (isa_irq & 7));
>  
>      ASSERT(src == hvm_intsrc_lapic);
> -    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
> +    vioapic = gsi_vioapic(v->domain, gsi, &pin);
> +    if ( !vioapic )
> +    {
> +        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", 
> gsi);

Unless v == current at all times, gdprintk() is not suitable here, and
you'd rather want to include d->domain_id in what is being logged.

> @@ -110,9 +120,16 @@ static int pt_irq_masked(struct periodic_time *pt)
>      isa_irq = pt->irq;
>      gsi = hvm_isa_irq_to_gsi(isa_irq);
>      pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
> +    vioapic = gsi_vioapic(v->domain, gsi, &pin);
> +    if ( !vioapic )
> +    {
> +        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", 
> gsi);

Same here.

> --- a/xen/include/asm-x86/hvm/vioapic.h
> +++ b/xen/include/asm-x86/hvm/vioapic.h
> @@ -57,8 +57,10 @@ struct hvm_vioapic {
>  };
>  
>  #define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
> -#define domain_vioapic(d) ((d)->arch.hvm_domain.vioapic)
> +#define domain_vioapic(d, i) ((d)->arch.hvm_domain.vioapic[i])
>  #define vioapic_domain(v) ((v)->domain)
> +struct hvm_vioapic *gsi_vioapic(const struct domain *d, unsigned int gsi,
> +                                unsigned int *pin);

Please don't munge this together with macros, but with other
function declarations (or at least add a blank line in between).

Jan

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

 


Rackspace

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