aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/physdev.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-06-23 11:32:43 +0100
committerJan Beulich <jbeulich@novell.com>2011-06-23 11:32:43 +0100
commitc24536b636f23e4d3202968fcad129d979881e2c (patch)
treee3e188d484b371f8770714bc0453f6395d6da241 /xen/arch/x86/physdev.c
parenteebfd58f212c5fb75e602ac1aa126863452375da (diff)
downloadxen-c24536b636f23e4d3202968fcad129d979881e2c.tar.gz
xen-c24536b636f23e4d3202968fcad129d979881e2c.tar.bz2
xen-c24536b636f23e4d3202968fcad129d979881e2c.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. Note that ia64, the build of which is broken currently anyway, is only being partially fixed up. v2: adjustments for split setup/teardown of translation data v3: re-sync with radix tree implementation changes Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/physdev.c')
-rw-r--r--xen/arch/x86/physdev.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 4f188546fd..428d9ff1b9 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -252,20 +252,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;
}
@@ -558,11 +566,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;