From: Alex Williamson <alex.williamson@hp.com>
To: Keir Fraser <Keir.Fraser@cl.cam.ac.uk>
Cc: xen-ia64-devel <xen-ia64-devel@lists.xensource.com>,
xen-devel <xen-devel@lists.xensource.com>,
Ben Guthro <bguthro@virtualiron.com>,
xen-ppc-devel <xen-ppc-devel@lists.xensource.com>
Subject: [PATCH] Re: Xen 3.1.1 -- initial patchqueue
Date: Tue, 11 Sep 2007 14:00:19 -0600 [thread overview]
Message-ID: <1189540819.11204.43.camel@bling> (raw)
In-Reply-To: <C30C9256.D6E6%Keir.Fraser@cl.cam.ac.uk>
[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]
On Tue, 2007-09-11 at 18:43 +0100, Keir Fraser wrote:
> Can you please provide a patch to apply to xen-3.1-testing.pq.hg? The
> patches you add to the queue should have the same style of changeset comment
> as the existing ones -- 'hg export' format plus the two xen-unstable
> changeset references immediately after the signed-off-by line(s).
Here you go. I went ahead and fixed the odd character problem in
this patch since it was getting in my way too. Thanks,
Alex
Xen-3.1.1 patches for ia64
- build fixes
- NUMA system fixes
- update for ACM interface
- avoid allocating SAL logs w/ GFP_KERNEL
- NVRAM fixes
- PCI Controller backend
- extended I/O port space support
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
15078-6145e5508d6b | 2
b/15096-d4f59e652078 | 26 +
b/15265-634b7f7f8584 | 48 ++
b/15331-b46c2ff6dfb0 | 63 +++
b/15348-51f5bea7b0d8 | 48 ++
b/15349-71377eab1874 | 388 ++++++++++++++++++++++
b/15353-601509daabfc | 310 ++++++++++++++++++
b/15364-1623f5f5094f | 38 ++
b/15365-33cc64dcaead | 34 +
b/15366-fd0103b55504 | 67 +++
b/15555-38d061886873 | 73 ++++
b/15557-2a5b463f2e8d | 52 +++
b/15579-f536eb8576ee | 33 +
b/15850-6644d8486266 | 31 +
b/15852-f88eea67a469 | 104 ++++++
b/ia64-sal-get-state-info | 19 +
b/linux-46-93a955c2bebb | 786 ++++++++++++++++++++++++++++++++++++++++++++++
b/linux-55-a62cfa35d3b5 | 60 +++
b/linux-56-1483ef74511b | 101 +++++
b/linux-61-452c5d4a5537 | 37 ++
series | 19 +
21 files changed, 2338 insertions(+), 1 deletion(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: xen-3.1.1-ia64.pq.patch --]
[-- Type: text/x-patch; name=xen-3.1.1-ia64.pq.patch; charset=UTF-8, Size: 84781 bytes --]
diff -r 7ba52aa72ae5 15078-6145e5508d6b
--- a/15078-6145e5508d6b Fri Sep 07 15:49:00 2007 +0100
+++ b/15078-6145e5508d6b Tue Sep 11 11:54:34 2007 -0600
@@ -6,7 +6,7 @@ Xen-API. This also serves as a good exa
Xen-API. This also serves as a good example of the use of XML::RPC::Client
with the Xen-API.
-By Ingard Mevåg <ingard [at] mevaag [dot] no>.
+By Ingard Mevag <ingard [at] mevaag [dot] no>.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
xen-unstable changeset: 15078:6145e5508d6b5ff188df250fb9c97e3e47762005
diff -r 7ba52aa72ae5 15096-d4f59e652078
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15096-d4f59e652078 Tue Sep 11 12:26:45 2007 -0600
@@ -0,0 +1,26 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1178548346 21600
+# Node ID d4f59e6520781a3f1d025e754d11992be68c309c
+# Parent 642a9bcaf19c63f12722a30d94de2ad2607d9d47
+[IA64] Fix PCI front with CONFIG_NUMA
+
+We get a bad pointer dereference if we don't fill something in
+here. -1 will give us a global allocation, which is good enough
+until we have better NUMA support.
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+xen-unstable changeset: 15096:d4f59e6520781a3f1d025e754d11992be68c309c
+xen-unstable date: Mon May 07 08:32:26 2007 -0600
+
+diff -r 642a9bcaf19c -r d4f59e652078 linux-2.6-xen-sparse/include/xen/pcifront.h
+--- a/linux-2.6-xen-sparse/include/xen/pcifront.h Sun May 06 20:34:15 2007 -0600
++++ b/linux-2.6-xen-sparse/include/xen/pcifront.h Mon May 07 08:32:26 2007 -0600
+@@ -62,6 +62,7 @@ static inline void pcifront_init_sd(stru
+ sd->segment = domain;
+ sd->acpi_handle = NULL;
+ sd->iommu = NULL;
++ sd->node = -1;
+ sd->windows = 0;
+ sd->window = NULL;
+ sd->platform_data = pdev;
diff -r 7ba52aa72ae5 15265-634b7f7f8584
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15265-634b7f7f8584 Tue Sep 11 12:27:10 2007 -0600
@@ -0,0 +1,48 @@
+# HG changeset patch
+# User kfraser@localhost.localdomain
+# 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 <xing.z.zhang@intel.com>
+xen-unstable changeset: 15265:634b7f7f8584f478c9e45a98998c7e7c1b8e3b3d
+xen-unstable date: Tue Jun 12 11:32:03 2007 +0100
+
+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;
+
diff -r 7ba52aa72ae5 15331-b46c2ff6dfb0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15331-b46c2ff6dfb0 Tue Sep 11 12:27:33 2007 -0600
@@ -0,0 +1,63 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1180644428 21600
+# Node ID b46c2ff6dfb0de75e17fee01f0adc4d35d5e8322
+# Parent 148b6fc8f29b7b3de496e29f99afdd1e2cfb2bc4
+[IA64] Fix initialization order for buddy allocator
+
+Fix initialization order of buddy allocator to avoid panic
+on machines with multi NUMA node.
+
+Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
+xen-unstable changeset: 15331:b46c2ff6dfb0de75e17fee01f0adc4d35d5e8322
+xen-unstable date: Thu May 31 14:47:08 2007 -0600
+
+diff -r 148b6fc8f29b -r b46c2ff6dfb0 xen/arch/ia64/linux-xen/setup.c
+--- a/xen/arch/ia64/linux-xen/setup.c Thu May 31 11:42:40 2007 -0600
++++ b/xen/arch/ia64/linux-xen/setup.c Thu May 31 14:47:08 2007 -0600
+@@ -506,13 +506,6 @@ setup_arch (char **cmdline_p)
+ if (early_console_setup(*cmdline_p) == 0)
+ mark_bsp_online();
+
+-#ifdef XEN
+-}
+-
+-void __init
+-late_setup_arch (char **cmdline_p)
+-{
+-#endif
+ #ifdef CONFIG_ACPI_BOOT
+ /* Initialize the ACPI boot-time table parser */
+ acpi_table_init();
+@@ -525,6 +518,13 @@ late_setup_arch (char **cmdline_p)
+ # endif
+ #endif /* CONFIG_APCI_BOOT */
+
++#ifdef XEN
++}
++
++void __init
++late_setup_arch (char **cmdline_p)
++{
++#endif
+ #ifndef XEN
+ find_memory();
+ #endif
+diff -r 148b6fc8f29b -r b46c2ff6dfb0 xen/arch/ia64/xen/xensetup.c
+--- a/xen/arch/ia64/xen/xensetup.c Thu May 31 11:42:40 2007 -0600
++++ b/xen/arch/ia64/xen/xensetup.c Thu May 31 14:47:08 2007 -0600
+@@ -433,12 +433,12 @@ void __init start_kernel(void)
+
+ alloc_dom0();
+
+- end_boot_allocator();
+-
+ init_xenheap_pages(__pa(xen_heap_start), xenheap_phys_end);
+ printk("Xen heap: %luMB (%lukB)\n",
+ (xenheap_phys_end-__pa(xen_heap_start)) >> 20,
+ (xenheap_phys_end-__pa(xen_heap_start)) >> 10);
++
++ end_boot_allocator();
+
+ late_setup_arch(&cmdline);
+
diff -r 7ba52aa72ae5 15348-51f5bea7b0d8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15348-51f5bea7b0d8 Tue Sep 11 12:27:55 2007 -0600
@@ -0,0 +1,48 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181591988 21600
+# Node ID 51f5bea7b0d84d639a9823ddf1d27a71a869b6f4
+# Parent 154878b6ec4bf58fb3a9a6c6b420097b2f4a6f1e
+[IA64] create free_irq()
+
+This isn't well tested, since it's not likely to get called, but
+it is required to build.
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+xen-unstable changeset: 15348:51f5bea7b0d84d639a9823ddf1d27a71a869b6f4
+xen-unstable date: Mon Jun 11 13:59:48 2007 -0600
+
+diff -r 154878b6ec4b -r 51f5bea7b0d8 xen/arch/ia64/xen/irq.c
+--- a/xen/arch/ia64/xen/irq.c Mon Jun 11 13:46:42 2007 -0600
++++ b/xen/arch/ia64/xen/irq.c Mon Jun 11 13:59:48 2007 -0600
+@@ -281,6 +281,30 @@ int setup_irq(unsigned int irq, struct i
+ return res;
+ }
+
++void free_irq(unsigned int irq)
++{
++ unsigned int vec;
++ unsigned long flags;
++ irq_desc_t *desc;
++
++ /* Get vector for IRQ. */
++ if (acpi_gsi_to_irq(irq, &vec) < 0)
++ return;
++
++ desc = irq_descp(vec);
++
++ spin_lock_irqsave(&desc->lock, flags);
++ clear_bit(vec, ia64_xen_vector);
++ desc->action = NULL;
++ desc->depth = 1;
++ desc->status |= IRQ_DISABLED;
++ desc->handler->shutdown(vec);
++ spin_unlock_irqrestore(&desc->lock, flags);
++
++ while (desc->status & IRQ_INPROGRESS)
++ cpu_relax();
++}
++
+ /*
+ * HANDLING OF GUEST-BOUND PHYSICAL IRQS
+ */
diff -r 7ba52aa72ae5 15349-71377eab1874
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15349-71377eab1874 Tue Sep 11 12:28:11 2007 -0600
@@ -0,0 +1,388 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181593145 21600
+# Node ID 71377eab1874e126caeb4c1869374befa07f1c70
+# Parent 51f5bea7b0d84d639a9823ddf1d27a71a869b6f4
+[IA64] White space cleanup from nvram patch
+
+This file is using space indenting. No functional changes.
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+xen-unstable changeset: 15349:71377eab1874e126caeb4c1869374befa07f1c70
+xen-unstable date: Mon Jun 11 14:19:05 2007 -0600
+
+diff -r 51f5bea7b0d8 -r 71377eab1874 tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jun 11 13:59:48 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jun 11 14:19:05 2007 -0600
+@@ -124,7 +124,7 @@ typedef enum {
+ HOB_TYPE_PAL_VM_INFO,
+ HOB_TYPE_PAL_VM_PAGE_SIZE,
+ HOB_TYPE_NR_VCPU,
+- HOB_TYPE_NVRAM,
++ HOB_TYPE_NVRAM,
+ HOB_TYPE_MAX
+ } hob_type_t;
+
+@@ -135,14 +135,14 @@ static int add_nvram_hob(void* hob_buf,
+ static int add_nvram_hob(void* hob_buf, unsigned long nvram_addr);
+ static int build_hob(void* hob_buf, unsigned long hob_buf_size,
+ unsigned long dom_mem_size, unsigned long vcpus,
+- unsigned long nvram_addr);
++ unsigned long nvram_addr);
+ static int load_hob(int xc_handle,uint32_t dom, void *hob_buf,
+ unsigned long dom_mem_size);
+
+ static int
+ xc_ia64_build_hob(int xc_handle, uint32_t dom,
+ unsigned long memsize, unsigned long vcpus,
+- unsigned long nvram_addr)
++ unsigned long nvram_addr)
+ {
+ char *hob_buf;
+
+@@ -251,7 +251,7 @@ static int
+ static int
+ build_hob(void* hob_buf, unsigned long hob_buf_size,
+ unsigned long dom_mem_size, unsigned long vcpus,
+- unsigned long nvram_addr)
++ unsigned long nvram_addr)
+ {
+ //Init HOB List
+ if (hob_init(hob_buf, hob_buf_size) < 0) {
+@@ -274,10 +274,10 @@ build_hob(void* hob_buf, unsigned long h
+ goto err_out;
+ }
+
+- if (add_nvram_hob( hob_buf, nvram_addr ) < 0) {
+- PERROR("Add nvram hob failed, buffer too small");
+- goto err_out;
+- }
++ if (add_nvram_hob( hob_buf, nvram_addr ) < 0) {
++ PERROR("Add nvram hob failed, buffer too small");
++ goto err_out;
++ }
+
+ return 0;
+
+@@ -342,7 +342,7 @@ static int
+ static int
+ add_nvram_hob(void *hob_buf, unsigned long nvram_addr)
+ {
+- return hob_add(hob_buf, HOB_TYPE_NVRAM, &nvram_addr, sizeof(nvram_addr));
++ return hob_add(hob_buf, HOB_TYPE_NVRAM, &nvram_addr, sizeof(nvram_addr));
+ }
+
+ static const unsigned char config_pal_bus_get_features_data[24] = {
+@@ -576,49 +576,48 @@ static uint64_t
+ static uint64_t
+ nvram_init(const char *nvram_path)
+ {
+- uint64_t fd = 0;
+- fd = open(nvram_path, O_CREAT|O_RDWR, 0666);
+-
+- if ( fd < 0 )
+- {
+- PERROR("Nvram open failed at %s. Guest will boot without"
+- " nvram support!\n", nvram_path);
+- return -1;
+- }
+-
+- return VALIDATE_NVRAM_FD(fd);
++ uint64_t fd = 0;
++ fd = open(nvram_path, O_CREAT|O_RDWR, 0666);
++
++ if ( fd < 0 )
++ {
++ PERROR("Nvram open failed at %s. Guest will boot without"
++ " nvram support!\n", nvram_path);
++ return -1;
++ }
++
++ return VALIDATE_NVRAM_FD(fd);
+ }
+
+ static int
+ copy_from_nvram_to_GFW(int xc_handle, uint32_t dom, int nvram_fd)
+ {
+- unsigned int nr_pages = NVRAM_SIZE >> PAGE_SHIFT;
+- struct stat file_stat;
+- char buf[NVRAM_SIZE] = {0};
++ 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 "
+- "nvram support!\n");
+- return -1;
+- }
+-
+- if ( 0 == file_stat.st_size )
+- {
+- DPRINTF("Nvram file create successful!\n");
+- return 0;
+- }
+-
+- if ( read(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE )
+- {
+- PERROR("Load nvram fail. guest will boot without"
+- " nvram support!\n");
+- return -1;
+- }
+-
+- return xc_ia64_copy_to_domain_pages(xc_handle, dom, buf,
+- NVRAM_START >> PAGE_SHIFT,
+- nr_pages);
++ if ( fstat(nvram_fd, &file_stat) < 0 )
++ {
++ PERROR("Cannot get Nvram file info! Guest will boot without "
++ "nvram support!\n");
++ return -1;
++ }
++
++ if ( 0 == file_stat.st_size )
++ {
++ DPRINTF("Nvram file create successful!\n");
++ return 0;
++ }
++
++ if ( read(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE )
++ {
++ PERROR("Load nvram fail. guest will boot without"
++ " nvram support!\n");
++ return -1;
++ }
++
++ return xc_ia64_copy_to_domain_pages(xc_handle, dom, buf,
++ NVRAM_START >> PAGE_SHIFT, nr_pages);
+ }
+
+
+@@ -630,121 +629,120 @@ static int
+ static int
+ copy_from_GFW_to_nvram(int xc_handle, uint32_t dom, int nvram_fd)
+ {
+- xen_pfn_t *pfn_list = NULL;
+- char *tmp_ptr = NULL;
+- unsigned int nr_pages = 0;
+- uint64_t addr_from_GFW_4k_align = 0;
+- uint32_t offset = 0;
+- uint64_t nvram_base_addr = 0;
+- char buf[NVRAM_SIZE] = {0};
+- int i;
+-
+-
+- // map one more page
+- nr_pages = (NVRAM_SIZE + PAGE_SIZE) >> PAGE_SHIFT;
+- pfn_list = (xen_pfn_t *)malloc(sizeof(xen_pfn_t) * nr_pages);
+- if ( NULL == pfn_list )
+- {
+- PERROR("Cannot allocate memory for nvram save!\n");
+- close(nvram_fd);
+- return -1;
+- }
+-
+- /*
+- * GFW allocate memory dynamicly to save nvram data
+- * and save address of the dynamic memory at NVRAM_START.
+- * To save nvram data to file, we must get the dynamic
+- * memory address first.
+- */
+- pfn_list[0] = NVRAM_START >> PAGE_SHIFT;
+- tmp_ptr = (char *)xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+- PROT_READ | PROT_WRITE, pfn_list[0]);
+-
+- if ( NULL == tmp_ptr )
+- {
+- PERROR("Cannot get nvram data from GFW!\n");
+- free(pfn_list);
+- close(nvram_fd);
+- return -1;
+- }
+-
+- addr_from_GFW_4k_align = *((uint64_t *)tmp_ptr);
+- munmap(tmp_ptr, PAGE_SIZE);
+-
+- // align address to 16k
+- offset = addr_from_GFW_4k_align % ( 16 * MEM_K );
+- addr_from_GFW_4k_align = addr_from_GFW_4k_align - offset;
+- for ( i=0; i<nr_pages; i++ )
+- pfn_list[i] = (addr_from_GFW_4k_align >> PAGE_SHIFT) + i;
+-
+- tmp_ptr = (char *)xc_map_foreign_batch(xc_handle, dom,
+- PROT_READ | PROT_WRITE, pfn_list, nr_pages);
+- if ( NULL == tmp_ptr )
+- {
+- PERROR("Cannot get nvram data from GFW!\n");
+- free(pfn_list);
+- close(nvram_fd);
+- return -1;
+- }
+-
+- // calculate nvram data base addrees
+- nvram_base_addr = (uint64_t)(tmp_ptr + offset);
+-
+- memcpy(buf, (void *)nvram_base_addr, NVRAM_SIZE);
+- free(pfn_list);
+- munmap(tmp_ptr, NVRAM_SIZE + PAGE_SIZE);
+-
+- lseek(nvram_fd, 0, SEEK_SET);
+- if ( write(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE )
+- {
+- PERROR("Save to nvram fail!\n");
+- return -1;
+- }
+-
+- close(nvram_fd);
+-
+- DPRINTF("Nvram save successful!\n");
+-
+- return 0;
++ xen_pfn_t *pfn_list = NULL;
++ char *tmp_ptr = NULL;
++ unsigned int nr_pages = 0;
++ uint64_t addr_from_GFW_4k_align = 0;
++ uint32_t offset = 0;
++ uint64_t nvram_base_addr = 0;
++ char buf[NVRAM_SIZE] = {0};
++ int i;
++
++ // map one more page
++ nr_pages = (NVRAM_SIZE + PAGE_SIZE) >> PAGE_SHIFT;
++ pfn_list = (xen_pfn_t *)malloc(sizeof(xen_pfn_t) * nr_pages);
++ if ( NULL == pfn_list )
++ {
++ PERROR("Cannot allocate memory for nvram save!\n");
++ close(nvram_fd);
++ return -1;
++ }
++
++ /*
++ * GFW allocate memory dynamicly to save nvram data
++ * and save address of the dynamic memory at NVRAM_START.
++ * To save nvram data to file, we must get the dynamic
++ * memory address first.
++ */
++ pfn_list[0] = NVRAM_START >> PAGE_SHIFT;
++ tmp_ptr = (char *)xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
++ PROT_READ | PROT_WRITE, pfn_list[0]);
++
++ if ( NULL == tmp_ptr )
++ {
++ PERROR("Cannot get nvram data from GFW!\n");
++ free(pfn_list);
++ close(nvram_fd);
++ return -1;
++ }
++
++ addr_from_GFW_4k_align = *((uint64_t *)tmp_ptr);
++ munmap(tmp_ptr, PAGE_SIZE);
++
++ // align address to 16k
++ offset = addr_from_GFW_4k_align % ( 16 * MEM_K );
++ addr_from_GFW_4k_align = addr_from_GFW_4k_align - offset;
++ for ( i=0; i<nr_pages; i++ )
++ pfn_list[i] = (addr_from_GFW_4k_align >> PAGE_SHIFT) + i;
++
++ tmp_ptr = (char *)xc_map_foreign_batch(xc_handle, dom,
++ PROT_READ | PROT_WRITE, pfn_list, nr_pages);
++ if ( NULL == tmp_ptr )
++ {
++ PERROR("Cannot get nvram data from GFW!\n");
++ free(pfn_list);
++ close(nvram_fd);
++ return -1;
++ }
++
++ // calculate nvram data base addrees
++ nvram_base_addr = (uint64_t)(tmp_ptr + offset);
++
++ memcpy(buf, (void *)nvram_base_addr, NVRAM_SIZE);
++ free(pfn_list);
++ munmap(tmp_ptr, NVRAM_SIZE + PAGE_SIZE);
++
++ lseek(nvram_fd, 0, SEEK_SET);
++ if ( write(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE )
++ {
++ PERROR("Save to nvram fail!\n");
++ return -1;
++ }
++
++ close(nvram_fd);
++
++ DPRINTF("Nvram save successful!\n");
++
++ return 0;
+ }
+
+ int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom)
+ {
+- uint64_t nvram_fd = 0;
+- 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);
++ uint64_t nvram_fd = 0;
++ 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);
+ }
+
+ #define NVRAM_FILE_PATH "/usr/lib/xen/boot/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};
+-
+- strncpy(nvram_path, NVRAM_FILE_PATH, file_path_len);
+- if ( file_path_len + 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);
+-
+- nvram_fd = nvram_init(nvram_path);
+- if ( nvram_fd == (uint64_t)(-1) )
+- {
+- xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, 0);
+- return -1;
+- }
+-
+- xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, nvram_fd);
+- return 0;
++ int file_path_len = strlen(NVRAM_FILE_PATH);
++ uint64_t nvram_fd = 0;
++ char nvram_path[100] = {0};
++
++ strncpy(nvram_path, NVRAM_FILE_PATH, file_path_len);
++ if ( file_path_len + 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);
++
++ nvram_fd = nvram_init(nvram_path);
++ if ( nvram_fd == (uint64_t)(-1) )
++ {
++ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, 0);
++ return -1;
++ }
++
++ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, nvram_fd);
++ return 0;
+ }
+
+ #define GFW_PAGES (GFW_SIZE >> PAGE_SHIFT)
diff -r 7ba52aa72ae5 15353-601509daabfc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15353-601509daabfc Tue Sep 11 12:28:40 2007 -0600
@@ -0,0 +1,310 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# 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 <alex.williamson@hp.com>
+xen-unstable changeset: 15353:601509daabfc0f33bae7cc5c07ef620b41c4a7a0
+xen-unstable date: Tue Jun 12 15:07:05 2007 -0600
+
+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)
diff -r 7ba52aa72ae5 15364-1623f5f5094f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15364-1623f5f5094f Tue Sep 11 12:28:55 2007 -0600
@@ -0,0 +1,38 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181856742 21600
+# Node ID 1623f5f5094f4bc41be0d67f906b155e3704109c
+# Parent a371cfbd62e8278e2bc9e6980eaa289c099f0ad8
+[IA64] Don't try to save nvram on PV domains
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+xen-unstable changeset: 15364:1623f5f5094f4bc41be0d67f906b155e3704109c
+xen-unstable date: Thu Jun 14 15:32:22 2007 -0600
+
+diff -r a371cfbd62e8 -r 1623f5f5094f tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Jun 14 15:29:52 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Jun 14 15:32:22 2007 -0600
+@@ -709,11 +709,22 @@ copy_from_GFW_to_nvram(int xc_handle, ui
+
+ int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom)
+ {
++ xc_dominfo_t info;
+ uint64_t nvram_fd = 0;
++
++ if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1 )
++ {
++ PERROR("Could not get info for domain");
++ return -1;
++ }
++
++ if ( !info.hvm )
++ return 0;
++
+ 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");
++ PERROR("Nvram not initialized. Nvram save failed!\n");
+ else
+ copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd);
+
diff -r 7ba52aa72ae5 15365-33cc64dcaead
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15365-33cc64dcaead Tue Sep 11 12:29:18 2007 -0600
@@ -0,0 +1,34 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181921109 21600
+# Node ID 33cc64dcaead095d4f8115a5b7f8565f5becaf1c
+# Parent 1623f5f5094f4bc41be0d67f906b155e3704109c
+[IA64] Create NVRAM save directory
+
+If you use RPM to install XEN, the directory(/usr/lib/xen/boot)
+will be removed when you un-install the RPM. This patch create
+that directory before NVRAM file creating.
+
+Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
+xen-unstable changeset: 15365:33cc64dcaead095d4f8115a5b7f8565f5becaf1c
+xen-unstable date: Fri Jun 15 09:25:09 2007 -0600
+
+diff -r 1623f5f5094f -r 33cc64dcaead tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Jun 14 15:32:22 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Jun 15 09:25:09 2007 -0600
+@@ -735,6 +735,7 @@ 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_"
+ int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom)
+ {
+@@ -749,6 +750,7 @@ int xc_ia64_nvram_init(int xc_handle, ch
+ return -1;
+ }
+ strcpy(nvram_path + file_path_len, dom_name);
++ mkdir(NVRAM_DIR, 0765);
+
+ nvram_fd = nvram_init(nvram_path);
+ if ( nvram_fd == (uint64_t)(-1) )
diff -r 7ba52aa72ae5 15366-fd0103b55504
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15366-fd0103b55504 Tue Sep 11 12:29:48 2007 -0600
@@ -0,0 +1,67 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181928874 21600
+# Node ID fd0103b55504bac392864de87d21506e18ba2d6b
+# Parent 33cc64dcaead095d4f8115a5b7f8565f5becaf1c
+[IA64] Add error checking to nvram store mkdir
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+xen-unstable changeset: 15366:fd0103b55504bac392864de87d21506e18ba2d6b
+xen-unstable date: Fri Jun 15 11:34:34 2007 -0600
+
+diff -r 33cc64dcaead -r fd0103b55504 tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Jun 15 09:25:09 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Jun 15 11:34:34 2007 -0600
+@@ -578,7 +578,7 @@ nvram_init(const char *nvram_path)
+ nvram_init(const char *nvram_path)
+ {
+ uint64_t fd = 0;
+- fd = open(nvram_path, O_CREAT|O_RDWR, 0666);
++ fd = open(nvram_path, O_CREAT|O_RDWR, 0644);
+
+ if ( fd < 0 )
+ {
+@@ -736,12 +736,34 @@ int xc_ia64_save_to_nvram(int xc_handle,
+ }
+
+ #define NVRAM_DIR "/usr/lib/xen/boot/"
+-#define NVRAM_FILE_PATH "/usr/lib/xen/boot/nvram_"
++#define NVRAM_FILE_PATH "/usr/lib/xen/boot/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 ) {
++ if ( errno != ENOENT )
++ {
++ PERROR("Error stat'ing NVRAM dir %s.", NVRAM_DIR);
++ return -1;
++ }
++ if ( mkdir(NVRAM_DIR, 0755) == -1 )
++ {
++ PERROR("Unable to create NVRAM store directory %s.", NVRAM_DIR);
++ return -1;
++ }
++ }
++
++ if ( !(stat_buf.st_mode & S_IRUSR) || !(stat_buf.st_mode & S_IWUSR) )
++ {
++ 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) )
+@@ -750,7 +772,6 @@ int xc_ia64_nvram_init(int xc_handle, ch
+ return -1;
+ }
+ strcpy(nvram_path + file_path_len, dom_name);
+- mkdir(NVRAM_DIR, 0765);
+
+ nvram_fd = nvram_init(nvram_path);
+ if ( nvram_fd == (uint64_t)(-1) )
diff -r 7ba52aa72ae5 15555-38d061886873
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15555-38d061886873 Tue Sep 11 12:30:14 2007 -0600
@@ -0,0 +1,73 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1183388724 21600
+# Node ID 38d0618868738b03611bdbb9f3fe29c73f1c34dd
+# Parent 89596982890b78ebceffc4c5803662adc3dddc73
+[IA64] Fix incorrect NVRAM saving if domain is destroyed by config error
+
+Nvram saving is always executed even if a domain is destroyed by a
+configuration parameter error. In this case, Nvram saving function
+will get a bad address for the NVRAM data and save garbage into the
+NVRAM file. Configuring a wrong vif parameter can expose this issue.
+
+This patch fixes the issue by adding an address check function in
+NVRAM saving path.
+
+Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
+xen-unstable changeset: 15555:38d0618868738b03611bdbb9f3fe29c73f1c34dd
+xen-unstable date: Mon Jul 02 09:05:24 2007 -0600
+
+diff -r 89596982890b -r 38d061886873 tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jul 02 08:51:59 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jul 02 09:05:24 2007 -0600
+@@ -623,6 +623,21 @@ copy_from_nvram_to_GFW(int xc_handle, ui
+
+
+ /*
++ *Check is the address where NVRAM data located valid
++ */
++static int is_valid_address(void *addr)
++{
++ struct nvram_save_addr *p = (struct nvram_save_addr *)addr;
++
++ if ( p->signature == NVRAM_VALID_SIG )
++ return 1;
++ else {
++ PERROR("Invalid nvram signature. Nvram save failed!\n");
++ return 0;
++ }
++}
++
++/*
+ * GFW use 4k page. when doing foreign map, we should 16k align
+ * the address and map one more page to guarantee all 64k nvram data
+ * can be got.
+@@ -667,7 +682,11 @@ copy_from_GFW_to_nvram(int xc_handle, ui
+ return -1;
+ }
+
+- addr_from_GFW_4k_align = *((uint64_t *)tmp_ptr);
++ /* Check is NVRAM data vaild */
++ if ( !is_valid_address(tmp_ptr) )
++ return -1;
++
++ addr_from_GFW_4k_align = ((struct nvram_save_addr *)tmp_ptr)->addr;
+ munmap(tmp_ptr, PAGE_SIZE);
+
+ // align address to 16k
+diff -r 89596982890b -r 38d061886873 xen/include/public/arch-ia64.h
+--- a/xen/include/public/arch-ia64.h Mon Jul 02 08:51:59 2007 -0600
++++ b/xen/include/public/arch-ia64.h Mon Jul 02 09:05:24 2007 -0600
+@@ -116,6 +116,12 @@ typedef unsigned long xen_ulong_t;
+ /* Nvram belongs to GFW memory space */
+ #define NVRAM_SIZE (MEM_K * 64)
+ #define NVRAM_START (GFW_START + 10 * MEM_M)
++
++#define NVRAM_VALID_SIG 0x4650494e45584948 // "HIXENIPF"
++struct nvram_save_addr {
++ unsigned long addr;
++ unsigned long signature;
++};
+
+ struct pt_fpreg {
+ union {
diff -r 7ba52aa72ae5 15557-2a5b463f2e8d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15557-2a5b463f2e8d Tue Sep 11 12:30:34 2007 -0600
@@ -0,0 +1,52 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1183390731 21600
+# Node ID 2a5b463f2e8dcb5b132062547f2ea76780d80aae
+# Parent 88ab11d8fd1c1052f0e0f1aa5b029c353d03b067
+[IA64] Fix NVRAM data cannot be saved when guest execute "reboot"
+
+Also fix "xm reboot" instruction in Xend.
+
+Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
+xen-unstable changeset: 15557:2a5b463f2e8dcb5b132062547f2ea76780d80aae
+xen-unstable date: Mon Jul 02 09:38:51 2007 -0600
+
+diff -r 88ab11d8fd1c -r 2a5b463f2e8d tools/ioemu/target-i386-dm/helper2.c
+--- a/tools/ioemu/target-i386-dm/helper2.c Mon Jul 02 09:29:08 2007 -0600
++++ b/tools/ioemu/target-i386-dm/helper2.c Mon Jul 02 09:38:51 2007 -0600
+@@ -140,6 +140,7 @@ void cpu_reset(CPUX86State *env)
+ if (xcHandle < 0)
+ fprintf(logfile, "Cannot acquire xenctrl handle\n");
+ else {
++ xc_domain_shutdown_hook(xcHandle, domid);
+ sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
+ if (sts != 0)
+ fprintf(logfile,
+diff -r 88ab11d8fd1c -r 2a5b463f2e8d tools/ioemu/vl.h
+--- a/tools/ioemu/vl.h Mon Jul 02 09:29:08 2007 -0600
++++ b/tools/ioemu/vl.h Mon Jul 02 09:38:51 2007 -0600
+@@ -1498,4 +1498,13 @@ void destroy_hvm_domain(void);
+ /* VNC Authentication */
+ #define AUTHCHALLENGESIZE 16
+
++#ifdef __ia64__
++static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid)
++{
++ xc_ia64_save_to_nvram(xc_handle, domid);
++}
++#else
++#define xc_domain_shutdown_hook(xc_handle. domid) do {} while (0)
++#endif
++
+ #endif /* VL_H */
+diff -r 88ab11d8fd1c -r 2a5b463f2e8d tools/python/xen/xend/XendDomainInfo.py
+--- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 02 09:29:08 2007 -0600
++++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jul 02 09:38:51 2007 -0600
+@@ -459,6 +459,7 @@ class XendDomainInfo:
+ hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
+ if not hvm_pvdrv:
+ code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
++ xc.domain_destroy_hook(self.domid)
+ log.info("HVM save:remote shutdown dom %d!", self.domid)
+ xc.domain_shutdown(self.domid, code)
+
diff -r 7ba52aa72ae5 15579-f536eb8576ee
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15579-f536eb8576ee Tue Sep 11 12:30:56 2007 -0600
@@ -0,0 +1,33 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1184175150 21600
+# Node ID f536eb8576eeb7363212911b02fbaff4918172df
+# Parent a36c51f43fdb8734c1ea117334886aa47c4fd216
+[IA64] Fix VTi domain shutdown
+
+Event channel destruction is now done earlier, this patch does
+the corresponding modification in IA64 side. It fixes dom0 crash
+when VTI destroyed.
+
+Signed-off-by: Zhang Xin <xing.z.zhang@intel.com>
+xen-unstable changeset: 15579:f536eb8576eeb7363212911b02fbaff4918172df
+xen-unstable date: Wed Jul 11 11:32:30 2007 -0600
+
+diff -r a36c51f43fdb -r f536eb8576ee xen/arch/ia64/vmx/vmx_init.c
+--- a/xen/arch/ia64/vmx/vmx_init.c Tue Jul 10 11:15:54 2007 -0600
++++ b/xen/arch/ia64/vmx/vmx_init.c Wed Jul 11 11:32:30 2007 -0600
+@@ -283,9 +283,13 @@ static void vmx_create_event_channels(st
+ }
+ }
+
++/*
++ * Event channel has destoryed in domain_kill(), so we needn't
++ * do anything here
++ */
+ static void vmx_release_assist_channel(struct vcpu *v)
+ {
+- free_xen_event_channel(v, v->arch.arch_vmx.xen_port);
++ return;
+ }
+
+ /*
diff -r 7ba52aa72ae5 15850-6644d8486266
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15850-6644d8486266 Tue Sep 11 12:31:12 2007 -0600
@@ -0,0 +1,31 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1187989754 21600
+# Node ID 6644d848626685f01d6832837fdb4ab2e06fffde
+# Parent 0cc2e0a1b2fcf0f46a23f51e691650893ae5aee9
+[IA64] Clean up NVRAM failure case
+
+copy_from_GFW_to_nvram() in libxc forgot munmap() if NVRAM data
+invalid. Also it forgot free() and close() too.
+
+Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
+xen-unstable changeset: 15850:6644d848626685f01d6832837fdb4ab2e06fffde
+xen-unstable date: Fri Aug 24 15:09:14 2007 -0600
+
+diff -r 0cc2e0a1b2fc -r 6644d8486266 tools/libxc/ia64/xc_ia64_hvm_build.c
+--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Aug 24 15:06:49 2007 -0600
++++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Aug 24 15:09:14 2007 -0600
+@@ -684,7 +684,12 @@ copy_from_GFW_to_nvram(int xc_handle, ui
+
+ /* Check is NVRAM data vaild */
+ if ( !is_valid_address(tmp_ptr) )
+- return -1;
++ {
++ free(pfn_list);
++ munmap(tmp_ptr, PAGE_SIZE);
++ close(nvram_fd);
++ return -1;
++ }
+
+ addr_from_GFW_4k_align = ((struct nvram_save_addr *)tmp_ptr)->addr;
+ munmap(tmp_ptr, PAGE_SIZE);
diff -r 7ba52aa72ae5 15852-f88eea67a469
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/15852-f88eea67a469 Tue Sep 11 12:31:28 2007 -0600
@@ -0,0 +1,104 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# 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 <aron@hp.com>
+xen-unstable changeset: 15852:f88eea67a46997c79b56e5ba595f0572584d9d51
+xen-unstable date: Tue Aug 28 12:25:37 2007 -0600
+
+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) )
diff -r 7ba52aa72ae5 ia64-sal-get-state-info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ia64-sal-get-state-info Tue Sep 11 12:36:03 2007 -0600
@@ -0,0 +1,19 @@
+[IA64] Use GFP_ATOMIC for ia64_sal_get_state_info()
+
+This can be called in interrupt context.
+
+Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
+[patch from xen-ia64-devel mailing list]
+
+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,
diff -r 7ba52aa72ae5 linux-46-93a955c2bebb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-46-93a955c2bebb Tue Sep 11 12:32:53 2007 -0600
@@ -0,0 +1,786 @@
+# HG changeset patch
+# User kfraser@localhost.localdomain
+# Date 1181644618 -3600
+# Node ID 93a955c2bebbf3be1a4b455d106762ac179ee845
+# Parent e5b50dd9fcf5aad4567ffe74a80c93ad55e383e2
+pciback: "Controller" pcibackend and frontend extensions.
+
+On ia64, we've run into the case where the I/O hierarchies are more
+complicated than the current set of driver domain backends can describe.
+Some platforms make use of translation offsets for I/O port and MMIO
+ranges. Without knowledge of these translation offsets, devices are
+unusable by driver domains. For instance, here's an example of a
+tulip card that lives under a PCI root bus making use of an I/O port
+translation:
+
+# lspci -v -s 02:05.0
+02:05.0 Ethernet controller: Digital Equipment Corporation DECchip 21142/43 (rev 41)
+ Subsystem: Hewlett-Packard Company Unknown device 125a
+ Flags: bus master, medium devsel, latency 128, IRQ 67
+ I/O ports at 2001100 [size=128]
+ Memory at 90102000 (32-bit, non-prefetchable) [size=1K]
+ Expansion ROM at 90080000 [disabled] [size=256K]
+
+# setpci -s 02:05.0 BASE_ADDRESS_0
+00001101
+
+# cat /proc/ioports
+...
+02000000-0200ffff : PCI Bus 0000:01
+ 02001000-02001fff : PCI Bus #02
+ 02001100-0200117f : 0000:02:05.0
+ 02001100-0200117f : tulip
+...
+
+# cat /proc/iomem
+...
+80100000000-80103ffffff : PCI Bus 0000:01 I/O Ports 02000000-0200ffff
+...
+
+I/O port spaces are of course limited to 64k, but on this system
+multiple I/O port spaces are available (one per PCI root bridge in
+this case). On ia64, I/O port spaces are typically a sparse encoding
+of an MMIO range. The legacy I/O port range is decoded directly by
+the processor, additional ranges are decoded by the I/O hardware. To
+access I/O port 0x1100 on this device, the driver needs to do an
+inb/outb to address 0x2001100. The kernel will then swizzle the bits
+to create an MMIO transaction within the MMIO range for that set of
+I/O ports.
+
+To support this, I've created the "controller" backend as shown below.
+This is unfortunately an ia64-specific backend, but I don't see
+any mechanism to generically support the kinds of things this backend
+needs to do. PCI controllers on ia64 are created to represent the PCI
+root bridges found in ACPI. These root bridge ACPI nodes have _CRS
+(Current Resource Setting) methods that describe the address ranges
+consumed by the bus below the root bridge. Address ranges described
+with a translation attribute make use of a translation offset to reach
+the desired address. This information must be provided to a driver
+domain guest to allow it to access the devices.
+
+Given this architecture, the obvious choice is to create virtual PCI
+buses based on controllers. All devices physically under the same
+controller are virtualized under the same domain:bus. Within a bus,
+device slots are virtualized much like the slot backend. The tricky
+part comes with how to describe the address translation for a
+controller to the guest driver domain. For this, I chose to store the
+information in xenbus. We already make use of the following keys for
+driver domains:
+
+root_num /* Number of PCI roots exposed */
+root-X /* domain:bus information for root X */
+
+To this, I've added:
+
+root-X-resources /* number of resources for root X */
+root-X-resource-Y /* resource umber Y for root X */
+root-resource-magic /* synchronization/versioning for resource
+info */
+
+I debated for a while how to expose the root-X-resource-Y information
+and came up with a simple ASCII dump of the struct acpi_resource
+returned from the ACPI _CRS method. This isn't quite a silly as it
+sounds because the structure is a fixed size regardless of word
+length, and it's contents are largely based on fixed tables found in
+the ACPI spec. This makes it relatively immune to frequent changes.
+The PCI backend stores the ASCII byte stream of the controller
+resources into xenbus, the PCI frontend then extracts the byte stream,
+and decodes it back into a struct acpi_resource for use.
+
+The only changes to the existing code to support the frontend is a
+trivial addition of passing the bus number to pcifront_init_sd() and a
+hook to setup the root windows after the bus is scanned. No changes
+are required for the controller backend.
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+linux-2.6.18-xen changeset: 46:93a955c2bebbf3be1a4b455d106762ac179ee845
+linux-2.6.18-xen date: Tue Jun 12 11:36:58 2007 +0100
+
+diff -r e5b50dd9fcf5 -r 93a955c2bebb arch/ia64/pci/pci.c
+--- a/linux-2.6-xen-sparse/arch/ia64/pci/pci.c Tue Jun 12 11:15:20 2007 +0100
++++ b/linux-2.6-xen-sparse/arch/ia64/pci/pci.c Tue Jun 12 11:36:58 2007 +0100
+@@ -834,3 +834,31 @@ int pci_vector_resources(int last, int n
+
+ return count;
+ }
++
++#ifdef CONFIG_XEN
++void __devinit xen_add_resource(struct pci_controller *controller,
++ unsigned int domain, unsigned int bus,
++ struct acpi_resource *resource)
++{
++ struct pci_root_info info;
++ char *name;
++
++ name = kmalloc(16, GFP_KERNEL);
++ if (!name)
++ return;
++
++ sprintf(name, "PCI Bus %04x:%02x", domain, bus);
++ info.controller = controller;
++ info.name = name;
++
++ add_window(resource, &info);
++}
++EXPORT_SYMBOL(xen_add_resource);
++
++void __devinit xen_pcibios_setup_root_windows(struct pci_bus *bus,
++ struct pci_controller *controller)
++{
++ pcibios_setup_root_windows(bus, controller);
++}
++EXPORT_SYMBOL(xen_pcibios_setup_root_windows);
++#endif
+diff -r e5b50dd9fcf5 -r 93a955c2bebb drivers/xen/Kconfig
+--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jun 12 11:15:20 2007 +0100
++++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jun 12 11:36:58 2007 +0100
+@@ -109,7 +109,8 @@ choice
+ choice
+ prompt "PCI Backend Mode"
+ depends on XEN_PCIDEV_BACKEND
+- default XEN_PCIDEV_BACKEND_VPCI
++ default XEN_PCIDEV_BACKEND_VPCI if !IA64
++ default XEN_PCIDEV_BACKEND_CONTROLLER if IA64
+
+ config XEN_PCIDEV_BACKEND_VPCI
+ bool "Virtual PCI"
+@@ -138,6 +139,21 @@ config XEN_PCIDEV_BACKEND_SLOT
+ For example, a device at 03:05.2 will be re-assigned to 00:00.0. A
+ second device at 02:1a.1 will be re-assigned to 00:01.0.
+
++config XEN_PCIDEV_BACKEND_CONTROLLER
++ bool "Controller"
++ depends on IA64
++ ---help---
++ This PCI backend virtualizes the PCI bus topology by providing a
++ virtual bus per PCI root device. Devices which are physically under
++ the same root bus will appear on the same virtual bus. For systems
++ with complex I/O addressing, this is the only backend which supports
++ extended I/O port spaces and MMIO translation offsets. This backend
++ also supports slot virtualization. For example, a device at
++ 0000:01:02.1 will be re-assigned to 0000:00:00.0. A second device
++ at 0000:02:05.0 (behind a P2P bridge on bus 0000:01) will be
++ re-assigned to 0000:00:01.0. A third device at 0000:16:05.0 (under
++ a different PCI root bus) will be re-assigned to 0000:01:00.0.
++
+ endchoice
+
+ config XEN_PCIDEV_BE_DEBUG
+diff -r e5b50dd9fcf5 -r 93a955c2bebb drivers/xen/pciback/Makefile
+--- a/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Tue Jun 12 11:15:20 2007 +0100
++++ b/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Tue Jun 12 11:36:58 2007 +0100
+@@ -9,6 +9,7 @@ pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI
+ pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
+ pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o
+ pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
++pciback-$(CONFIG_XEN_PCIDEV_BACKEND_CONTROLLER) += controller.o
+
+ ifeq ($(CONFIG_XEN_PCIDEV_BE_DEBUG),y)
+ EXTRA_CFLAGS += -DDEBUG
+diff -r e5b50dd9fcf5 -r 93a955c2bebb drivers/xen/pciback/controller.c
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/linux-2.6-xen-sparse/drivers/xen/pciback/controller.c Tue Jun 12 11:36:58 2007 +0100
+@@ -0,0 +1,404 @@
++/*
++ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
++ * Alex Williamson <alex.williamson@hp.com>
++ *
++ * PCI "Controller" Backend - virtualize PCI bus topology based on PCI
++ * controllers. Devices under the same PCI controller are exposed on the
++ * same virtual domain:bus. Within a bus, device slots are virtualized
++ * to compact the bus.
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++
++#include <linux/acpi.h>
++#include <linux/list.h>
++#include <linux/pci.h>
++#include <linux/spinlock.h>
++#include "pciback.h"
++
++#define PCI_MAX_BUSSES 255
++#define PCI_MAX_SLOTS 32
++
++struct controller_dev_entry {
++ struct list_head list;
++ struct pci_dev *dev;
++ unsigned int devfn;
++};
++
++struct controller_list_entry {
++ struct list_head list;
++ struct pci_controller *controller;
++ unsigned int domain;
++ unsigned int bus;
++ unsigned int next_devfn;
++ struct list_head dev_list;
++};
++
++struct controller_dev_data {
++ struct list_head list;
++ unsigned int next_domain;
++ unsigned int next_bus;
++ spinlock_t lock;
++};
++
++struct walk_info {
++ struct pciback_device *pdev;
++ int resource_count;
++ int root_num;
++};
++
++struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
++ unsigned int domain, unsigned int bus,
++ unsigned int devfn)
++{
++ struct controller_dev_data *dev_data = pdev->pci_dev_data;
++ struct controller_dev_entry *dev_entry;
++ struct controller_list_entry *cntrl_entry;
++ struct pci_dev *dev = NULL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dev_data->lock, flags);
++
++ list_for_each_entry(cntrl_entry, &dev_data->list, list) {
++ if (cntrl_entry->domain != domain ||
++ cntrl_entry->bus != bus)
++ continue;
++
++ list_for_each_entry(dev_entry, &cntrl_entry->dev_list, list) {
++ if (devfn == dev_entry->devfn) {
++ dev = dev_entry->dev;
++ goto found;
++ }
++ }
++ }
++found:
++ spin_unlock_irqrestore(&dev_data->lock, flags);
++
++ return dev;
++}
++
++int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
++{
++ struct controller_dev_data *dev_data = pdev->pci_dev_data;
++ struct controller_dev_entry *dev_entry;
++ struct controller_list_entry *cntrl_entry;
++ struct pci_controller *dev_controller = PCI_CONTROLLER(dev);
++ unsigned long flags;
++ int ret = 0, found = 0;
++
++ spin_lock_irqsave(&dev_data->lock, flags);
++
++ /* Look to see if we already have a domain:bus for this controller */
++ list_for_each_entry(cntrl_entry, &dev_data->list, list) {
++ if (cntrl_entry->controller == dev_controller) {
++ found = 1;
++ break;
++ }
++ }
++
++ if (!found) {
++ cntrl_entry = kmalloc(sizeof(*cntrl_entry), GFP_ATOMIC);
++ if (!cntrl_entry) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ cntrl_entry->controller = dev_controller;
++ cntrl_entry->next_devfn = PCI_DEVFN(0, 0);
++
++ cntrl_entry->domain = dev_data->next_domain;
++ cntrl_entry->bus = dev_data->next_bus++;
++ if (dev_data->next_bus > PCI_MAX_BUSSES) {
++ dev_data->next_domain++;
++ dev_data->next_bus = 0;
++ }
++
++ INIT_LIST_HEAD(&cntrl_entry->dev_list);
++
++ list_add_tail(&cntrl_entry->list, &dev_data->list);
++ }
++
++ if (PCI_SLOT(cntrl_entry->next_devfn) > PCI_MAX_SLOTS) {
++ /*
++ * While it seems unlikely, this can actually happen if
++ * a controller has P2P bridges under it.
++ */
++ xenbus_dev_fatal(pdev->xdev, -ENOSPC, "Virtual bus %04x:%02x "
++ "is full, no room to export %04x:%02x:%02x.%x",
++ cntrl_entry->domain, cntrl_entry->bus,
++ pci_domain_nr(dev->bus), dev->bus->number,
++ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
++ ret = -ENOSPC;
++ goto out;
++ }
++
++ dev_entry = kmalloc(sizeof(*dev_entry), GFP_ATOMIC);
++ if (!dev_entry) {
++ if (list_empty(&cntrl_entry->dev_list)) {
++ list_del(&cntrl_entry->list);
++ kfree(cntrl_entry);
++ }
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ dev_entry->dev = dev;
++ dev_entry->devfn = cntrl_entry->next_devfn;
++
++ list_add_tail(&dev_entry->list, &cntrl_entry->dev_list);
++
++ cntrl_entry->next_devfn += PCI_DEVFN(1, 0);
++
++out:
++ spin_unlock_irqrestore(&dev_data->lock, flags);
++ return ret;
++}
++
++void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
++{
++ struct controller_dev_data *dev_data = pdev->pci_dev_data;
++ struct controller_list_entry *cntrl_entry;
++ struct controller_dev_entry *dev_entry = NULL;
++ struct pci_dev *found_dev = NULL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dev_data->lock, flags);
++
++ list_for_each_entry(cntrl_entry, &dev_data->list, list) {
++ if (cntrl_entry->controller != PCI_CONTROLLER(dev))
++ continue;
++
++ list_for_each_entry(dev_entry, &cntrl_entry->dev_list, list) {
++ if (dev_entry->dev == dev) {
++ found_dev = dev_entry->dev;
++ break;
++ }
++ }
++ }
++
++ if (!found_dev) {
++ spin_unlock_irqrestore(&dev_data->lock, flags);
++ return;
++ }
++
++ list_del(&dev_entry->list);
++ kfree(dev_entry);
++
++ if (list_empty(&cntrl_entry->dev_list)) {
++ list_del(&cntrl_entry->list);
++ kfree(cntrl_entry);
++ }
++
++ spin_unlock_irqrestore(&dev_data->lock, flags);
++ pcistub_put_pci_dev(found_dev);
++}
++
++int pciback_init_devices(struct pciback_device *pdev)
++{
++ struct controller_dev_data *dev_data;
++
++ dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
++ if (!dev_data)
++ return -ENOMEM;
++
++ spin_lock_init(&dev_data->lock);
++
++ INIT_LIST_HEAD(&dev_data->list);
++
++ /* Starting domain:bus numbers */
++ dev_data->next_domain = 0;
++ dev_data->next_bus = 0;
++
++ pdev->pci_dev_data = dev_data;
++
++ return 0;
++}
++
++static acpi_status write_xenbus_resource(struct acpi_resource *res, void *data)
++{
++ struct walk_info *info = data;
++ struct acpi_resource_address64 addr;
++ acpi_status status;
++ int i, len, err;
++ char str[32], tmp[3];
++ unsigned char *ptr, *buf;
++
++ status = acpi_resource_to_address64(res, &addr);
++
++ /* Do we care about this range? Let's check. */
++ if (!ACPI_SUCCESS(status) ||
++ !(addr.resource_type == ACPI_MEMORY_RANGE ||
++ addr.resource_type == ACPI_IO_RANGE) ||
++ !addr.address_length || addr.producer_consumer != ACPI_PRODUCER)
++ return AE_OK;
++
++ /*
++ * Furthermore, we really only care to tell the guest about
++ * address ranges that require address translation of some sort.
++ */
++ if (!(addr.resource_type == ACPI_MEMORY_RANGE &&
++ addr.info.mem.translation) &&
++ !(addr.resource_type == ACPI_IO_RANGE &&
++ addr.info.io.translation))
++ return AE_OK;
++
++ /* Store the resource in xenbus for the guest */
++ len = snprintf(str, sizeof(str), "root-%d-resource-%d",
++ info->root_num, info->resource_count);
++ if (unlikely(len >= (sizeof(str) - 1)))
++ return AE_OK;
++
++ buf = kzalloc((sizeof(*res) * 2) + 1, GFP_KERNEL);
++ if (!buf)
++ return AE_OK;
++
++ /* Clean out resource_source */
++ res->data.address64.resource_source.index = 0xFF;
++ res->data.address64.resource_source.string_length = 0;
++ res->data.address64.resource_source.string_ptr = NULL;
++
++ ptr = (unsigned char *)res;
++
++ /* Turn the acpi_resource into an ASCII byte stream */
++ for (i = 0; i < sizeof(*res); i++) {
++ snprintf(tmp, sizeof(tmp), "%02x", ptr[i]);
++ strncat(buf, tmp, 2);
++ }
++
++ err = xenbus_printf(XBT_NIL, info->pdev->xdev->nodename,
++ str, "%s", buf);
++
++ if (!err)
++ info->resource_count++;
++
++ kfree(buf);
++
++ return AE_OK;
++}
++
++int pciback_publish_pci_roots(struct pciback_device *pdev,
++ publish_pci_root_cb publish_root_cb)
++{
++ struct controller_dev_data *dev_data = pdev->pci_dev_data;
++ struct controller_list_entry *cntrl_entry;
++ int i, root_num, len, err = 0;
++ unsigned int domain, bus;
++ char str[64];
++ struct walk_info info;
++
++ spin_lock(&dev_data->lock);
++
++ list_for_each_entry(cntrl_entry, &dev_data->list, list) {
++ /* First publish all the domain:bus info */
++ err = publish_root_cb(pdev, cntrl_entry->domain,
++ cntrl_entry->bus);
++ if (err)
++ goto out;
++
++ /*
++ * Now figure out which root-%d this belongs to
++ * so we can associate resources with it.
++ */
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
++ "root_num", "%d", &root_num);
++
++ if (err != 1)
++ goto out;
++
++ for (i = 0; i < root_num; i++) {
++ len = snprintf(str, sizeof(str), "root-%d", i);
++ if (unlikely(len >= (sizeof(str) - 1))) {
++ err = -ENOMEM;
++ goto out;
++ }
++
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
++ str, "%x:%x", &domain, &bus);
++ if (err != 2)
++ goto out;
++
++ /* Is this the one we just published? */
++ if (domain == cntrl_entry->domain &&
++ bus == cntrl_entry->bus)
++ break;
++ }
++
++ if (i == root_num)
++ goto out;
++
++ info.pdev = pdev;
++ info.resource_count = 0;
++ info.root_num = i;
++
++ /* Let ACPI do the heavy lifting on decoding resources */
++ acpi_walk_resources(cntrl_entry->controller->acpi_handle,
++ METHOD_NAME__CRS, write_xenbus_resource,
++ &info);
++
++ /* No resouces. OK. On to the next one */
++ if (!info.resource_count)
++ continue;
++
++ /* Store the number of resources we wrote for this root-%d */
++ len = snprintf(str, sizeof(str), "root-%d-resources", i);
++ if (unlikely(len >= (sizeof(str) - 1))) {
++ err = -ENOMEM;
++ goto out;
++ }
++
++ err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
++ "%d", info.resource_count);
++ if (err)
++ goto out;
++ }
++
++ /* Finally, write some magic to synchronize with the guest. */
++ len = snprintf(str, sizeof(str), "root-resource-magic");
++ if (unlikely(len >= (sizeof(str) - 1))) {
++ err = -ENOMEM;
++ goto out;
++ }
++
++ err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
++ "%lx", (sizeof(struct acpi_resource) * 2) + 1);
++
++out:
++ spin_unlock(&dev_data->lock);
++
++ return err;
++}
++
++void pciback_release_devices(struct pciback_device *pdev)
++{
++ struct controller_dev_data *dev_data = pdev->pci_dev_data;
++ struct controller_list_entry *cntrl_entry, *c;
++ struct controller_dev_entry *dev_entry, *d;
++
++ list_for_each_entry_safe(cntrl_entry, c, &dev_data->list, list) {
++ list_for_each_entry_safe(dev_entry, d,
++ &cntrl_entry->dev_list, list) {
++ list_del(&dev_entry->list);
++ pcistub_put_pci_dev(dev_entry->dev);
++ kfree(dev_entry);
++ }
++ list_del(&cntrl_entry->list);
++ kfree(cntrl_entry);
++ }
++
++ kfree(dev_data);
++ pdev->pci_dev_data = NULL;
++}
+diff -r e5b50dd9fcf5 -r 93a955c2bebb drivers/xen/pcifront/pci_op.c
+--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Tue Jun 12 11:15:20 2007 +0100
++++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Tue Jun 12 11:36:58 2007 +0100
+@@ -14,6 +14,122 @@
+
+ static int verbose_request = 0;
+ module_param(verbose_request, int, 0644);
++
++#ifdef __ia64__
++static void pcifront_init_sd(struct pcifront_sd *sd,
++ unsigned int domain, unsigned int bus,
++ struct pcifront_device *pdev)
++{
++ int err, i, j, k, len, root_num, res_count;
++ struct acpi_resource res;
++ unsigned int d, b, byte;
++ unsigned long magic;
++ char str[64], tmp[3];
++ unsigned char *buf, *bufp;
++ u8 *ptr;
++
++ memset(sd, 0, sizeof(*sd));
++
++ sd->segment = domain;
++ sd->node = -1; /* Revisit for NUMA */
++ sd->platform_data = pdev;
++
++ /* Look for resources for this controller in xenbus. */
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "root_num",
++ "%d", &root_num);
++ if (err != 1)
++ return;
++
++ for (i = 0; i < root_num; i++) {
++ len = snprintf(str, sizeof(str), "root-%d", i);
++ if (unlikely(len >= (sizeof(str) - 1)))
++ return;
++
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
++ str, "%x:%x", &d, &b);
++ if (err != 2)
++ return;
++
++ if (d == domain && b == bus)
++ break;
++ }
++
++ if (i == root_num)
++ return;
++
++ len = snprintf(str, sizeof(str), "root-resource-magic");
++
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
++ str, "%lx", &magic);
++
++ if (err != 1)
++ return; /* No resources, nothing to do */
++
++ if (magic != (sizeof(res) * 2) + 1) {
++ printk(KERN_WARNING "pcifront: resource magic mismatch\n");
++ return;
++ }
++
++ len = snprintf(str, sizeof(str), "root-%d-resources", i);
++ if (unlikely(len >= (sizeof(str) - 1)))
++ return;
++
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
++ str, "%d", &res_count);
++
++ if (err != 1)
++ return; /* No resources, nothing to do */
++
++ sd->window = kzalloc(sizeof(*sd->window) * res_count, GFP_KERNEL);
++ if (!sd->window)
++ return;
++
++ /* magic is also the size of the byte stream in xenbus */
++ buf = kmalloc(magic, GFP_KERNEL);
++ if (!buf) {
++ kfree(sd->window);
++ sd->window = NULL;
++ return;
++ }
++
++ /* Read the resources out of xenbus */
++ for (j = 0; j < res_count; j++) {
++ memset(&res, 0, sizeof(res));
++ memset(buf, 0, magic);
++
++ len = snprintf(str, sizeof(str), "root-%d-resource-%d", i, j);
++ if (unlikely(len >= (sizeof(str) - 1)))
++ return;
++
++ err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
++ "%s", buf);
++ if (err != 1) {
++ printk(KERN_WARNING "pcifront: error reading "
++ "resource %d on bus %04x:%02x\n",
++ j, domain, bus);
++ continue;
++ }
++
++ bufp = buf;
++ ptr = (u8 *)&res;
++ memset(tmp, 0, sizeof(tmp));
++
++ /* Copy ASCII byte stream into structure */
++ for (k = 0; k < magic - 1; k += 2) {
++ memcpy(tmp, bufp, 2);
++ bufp += 2;
++
++ sscanf(tmp, "%02x", &byte);
++ *ptr = byte;
++ ptr++;
++ }
++
++ xen_add_resource(sd, domain, bus, &res);
++ sd->windows++;
++ }
++ kfree(buf);
++}
++#endif
+
+ static int errno_to_pcibios_err(int errno)
+ {
+@@ -207,7 +323,7 @@ int pcifront_scan_root(struct pcifront_d
+ err = -ENOMEM;
+ goto err_out;
+ }
+- pcifront_init_sd(sd, domain, pdev);
++ pcifront_init_sd(sd, domain, bus, pdev);
+
+ b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
+ &pcifront_bus_ops, sd);
+@@ -217,6 +333,8 @@ int pcifront_scan_root(struct pcifront_d
+ err = -ENOMEM;
+ goto err_out;
+ }
++
++ pcifront_setup_root_resources(b, sd);
+ bus_entry->bus = b;
+
+ list_add(&bus_entry->list, &pdev->root_buses);
+diff -r e5b50dd9fcf5 -r 93a955c2bebb include/xen/pcifront.h
+--- a/linux-2.6-xen-sparse/include/xen/pcifront.h Tue Jun 12 11:15:20 2007 +0100
++++ b/linux-2.6-xen-sparse/include/xen/pcifront.h Tue Jun 12 11:36:58 2007 +0100
+@@ -26,7 +26,8 @@ pcifront_get_pdev(struct pcifront_sd *sd
+ return sd->pdev;
+ }
+
+-static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
++static inline void pcifront_init_sd(struct pcifront_sd *sd,
++ unsigned int domain, unsigned int bus,
+ struct pcifront_device *pdev)
+ {
+ sd->domain = domain;
+@@ -45,10 +46,21 @@ static inline int pci_proc_domain(struct
+ }
+ #endif /* CONFIG_PCI_DOMAINS */
+
++static inline void pcifront_setup_root_resources(struct pci_bus *bus,
++ struct pcifront_sd *sd)
++{
++}
++
+ #else /* __ia64__ */
+
++#include <linux/acpi.h>
+ #include <asm/pci.h>
+ #define pcifront_sd pci_controller
++
++extern void xen_add_resource(struct pci_controller *, unsigned int,
++ unsigned int, struct acpi_resource *);
++extern void xen_pcibios_setup_root_windows(struct pci_bus *,
++ struct pci_controller *);
+
+ static inline struct pcifront_device *
+ pcifront_get_pdev(struct pcifront_sd *sd)
+@@ -56,16 +68,10 @@ pcifront_get_pdev(struct pcifront_sd *sd
+ return (struct pcifront_device *)sd->platform_data;
+ }
+
+-static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
+- struct pcifront_device *pdev)
++static inline void pcifront_setup_root_resources(struct pci_bus *bus,
++ struct pcifront_sd *sd)
+ {
+- sd->segment = domain;
+- sd->acpi_handle = NULL;
+- sd->iommu = NULL;
+- sd->node = -1;
+- sd->windows = 0;
+- sd->window = NULL;
+- sd->platform_data = pdev;
++ xen_pcibios_setup_root_windows(bus, sd);
+ }
+
+ #endif /* __ia64__ */
diff -r 7ba52aa72ae5 linux-55-a62cfa35d3b5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-55-a62cfa35d3b5 Tue Sep 11 12:33:14 2007 -0600
@@ -0,0 +1,60 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# 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 <alex.williamson@hp.com>
+linux-2.6.18-xen changeset: 55:a62cfa35d3b504d5ee1acd4a409a6fb3ee45a6bd
+linux-2.6.18-xen date: Tue Jun 12 15:48:23 2007 -0600
+
+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)
diff -r 7ba52aa72ae5 linux-56-1483ef74511b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-56-1483ef74511b Tue Sep 11 12:33:29 2007 -0600
@@ -0,0 +1,101 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181685161 21600
+# Node ID 1483ef74511b1c9819212aac9f67232a66f71adf
+# Parent a62cfa35d3b504d5ee1acd4a409a6fb3ee45a6bd
+[IA64] xencomm update for acm interface change
+
+Changed by c/s 15189:96915ca8d5f2 of xen-unstable.h
+
+Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
+linux-2.6.18-xen changeset: 56:1483ef74511b1c9819212aac9f67232a66f71adf
+linux-2.6.18-xen date: Tue Jun 12 15:52:41 2007 -0600
+
+diff -r a62cfa35d3b5 -r 1483ef74511b arch/ia64/xen/xcom_privcmd.c
+--- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Tue Jun 12 15:48:23 2007 -0600
++++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Tue Jun 12 15:52:41 2007 -0600
+@@ -338,40 +338,39 @@ static int
+ static int
+ xencomm_privcmd_acm_op(privcmd_hypercall_t *hypercall)
+ {
+- int cmd = hypercall->arg[0];
+- void __user *arg = (void __user *)hypercall->arg[1];
++ void __user *arg = (void __user *)hypercall->arg[0];
++ xen_acmctl_t kern_arg;
+ struct xencomm_handle *op_desc;
+ struct xencomm_handle *desc = NULL;
+ int ret;
+
+- switch (cmd) {
+- case ACMOP_getssid:
+- {
+- struct acm_getssid kern_arg;
+-
+- if (copy_from_user(&kern_arg, arg, sizeof (kern_arg)))
++ if (copy_from_user(&kern_arg, arg, sizeof(kern_arg)))
++ return -EFAULT;
++ if (kern_arg.interface_version != ACM_INTERFACE_VERSION)
++ return -ENOSYS;
++
++ switch (kern_arg.cmd) {
++ case ACMOP_getssid: {
++ op_desc = xencomm_create_inline(&kern_arg);
++
++ ret = xencomm_create(
++ xen_guest_handle(kern_arg.u.getssid.ssidbuf),
++ kern_arg.u.getssid.ssidbuf_size, &desc, GFP_KERNEL);
++ if (ret)
++ return ret;
++
++ set_xen_guest_handle(kern_arg.u.getssid.ssidbuf, (void *)desc);
++
++ ret = xencomm_arch_hypercall_acm_op(op_desc);
++
++ xencomm_free(desc);
++
++ if (copy_to_user(arg, &kern_arg, sizeof(kern_arg)))
+ return -EFAULT;
+-
+- op_desc = xencomm_create_inline(&kern_arg);
+-
+- ret = xencomm_create(xen_guest_handle(kern_arg.ssidbuf),
+- kern_arg.ssidbuf_size, &desc, GFP_KERNEL);
+- if (ret)
+- return ret;
+-
+- set_xen_guest_handle(kern_arg.ssidbuf, (void *)desc);
+-
+- ret = xencomm_arch_hypercall_acm_op(cmd, op_desc);
+-
+- xencomm_free(desc);
+-
+- if (copy_to_user(arg, &kern_arg, sizeof (kern_arg)))
+- return -EFAULT;
+-
+- return ret;
+- }
+- default:
+- printk("%s: unknown acm_op cmd %d\n", __func__, cmd);
++ return ret;
++ }
++ default:
++ printk("%s: unknown acm_op cmd %d\n", __func__, kern_arg.cmd);
+ return -ENOSYS;
+ }
+
+diff -r a62cfa35d3b5 -r 1483ef74511b include/asm-ia64/hypercall.h
+--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Tue Jun 12 15:48:23 2007 -0600
++++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Tue Jun 12 15:52:41 2007 -0600
+@@ -157,9 +157,9 @@ xencomm_arch_hypercall_event_channel_op(
+ }
+
+ static inline int
+-xencomm_arch_hypercall_acm_op(unsigned int cmd, struct xencomm_handle *arg)
+-{
+- return _hypercall2(int, acm_op, cmd, arg);
++xencomm_arch_hypercall_acm_op(struct xencomm_handle *arg)
++{
++ return _hypercall1(int, acm_op, arg);
+ }
+
+ static inline int
diff -r 7ba52aa72ae5 linux-61-452c5d4a5537
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-61-452c5d4a5537 Tue Sep 11 12:33:45 2007 -0600
@@ -0,0 +1,37 @@
+# HG changeset patch
+# User Alex Williamson <alex.williamson@hp.com>
+# Date 1181920189 21600
+# Node ID 452c5d4a55370c3c3a6cb6740b45be911ca3741e
+# Parent b492ac038d613212da3ee16646168b56ef8833cc
+[IA64] Default to Controller PCI backend
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+linux-2.6.18-xen changeset: 61:452c5d4a55370c3c3a6cb6740b45be911ca3741e
+linux-2.6.18-xen date: Fri Jun 15 09:09:49 2007 -0600
+
+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
diff -r 7ba52aa72ae5 series
--- a/series Fri Sep 07 15:49:00 2007 +0100
+++ b/series Tue Sep 11 13:40:54 2007 -0600
@@ -35,6 +35,7 @@ 15080-089696e0c603
15080-089696e0c603
15082-0fd2bf14f38a
15083-b9da101ed945
+15096-d4f59e652078
15128-f6928d636999
15130-a40967e39652
15132-17f6163ae930
@@ -147,6 +148,14 @@ 15289-8ad38aaaeb89
15289-8ad38aaaeb89
15290-56548d9a7ba7
15291-1feb91894e11
+15331-b46c2ff6dfb0
+15348-51f5bea7b0d8
+15349-71377eab1874
+15265-634b7f7f8584
+15353-601509daabfc
+15364-1623f5f5094f
+15365-33cc64dcaead
+15366-fd0103b55504
15373-58b6223074af
15374-b1eb43f94a3a
15375-342c85cfd00b
@@ -248,6 +257,9 @@ 15524-26eef8426110
15524-26eef8426110
15528-637ff26be6ff
15535-c6491ed12f84
+15555-38d061886873
+15557-2a5b463f2e8d
+15579-f536eb8576ee
15583-b27add01a929
15584-48c8244c47c7
15588-0aa2a954a6d1
@@ -277,7 +289,11 @@ linux-34-0301c1fd8c0d
linux-34-0301c1fd8c0d
linux-35-85b046c1da18
linux-42-c09686d2bbff
+linux-46-93a955c2bebb
linux-47-33c3009e73ec
+linux-55-a62cfa35d3b5
+linux-56-1483ef74511b
+linux-61-452c5d4a5537
linux-65-87bb8705768a
linux-66-496e3157a35c
linux-68-cadc6d58a9e6
@@ -345,5 +361,8 @@ 15830-32f331858d75
15830-32f331858d75
15832-f779ee15c553
15833-05950e909ba6
+15850-6644d8486266
+15852-f88eea67a469
linux-191-1e2284d885fb
linux-192-5ce5bd383ea9
+ia64-sal-get-state-info
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next prev parent reply other threads:[~2007-09-11 20:00 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-10 8:56 Xen 3.1.1 -- initial patchqueue Keir Fraser
2007-09-10 10:55 ` Jambunathan K
2007-09-10 10:58 ` Keir Fraser
2007-09-10 12:03 ` [Xen-devel] " Ben Guthro
2007-09-10 12:10 ` Keir Fraser
2007-09-10 12:18 ` Ben Guthro
2007-09-10 12:28 ` Ben Guthro
2007-09-10 12:31 ` Keir Fraser
2007-09-10 12:48 ` Ben Guthro
2007-09-10 12:55 ` Ian Campbell
2007-09-10 12:56 ` [Xen-devel] " Keir Fraser
2007-09-10 15:00 ` Brendan Cully
2007-09-10 13:21 ` Ben Guthro
2007-09-10 19:18 ` Alex Williamson
2007-09-11 15:15 ` Alex Williamson
2007-09-11 17:43 ` Keir Fraser
2007-09-11 20:00 ` Alex Williamson [this message]
2007-09-12 6:33 ` Re: [Xen-devel] " Kouya Shimura
2007-09-12 15:28 ` [Xen-ia64-devel] " Alex Williamson
2007-09-11 18:36 ` [Xen-devel] " Chris Lalancette
2007-09-11 21:15 ` Travis Betak
2007-09-13 20:57 ` [Xen-devel] " Eduardo Habkost
2007-09-14 6:47 ` Keir Fraser
2007-09-14 15:35 ` Keir Fraser
2007-09-14 16:08 ` Alex Williamson
2007-09-14 16:16 ` Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1189540819.11204.43.camel@bling \
--to=alex.williamson@hp.com \
--cc=Keir.Fraser@cl.cam.ac.uk \
--cc=bguthro@virtualiron.com \
--cc=xen-devel@lists.xensource.com \
--cc=xen-ia64-devel@lists.xensource.com \
--cc=xen-ppc-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.