# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 199d53efd02974b9e78f4492a3baee426e4e03c3
# Parent 14f8c17c980834ccb9da8c1f712a593ac6eacfcd
[IA64] IO ports for driver domains.
Map/unmap IO ports.
Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
xen/arch/ia64/xen/dom0_ops.c | 5 ++-
xen/arch/ia64/xen/dom_fw.c | 20 ++++++++-------
xen/arch/ia64/xen/mm.c | 56 ++++++++++++++++++++++++++++++++++++++++++
xen/include/asm-ia64/domain.h | 4 +++
xen/include/asm-ia64/iocap.h | 9 +++---
5 files changed, 79 insertions(+), 15 deletions(-)
diff -r 14f8c17c9808 -r 199d53efd029 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Thu Jul 27 09:47:59 2006 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c Thu Jul 27 10:00:00 2006 -0600
@@ -285,6 +285,7 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_
struct domain *d;
unsigned int fp = op->u.ioport_permission.first_port;
unsigned int np = op->u.ioport_permission.nr_ports;
+ unsigned int lp = fp + np - 1;
ret = -ESRCH;
d = find_domain_by_id(op->u.ioport_permission.domain);
@@ -295,9 +296,9 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_
ret = 0;
else {
if (op->u.ioport_permission.allow_access)
- ret = ioports_permit_access(d, fp, fp + np - 1);
+ ret = ioports_permit_access(d, fp, lp);
else
- ret = ioports_deny_access(d, fp, fp + np - 1);
+ ret = ioports_deny_access(d, fp, lp);
}
put_domain(d);
diff -r 14f8c17c9808 -r 199d53efd029 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c Thu Jul 27 09:47:59 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c Thu Jul 27 10:00:00 2006 -0600
@@ -855,15 +855,17 @@ dom_fw_init (struct domain *d, struct ia
} else {
#ifndef CONFIG_XEN_IA64_DOM0_VP
/* Dom0 maps legacy mmio in first MB. */
- MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1);
-
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
-#endif
- /* hypercall patches live here, masquerade as reserved PAL
memory */
-
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
1);
- /* Create a dummy entry for IO ports, so that IO accesses are
- trapped by Xen. */
- MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE,EFI_MEMORY_UC,
- 0x00000ffffc000000, 0x00000fffffffffff, 1);
+ MAKE_MD(EFI_LOADER_DATA, EFI_MEMORY_WB, 0*MB, 1*MB, 1);
+ MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+ HYPERCALL_END, maxmem, 1);
+#endif
+ /* hypercall patches live here, masquerade as reserved
+ PAL memory */
+ MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+ HYPERCALL_START, HYPERCALL_END, 1);
+ /* Create an entry for IO ports. */
+ MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
+ IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE, 1);
MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
}
diff -r 14f8c17c9808 -r 199d53efd029 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Thu Jul 27 09:47:59 2006 -0600
+++ b/xen/arch/ia64/xen/mm.c Thu Jul 27 10:00:00 2006 -0600
@@ -179,6 +179,8 @@ static void domain_page_flush(struct dom
static void domain_page_flush(struct domain* d, unsigned long mpaddr,
unsigned long old_mfn, unsigned long new_mfn);
#endif
+
+extern unsigned long ia64_iobase;
static struct domain *dom_xen, *dom_io;
@@ -892,6 +894,60 @@ assign_domain_page(struct domain *d,
// because __assign_domain_page() uses set_pte_rel() which has
// release semantics, smp_mb() isn't needed.
__assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
+}
+
+int
+ioports_permit_access(struct domain *d, unsigned long fp, unsigned long lp)
+{
+ int ret;
+ unsigned long off;
+ unsigned long fp_offset;
+ unsigned long lp_offset;
+
+ ret = rangeset_add_range(d->arch.ioport_caps, fp, lp);
+ if (ret != 0)
+ return ret;
+
+ fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK;
+ lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
+
+ for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE)
+ __assign_domain_page(d, IO_PORTS_PADDR + off,
+ ia64_iobase + off, ASSIGN_nocache);
+
+ return 0;
+}
+
+int
+ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp)
+{
+ int ret;
+ struct mm_struct *mm = &d->arch.mm;
+ unsigned long off;
+ unsigned long fp_offset;
+ unsigned long lp_offset;
+
+ ret = rangeset_remove_range(d->arch.ioport_caps, fp, lp);
+ if (ret != 0)
+ return ret;
+
+ fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK;
+ lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
+
+ for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) {
+ unsigned long mpaddr = IO_PORTS_PADDR + off;
+ volatile pte_t *pte;
+ pte_t old_pte;
+
+ pte = lookup_noalloc_domain_pte_none(d, mpaddr);
+ BUG_ON(pte == NULL);
+ BUG_ON(pte_none(*pte));
+
+ // clear pte
+ old_pte = ptep_get_and_clear(mm, mpaddr, pte);
+ }
+ domain_flush_vtlb_all();
+ return 0;
}
#ifdef CONFIG_XEN_IA64_DOM0_VP
diff -r 14f8c17c9808 -r 199d53efd029 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h Thu Jul 27 09:47:59 2006 -0600
+++ b/xen/include/asm-ia64/domain.h Thu Jul 27 10:00:00 2006 -0600
@@ -196,6 +196,10 @@ struct arch_vcpu {
#include <asm/uaccess.h> /* for KERNEL_DS */
#include <asm/pgtable.h>
+/* Guest physical address of IO ports space. */
+#define IO_PORTS_PADDR 0x00000ffffc000000UL
+#define IO_PORTS_SIZE 0x0000000004000000UL
+
#endif /* __ASM_DOMAIN_H__ */
/*
diff -r 14f8c17c9808 -r 199d53efd029 xen/include/asm-ia64/iocap.h
--- a/xen/include/asm-ia64/iocap.h Thu Jul 27 09:47:59 2006 -0600
+++ b/xen/include/asm-ia64/iocap.h Thu Jul 27 10:00:00 2006 -0600
@@ -7,10 +7,11 @@
#ifndef __IA64_IOCAP_H__
#define __IA64_IOCAP_H__
-#define ioports_permit_access(d, s, e) \
- rangeset_add_range((d)->arch.ioport_caps, s, e)
-#define ioports_deny_access(d, s, e) \
- rangeset_remove_range((d)->arch.ioport_caps, s, e)
+extern int ioports_permit_access(struct domain *d,
+ unsigned long s, unsigned long e);
+extern int ioports_deny_access(struct domain *d,
+ unsigned long s, unsigned long e);
+
#define ioports_access_permitted(d, s, e) \
rangeset_contains_range((d)->arch.ioport_caps, s, e)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|