# HG changeset patch # User gingold@virtu10 # Node ID d9aff5c0d64324c44f555be1a7ed312725489599 # Parent 2d73714911c2103958e3bc82957a78cacf4d8bfe Bug fixes: dom0 do not virtualize IO space, do not over-deny IO ports. Signed-off-by: Tristan Gingold diff -r 2d73714911c2 -r d9aff5c0d643 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Thu Jul 27 10:43:34 2006 -0600 +++ b/xen/arch/ia64/xen/mm.c Mon Jul 31 07:17:50 2006 +0200 @@ -908,6 +908,10 @@ ioports_permit_access(struct domain *d, if (ret != 0) return ret; + /* Domain 0 doesn't virtualize IO ports space. */ + if (d == dom0) + return 0; + fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK; lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp)); @@ -915,6 +919,16 @@ ioports_permit_access(struct domain *d, __assign_domain_page(d, IO_PORTS_PADDR + off, ia64_iobase + off, ASSIGN_nocache); + return 0; +} + +static int +ioports_has_allowed (struct domain *d, unsigned long fp, unsigned long lp) +{ + unsigned long i; + for (i = fp; i < lp; i++) + if (rangeset_contains_singleton (d->arch.ioport_caps, i)) + return 1; return 0; } @@ -936,8 +950,17 @@ ioports_deny_access(struct domain *d, un for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) { unsigned long mpaddr = IO_PORTS_PADDR + off; + unsigned long port; volatile pte_t *pte; pte_t old_pte; + + port = IO_SPACE_SPARSE_DECODING (off); + if (port < fp || port + IO_SPACE_SPARSE_PORTS_PER_PAGE > lp) { + /* Maybe this covers an allowed port. */ + if (ioports_has_allowed (d, port, + port + IO_SPACE_SPARSE_PORTS_PER_PAGE)) + continue; + } pte = lookup_noalloc_domain_pte_none(d, mpaddr); BUG_ON(pte == NULL); diff -r 2d73714911c2 -r d9aff5c0d643 xen/include/asm-ia64/linux-xen/asm/io.h --- a/xen/include/asm-ia64/linux-xen/asm/io.h Thu Jul 27 10:43:34 2006 -0600 +++ b/xen/include/asm-ia64/linux-xen/asm/io.h Mon Jul 31 07:17:50 2006 +0200 @@ -46,6 +46,12 @@ #define IO_SPACE_PORT(port) ((port) & (IO_SPACE_SIZE - 1)) #define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | (p & 0xfff)) + +#ifdef XEN +/* Offset to IO port; do not catch error. */ +#define IO_SPACE_SPARSE_DECODING(off) ((((off) >> 12) << 2) | (off & 0x3)) +#define IO_SPACE_SPARSE_PORTS_PER_PAGE (0x4 << (PAGE_SHIFT - 12)) +#endif struct io_space { unsigned long mmio_base; /* base in MMIO space */