On Mon, 2007-09-10 at 09:56 +0100, Keir Fraser wrote:
> Hi,
> 
> A provisional patchqueue for Xen 3.1.1 is available at
> http://xenbits.xensource.com/xen-3.1-testing.pq.hg. This pq partners with
> http://xenbits.xensource.com/xen-3.1-testing.hg.
> 
> Please kick this pq around and check whether the patches you want to see in
> 3.1.1 are included.

Hi Keir,

   Here's a proposed list of patches for ia64:

Must have fixes:

http://xenbits.xensource.com/xen-unstable.hg?rev/51f5bea7b0d8
15348:51f5bea7b0d8 - adds free_irq(), necessary for build

http://xenbits.xensource.com/xen-unstable.hg?rev/b46c2ff6dfb0
15331:b46c2ff6dfb0 - fixes boot on NUMA systems

http://xenbits.xensource.com/xen-unstable.hg?rev/f536eb8576ee
15579:f536eb8576ee - fix VTI domain shutdown

http://xenbits.xensource.com/xen-unstable.hg?rev/d4f59e652078
15096:d4f59e652078 - fix pcifront with CONFIG_NUMA

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/1483ef74511b
linux/56:1483ef74511b - update for acm interface changes

http://lists.xensource.com/archives/html/xen-ia64-devel/2006-11/msg00358.html
ia64-sal-get-state-info - Avoid GFP_KERNEL allocation from interrupt
context.  This was only recently fixed in upstream and is dependent on
other patches.  This is the simple fix proposed on the mailing list.
Patch attached.

These are all related to working out bugs and save location for NVRAM
support (must have):

http://xenbits.xensource.com/xen-unstable.hg?rev/71377eab1874
15349:71377eab1874 - white space cleanup - necessary for subsequent
patches

http://xenbits.xensource.com/xen-unstable.hg?rev/634b7f7f8584
*15265:634b7f7f8584 - allow domu nvram saving to fail gracefully

http://xenbits.xensource.com/xen-unstable.hg?rev/1623f5f5094f
15364:1623f5f5094f - don't save NVRAM on PV guests

http://xenbits.xensource.com/xen-unstable.hg?rev/33cc64dcaead
15365:33cc64dcaead - create NVRAM save directory

http://xenbits.xensource.com/xen-unstable.hg?rev/fd0103b55504
15366:fd0103b55504 - error checking for creat NVRAM save directory

http://xenbits.xensource.com/xen-unstable.hg?rev/38d061886873
15555:38d061886873 - avoid saving garbage to NVRAM on config error

http://xenbits.xensource.com/xen-unstable.hg?rev/2a5b463f2e8d
15557:2a5b463f2e8d - fix NVRAM save on reboot

http://xenbits.xensource.com/ext/xen-ia64-unstable.hg?rev/6644d8486266
ia64/15762:6644d8486266 - cleanup NVRAM failure case

http://xenbits.xensource.com/ext/xen-ia64-unstable.hg?rev/f88eea67a469
*ia64/15764:f88eea67a469 - move NVRAM from /usr to /var

These add the PCI Controller backend (high want - driver domains on some
systems won't work without this):

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/93a955c2bebb
linux/46:93a955c2bebb - introduces controller backend

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/a62cfa35d3b5
*linux/55:a62cfa35d3b5 - add hypercall to register i/o spaces

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/452c5d4a5537
*linux/61:452c5d4a5537 - enable controller as default PCI backend

http://xenbits.xensource.com/xen-unstable.hg?rev/601509daabfc
*15353:601509daabfc - xen side support for multiple i/o spaces

Patches with an asterisk above require some modification to apply (white
space/file location/invalid chunks).  I've attached the modified
versions below.  Also note that 15265 is intentionally applied after
15349 above.  There's some screwiness around a merge for these and it
was easier to modify the white space in the smaller one and apply it
later.

   Other ia64'ers, please speak up if there's something else missing.
Thanks,

        Alex


-- 
Alex Williamson                             HP Open Source & Linux Org.
# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1181644323 -3600
# Node ID 634b7f7f8584f478c9e45a98998c7e7c1b8e3b3d
# Parent  e1c54c14220a4d4ab38d8a3d409ab678275a5426
[IA64] When a domU is destroyed, it will fall into NVRAM saving
path. But if there is no NVRAM file for the domU, the save operation
would fail. Then domU blocked by Xend's exception. This patch fixs
that issue.

Signed-off-by: Zhang Xin <[EMAIL PROTECTED]>

diff -r e1c54c14220a -r 634b7f7f8584 tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Tue Jun 12 11:29:27 2007 +0100
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Tue Jun 12 11:32:03 2007 +0100
@@ -712,11 +712,15 @@ int xc_ia64_save_to_nvram(int xc_handle,
     xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd);
 
     if ( !IS_VALID_NVRAM_FD(nvram_fd) )
-    {
         PERROR("Nvram not be initialized. Nvram save fail!\n");
-        return -1;
-    }
-    return copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd);      
+    else
+        copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd); 
+
+    // although save to nvram maybe fail, we don't return any error number
+    // to Xend. This is quite logical because damage of NVRAM on native would 
+    // not block OS's executive path. Return error number will cause an 
exception 
+    // of Xend and block XenU when it destroy.
+    return 0;
 }
 
 #define NVRAM_FILE_PATH        "/usr/lib/xen/boot/nvram_"
@@ -862,7 +866,10 @@ setup_guest(int xc_handle, uint32_t dom,
                nvram_start = 0;
        else
                if ( copy_from_nvram_to_GFW(xc_handle, dom, (int)nvram_fd ) == 
-1 )
+               {
                        nvram_start = 0;
+                       close(nvram_fd);
+               }
 
     vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1;
 
# HG changeset patch
# User Alex Williamson <[EMAIL PROTECTED]>
# Date 1188325537 21600
# Node ID f88eea67a46997c79b56e5ba595f0572584d9d51
# Parent  c21bd325088a2161206bb0ae03ebf4a5bee5569e
[IA64] Move nvram from /usr to /var

Presently nvram is stored in /usr/lib/xen/boot/nvram_<domain> next to the guest
firmware.  This violates the FHS because /usr might be mounted read-only.  This
patch moves the nvram storage to /var/lib/xen/nvram/nvram_<domain>

Also clean up:
- references to stat_buf assumed that stat() had succeeded; use access()
  instead since it's easier and doesn't require stat_buf at all
- nvram_path[PATH_MAX] instead of nvram_path[100]
- strncpy(..., strlen(src)) is meaningless, re-order length tests to work
  correctly

Signed-off-by: Aron Griffis <[EMAIL PROTECTED]>

diff -r c21bd325088a -r f88eea67a469 tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Tue Aug 28 12:24:27 2007 -0600
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Tue Aug 28 12:25:37 2007 -0600
@@ -5,6 +5,7 @@
 #include "xc_elf.h"
 #include "xc_efi.h"
 #include <stdlib.h>
+#include <unistd.h>
 #include <zlib.h>
 #include "xen/arch-ia64.h"
 #include <xen/hvm/ioreq.h>
@@ -596,7 +597,7 @@ copy_from_nvram_to_GFW(int xc_handle, ui
     unsigned int nr_pages = NVRAM_SIZE >> PAGE_SHIFT;
     struct stat file_stat;
     char buf[NVRAM_SIZE] = {0};
-       
+
     if ( fstat(nvram_fd, &file_stat) < 0 )
     {
         PERROR("Cannot get Nvram file info! Guest will boot without "
@@ -759,43 +760,41 @@ int xc_ia64_save_to_nvram(int xc_handle,
     return 0;
 }
 
-#define NVRAM_DIR       "/usr/lib/xen/boot/"
-#define NVRAM_FILE_PATH "/usr/lib/xen/boot/nvram_"
+#define NVRAM_DIR         "/var/lib/xen/nvram/"
+#define NVRAM_FILE_PREFIX "nvram_"
 
 int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom)
 {
-    int file_path_len = strlen(NVRAM_FILE_PATH);
-    uint64_t nvram_fd = 0;
-    char nvram_path[100] = {0};
-    struct stat stat_buf;
-
-    if ( stat(NVRAM_DIR, &stat_buf) == -1 ) {
+    uint64_t nvram_fd;
+    char nvram_path[PATH_MAX] = NVRAM_DIR;
+
+    if ( access(nvram_path, R_OK|W_OK|X_OK) == -1 ) {
         if ( errno != ENOENT )
         {
-            PERROR("Error stat'ing NVRAM dir %s.", NVRAM_DIR);
+            PERROR("Error stat'ing NVRAM dir %s.", nvram_path);
             return -1;
         }
-        if ( mkdir(NVRAM_DIR, 0755) == -1 )
+        if ( mkdir(nvram_path, 0755) == -1 )
         {
-            PERROR("Unable to create NVRAM store directory %s.", NVRAM_DIR);
+            PERROR("Unable to create NVRAM store directory %s.", nvram_path);
             return -1;
         }
     }
 
-    if ( !(stat_buf.st_mode & S_IRUSR) || !(stat_buf.st_mode & S_IWUSR) )
-    {
+    if ( access(nvram_path, R_OK|W_OK|X_OK) == -1 ) {
         errno = EACCES;
-        PERROR("No R/W permission to NVRAM store directory %s.", NVRAM_DIR);
-        return -1;
-    }
-
-    strncpy(nvram_path, NVRAM_FILE_PATH, file_path_len);
-    if ( file_path_len + strlen(dom_name) + 1 > sizeof(nvram_path) )
+        PERROR("No RWX permission to NVRAM store directory %s.", nvram_path);
+        return -1;
+    }
+
+    if ( strlen(nvram_path) + strlen(NVRAM_FILE_PREFIX) +
+         strlen(dom_name) + 1 > sizeof(nvram_path) )
     {
         PERROR("Nvram file path is too long!\n");
         return -1;
     }
-    strcpy(nvram_path + file_path_len, dom_name);
+    strcat(nvram_path, NVRAM_FILE_PREFIX);
+    strcat(nvram_path, dom_name);
 
     nvram_fd = nvram_init(nvram_path);
     if ( nvram_fd == (uint64_t)(-1) )
# HG changeset patch
# User Alex Williamson <[EMAIL PROTECTED]>
# Date 1181684903 21600
# Node ID a62cfa35d3b504d5ee1acd4a409a6fb3ee45a6bd
# Parent  bab3dd910801edf8763d55e0c8133bc08d1cbcfd
[IA64] Add HYPERVISOR_add_io_space

And call it to register new I/O spaces with Xen

Signed-off-by: Alex Williamson <[EMAIL PROTECTED]>

diff -r bab3dd910801 -r a62cfa35d3b5 arch/ia64/pci/pci.c
--- a/linux-2.6-xen-sparse/arch/ia64/pci/pci.c  Tue Jun 12 15:43:27 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/pci/pci.c  Tue Jun 12 15:48:23 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 bab3dd910801 -r a62cfa35d3b5 include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Tue Jun 12 15:43:27 
2007 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Tue Jun 12 15:48:23 
2007 -0600
@@ -387,6 +387,15 @@ xencomm_arch_hypercall_perfmon_op(un
 {
        return _hypercall4(int, ia64_dom0vp_op,
                           IA64_DOM0VP_perfmon, cmd, arg, count);
+}
+
+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 bab3dd910801 -r a62cfa35d3b5 include/xen/interface/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Tue Jun 12 15:43:27 2007 -0600
+++ b/xen/include/public/arch-ia64.h    Tue Jun 12 15:48:23 2007 -0600
@@ -531,6 +531,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)
# HG changeset patch
# User Alex Williamson <[EMAIL PROTECTED]>
# Date 1181920189 21600
# Node ID 452c5d4a55370c3c3a6cb6740b45be911ca3741e
# Parent  b492ac038d613212da3ee16646168b56ef8833cc
[IA64] Default to Controller PCI backend

Signed-off-by: Alex Williamson <[EMAIL PROTECTED]>

diff -r b492ac038d61 -r 452c5d4a5537 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Thu Jun 14 14:23:21 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Fri Jun 15 09:09:49 2007 -0600
@@ -1666,7 +1666,8 @@ CONFIG_XEN_PCIDEV_BACKEND=y
 CONFIG_XEN_PCIDEV_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
-CONFIG_XEN_PCIDEV_BACKEND_SLOT=y
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+CONFIG_XEN_PCIDEV_BACKEND_CONTROLLER=y
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_TPMDEV_BACKEND=m
 CONFIG_XEN_BLKDEV_FRONTEND=y
diff -r b492ac038d61 -r 452c5d4a5537 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Thu Jun 14 14:23:21 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64     Fri Jun 15 09:09:49 2007 -0600
@@ -1666,7 +1666,8 @@ CONFIG_XEN_PCIDEV_BACKEND=y
 CONFIG_XEN_PCIDEV_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
-CONFIG_XEN_PCIDEV_BACKEND_SLOT=y
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+CONFIG_XEN_PCIDEV_BACKEND_CONTROLLER=y
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_TPMDEV_BACKEND=m
 CONFIG_XEN_BLKDEV_FRONTEND=y
# HG changeset patch
# User Alex Williamson <[EMAIL PROTECTED]>
# Date 1181682425 21600
# Node ID 601509daabfc0f33bae7cc5c07ef620b41c4a7a0
# Parent  ba1f933f2382c95b9d735215f608ad3aa85eec4d
[IA64] Support for multiple I/O port spaces

Linux has support for multiple I/O port spaces on a system.  Depending
on the system configuration, this might allow for 64k of I/O port space
per PCI bus.  The "extended" I/O port ranges are described to the OS by
_CRS methods on PCI root devices in ACPI namespace.  For instance, on my
system, /proc/iomem shows several entries like these:

80000000000-80003ffffff : PCI Bus 0000:00 I/O Ports 01000000-0100ffff
80100000000-80103ffffff : PCI Bus 0000:01 I/O Ports 02000000-0200ffff
80200000000-80203ffffff : PCI Bus 0000:0a I/O Ports 03000000-0300ffff
80300000000-80303ffffff : PCI Bus 0000:0f I/O Ports 04000000-0400ffff
...

These describe MMIO ranges that provide I/O port ranges per PCI bus.
My /proc/ioports then shows entries like these:

01000000-0100ffff : PCI Bus 0000:00
  01001000-010010ff : 0000:00:04.0
02000000-0200ffff : PCI Bus 0000:01
  02001000-02001fff : PCI Bus #02
    02001000-0200107f : 0000:02:07.0
      02001000-0200107f : tulip
    02001080-020010ff : 0000:02:06.0
      02001080-020010ff : tulip
    02001100-0200117f : 0000:02:05.0
    02001180-020011ff : 0000:02:04.0
      02001180-020011ff : tulip
  02002000-0200203f : 0000:01:02.1
  02002040-0200207f : 0000:01:02.0
    02002040-0200207f : e1000
03000000-0300ffff : PCI Bus 0000:0a
...

Xen currently has no concept of these extended I/O port space ranges and
prevents dom0 from doing the MMIO transactions required to access these
ports.  This patch solves the problem.  First we need to make
ioports_permit/deny_access() aware that multiple I/O port ranges with
different MMIO base address exist.  Next we need to provide a mechanism
to register new I/O port spaces, for this I've created the dom0vp op
IA64_DOM0VP_add_io_space.  This allows dom0 to do the work of finding
the ranges in ACPI namespace since we don't want to add that kind of
bulk to Xen.  Finally, dom0 needs to make use of this interface when new
ranges are found.

Signed-off-by: Alex Williamson <[EMAIL PROTECTED]>

diff -r ba1f933f2382 -r 601509daabfc xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Tue Jun 12 14:58:39 2007 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c      Tue Jun 12 15:07:05 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;
+
+    /*
+     * Registering new io_space roughly based on linux
+     * arch/ia64/pci/pci.c:new_space()
+     */
+
+    /* Skip legacy I/O port space, we already know about it */
+    if (phys_base == 0)
+        return 0;
+
+    /*
+     * Dom0 Linux initializes io spaces sequentially, if that changes,
+     * we'll need to add thread protection and the ability to handle
+     * a sparsely populated io_space array.
+     */
+    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 ba1f933f2382 -r 601509daabfc xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Tue Jun 12 14:58:39 2007 -0600
+++ b/xen/arch/ia64/xen/mm.c    Tue Jun 12 15:07:05 2007 -0600
@@ -890,81 +890,144 @@ 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;
-
+
+    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 dom0.  This is also a requirement because
+     * the hypercall to pass these port ranges only uses a u32.
+     *
+     * NB - non-dom0 driver domains may only have a subset of the
+     * 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);
     if (ret != 0)
         return ret;
 
-    /* Domain 0 doesn't virtualize IO ports space. */
-    if (d == dom0)
+    space = &io_space[IO_SPACE_NR(fp)];
+
+    /* Legacy I/O on dom0 is already setup */
+    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]) {
+        mmio_start |= IO_PORTS_PADDR;
+        mmio_end |= IO_PORTS_PADDR;
+    } else {
+        mmio_start |= __pa(space->mmio_base);
+        mmio_end |= __pa(space->mmio_base);
+    }
+
+    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;
+
+    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;
     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);
+
+    for (; mmio_start < mmio_end; mmio_start += PAGE_SIZE) {
+        unsigned int port, range;
+        unsigned long mpaddr;
         volatile pte_t *pte;
         pte_t old_pte;
 
-        port = IO_SPACE_SPARSE_DECODING (off);
-        if (port < fp || port + IO_SPACE_SPARSE_PORTS_PER_PAGE - 1 > lp) {
+        if (space->sparse) {
+            port = IO_SPACE_SPARSE_DECODING(mmio_start);
+            range = IO_SPACE_SPARSE_PORTS_PER_PAGE - 1;
+        } else {
+            port = mmio_start;
+            range = PAGE_SIZE - 1;
+        }
+
+        port |= IO_SPACE_BASE(IO_SPACE_NR(fp));
+
+        if (port < fp || port + range > lp) {
             /* Maybe this covers an allowed port.  */
-            if (ioports_has_allowed(d, port,
-                                    port + IO_SPACE_SPARSE_PORTS_PER_PAGE - 1))
+            if (ioports_has_allowed(d, port, port + range))
                 continue;
         }
 
+        mpaddr = mmio_start | mmio_base;
         pte = lookup_noalloc_domain_pte_none(d, mpaddr);
         BUG_ON(pte == NULL);
         BUG_ON(pte_none(*pte));
 
-        // clear pte
+        /* clear pte */
         old_pte = ptep_get_and_clear(mm, mpaddr, pte);
     }
     domain_flush_vtlb_all(d);
diff -r ba1f933f2382 -r 601509daabfc xen/include/asm-ia64/iocap.h
--- a/xen/include/asm-ia64/iocap.h      Tue Jun 12 14:58:39 2007 -0600
+++ b/xen/include/asm-ia64/iocap.h      Tue Jun 12 15:07:05 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)
[IA64] Use GFP_ATOMIC for ia64_sal_get_state_info()

This can be called in interrupt context.

Signed-off-by: Kazuhiro Suzuki <[EMAIL PROTECTED]>
---

diff -r 9ac03e8238f6 linux-2.6-xen-sparse/include/asm-ia64/sal.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/sal.h       Fri Sep 07 10:19:22 
2007 +0100
+++ b/linux-2.6-xen-sparse/include/asm-ia64/sal.h       Mon Sep 10 12:59:48 
2007 -0600
@@ -703,7 +703,7 @@ ia64_sal_get_state_info (u64 sal_info_ty
 
                if (xencomm_create(sal_info,
                                   ia64_sal_get_state_info_size(sal_info_type),
-                                  &desc, GFP_KERNEL))
+                                  &desc, GFP_ATOMIC))
                        return 0;
 
                SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to