debuggers.hg

view xen/common/physdev.c @ 3763:0823f72cd071

bitkeeper revision 1.1159.223.80 (4208de05Xtv_u_3smJSRU6ex6bTAfA)

Some functions aren't static and could be (damn C language!).

I tried turning on -Wmissing-prototypes: unfortunately gives warnings
for functions used in asm, which means introducing gratuitous prototypes
for them. Not sure it's worth it.

1) keyhandler.c: keypress_softirq() and do_task_queues() can be static.
2) physdev.c: pcidev_dom0_hidden() can be static.
3) resource.c/resource.h: check_region is deprecated (racy): remove.
4) sched_bvt.c: lots of things can be static.
5) pci/compat.c: not required for Xen.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (authored)
Signed-off-by: ian.pratt@cl.cam.ac.uk
author iap10@freefall.cl.cam.ac.uk
date Tue Feb 08 15:43:01 2005 +0000 (2005-02-08)
parents dee91b44a753
children a00d7a994a59 735a0b87a9a1 dbdf796cd98c 3a5d8cd66c0b
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge
4 * (c) 2004 - Keir Fraser - University of Cambridge
5 ****************************************************************************
6 *
7 * Description: allows a domain to access devices on the PCI bus
8 *
9 * A guest OS may be given access to particular devices on the PCI bus.
10 * For each domain a list of PCI devices is maintained, describing the
11 * access mode for the domain.
12 *
13 * Guests can figure out the virtualised PCI space through normal PCI config
14 * register access. Some of the accesses, in particular write accesses, are
15 * faked. For example the sequence for detecting the IO regions, which requires
16 * writes to determine the size of the region, is faked out by a very simple
17 * state machine, preventing direct writes to the PCI config registers by a
18 * guest.
19 */
21 #include <xen/config.h>
22 #include <xen/init.h>
23 #include <xen/lib.h>
24 #include <xen/types.h>
25 #include <xen/sched.h>
26 #include <xen/pci.h>
27 #include <xen/irq.h>
28 #include <xen/event.h>
29 #include <asm/pci.h>
30 #include <public/xen.h>
31 #include <public/physdev.h>
33 /* Called by PHYSDEV_PCI_INITIALISE_DEVICE to finalise IRQ routing. */
34 extern void pcibios_enable_irq(struct pci_dev *dev);
36 #if 0
37 #define VERBOSE_INFO(_f, _a...) printk( _f , ## _a )
38 #else
39 #define VERBOSE_INFO(_f, _a...) ((void)0)
40 #endif
42 #ifdef VERBOSE
43 #define INFO(_f, _a...) printk( _f, ## _a )
44 #else
45 #define INFO(_f, _a...) ((void)0)
46 #endif
48 #define SLOPPY_CHECKING
50 #define ACC_READ 1
51 #define ACC_WRITE 2
53 /* Upper bounds for PCI-device addressing. */
54 #define PCI_BUSMAX 255
55 #define PCI_DEVMAX 31
56 #define PCI_FUNCMAX 7
57 #define PCI_REGMAX 255
59 /* Bit offsets into state. */
60 #define ST_BASE_ADDRESS 0 /* bits 0-5: are for base address access */
61 #define ST_ROM_ADDRESS 6 /* bit 6: is for rom address access */
63 typedef struct _phys_dev_st {
64 int flags; /* flags for access etc */
65 struct pci_dev *dev; /* the device */
66 struct list_head node; /* link to the list */
67 struct domain *owner; /* 'owner of this device' */
68 int state; /* state for various checks */
69 } phys_dev_t;
72 /* Find a device on a per-domain device list. */
73 static phys_dev_t *find_pdev(struct domain *p, struct pci_dev *dev)
74 {
75 phys_dev_t *t, *res = NULL;
77 list_for_each_entry ( t, &p->pcidev_list, node )
78 {
79 if ( dev == t->dev )
80 {
81 res = t;
82 break;
83 }
84 }
85 return res;
86 }
88 /* Add a device to a per-domain device-access list. */
89 static void add_dev_to_task(struct domain *p,
90 struct pci_dev *dev, int acc)
91 {
92 phys_dev_t *pdev;
94 if ( (pdev = find_pdev(p, dev)) )
95 {
96 /* Sevice already on list: update access permissions. */
97 pdev->flags = acc;
98 return;
99 }
101 if ( (pdev = xmalloc(sizeof(phys_dev_t))) == NULL )
102 {
103 INFO("Error allocating pdev structure.\n");
104 return;
105 }
107 pdev->dev = dev;
108 pdev->flags = acc;
109 pdev->state = 0;
110 list_add(&pdev->node, &p->pcidev_list);
112 if ( acc == ACC_WRITE )
113 pdev->owner = p;
114 }
116 /*
117 * physdev_pci_access_modify:
118 * Allow/disallow access to a specific PCI device. Guests should not be
119 * allowed to see bridge devices as it needlessly complicates things (one
120 * possible exception to this is the AGP bridge). If the given device is a
121 * bridge, then the domain should get access to all the leaf devices below
122 * that bridge (XXX this is unimplemented!).
123 */
124 int physdev_pci_access_modify(
125 domid_t dom, int bus, int dev, int func, int enable)
126 {
127 struct domain *p;
128 struct pci_dev *pdev;
129 int i, j, rc = 0;
131 if ( !IS_PRIV(current) )
132 BUG();
134 if ( (bus > PCI_BUSMAX) || (dev > PCI_DEVMAX) || (func > PCI_FUNCMAX) )
135 return -EINVAL;
137 if ( !enable )
138 {
139 INFO("Disallowing access is not yet supported.\n");
140 return -EINVAL;
141 }
143 INFO("physdev_pci_access_modify: %02x:%02x:%02x\n", bus, dev, func);
145 if ( (p = find_domain_by_id(dom)) == NULL )
146 return -ESRCH;
148 /* Make the domain privileged. */
149 set_bit(DF_PHYSDEV, &p->flags);
150 /* FIXME: MAW for now make the domain REALLY privileged so that it
151 * can run a backend driver (hw access should work OK otherwise) */
152 set_bit(DF_PRIVILEGED, &p->flags);
154 /* Grant write access to the specified device. */
155 if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL )
156 {
157 INFO(" dev does not exist\n");
158 rc = -ENODEV;
159 goto out;
160 }
161 add_dev_to_task(p, pdev, ACC_WRITE);
163 INFO(" add RW %02x:%02x:%02x\n", pdev->bus->number,
164 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
166 /* Is the device a bridge or cardbus? */
167 if ( pdev->hdr_type != PCI_HEADER_TYPE_NORMAL )
168 INFO("XXX can't give access to bridge devices yet\n");
170 /* Now, setup access to the IO ports and memory regions for the device. */
172 if ( p->thread.io_bitmap == NULL )
173 {
174 if ( (p->thread.io_bitmap = xmalloc(IOBMP_BYTES)) == NULL )
175 {
176 rc = -ENOMEM;
177 goto out;
178 }
179 memset(p->thread.io_bitmap, 0xFF, IOBMP_BYTES);
181 p->thread.io_bitmap_sel = ~0ULL;
182 }
184 for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ )
185 {
186 struct resource *r = &pdev->resource[i];
188 if ( r->flags & IORESOURCE_IO )
189 {
190 /* Give the domain access to the IO ports it needs. Currently,
191 * this will allow all processes in that domain access to those
192 * ports as well. This will do for now, since driver domains don't
193 * run untrusted processes! */
194 INFO("Giving domain %u IO resources (%lx - %lx) "
195 "for device %s\n", dom, r->start, r->end, pdev->slot_name);
196 for ( j = r->start; j < r->end + 1; j++ )
197 {
198 clear_bit(j, p->thread.io_bitmap);
199 clear_bit(j / IOBMP_BITS_PER_SELBIT, &p->thread.io_bitmap_sel);
200 }
201 }
203 /* rights to IO memory regions are checked when the domain maps them */
204 }
205 out:
206 put_domain(p);
207 return rc;
208 }
210 /* Check if a domain controls a device with IO memory within frame @pfn.
211 * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */
212 int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
213 {
214 int ret = 0;
215 phys_dev_t *phys_dev;
217 VERBOSE_INFO("Checking if physdev-capable domain %u needs access to "
218 "pfn %08lx\n", p->id, pfn);
220 spin_lock(&p->pcidev_lock);
222 list_for_each_entry ( phys_dev, &p->pcidev_list, node )
223 {
224 int i;
225 struct pci_dev *pci_dev = phys_dev->dev;
227 for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ )
228 {
229 struct resource *r = &pci_dev->resource[i];
231 if ( r->flags & IORESOURCE_MEM )
232 if ( (r->start >> PAGE_SHIFT) == pfn
233 || (r->end >> PAGE_SHIFT) == pfn
234 || ((r->start >> PAGE_SHIFT < pfn)
235 && (r->end >> PAGE_SHIFT > pfn)) )
236 ret = 1;
237 }
239 if ( ret != 0 ) break;
240 }
242 spin_unlock(&p->pcidev_lock);
244 VERBOSE_INFO("Domain %u %s mapping of pfn %08lx\n",
245 p->id, ret ? "allowed" : "disallowed", pfn);
247 return ret;
248 }
250 /* check if a domain has general access to a device */
251 inline static int check_dev_acc (struct domain *p,
252 int bus, int dev, int func,
253 phys_dev_t **pdev)
254 {
255 struct pci_dev *target_dev;
256 phys_dev_t *target_pdev;
257 unsigned int target_devfn;
259 *pdev = NULL;
261 if ( !IS_CAPABLE_PHYSDEV(p) )
262 return -EPERM; /* no pci access permission */
264 if ( bus > PCI_BUSMAX || dev > PCI_DEVMAX || func > PCI_FUNCMAX )
265 return -EINVAL;
267 VERBOSE_INFO("b=%x d=%x f=%x ", bus, dev, func);
269 /* check target device */
270 target_devfn = PCI_DEVFN(dev, func);
271 target_dev = pci_find_slot(bus, target_devfn);
272 if ( !target_dev )
273 {
274 VERBOSE_INFO("target does not exist\n");
275 return -ENODEV;
276 }
278 /* check access */
279 target_pdev = find_pdev(p, target_dev);
280 if ( !target_pdev )
281 {
282 VERBOSE_INFO("dom has no access to target\n");
283 return -EPERM;
284 }
286 *pdev = target_pdev;
287 return 0;
288 }
290 #ifndef SLOPPY_CHECKING
291 /*
292 * Base address registers contain the base address for IO regions.
293 * The length can be determined by writing all 1s to the register and
294 * reading the value again. The device will zero the lower unused bits.
295 *
296 * to work out the length of the io region a device probe typically does:
297 * 1) a = read_base_addr_reg()
298 * 2) write_base_addr_reg(0xffffffff)
299 * 3) b = read_base_addr_reg() [device zeros lower bits]
300 * 4) write_base_addr_reg(a) [restore original value]
301 * this function fakes out step 2-4. *no* writes are made to the device.
302 *
303 * phys_dev_t contains a bit field (a bit for each base address register).
304 * if the bit for a register is set the guest had writen all 1s to the
305 * register and subsequent read request need to fake out the b.
306 * if the guest restores the original value (step 4 above) the bit is
307 * cleared again. If the guest attempts to "restores" a wrong value an
308 * error is flagged.
309 */
310 static int do_base_address_access(phys_dev_t *pdev, int acc, int idx,
311 int len, u32 *val)
312 {
313 int st_bit, reg = PCI_BASE_ADDRESS_0 + (idx*4), ret = -EINVAL;
314 struct pci_dev *dev = pdev->dev;
315 u32 orig_val, sz;
316 struct resource *res;
318 if ( len != sizeof(u32) )
319 {
320 /* This isn't illegal, but there doesn't seem to be a very good reason
321 * to do it for normal devices (bridges are another matter). Since it
322 * would complicate the code below, we don't support this for now. */
324 /* We could set *val to some value but the guest may well be in trouble
325 * anyway if this write fails. Hopefully the printk will give us a
326 * clue what went wrong. */
327 INFO("Guest %u attempting sub-dword %s to BASE_ADDRESS %d\n",
328 pdev->owner->id, (acc == ACC_READ) ? "read" : "write", idx);
330 return -EPERM;
331 }
333 st_bit = idx + ST_BASE_ADDRESS;
334 res = &(pdev->dev->resource[idx]);
336 if ( acc == ACC_WRITE )
337 {
338 if ( (*val == 0xffffffff) ||
339 ((res->flags & IORESOURCE_IO) && (*val == 0xffff)) )
340 {
341 /* Set bit and return. */
342 set_bit(st_bit, &pdev->state);
343 ret = 0;
344 }
345 else
346 {
347 /* Assume guest wants to set the base address. */
348 clear_bit(st_bit, &pdev->state);
350 /* check if guest tries to restore orig value */
351 ret = pci_read_config_dword(dev, reg, &orig_val);
352 if ( (ret == 0) && (*val != orig_val) )
353 {
354 INFO("Guest attempting update to BASE_ADDRESS %d\n", idx);
355 ret = -EPERM;
356 }
357 }
358 VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
359 " val=0x%08x %x\n",
360 dev->bus->number, PCI_SLOT(dev->devfn),
361 PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
362 }
363 else if ( acc == ACC_READ )
364 {
365 ret = pci_read_config_dword(dev, reg, val);
366 if ( (ret == 0) && test_bit(st_bit, &pdev->state) )
367 {
368 /* Cook the value. */
369 sz = res->end - res->start;
370 if ( res->flags & IORESOURCE_MEM )
371 {
372 /* this is written out explicitly for clarity */
373 *val = 0xffffffff;
374 /* bit 0 = 0 */
375 /* bit 21 = memory type */
376 /* bit 3 = prefetchable */
377 /* bit 4-31 width */
378 sz = sz >> 4; /* size in blocks of 16 byte */
379 sz = ~sz; /* invert */
380 *val = *val & (sz << 4); /* and in the size */
381 /* use read values for low 4 bits */
382 *val = *val | (orig_val & 0xf);
383 }
384 else if ( res->flags & IORESOURCE_IO )
385 {
386 *val = 0x0000ffff;
387 /* bit 10 = 01 */
388 /* bit 2-31 width */
389 sz = sz >> 2; /* size in dwords */
390 sz = ~sz & 0x0000ffff;
391 *val = *val & (sz << 2);
392 *val = *val | 0x1;
393 }
394 }
395 VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
396 " val=0x%08x %x\n",
397 dev->bus->number, PCI_SLOT(dev->devfn),
398 PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
399 }
401 return ret;
402 }
405 static int do_rom_address_access(phys_dev_t *pdev, int acc, int len, u32 *val)
406 {
407 int st_bit, ret = -EINVAL;
408 struct pci_dev *dev = pdev->dev;
409 u32 orig_val, sz;
410 struct resource *res;
412 if ( len != sizeof(u32) )
413 {
414 INFO("Guest attempting sub-dword %s to ROM_ADDRESS\n",
415 (acc == ACC_READ) ? "read" : "write");
416 return -EPERM;
417 }
419 st_bit = ST_ROM_ADDRESS;
420 res = &(pdev->dev->resource[PCI_ROM_RESOURCE]);
422 if ( acc == ACC_WRITE )
423 {
424 if ( (*val == 0xffffffff) || (*val == 0xfffffffe) )
425 {
426 /* NB. 0xffffffff would be unusual, but we trap it anyway. */
427 set_bit(st_bit, &pdev->state);
428 ret = 0;
429 }
430 else
431 {
432 /* Assume guest wants simply to set the base address. */
433 clear_bit(st_bit, &pdev->state);
435 /* Check if guest tries to restore the original value. */
436 ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, &orig_val);
437 if ( (ret == 0) && (*val != orig_val) )
438 {
439 if ( (*val != 0x00000000) )
440 {
441 INFO("caution: guest tried to change rom address.\n");
442 ret = -EPERM;
443 }
444 else
445 {
446 INFO("guest disabled rom access for %02x:%02x:%02x\n",
447 dev->bus->number, PCI_SLOT(dev->devfn),
448 PCI_FUNC(dev->devfn));
449 }
450 }
451 }
452 VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
453 " val=0x%08x %x\n",
454 dev->bus->number, PCI_SLOT(dev->devfn),
455 PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
456 }
457 else if ( acc == ACC_READ )
458 {
459 ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, val);
460 if ( (ret == 0) && test_bit(st_bit, &pdev->state) )
461 {
462 /* Cook the value. */
463 sz = res->end - res->start;
464 *val = 0xffffffff;
465 /* leave bit 0 untouched */
466 /* bit 1-10 reserved, harwired to 0 */
467 sz = sz >> 11; /* size is in 2KB blocks */
468 sz = ~sz;
469 *val = *val & (sz << 11);
470 *val = *val | (orig_val & 0x1);
471 }
472 VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
473 " val=0x%08x %x\n",
474 dev->bus->number, PCI_SLOT(dev->devfn),
475 PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
476 }
478 return ret;
480 }
481 #endif /* SLOPPY_CHECKING */
483 /*
484 * Handle a PCI config space read access if the domain has access privileges.
485 */
486 static long pci_cfgreg_read(int bus, int dev, int func, int reg,
487 int len, u32 *val)
488 {
489 int ret;
490 phys_dev_t *pdev;
492 if ( (ret = check_dev_acc(current, bus, dev, func, &pdev)) != 0 )
493 {
494 /* PCI spec states that reads from non-existent devices should return
495 * all 1s. In this case the domain has no read access, which should
496 * also look like the device is non-existent. */
497 *val = 0xFFFFFFFF;
498 return ret;
499 }
501 /* Fake out read requests for some registers. */
502 switch ( reg )
503 {
504 #ifndef SLOPPY_CHECKING
505 case PCI_BASE_ADDRESS_0:
506 ret = do_base_address_access(pdev, ACC_READ, 0, len, val);
507 break;
509 case PCI_BASE_ADDRESS_1:
510 ret = do_base_address_access(pdev, ACC_READ, 1, len, val);
511 break;
513 case PCI_BASE_ADDRESS_2:
514 ret = do_base_address_access(pdev, ACC_READ, 2, len, val);
515 break;
517 case PCI_BASE_ADDRESS_3:
518 ret = do_base_address_access(pdev, ACC_READ, 3, len, val);
519 break;
521 case PCI_BASE_ADDRESS_4:
522 ret = do_base_address_access(pdev, ACC_READ, 4, len, val);
523 break;
525 case PCI_BASE_ADDRESS_5:
526 ret = do_base_address_access(pdev, ACC_READ, 5, len, val);
527 break;
529 case PCI_ROM_ADDRESS:
530 ret = do_rom_address_access(pdev, ACC_READ, len, val);
531 break;
532 #endif
534 case PCI_INTERRUPT_LINE:
535 *val = pdev->dev->irq;
536 ret = 0;
537 break;
539 default:
540 ret = pci_config_read(0, bus, dev, func, reg, len, val);
541 VERBOSE_INFO("pci read : %02x:%02x:%02x reg=0x%02x len=0x%02x "
542 "val=0x%08x\n", bus, dev, func, reg, len, *val);
543 break;
544 }
546 return ret;
547 }
550 /*
551 * Handle a PCI config space write access if the domain has access privileges.
552 */
553 static long pci_cfgreg_write(int bus, int dev, int func, int reg,
554 int len, u32 val)
555 {
556 int ret;
557 phys_dev_t *pdev;
559 if ( (ret = check_dev_acc(current, bus, dev, func, &pdev)) != 0 )
560 return ret;
562 /* special treatment for some registers */
563 switch (reg)
564 {
565 #ifndef SLOPPY_CHECKING
566 case PCI_BASE_ADDRESS_0:
567 ret = do_base_address_access(pdev, ACC_WRITE, 0, len, &val);
568 break;
570 case PCI_BASE_ADDRESS_1:
571 ret = do_base_address_access(pdev, ACC_WRITE, 1, len, &val);
572 break;
574 case PCI_BASE_ADDRESS_2:
575 ret = do_base_address_access(pdev, ACC_WRITE, 2, len, &val);
576 break;
578 case PCI_BASE_ADDRESS_3:
579 ret = do_base_address_access(pdev, ACC_WRITE, 3, len, &val);
580 break;
582 case PCI_BASE_ADDRESS_4:
583 ret = do_base_address_access(pdev, ACC_WRITE, 4, len, &val);
584 break;
586 case PCI_BASE_ADDRESS_5:
587 ret = do_base_address_access(pdev, ACC_WRITE, 5, len, &val);
588 break;
590 case PCI_ROM_ADDRESS:
591 ret = do_rom_address_access(pdev, ACC_WRITE, len, &val);
592 break;
593 #endif
595 default:
596 if ( pdev->flags != ACC_WRITE )
597 {
598 INFO("pci write not allowed %02x:%02x:%02x: "
599 "reg=0x%02x len=0x%02x val=0x%08x\n",
600 bus, dev, func, reg, len, val);
601 ret = -EPERM;
602 }
603 else
604 {
605 ret = pci_config_write(0, bus, dev, func, reg, len, val);
606 VERBOSE_INFO("pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x "
607 "val=0x%08x\n", bus, dev, func, reg, len, val);
608 }
609 break;
610 }
612 return ret;
613 }
616 static long pci_probe_root_buses(u32 *busmask)
617 {
618 phys_dev_t *pdev;
620 memset(busmask, 0, 256/8);
622 list_for_each_entry ( pdev, &current->pcidev_list, node )
623 set_bit(pdev->dev->bus->number, busmask);
625 return 0;
626 }
629 /*
630 * Demuxing hypercall.
631 */
632 long do_physdev_op(physdev_op_t *uop)
633 {
634 phys_dev_t *pdev;
635 physdev_op_t op;
636 long ret;
637 int irq;
639 if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
640 return -EFAULT;
642 switch ( op.cmd )
643 {
644 case PHYSDEVOP_PCI_CFGREG_READ:
645 ret = pci_cfgreg_read(op.u.pci_cfgreg_read.bus,
646 op.u.pci_cfgreg_read.dev,
647 op.u.pci_cfgreg_read.func,
648 op.u.pci_cfgreg_read.reg,
649 op.u.pci_cfgreg_read.len,
650 &op.u.pci_cfgreg_read.value);
651 break;
653 case PHYSDEVOP_PCI_CFGREG_WRITE:
654 ret = pci_cfgreg_write(op.u.pci_cfgreg_write.bus,
655 op.u.pci_cfgreg_write.dev,
656 op.u.pci_cfgreg_write.func,
657 op.u.pci_cfgreg_write.reg,
658 op.u.pci_cfgreg_write.len,
659 op.u.pci_cfgreg_write.value);
660 break;
662 case PHYSDEVOP_PCI_INITIALISE_DEVICE:
663 if ( (ret = check_dev_acc(current,
664 op.u.pci_initialise_device.bus,
665 op.u.pci_initialise_device.dev,
666 op.u.pci_initialise_device.func,
667 &pdev)) == 0 )
668 pcibios_enable_irq(pdev->dev);
669 break;
671 case PHYSDEVOP_PCI_PROBE_ROOT_BUSES:
672 ret = pci_probe_root_buses(op.u.pci_probe_root_buses.busmask);
673 break;
675 case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
676 ret = pirq_guest_unmask(current);
677 break;
679 case PHYSDEVOP_IRQ_STATUS_QUERY:
680 irq = op.u.irq_status_query.irq;
681 ret = -EINVAL;
682 if ( (irq < 0) || (irq >= NR_IRQS) )
683 break;
684 op.u.irq_status_query.flags = 0;
685 /* Edge-triggered interrupts don't need an explicit unmask downcall. */
686 if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL )
687 op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
688 ret = 0;
689 break;
691 default:
692 ret = -EINVAL;
693 break;
694 }
696 copy_to_user(uop, &op, sizeof(op));
697 return ret;
698 }
700 /* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */
701 /* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */
702 static char opt_physdev_dom0_hide[200] = "";
703 string_param("physdev_dom0_hide", opt_physdev_dom0_hide);
705 /* Test if boot params specify this device should NOT be visible to DOM0
706 * (e.g. so that another domain can control it instead) */
707 static int pcidev_dom0_hidden(struct pci_dev *dev)
708 {
709 char cmp[10] = "(.......)";
711 strncpy(&cmp[1], dev->slot_name, 7);
713 if ( strstr(opt_physdev_dom0_hide, dev->slot_name) == NULL )
714 return 0;
716 return 1;
717 }
720 /* Domain 0 has read access to all devices. */
721 void physdev_init_dom0(struct domain *p)
722 {
723 struct pci_dev *dev;
724 phys_dev_t *pdev;
726 INFO("Give DOM0 read access to all PCI devices\n");
728 pci_for_each_dev(dev)
729 {
730 if ( pcidev_dom0_hidden(dev) )
731 {
732 printk("Hiding PCI device %s from DOM0\n", dev->slot_name);
733 continue;
734 }
736 /* Skip bridges and other peculiarities for now.
737 *
738 * Note that this can prevent the guest from detecting devices
739 * with fn>0 on slots where the fn=0 device is a bridge. We
740 * can identify such slots by looking at the multifunction bit
741 * (top bit of hdr_type, masked out in dev->hdr_type).
742 *
743 * In Linux2.4 we find all devices because the detection code
744 * scans all functions if the read of the fn=0 device's header
745 * type fails.
746 *
747 * In Linux2.6 we set pcibios_scan_all_fns().
748 */
749 if ( (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) &&
750 (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) )
751 continue;
752 pdev = xmalloc(sizeof(phys_dev_t));
753 pdev->dev = dev;
754 pdev->flags = ACC_WRITE;
755 pdev->state = 0;
756 pdev->owner = p;
757 list_add(&pdev->node, &p->pcidev_list);
758 }
760 set_bit(DF_PHYSDEV, &p->flags);
761 }