[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-ia64-devel] [RFC] Extended I/O port space support



Hi Alex,

I have a small comment.  The patch includes indent both tab and 
white space.  It has six lines.  I comment into the patch. 

Best regards,
 Kan


>diff -r 0cf6b75423e9 linux-2.6-xen-sparse/arch/ia64/pci/pci.c
>--- a/linux-2.6-xen-sparse/arch/ia64/pci/pci.c Mon Jun 04 14:17:54 2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/ia64/pci/pci.c Thu Jun 07 11:38:41 2007 -0600
>@@ -164,6 +164,11 @@ new_space (u64 phys_base, int sparse)
>       i = num_io_spaces++;
>       io_space[i].mmio_base = mmio_base;
>       io_space[i].sparse = sparse;
>+
>+#ifdef CONFIG_XEN
>+      if (is_initial_xendomain())
>+              HYPERVISOR_add_io_space(phys_base, sparse, i);
>+#endif
> 
>       return i;
> }
>diff -r 0cf6b75423e9 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
>--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h        Mon Jun 04 
>14:17:54
> 2007 -0600
>+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h        Thu Jun 07 
>08:37:01
> 2007 -0600
>@@ -387,6 +387,15 @@ xencomm_arch_hypercall_fpswa_revision(st
> {
>       return _hypercall2(int, ia64_dom0vp_op,
>                          IA64_DOM0VP_fpswa_revision, arg);
>+}
>+
>+static inline int
>+HYPERVISOR_add_io_space(unsigned long phys_base,
>+                      unsigned long sparse,
>+                      unsigned long space_number)
>+{
>+      return _hypercall4(int, ia64_dom0vp_op, IA64_DOM0VP_add_io_space,
>+                         phys_base, sparse, space_number);
> }
> 
> // for balloon driver
>diff -r 0cf6b75423e9 xen/arch/ia64/xen/dom0_ops.c
>--- a/xen/arch/ia64/xen/dom0_ops.c     Mon Jun 04 14:17:54 2007 -0600
>+++ b/xen/arch/ia64/xen/dom0_ops.c     Thu Jun 07 15:52:28 2007 -0600
>@@ -363,6 +363,40 @@ dom0vp_fpswa_revision(XEN_GUEST_HANDLE(u
>     return 0;
> }
> 
>+static unsigned long
>+dom0vp_add_io_space(struct domain *d, unsigned long phys_base,
>+                    unsigned long sparse, unsigned long space_number)
>+{
>+    unsigned int fp, lp;
>+
>+    printk("%s(%d, 0x%016lx, %ssparse, %d)\n", __func__, d->domain_id,
>+           phys_base, sparse ? "" : "not-", space_number);
>+    /*
>+     * Registering new io_space roughly based on linux
>+     * arch/ia64/pci/pci.c:new_space()
>+     */
>+    if (phys_base == 0)
>+        return 0;  /* legacy I/O port space */
>+
>+    /*
>+     * We may need a valid bit in the io_space struct so we
>+     * can initialize these more asynchornously.  But this makes
>+     * sure we register spaces in lock step with dom0.
>+     */
>+    if (space_number > MAX_IO_SPACES || space_number != num_io_spaces)
>+        return -EINVAL;
>+
>+    io_space[space_number].mmio_base = phys_base;
>+    io_space[space_number].sparse = sparse;
>+
>+    num_io_spaces++;
>+
>+    fp = space_number << IO_SPACE_BITS;
>+    lp = fp | 0xffff;
>+
>+    return ioports_permit_access(d, fp, lp);
>+}
>+
> unsigned long
> do_dom0vp_op(unsigned long cmd,
>              unsigned long arg0, unsigned long arg1, unsigned long arg2,
>@@ -419,6 +453,9 @@ do_dom0vp_op(unsigned long cmd,
>         ret = dom0vp_fpswa_revision(hnd);
>         break;
>     }
>+    case IA64_DOM0VP_add_io_space:
>+        ret = dom0vp_add_io_space(d, arg0, arg1, arg2);
>+        break;
>     default:
>         ret = -1;
>               printk("unknown dom0_vp_op 0x%lx\n", cmd);
>diff -r 0cf6b75423e9 xen/arch/ia64/xen/mm.c
>--- a/xen/arch/ia64/xen/mm.c   Mon Jun 04 14:17:54 2007 -0600
>+++ b/xen/arch/ia64/xen/mm.c   Thu Jun 07 15:55:58 2007 -0600
>@@ -886,69 +886,123 @@ assign_domain_page(struct domain *d,
> }
> 
> int
>-ioports_permit_access(struct domain *d, unsigned long fp, unsigned long lp)
>-{
>+ioports_permit_access(struct domain *d, unsigned int fp, unsigned int lp)
>+{
>+    struct io_space *space;
>+    unsigned long mmio_start, mmio_end, mach_start;
>     int ret;
>-    unsigned long off;
>-    unsigned long fp_offset;
>-    unsigned long lp_offset;
>-
>+
>+    printk("%s(%d, 0x%x, 0x%x)\n", __func__, d->domain_id, fp, lp);
>+
>+    if (IO_SPACE_NR(fp) >= num_io_spaces) {
>+        dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fp
>, lp);
>+        return -EFAULT;
>+    }
>+
>+    /*
>+     * The ioport_cap rangeset tracks the I/O port address including
>+     * the port space ID.  This means port space IDs need to match
>+     * between Xen and the guest.  This is also a requirement because
>+     * the hypercall to pass these port ranges only uses a u32.
>+     */
>     ret = rangeset_add_range(d->arch.ioport_caps, fp, lp);
>     if (ret != 0)
>         return ret;
> 
>-    /* Domain 0 doesn't virtualize IO ports space. */
>-    if (d == dom0)
>+    space = &io_space[IO_SPACE_NR(fp)];
>+
>+    /* Domain 0 doesn't virtualize legacy IO ports space. */
>+    if (d == dom0 && space == &io_space[0])
>         return 0;
> 
>-    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)
>-        (void)__assign_domain_page(d, IO_PORTS_PADDR + off,
>-                                   __pa(ia64_iobase) + off, ASSIGN_nocache);
>+    fp = IO_SPACE_PORT(fp);
>+    lp = IO_SPACE_PORT(lp);
>+
>+    if (space->sparse) {
>+        mmio_start = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK;
>+        mmio_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
>+    } else {
>+        mmio_start = fp & ~PAGE_MASK;
>+        mmio_end = PAGE_ALIGN(lp);
>+    }
>+
>+    /*
>+     * The "machine first port" is not necessarily identity mapped
>+     * to the guest first port.  At least for the legacy range.
>+     */
>+    mach_start = mmio_start | __pa(space->mmio_base);
>+
>+    if (space == &io_space[0] && d != dom0) {
>+      mmio_start |= IO_PORTS_PADDR;
>+      mmio_end |= IO_PORTS_PADDR;

Here, two lines.


>+    } else {
>+      mmio_start |= __pa(space->mmio_base);
>+      mmio_end |= __pa(space->mmio_base);

Here, two lines.

>+    }
>+
>+    while (mmio_start <= mmio_end) {
>+        (void)__assign_domain_page(d, mmio_start, mach_start, 
>ASSIGN_nocache); 
>+        mmio_start += PAGE_SIZE;
>+        mach_start += PAGE_SIZE;
>+    }
> 
>     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))
>+ioports_has_allowed(struct domain *d, unsigned int fp, unsigned int lp)
>+{
>+    for (; fp < lp; fp++)
>+        if (rangeset_contains_singleton(d->arch.ioport_caps, fp))
>             return 1;
>+
>     return 0;
> }
> 
> int
>-ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp)
>+ioports_deny_access(struct domain *d, unsigned int fp, unsigned int lp)
> {
>     int ret;
>     struct mm_struct *mm = &d->arch.mm;
>-    unsigned long off;
>-    unsigned long io_ports_base;
>-    unsigned long fp_offset;
>-    unsigned long lp_offset;
>+    unsigned long mmio_start, mmio_end, mmio_base;
>+    unsigned int fp_base, lp_base;
>+    struct io_space *space;
>+
>+    printk("%s(%d, 0x%x, 0x%x)\n", __func__, d->domain_id, fp, lp);
>+
>+    if (IO_SPACE_NR(fp) >= num_io_spaces) {
>+        dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fp
>, lp);
>+        return -EFAULT;
>+    }
> 
>     ret = rangeset_remove_range(d->arch.ioport_caps, fp, lp);
>     if (ret != 0)
>         return ret;
>-    if (d == dom0)
>-        io_ports_base = __pa(ia64_iobase);
>+
>+    space = &io_space[IO_SPACE_NR(fp)];
>+    fp_base = IO_SPACE_PORT(fp);
>+    lp_base = IO_SPACE_PORT(lp);
>+
>+    if (space->sparse) {
>+        mmio_start = IO_SPACE_SPARSE_ENCODING(fp_base) & ~PAGE_MASK;
>+        mmio_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp_base));
>+    } else {
>+        mmio_start = fp_base & ~PAGE_MASK;
>+        mmio_end = PAGE_ALIGN(lp_base);
>+    }
>+
>+    if (space == &io_space[0] && d != dom0)
>+      mmio_base = IO_PORTS_PADDR;

Here.


>     else
>-        io_ports_base = IO_PORTS_PADDR;
>-
>-    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_base + off;
>-        unsigned long port;
>+      mmio_base = __pa(space->mmio_base);

Here.


>+
>+    for (; mmio_start < mmio_end; mmio_start += PAGE_SIZE) {
>+        unsigned int port;
>+        unsigned long mpaddr;
>         volatile pte_t *pte;
>         pte_t old_pte;
> 
>-        port = IO_SPACE_SPARSE_DECODING (off);
>+        port = IO_SPACE_SPARSE_DECODING(mmio_start);
>         if (port < fp || port + IO_SPACE_SPARSE_PORTS_PER_PAGE - 1 > lp) {
>             /* Maybe this covers an allowed port.  */
>             if (ioports_has_allowed(d, port,
>@@ -956,6 +1010,7 @@ ioports_deny_access(struct domain *d, un
>                 continue;
>         }
> 
>+        mpaddr = mmio_start | mmio_base;
>         pte = lookup_noalloc_domain_pte_none(d, mpaddr);
>         BUG_ON(pte == NULL);
>         BUG_ON(pte_none(*pte));
>diff -r 0cf6b75423e9 xen/include/asm-ia64/iocap.h
>--- a/xen/include/asm-ia64/iocap.h     Mon Jun 04 14:17:54 2007 -0600
>+++ b/xen/include/asm-ia64/iocap.h     Thu Jun 07 15:57:30 2007 -0600
>@@ -8,9 +8,9 @@
> #define __IA64_IOCAP_H__
> 
> extern int ioports_permit_access(struct domain *d,
>-                                 unsigned long s, unsigned long e);
>+                               unsigned int s, unsigned int e);
> extern int ioports_deny_access(struct domain *d,
>-                               unsigned long s, unsigned long e);
>+                             unsigned int s, unsigned int e);
> 
> #define ioports_access_permitted(d, s, e)               \
>     rangeset_contains_range((d)->arch.ioport_caps, s, e)
>diff -r 0cf6b75423e9 xen/include/public/arch-ia64.h
>--- a/xen/include/public/arch-ia64.h   Mon Jun 04 14:17:54 2007 -0600
>+++ b/xen/include/public/arch-ia64.h   Wed Jun 06 16:52:17 2007 -0600
>@@ -526,6 +526,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
> /* get fpswa revision */
> #define IA64_DOM0VP_fpswa_revision      10
> 
>+/* Add an I/O port space range */
>+#define IA64_DOM0VP_add_io_space        11
>+
> // flags for page assignement to pseudo physical address space
> #define _ASSIGN_readonly                0
> #define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)
>
>
>
>_______________________________________________
>Xen-ia64-devel mailing list
>Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
>http://lists.xensource.com/xen-ia64-devel


_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.