[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |