aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-23 09:18:50 +0000
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2013-01-23 09:18:50 +0000
commit00b70689c193b9cccb1fac3c3764bed77e152c4e (patch)
tree7407375dc345426e1300ac53bd7ea166996856a8 /xen/arch/x86
parentdb984809d61b1c605d22520b89fa393bcb21430a (diff)
downloadxen-00b70689c193b9cccb1fac3c3764bed77e152c4e.tar.gz
xen-00b70689c193b9cccb1fac3c3764bed77e152c4e.tar.bz2
xen-00b70689c193b9cccb1fac3c3764bed77e152c4e.zip
xen/arch/x86: complete XSM hooks on irq/pirq mappings
Manipulation of a domain's pirq namespace was not fully protected by XSM hooks because the XSM hooks for IRQs needed a physical IRQ. Since this may not apply to HVM domains, a complete solution needs to split the XSM hook for this operation, using one hook for the PIRQ manipulation and one for controlling access to the hardware IRQ. This reworking has the advantage of providing the same MSI data to remove_irq that is provided to add_irq, allowing the PCI device to be determined in both functions. It also eliminates the last callers of rcu_lock_target_domain_by_id in x86 and common code in preparation for this function's removal. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86')
-rw-r--r--xen/arch/x86/irq.c13
-rw-r--r--xen/arch/x86/physdev.c18
2 files changed, 20 insertions, 11 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 095c17dbac..068c5a0228 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1874,7 +1874,7 @@ int map_domain_pirq(
return 0;
}
- ret = xsm_map_domain_pirq(XSM_HOOK, d, irq, data);
+ ret = xsm_map_domain_irq(XSM_HOOK, d, irq, data);
if ( ret )
{
dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d mapping to pirq %d\n",
@@ -1978,14 +1978,19 @@ int unmap_domain_pirq(struct domain *d, int pirq)
goto done;
}
+ desc = irq_to_desc(irq);
+ msi_desc = desc->msi_desc;
+
+ ret = xsm_unmap_domain_irq(XSM_HOOK, d, irq, msi_desc);
+ if ( ret )
+ goto done;
+
forced_unbind = pirq_guest_force_unbind(d, info);
if ( forced_unbind )
dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
d->domain_id, pirq);
- desc = irq_to_desc(irq);
-
- if ( (msi_desc = desc->msi_desc) != NULL )
+ if ( msi_desc != NULL )
pci_disable_msi(msi_desc);
spin_lock_irqsave(&desc->lock, flags);
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index b45e18ac51..d9ed5dfd0c 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -105,7 +105,11 @@ int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
return physdev_hvm_map_pirq(d, type, index, pirq_p);
}
- ret = rcu_lock_target_domain_by_id(domid, &d);
+ d = rcu_lock_domain_by_any_id(domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ ret = xsm_map_domain_pirq(XSM_TARGET, d);
if ( ret )
return ret;
@@ -218,9 +222,13 @@ int physdev_unmap_pirq(domid_t domid, int pirq)
struct domain *d;
int ret;
- ret = rcu_lock_target_domain_by_id(domid, &d);
+ d = rcu_lock_domain_by_any_id(domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
if ( ret )
- return ret;
+ goto free_domain;
if ( is_hvm_domain(d) )
{
@@ -232,10 +240,6 @@ int physdev_unmap_pirq(domid_t domid, int pirq)
goto free_domain;
}
- ret = xsm_unmap_domain_pirq(XSM_TARGET, d, domain_pirq_to_irq(d, pirq));
- if ( ret )
- goto free_domain;
-
spin_lock(&pcidevs_lock);
spin_lock(&d->event_lock);
ret = unmap_domain_pirq(d, pirq);