ia64/xen-unstable

view xen/arch/x86/physdev.c @ 11353:926d7b131689

[XEN] physdev: Check for negative irqs in alloc_irq_vector.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
author kaf24@firebug.cl.cam.ac.uk
date Wed Aug 30 18:02:32 2006 +0100 (2006-08-30)
parents 1a500cc4fcd5
children bfe3f8f35e87
line source
2 #include <xen/config.h>
3 #include <xen/init.h>
4 #include <xen/lib.h>
5 #include <xen/types.h>
6 #include <xen/sched.h>
7 #include <xen/irq.h>
8 #include <xen/event.h>
9 #include <xen/guest_access.h>
10 #include <asm/current.h>
11 #include <asm/smpboot.h>
12 #include <public/xen.h>
13 #include <public/physdev.h>
15 int
16 ioapic_guest_read(
17 unsigned long physbase, unsigned int reg, u32 *pval);
18 int
19 ioapic_guest_write(
20 unsigned long physbase, unsigned int reg, u32 pval);
22 long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
23 {
24 int irq;
25 long ret;
27 switch ( cmd )
28 {
29 case PHYSDEVOP_eoi: {
30 struct physdev_eoi eoi;
31 ret = -EFAULT;
32 if ( copy_from_guest(&eoi, arg, 1) != 0 )
33 break;
34 ret = pirq_guest_eoi(current->domain, eoi.irq);
35 break;
36 }
38 /* Legacy since 0x00030202. */
39 case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
40 ret = pirq_guest_unmask(current->domain);
41 break;
42 }
44 case PHYSDEVOP_irq_status_query: {
45 struct physdev_irq_status_query irq_status_query;
46 ret = -EFAULT;
47 if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
48 break;
49 irq = irq_status_query.irq;
50 ret = -EINVAL;
51 if ( (irq < 0) || (irq >= NR_IRQS) )
52 break;
53 irq_status_query.flags = 0;
54 if ( pirq_acktype(irq) != 0 )
55 irq_status_query.flags |= XENIRQSTAT_needs_eoi;
56 if ( pirq_shared(irq) )
57 irq_status_query.flags |= XENIRQSTAT_shared;
58 ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
59 break;
60 }
62 case PHYSDEVOP_apic_read: {
63 struct physdev_apic apic;
64 ret = -EFAULT;
65 if ( copy_from_guest(&apic, arg, 1) != 0 )
66 break;
67 ret = -EPERM;
68 if ( !IS_PRIV(current->domain) )
69 break;
70 ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
71 if ( copy_to_guest(arg, &apic, 1) != 0 )
72 ret = -EFAULT;
73 break;
74 }
76 case PHYSDEVOP_apic_write: {
77 struct physdev_apic apic;
78 ret = -EFAULT;
79 if ( copy_from_guest(&apic, arg, 1) != 0 )
80 break;
81 ret = -EPERM;
82 if ( !IS_PRIV(current->domain) )
83 break;
84 ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
85 break;
86 }
88 case PHYSDEVOP_alloc_irq_vector: {
89 struct physdev_irq irq_op;
91 ret = -EFAULT;
92 if ( copy_from_guest(&irq_op, arg, 1) != 0 )
93 break;
95 ret = -EPERM;
96 if ( !IS_PRIV(current->domain) )
97 break;
99 irq = irq_op.irq;
100 ret = -EINVAL;
101 if ( (irq < 0) || (irq >= NR_IRQS) )
102 break;
104 irq_op.vector = assign_irq_vector(irq);
105 ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
106 break;
107 }
109 case PHYSDEVOP_set_iopl: {
110 struct physdev_set_iopl set_iopl;
111 ret = -EFAULT;
112 if ( copy_from_guest(&set_iopl, arg, 1) != 0 )
113 break;
114 ret = -EINVAL;
115 if ( set_iopl.iopl > 3 )
116 break;
117 ret = 0;
118 current->arch.iopl = set_iopl.iopl;
119 break;
120 }
122 case PHYSDEVOP_set_iobitmap: {
123 struct physdev_set_iobitmap set_iobitmap;
124 ret = -EFAULT;
125 if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 )
126 break;
127 ret = -EINVAL;
128 if ( !access_ok(set_iobitmap.bitmap, IOBMP_BYTES) ||
129 (set_iobitmap.nr_ports > 65536) )
130 break;
131 ret = 0;
132 current->arch.iobmp = set_iobitmap.bitmap;
133 current->arch.iobmp_limit = set_iobitmap.nr_ports;
134 break;
135 }
137 default:
138 ret = -EINVAL;
139 break;
140 }
142 return ret;
143 }
145 /*
146 * Local variables:
147 * mode: C
148 * c-set-style: "BSD"
149 * c-basic-offset: 4
150 * tab-width: 4
151 * indent-tabs-mode: nil
152 * End:
153 */