[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 28.03.17 at 13:40, <roger.pau@xxxxxxxxxx> wrote: > On Tue, Mar 28, 2017 at 04:32:05AM -0600, Jan Beulich wrote: >> >>> On 27.03.17 at 12:18, <roger.pau@xxxxxxxxxx> wrote: >> > @@ -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. > > Yes, this is called from vioapic_init in order to set the initial vIO APIC > state and mask all the redir entries. For the Dom0 case we use what's found on > the native MADT tables. > > For now I could fix that by adding: > > BUILD_BUG_ON(VIOAPIC_MEM_LENGTH > PAGE_SIZE); > > And then use PAGE_SIZE above instead of VIOAPIC_MEM_LENGTH. Hmm - see my reply to patch 7. >> > 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. > > Yes, Dom0 will need to come here. If it's cleaner I could have two different > init functions, one for DomU and one for Dom0, and call them from > vioapic_init. > > Or add something like: > > ASSERT(is_hardware_domain(d) || nr_vioapics == 1); > > (the same could be added to vioapic_reset). Which is basically in line with what I've said in reply to patch 7. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |