[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/3] xen/arm: domain_build: Rework the way to allocate the event channel interrupt
On Tue, 27 Feb 2018, julien.grall@xxxxxxx wrote: > From: Julien Grall <julien.grall@xxxxxxx> > > At the moment, a placeholder will be created in the device-tree for the > event channel information. Later in the domain construction, the > interrupt for the event channel upcall will be allocated the device-tree > fixed up. > > Looking at the code, the current split is not necessary because all the > PPIs used by the hardware domain will by the time we create the node in > the device-tree. > > >From now, mandate that all interrupts are registered before > acpi_prepare() and dtb_prepare(). This allows us to rework the event > channel code and remove one placeholder. > > Note, this will also help to fix the BUG(...) condition in set_interrupt_ppi > which is completely wrong. See in a follow-up patch. > > Signed-off-by: Julien Grall <julien.grall@xxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > --- > xen/arch/arm/domain_build.c | 74 > +++++++++++++++++++++------------------------ > 1 file changed, 35 insertions(+), 39 deletions(-) > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index a5e5c82355..ed1a393bb5 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -576,7 +576,10 @@ static int make_memory_node(const struct domain *d, > return res; > } > > -static int make_hypervisor_node(const struct kernel_info *kinfo, > +static void evtchn_allocate(struct domain *d); > + > +static int make_hypervisor_node(struct domain *d, > + const struct kernel_info *kinfo, > const struct dt_device_node *parent) > { > const char compat[] = > @@ -620,10 +623,18 @@ static int make_hypervisor_node(const struct > kernel_info *kinfo, > return res; > > /* > - * Placeholder for the event channel interrupt. The values will be > - * replaced later. > + * It is safe to allocate the event channel here because all the > + * PPIs used by the hardware domain have been registered. > + */ > + evtchn_allocate(d); > + > + /* > + * Interrupt event channel upcall: > + * - Active-low level-sensitive > + * - All CPUs > + * TODO: Handle properly the cpumask; > */ > - set_interrupt_ppi(intr, ~0, 0xf, IRQ_TYPE_INVALID); > + set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf, IRQ_TYPE_LEVEL_LOW); > res = fdt_property_interrupts(fdt, &intr, 1); > if ( res ) > return res; > @@ -1282,7 +1293,11 @@ static int handle_node(struct domain *d, struct > kernel_info *kinfo, > > if ( node == dt_host ) > { > - res = make_hypervisor_node(kinfo, node); > + /* > + * The hypervisor node should always be created after all nodes > + * from the host DT have been parsed. > + */ > + res = make_hypervisor_node(d, kinfo, node); > if ( res ) > return res; > > @@ -1939,6 +1954,12 @@ static int prepare_acpi(struct domain *d, struct > kernel_info *kinfo) > if ( rc != 0 ) > return rc; > > + /* > + * All PPIs have been registered, allocate the event channel > + * interrupts. > + */ > + evtchn_allocate(d); > + > return 0; > } > #else > @@ -2014,16 +2035,18 @@ static void initrd_load(struct kernel_info *kinfo) > panic("Unable to copy the initrd in the hwdom memory"); > } > > -static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) > +/* > + * Allocate the event channel PPIs and setup the HVM_PARAM_CALLBACK_IRQ. > + * The allocated IRQ will be found in d->arch.evtchn_irq. > + * > + * Note that this should only be called once all PPIs used by the > + * hardware domain have been registered. > + */ > +static void evtchn_allocate(struct domain *d) > { > - int res, node; > + int res; > u64 val; > - gic_interrupt_t intr; > > - /* > - * The allocation of the event channel IRQ has been deferred until > - * now. At this time, all PPIs used by DOM0 have been registered. > - */ > res = vgic_allocate_ppi(d); > if ( res < 0 ) > panic("Unable to allocate a PPI for the event channel interrupt\n"); > @@ -2041,31 +2064,6 @@ static void evtchn_fixup(struct domain *d, struct > kernel_info *kinfo) > HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK); > val |= d->arch.evtchn_irq; > d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ] = val; > - > - /* > - * When booting Dom0 using ACPI, Dom0 can only get the event channel > - * interrupt via hypercall. > - */ > - if ( !acpi_disabled ) > - return; > - > - /* Fix up "interrupts" in /hypervisor node */ > - node = fdt_path_offset(kinfo->fdt, "/hypervisor"); > - if ( node < 0 ) > - panic("Cannot find the /hypervisor node"); > - > - /* Interrupt event channel upcall: > - * - Active-low level-sensitive > - * - All CPUs > - * > - * TODO: Handle properly the cpumask > - */ > - set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf, > - IRQ_TYPE_LEVEL_LOW); > - res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts", > - &intr, sizeof(intr)); > - if ( res ) > - panic("Cannot fix up \"interrupts\" property of the hypervisor > node"); > } > > static void __init find_gnttab_region(struct domain *d, > @@ -2177,8 +2175,6 @@ int construct_dom0(struct domain *d) > kernel_load(&kinfo); > /* initrd_load will fix up the fdt, so call it before dtb_load */ > initrd_load(&kinfo); > - /* Allocate the event channel IRQ and fix up the device tree */ > - evtchn_fixup(d, &kinfo); > dtb_load(&kinfo); > > /* Now that we are done restore the original p2m and current. */ > -- > 2.11.0 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |