aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/physdev.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-11-24 14:43:07 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-11-24 14:43:07 +0000
commit7ec2f532303617ff075f595f02fb8ae06f9bf1d5 (patch)
tree4ca495e338e570058241a6451fbfefac038e17d4 /xen/arch/x86/physdev.c
parent24cb0f67eaeb10f34392c423b5159db049f6481e (diff)
downloadxen-7ec2f532303617ff075f595f02fb8ae06f9bf1d5.tar.gz
xen-7ec2f532303617ff075f595f02fb8ae06f9bf1d5.tar.bz2
xen-7ec2f532303617ff075f595f02fb8ae06f9bf1d5.zip
x86: Add a new physdev_op PHYSDEVOP_setup_gsi for GSI setup.
GSI 0-15 is setup by hypervisor, and GSI > =16 is setup by dom0 this physdev_op PHYSDEVOP_setup_gsi. This patch can help dom0 to get rid of intrusive changes of ioapic. Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Diffstat (limited to 'xen/arch/x86/physdev.c')
-rw-r--r--xen/arch/x86/physdev.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 2d65fa4df4..b0d777a6e8 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -62,13 +62,18 @@ static int physdev_map_pirq(struct physdev_map_pirq *map)
ret = -EINVAL;
goto free_domain;
}
+
irq = domain_pirq_to_irq(current->domain, map->index);
if ( !irq )
{
- dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
- d->domain_id);
- ret = -EINVAL;
- goto free_domain;
+ if ( IS_PRIV(current->domain) )
+ irq = map->index;
+ else {
+ dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
+ d->domain_id);
+ ret = -EINVAL;
+ goto free_domain;
+ }
}
break;
@@ -457,6 +462,28 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
spin_unlock(&pcidevs_lock);
break;
}
+ case PHYSDEVOP_setup_gsi: {
+ struct physdev_setup_gsi setup_gsi;
+
+ ret = -EPERM;
+ if ( !IS_PRIV(v->domain) )
+ break;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&setup_gsi, arg, 1) != 0 )
+ break;
+
+ ret = -EINVAL;
+ if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= nr_irqs_gsi )
+ break;
+ /* GSI < 16 has been setup by hypervisor */
+ if ( setup_gsi.gsi >= 16 )
+ ret = mp_register_gsi(setup_gsi.gsi, setup_gsi.triggering,
+ setup_gsi.polarity);
+ else
+ ret = -EEXIST;
+ break;
+ }
default:
ret = -ENOSYS;
break;