Hello, this is trying to make the point that having NULL pointer entries in the radix tree and letting Xen handle that is a valid case. To some degree this serves as a tag (LPI has been unmapped), so should semantically come close to what we are discussing. It has the big advantage of being able to immediately clean up the pending_irq and free it right away.
So I checked all call sites of irq_to_pending (see below). A number of them is *not* used for LPIs (but only for SPIs, for instance). An LPI number will never make it to those places. A number of calls is already protected in patch 10/34 in the v7, and I just added one case. Interestingly all those calls use the retrieved pending_irq pointer either already under the VCPU VGIC lock or can be easily moved under it without changing any semantics. Since irq_to_pending right now was just a wrapper around some static array lookup, so far we just didn't bother with taking the lock before or after the irq_to_pending call. Changing this now doesn't change anything for the existing code. So this means that the pending_irq pointer is only retrieved and used under the lock - which gives us the guarantee that it's always valid to use. So as long as we hold the VGIC VCPU lock while we replace the radix tree entry we can't never have a use-after-free race. So this is the summary based on "git grep irq_to_pending": xen/arch/arm/gic.c: gic_route_irq_to_guest(): only called for SPIs gic_remove_irq_from_guest(): only called for SPIs gic_remove_from_queues(): PROTECTED, VCPU VGIC lock gic_raise_inflight_irq(): PROTECTED, VCPU VGIC lock gic_raise_guest_irq(): TO BE PROTECTED, VCPU VGIC lock gic_update_one_lr(): PROTECTED, VCPU VGIC lock xen/arch/arm/vgic.c: vgic_migrate_irq(): not called for LPIs (not for virtual IRQs) arch_move_irqs(): not iterating over LPIs vgic_disable_irqs(): not called for LPIs vgic_enable_irqs(): not called for LPIs vgic_vcpu_inject_irq(): PROTECTED, moved under VCPU VGIC lock xen/include/asm-arm/event.h: local_events_need_delivery_nomask(): only called for a PPI xen/include/asm-arm/vgic.h: (prototype) So here is the suggestion (yet another one, I know): - DISCARD translates the DevID/EvID pair to a vCPU/vLPI pair. This is done under the vcmd lock and ITS lock. We then lock the respective vCPU VGIC lock, take the radix tree lock and remove the pending_irq from the radix tree (making it read NULL), drop the radix tree lock and vCPU VGIC lock again. We clean up the pending_irq (removing from lists) under the lock still. Any VGIC code either sees a valid pending_irq pointer (and uses it only while holding the vCPU lock!) or a NULL pointer, and due to patch 10/34 can deal with this. A VCPU returning will just clear the LR when it reads NULL (because there is nothing to handle). - MAPD(V=0) just does the above in a loop with every mapped event. At the end it can safely free the pend_irq array. I implemented that along with addressing the other comments and pushed this to http://www.linux-arm.org/git?p=xen-ap.git;a=shortlog;h=refs/heads/its/v8-pre Maybe we can use this as a discussion base? Cheers, Andre. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel