ia64/xen-unstable

view xen/arch/x86/physdev.c @ 6552:a9873d384da4

Merge.
author adsharma@los-vmm.sc.intel.com
date Thu Aug 25 12:24:48 2005 -0700 (2005-08-25)
parents 112d44270733 fa0754a9f64f
children dfaf788ab18c
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 <asm/current.h>
10 #include <asm/smpboot.h>
11 #include <public/xen.h>
12 #include <public/physdev.h>
14 extern int ioapic_guest_read(int apicid, int address, u32 *pval);
15 extern int ioapic_guest_write(int apicid, int address, u32 pval);
17 void physdev_modify_ioport_access_range(
18 struct domain *d, int enable, int port, int num)
19 {
20 int i;
21 for ( i = port; i < (port + num); i++ )
22 (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
23 }
25 void physdev_destroy_state(struct domain *d)
26 {
27 xfree(d->arch.iobmp_mask);
28 d->arch.iobmp_mask = NULL;
29 }
31 /* Check if a domain controls a device with IO memory within frame @pfn.
32 * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */
33 int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
34 {
35 return 0;
36 }
38 /*
39 * Demuxing hypercall.
40 */
41 long do_physdev_op(physdev_op_t *uop)
42 {
43 physdev_op_t op;
44 long ret;
45 int irq;
47 if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
48 return -EFAULT;
50 switch ( op.cmd )
51 {
52 case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
53 ret = pirq_guest_unmask(current->domain);
54 break;
56 case PHYSDEVOP_IRQ_STATUS_QUERY:
57 irq = op.u.irq_status_query.irq;
58 ret = -EINVAL;
59 if ( (irq < 0) || (irq >= NR_IRQS) )
60 break;
61 op.u.irq_status_query.flags = 0;
62 /* Edge-triggered interrupts don't need an explicit unmask downcall. */
63 if ( strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") == NULL )
64 op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
65 ret = 0;
66 break;
68 case PHYSDEVOP_APIC_READ:
69 ret = -EPERM;
70 if ( !IS_PRIV(current->domain) )
71 break;
72 ret = ioapic_guest_read(
73 op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value);
74 break;
76 case PHYSDEVOP_APIC_WRITE:
77 ret = -EPERM;
78 if ( !IS_PRIV(current->domain) )
79 break;
80 ret = ioapic_guest_write(
81 op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value);
82 break;
84 case PHYSDEVOP_ASSIGN_VECTOR:
85 if ( !IS_PRIV(current->domain) )
86 return -EPERM;
88 if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
89 return -EINVAL;
91 op.u.irq_op.vector = assign_irq_vector(irq);
92 ret = 0;
93 break;
95 case PHYSDEVOP_SET_IOPL:
96 ret = -EINVAL;
97 if ( op.u.set_iopl.iopl > 3 )
98 break;
99 ret = 0;
100 current->arch.iopl = op.u.set_iopl.iopl;
101 break;
103 case PHYSDEVOP_SET_IOBITMAP:
104 ret = -EINVAL;
105 if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
106 (op.u.set_iobitmap.nr_ports > 65536) )
107 break;
108 ret = 0;
109 current->arch.iobmp = op.u.set_iobitmap.bitmap;
110 current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
111 break;
112 default:
113 ret = -EINVAL;
114 break;
115 }
117 if ( copy_to_user(uop, &op, sizeof(op)) )
118 ret = -EFAULT;
120 return ret;
121 }
123 /* Domain 0 has read access to all devices. */
124 void physdev_init_dom0(struct domain *d)
125 {
126 /* Access to all I/O ports. */
127 d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
128 BUG_ON(d->arch.iobmp_mask == NULL);
129 memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
131 set_bit(_DOMF_physdev_access, &d->domain_flags);
132 }
135 /*
136 * Local variables:
137 * mode: C
138 * c-set-style: "BSD"
139 * c-basic-offset: 4
140 * tab-width: 4
141 * indent-tabs-mode: nil
142 * End:
143 */