|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |