diff options
author | Jan Beulich <jbeulich@novell.com> | 2011-05-01 13:17:44 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2011-05-01 13:17:44 +0100 |
commit | 76ce27755b87aa5a91ce0f5a02e560ab5c0515e4 (patch) | |
tree | f2a7fcbd31e863d8a0238782c12a716bbc0f21e9 /xen/arch/x86/physdev.c | |
parent | f22f2fe48d144141fffd42a380383f45efbea8e3 (diff) | |
download | xen-76ce27755b87aa5a91ce0f5a02e560ab5c0515e4.tar.gz xen-76ce27755b87aa5a91ce0f5a02e560ab5c0515e4.tar.bz2 xen-76ce27755b87aa5a91ce0f5a02e560ab5c0515e4.zip |
replace d->nr_pirqs sized arrays with radix tree
With this it is questionable whether retaining struct domain's
nr_pirqs is actually necessary - the value now only serves for bounds
checking, and this boundary could easily be nr_irqs.
Another thing to consider is whether it's worth storing the pirq
number in struct pirq, to avoid passing the number and a pointer to
quite a number of functions.
Note that ia64, the build of which is broken currently anyway, is only
partially fixed up.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/physdev.c')
-rw-r--r-- | xen/arch/x86/physdev.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index e15dd0a95d..fe3a39c098 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -258,20 +258,28 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) { case PHYSDEVOP_eoi: { struct physdev_eoi eoi; + struct pirq *pirq; + ret = -EFAULT; if ( copy_from_guest(&eoi, arg, 1) != 0 ) break; ret = -EINVAL; if ( eoi.irq >= v->domain->nr_pirqs ) break; + spin_lock(&v->domain->event_lock); + pirq = pirq_info(v->domain, eoi.irq); + if ( !pirq ) { + spin_unlock(&v->domain->event_lock); + break; + } if ( !is_hvm_domain(v->domain) && v->domain->arch.pv_domain.pirq_eoi_map ) - evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]); + evtchn_unmask(pirq->evtchn); if ( !is_hvm_domain(v->domain) || - domain_pirq_to_emuirq(v->domain, eoi.irq) == IRQ_PT ) - ret = pirq_guest_eoi(v->domain, eoi.irq); - else - ret = 0; + pirq->arch.hvm.emuirq == IRQ_PT ) + pirq_guest_eoi(v->domain, pirq); + spin_unlock(&v->domain->event_lock); + ret = 0; break; } @@ -564,11 +572,23 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) break; spin_lock(&d->event_lock); - out.pirq = get_free_pirq(d, out.type, 0); - d->arch.pirq_irq[out.pirq] = PIRQ_ALLOCATED; + ret = get_free_pirq(d, out.type, 0); + if ( ret >= 0 ) + { + struct pirq *info = pirq_get_info(d, ret); + + if ( info ) + info->arch.irq = PIRQ_ALLOCATED; + else + ret = -ENOMEM; + } spin_unlock(&d->event_lock); - ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0; + if ( ret >= 0 ) + { + out.pirq = ret; + ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0; + } rcu_unlock_domain(d); break; |