On Thu, Oct 16, 2008 at 07:37:51PM +0800, Xu, Anthony wrote:
> use VTD to assing device, guest port may not be equal to host port.
> Change ioports_permit_access interface
> add deassign_domain_mmio_page interface
> 
> Signed-off-by; Anthony Xu < [EMAIL PROTECTED] >

Some comments.

- ioports_permit_access()
  x86 didn't change its prototype.
  Why does only ia64 need to change it?
  Or will x86 also change it?

  I suppose, it would be nice to map the port io area
  to arbitrary guest physical area.
  But I'm not sure how x86 will go with XEN_DOMCTL_ioport_mapping.

- deassign_domain_mmio_page()
  calling __assgin_domain_page() may result in page reference count
  leak because the corresponding p2m entry may be changed to another
  value.
  So you want to modify zap_domain_page_one() so that it accepts
  iomem page and call it from deassign_domain_mmio_page().

- probably it would better to split this patch into two ones.

thanks,

> use VTD to assing device, guest port may not be equal to host port.
> Change ioports_permit_access interface
> add deassign_domain_mmio_page interface
> 
> Signed-off-by; Anthony Xu < [EMAIL PROTECTED] >
> 
> 
> 
> 
> 
> diff -r 42c7733c1a2a xen/arch/ia64/xen/dom0_ops.c
> --- a/xen/arch/ia64/xen/dom0_ops.c    Thu Oct 16 18:18:39 2008 +0800
> +++ b/xen/arch/ia64/xen/dom0_ops.c    Thu Oct 16 19:13:01 2008 +0800
> @@ -203,7 +203,7 @@
>              ret = 0;
>          else {
>              if (op->u.ioport_permission.allow_access)
> -                ret = ioports_permit_access(d, fp, lp);
> +                ret = ioports_permit_access(d, fp, fp, lp);
>              else
>                  ret = ioports_deny_access(d, fp, lp);
>          }
> @@ -522,7 +522,7 @@
>      fp = space_number << IO_SPACE_BITS;
>      lp = fp | 0xffff;
>  
> -    return ioports_permit_access(d, fp, lp);
> +    return ioports_permit_access(d, fp, fp, lp);
>  }
>  
>  unsigned long
> diff -r 42c7733c1a2a xen/arch/ia64/xen/domain.c
> --- a/xen/arch/ia64/xen/domain.c      Thu Oct 16 18:18:39 2008 +0800
> +++ b/xen/arch/ia64/xen/domain.c      Thu Oct 16 19:13:01 2008 +0800
> @@ -1995,7 +1995,7 @@
>               BUG();
>       if (irqs_permit_access(d, 0, NR_IRQS-1))
>               BUG();
> -     if (ioports_permit_access(d, 0, 0xffff))
> +     if (ioports_permit_access(d, 0, 0, 0xffff))
>               BUG();
>  }
>  
> diff -r 42c7733c1a2a xen/arch/ia64/xen/mm.c
> --- a/xen/arch/ia64/xen/mm.c  Thu Oct 16 18:18:39 2008 +0800
> +++ b/xen/arch/ia64/xen/mm.c  Thu Oct 16 19:13:01 2008 +0800
> @@ -984,15 +984,22 @@
>                                 ASSIGN_writable | ASSIGN_pgc_allocated);
>  }
>  
> +/* 
> + * Inpurt
> + * fgp: first guest port
> + * fmp: first machine port
> + * lmp: last machine port
> + */
>  int
> -ioports_permit_access(struct domain *d, unsigned int fp, unsigned int lp)
> +ioports_permit_access(struct domain *d, unsigned int fgp,
> +        unsigned int fmp, unsigned int lmp)
>  {
>      struct io_space *space;
> -    unsigned long mmio_start, mmio_end, mach_start;
> +    unsigned long mmio_start, mach_start, mach_end;
>      int ret;
>  
> -    if (IO_SPACE_NR(fp) >= num_io_spaces) {
> -        dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fp, 
> lp);
> +    if (IO_SPACE_NR(fmp) >= num_io_spaces) {
> +        dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fmp, 
> lmp);
>          return -EFAULT;
>      }
>  
> @@ -1006,42 +1013,44 @@
>       * I/O port spaces and thus will number port spaces differently.
>       * This is ok, they don't make use of this interface.
>       */
> -    ret = rangeset_add_range(d->arch.ioport_caps, fp, lp);
> +    ret = rangeset_add_range(d->arch.ioport_caps, fmp, lmp);
>      if (ret != 0)
>          return ret;
>  
> -    space = &io_space[IO_SPACE_NR(fp)];
> +    space = &io_space[IO_SPACE_NR(fmp)];
>  
>      /* Legacy I/O on dom0 is already setup */
>      if (d == dom0 && space == &io_space[0])
>          return 0;
>  
> -    fp = IO_SPACE_PORT(fp);
> -    lp = IO_SPACE_PORT(lp);
> +    fmp = IO_SPACE_PORT(fmp);
> +    lmp = IO_SPACE_PORT(lmp);
>  
>      if (space->sparse) {
> -        mmio_start = IO_SPACE_SPARSE_ENCODING(fp) & PAGE_MASK;
> -        mmio_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
> +        mach_start = IO_SPACE_SPARSE_ENCODING(fmp) & PAGE_MASK;
> +        mach_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lmp));
>      } else {
> -        mmio_start = fp & PAGE_MASK;
> -        mmio_end = PAGE_ALIGN(lp);
> +        mach_start = fmp & PAGE_MASK;
> +        mach_end = PAGE_ALIGN(lmp);
>      }
>  
>      /*
>       * 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);
> +    mach_start = mach_start | __pa(space->mmio_base);
> +    mach_end = mach_end | __pa(space->mmio_base);
>  
> -    if (space == &io_space[0]) {
> +    mmio_start = IO_SPACE_SPARSE_ENCODING(fgp) & PAGE_MASK;
> +
> +    if ( VMX_DOMAIN(d->vcpu[0]))
> +        mmio_start |= LEGACY_IO_START;
> +    else if (space == &io_space[0])
>          mmio_start |= IO_PORTS_PADDR;
> -        mmio_end |= IO_PORTS_PADDR;
> -    } else {
> +    else
>          mmio_start |= __pa(space->mmio_base);
> -        mmio_end |= __pa(space->mmio_base);
> -    }
>  
> -    while (mmio_start <= mmio_end) {
> +    while (mach_start < mach_end) {
>          __assign_domain_page(d, mmio_start,
>                  mach_start, ASSIGN_nocache | ASSIGN_direct_io); 
>          mmio_start += PAGE_SIZE;
> @@ -1091,7 +1100,9 @@
>          mmio_end = PAGE_ALIGN(lp_base);
>      }
>  
> -    if (space == &io_space[0] && d != dom0)
> +    if (VMX_DOMAIN(d->vcpu[0]))
> +        mmio_base = LEGACY_IO_START;
> +    else if (space == &io_space[0] && d != dom0)
>          mmio_base = IO_PORTS_PADDR;
>      else
>          mmio_base = __pa(space->mmio_base);
> @@ -1217,6 +1228,33 @@
>  
>      return mpaddr;
>  }
> +
> +int
> +deassign_domain_mmio_page(struct domain *d, unsigned long mpaddr,
> +        unsigned long phys_addr, unsigned long size )
> +{
> +    unsigned long addr = mpaddr & PAGE_MASK;
> +    unsigned long end = PAGE_ALIGN(mpaddr + size);
> +
> +    if (size == 0) {
> +        gdprintk(XENLOG_INFO, "%s: domain %p mpaddr 0x%lx size = 0x%lx\n",
> +                __func__, d, mpaddr, size);
> +    }
> +    if (!efi_mmio(phys_addr, size)) {
> +#ifndef NDEBUG
> +        gdprintk(XENLOG_INFO, "%s: domain %p mpaddr 0x%lx size = 0x%lx\n",
> +                __func__, d, mpaddr, size);
> +#endif
> +        return -EINVAL;
> +    }
> +
> +    for (; addr < end; addr += PAGE_SIZE ) {
> +        __assign_domain_page(d, addr, 0,
> +                ASSIGN_nocache | ASSIGN_direct_io);
> +    }
> +    return 0;
> +}
> +
>  
>  unsigned long
>  assign_domain_mach_page(struct domain *d,
> diff -r 42c7733c1a2a xen/include/asm-ia64/iocap.h
> --- a/xen/include/asm-ia64/iocap.h    Thu Oct 16 18:18:39 2008 +0800
> +++ b/xen/include/asm-ia64/iocap.h    Thu Oct 16 19:13:01 2008 +0800
> @@ -7,7 +7,7 @@
>  #ifndef __IA64_IOCAP_H__
>  #define __IA64_IOCAP_H__
>  
> -extern int ioports_permit_access(struct domain *d,
> +extern int ioports_permit_access(struct domain *d, unsigned int gs,
>                                unsigned int s, unsigned int e);
>  extern int ioports_deny_access(struct domain *d,
>                              unsigned int s, unsigned int e);
> 
> 

-- 
yamahata

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

Reply via email to