[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 5/7] x86/vioapic: introduce support for multiple vIO APICS
>>> On 27.03.17 at 12:18, <roger.pau@xxxxxxxxxx> wrote: > Changes since v1: > - Constify some parameters. Considering this I'm surprised the first thing I have to ask is ... > --- a/xen/arch/x86/hvm/vioapic.c > +++ b/xen/arch/x86/hvm/vioapic.c > @@ -44,6 +44,54 @@ > > static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq); > > +static struct hvm_vioapic *addr_vioapic(struct domain *d, unsigned long addr) ... const? The more that you have it like this ... > +struct hvm_vioapic *gsi_vioapic(const struct domain *d, unsigned int gsi, ... here. > + unsigned int *base_gsi) All callers of the function really want the pin number rather than the base GSI - why don't you make the function provide that instead? > +{ > + unsigned int i; > + *base_gsi = 0; Blank line between declaration(s) and statement(s) please. > +static unsigned int pin_gsi(const struct domain *d, > + const struct hvm_vioapic *vioapic, > + unsigned int pin) > +{ > + const struct hvm_vioapic *tmp; > + unsigned int base_gsi = 0; > + > + for ( tmp = domain_vioapic(d, 0); tmp != vioapic; tmp++ ) > + base_gsi += tmp->nr_pins; > + > + return base_gsi + pin; > +} Didn't we settle on having a function base_gsi(), with callers adding in the pin number as needed? The only reason the function here takes pin as a parameter is this final addition. Also shouldn't this function somehow guard itself against overrunning the array? > @@ -275,16 +327,17 @@ static inline int pit_channel0_enabled(void) > return pt_active(¤t->domain->arch.vpit.pt0); > } > > -static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq) > +static void vioapic_deliver(struct hvm_vioapic *vioapic, int pin) Occasionally we pass around negative IRQ numbers, but if this really is a pin number, I think the type wants changing to unsigned int - the more that it is being used as an array index below. > @@ -454,33 +517,70 @@ 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; > + vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS + > + VIOAPIC_MEM_LENGTH * i; > + vioapic->id = i; > + vioapic->nr_pins = nr_pins; > + vioapic->domain = d; > + } > +} Is this function validly reachable for Dom0? If not, better leave it alone (adding a nr_vioapics == 1 check), as at least the base address calculation looks rather suspicious (there shouldn't be multiple IO-APICs on a single page). If so, that same memory address calculation is actively wrong in the Dom0 case. > +static void vioapic_free(const struct domain *d, unsigned int nr_vioapics) > +{ > + unsigned int i; > + > + for ( i = 0; i < nr_vioapics; i++) > + { > + if ( domain_vioapic(d, i) == NULL ) > + break; Is this if() really needed? > int vioapic_init(struct domain *d) > { > + unsigned int i, nr_vioapics = 1; > + > if ( !has_vioapic(d) ) > + { > + ASSERT(!d->arch.hvm_domain.nr_vioapics); > return 0; > + } > > if ( (d->arch.hvm_domain.vioapic == NULL) && > ((d->arch.hvm_domain.vioapic = > - xmalloc_bytes(hvm_vioapic_size(VIOAPIC_NUM_PINS))) == NULL) ) > + xzalloc_array(struct hvm_vioapic *, nr_vioapics)) == NULL) ) > return -ENOMEM; > > - d->arch.hvm_domain.vioapic->domain = d; > - d->arch.hvm_domain.vioapic->nr_pins = VIOAPIC_NUM_PINS; > + for ( i = 0; i < nr_vioapics; i++ ) > + { > + if ( (domain_vioapic(d, i) = > + xmalloc_bytes(hvm_vioapic_size(VIOAPIC_NUM_PINS))) == NULL ) > + { > + vioapic_free(d, nr_vioapics); > + return -ENOMEM; > + } > + domain_vioapic(d, i)->nr_pins = VIOAPIC_NUM_PINS; > + } > + > + d->arch.hvm_domain.nr_vioapics = nr_vioapics; > vioapic_reset(d); These adjustments again don't look right for nr_vioapics > 1, so I wonder whether again this function wouldn't better be left alone. Alternatively, if Dom0 needs to come here, a comment is going to be needed to explain the (temporary) wrong setting of nr_pins. > @@ -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, &base_gsi); > + if ( !vioapic ) > + { > + gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", > gsi); > + domain_crash(v->domain); > + return -1; > + } Now that you have this check, ... > @@ -110,9 +120,10 @@ 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, &base_gsi); > > return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) > && > - domain_vioapic(v->domain)->redirtbl[gsi].fields.mask); > + vioapic->redirtbl[gsi - base_gsi].fields.mask); > } ... why is there still none here? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |