WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 10 Oct 2008 20:00:53 -0700
Delivery-date: Fri, 10 Oct 2008 20:03:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1223608006 -32400
# Node ID c2fc4d26ef18b53b19c4ca03a836b1b75143d158
# Parent  af8eaa3cf78200568bdfd7e7d87a546c53e6bd7b
# Parent  6ab55f716ce3c7a8d52fcb1211491954635a2d1d
merge with xen-unstable.hg
---
 buildconfigs/mk.linux-2.6-common                |    4 
 tools/firmware/hvmloader/smbios.c               |   79 +++++----
 tools/flask/policy/policy/modules/xen/xen.te    |    5 
 tools/misc/xenpm.c                              |    2 
 tools/pygrub/src/LiloConf.py                    |    6 
 tools/python/xen/util/xsm/flask/flask.py        |    5 
 tools/python/xen/xend/XendDomainInfo.py         |    2 
 tools/python/xen/xend/image.py                  |    2 
 xen/arch/x86/domain.c                           |    1 
 xen/arch/x86/hvm/svm/intr.c                     |    5 
 xen/arch/x86/hvm/vmsi.c                         |    2 
 xen/arch/x86/hvm/vmx/intr.c                     |   15 -
 xen/arch/x86/i8259.c                            |    4 
 xen/arch/x86/io_apic.c                          |   50 +++--
 xen/arch/x86/irq.c                              |  180 ++++++++++++++++++++
 xen/arch/x86/mm.c                               |    2 
 xen/arch/x86/pci.c                              |   61 -------
 xen/arch/x86/physdev.c                          |  208 +++---------------------
 xen/arch/x86/x86_32/xen.lds.S                   |    1 
 xen/arch/x86/x86_64/xen.lds.S                   |    1 
 xen/common/event_channel.c                      |   88 +++++-----
 xen/drivers/Makefile                            |    1 
 xen/drivers/passthrough/io.c                    |  182 ++++++++++++---------
 xen/drivers/passthrough/pci.c                   |   14 -
 xen/drivers/passthrough/vtd/intremap.c          |   10 -
 xen/drivers/passthrough/vtd/vtd.h               |   37 ++++
 xen/drivers/passthrough/vtd/x86/vtd.c           |   26 +--
 xen/drivers/pci/Makefile                        |    1 
 xen/drivers/pci/pci.c                           |   64 +++++++
 xen/include/asm-x86/domain.h                    |    2 
 xen/include/asm-x86/hvm/irq.h                   |    6 
 xen/include/asm-x86/io_apic.h                   |    1 
 xen/include/asm-x86/irq.h                       |   10 +
 xen/include/xen/irq.h                           |    2 
 xen/include/xen/sched.h                         |    2 
 xen/xsm/acm/acm_simple_type_enforcement_hooks.c |    8 
 36 files changed, 628 insertions(+), 461 deletions(-)

diff -r af8eaa3cf782 -r c2fc4d26ef18 buildconfigs/mk.linux-2.6-common
--- a/buildconfigs/mk.linux-2.6-common  Fri Oct 10 11:58:03 2008 +0900
+++ b/buildconfigs/mk.linux-2.6-common  Fri Oct 10 12:06:46 2008 +0900
@@ -75,7 +75,9 @@ endif
        # tree. Finally attempt to use make defconfig.
        set -e ; \
        CONFIG_VERSION=$$(sed -ne 's/$$(XENGUEST)//; s/^EXTRAVERSION = //p' 
$(LINUX_SRCDIR)/Makefile); \
-       if [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) ] ; then \
+       if [ ! -z "$(XEN_LINUX_CONFIG)" -a -r $(XEN_LINUX_CONFIG) ]; then \
+         cp $(XEN_LINUX_CONFIG) $(CONFIG_FILE); \
+       elif [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) ] ; then \
          cp 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) 
$(CONFIG_FILE) ; \
         elif [ -e $(LINUX_SRCDIR)/buildconfigs/create_config.sh ] ; then \
          cd $(LINUX_SRCDIR) && sh buildconfigs/create_config.sh \
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/firmware/hvmloader/smbios.c Fri Oct 10 12:06:46 2008 +0900
@@ -54,13 +54,13 @@ smbios_type_4_init(void *start, unsigned
 smbios_type_4_init(void *start, unsigned int cpu_number,
                    char *cpu_manufacturer);
 static void *
-smbios_type_16_init(void *start, uint32_t memory_size_mb);
-static void *
-smbios_type_17_init(void *start, uint32_t memory_size_mb);
-static void *
-smbios_type_19_init(void *start, uint32_t memory_size_mb);
-static void *
-smbios_type_20_init(void *start, uint32_t memory_size_mb);
+smbios_type_16_init(void *start, uint32_t memory_size_mb, int nr_mem_devs);
+static void *
+smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance);
+static void *
+smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance);
+static void *
+smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance);
 static void *
 smbios_type_32_init(void *start);
 static void *
@@ -92,6 +92,7 @@ write_smbios_tables(void *start,
     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
     char *p, *q;
     char cpu_manufacturer[15];
+    int i, nr_mem_devs;
 
     get_cpu_manufacturer(cpu_manufacturer, 15);
 
@@ -111,10 +112,19 @@ write_smbios_tables(void *start,
     do_struct(smbios_type_3_init(p));
     for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ )
         do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
-    do_struct(smbios_type_16_init(p, memsize));
-    do_struct(smbios_type_17_init(p, memsize));
-    do_struct(smbios_type_19_init(p, memsize));
-    do_struct(smbios_type_20_init(p, memsize));
+
+    /* Each 'memory device' covers up to 16GB of address space. */
+    nr_mem_devs = (memsize + 0x3fff) >> 14;
+    do_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
+    for ( i = 0; i < nr_mem_devs; i++ )
+    {
+        uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
+                                ? (memsize & 0x3fff) : 0x4000);
+        do_struct(smbios_type_17_init(p, dev_memsize, i));
+        do_struct(smbios_type_19_init(p, dev_memsize, i));
+        do_struct(smbios_type_20_init(p, dev_memsize, i));
+    }
+
     do_struct(smbios_type_32_init(p));
     do_struct(smbios_type_127_init(p));
 
@@ -441,7 +451,7 @@ smbios_type_4_init(
 
 /* Type 16 -- Physical Memory Array */
 static void *
-smbios_type_16_init(void *start, uint32_t memsize)
+smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
 {
     struct smbios_type_16 *p = (struct smbios_type_16*)start;
 
@@ -456,7 +466,7 @@ smbios_type_16_init(void *start, uint32_
     p->error_correction = 0x01; /* other */
     p->maximum_capacity = memsize * 1024;
     p->memory_error_information_handle = 0xfffe; /* none provided */
-    p->number_of_memory_devices = 1;
+    p->number_of_memory_devices = nr_mem_devs;
 
     start += sizeof(struct smbios_type_16);
     *((uint16_t *)start) = 0;
@@ -465,22 +475,22 @@ smbios_type_16_init(void *start, uint32_
 
 /* Type 17 -- Memory Device */
 static void *
-smbios_type_17_init(void *start, uint32_t memory_size_mb)
-{
+smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
+{
+    char buf[16];
     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
     
     memset(p, 0, sizeof(*p));
 
     p->header.type = 17;
     p->header.length = sizeof(struct smbios_type_17);
-    p->header.handle = 0x1100;
+    p->header.handle = 0x1100 + instance;
 
     p->physical_memory_array_handle = 0x1000;
     p->total_width = 64;
     p->data_width = 64;
-    /* truncate memory_size_mb to 16 bits and clear most significant
-       bit [indicates size in MB] */
-    p->size = (uint16_t) memory_size_mb & 0x7fff;
+    ASSERT((memory_size_mb & ~0x7fff) == 0);
+    p->size = memory_size_mb;
     p->form_factor = 0x09; /* DIMM */
     p->device_set = 0;
     p->device_locator_str = 1;
@@ -489,8 +499,11 @@ smbios_type_17_init(void *start, uint32_
     p->type_detail = 0;
 
     start += sizeof(struct smbios_type_17);
-    strcpy((char *)start, "DIMM 1");
-    start += strlen("DIMM 1") + 1;
+    strcpy(start, "DIMM ");
+    start += strlen("DIMM ");
+    itoa(buf, instance);
+    strcpy(start, buf);
+    start += strlen(buf) + 1;
     *((uint8_t *)start) = 0;
 
     return start+1;
@@ -498,7 +511,7 @@ smbios_type_17_init(void *start, uint32_
 
 /* Type 19 -- Memory Array Mapped Address */
 static void *
-smbios_type_19_init(void *start, uint32_t memory_size_mb)
+smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
 {
     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
     
@@ -506,10 +519,10 @@ smbios_type_19_init(void *start, uint32_
 
     p->header.type = 19;
     p->header.length = sizeof(struct smbios_type_19);
-    p->header.handle = 0x1300;
-
-    p->starting_address = 0;
-    p->ending_address = (memory_size_mb-1) * 1024;
+    p->header.handle = 0x1300 + instance;
+
+    p->starting_address = instance << 24;
+    p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
     p->memory_array_handle = 0x1000;
     p->partition_width = 1;
 
@@ -520,7 +533,7 @@ smbios_type_19_init(void *start, uint32_
 
 /* Type 20 -- Memory Device Mapped Address */
 static void *
-smbios_type_20_init(void *start, uint32_t memory_size_mb)
+smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
 {
     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
 
@@ -528,12 +541,12 @@ smbios_type_20_init(void *start, uint32_
 
     p->header.type = 20;
     p->header.length = sizeof(struct smbios_type_20);
-    p->header.handle = 0x1400;
-
-    p->starting_address = 0;
-    p->ending_address = (memory_size_mb-1)*1024;
-    p->memory_device_handle = 0x1100;
-    p->memory_array_mapped_address_handle = 0x1300;
+    p->header.handle = 0x1400 + instance;
+
+    p->starting_address = instance << 24;
+    p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
+    p->memory_device_handle = 0x1100 + instance;
+    p->memory_array_mapped_address_handle = 0x1300 + instance;
     p->partition_row_position = 1;
     p->interleave_position = 0;
     p->interleaved_data_depth = 0;
diff -r af8eaa3cf782 -r c2fc4d26ef18 
tools/flask/policy/policy/modules/xen/xen.te
--- a/tools/flask/policy/policy/modules/xen/xen.te      Fri Oct 10 11:58:03 
2008 +0900
+++ b/tools/flask/policy/policy/modules/xen/xen.te      Fri Oct 10 12:06:46 
2008 +0900
@@ -33,7 +33,7 @@ define(`create_domain', `
                                getvcpuinfo getaddrsize getvcpuaffinity};
        allow $1 $2:shadow {enable};
        allow $1 $2:mmu {map_read map_write memorymap adjust pinpage};
-       allow $2 $2:mmu {map_read map_write pinpage};
+       allow $2 $2:mmu {map_read map_write adjust pinpage};
        allow $2 domio_t:mmu {map_read};
        allow $2 $2:grant {query setup};
        allow $1 $2:grant {map_read unmap};
@@ -110,6 +110,9 @@ create_channel(domU_t, dom0_t, evchnU-0_
 create_channel(domU_t, dom0_t, evchnU-0_t)
 allow domU_t evchnU-0_t:event {send};
 
+allow dom0_t dom0_t:event {send};
+allow dom0_t domU_t:grant {copy};
+
 manage_domain(dom0_t, domU_t)
 
 
################################################################################
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/misc/xenpm.c
--- a/tools/misc/xenpm.c        Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/misc/xenpm.c        Fri Oct 10 12:06:46 2008 +0900
@@ -161,7 +161,7 @@ int main(int argc, char **argv)
                 break;
             }
 
-            ret = xc_pm_get_pxstat(xc_fd, 0, pxstat);
+            ret = xc_pm_get_pxstat(xc_fd, i, pxstat);
             if( ret ) {
                 fprintf(stderr, "failed to get P-states statistics 
information\n");
                 free(pxstat->trans_pt);
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/pygrub/src/LiloConf.py
--- a/tools/pygrub/src/LiloConf.py      Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/pygrub/src/LiloConf.py      Fri Oct 10 12:06:46 2008 +0900
@@ -142,7 +142,7 @@ class LiloConfigFile(object):
         self.images.append(image)
 
     def _get_default(self):
-        for i in range(0, len(self.images) - 1):
+        for i in range(len(self.images)):
             if self.images[i].title == self._default:
                 return i
         return 0
@@ -150,8 +150,8 @@ class LiloConfigFile(object):
         self._default = val
     default = property(_get_default, _set_default)
 
-    commands = { "default": "self.default",
-                 "timeout": "self.timeout",
+    commands = { "default": "default",
+                 "timeout": "timeout",
                  "prompt": None,
                  "relocatable": None,
                  }
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/python/xen/util/xsm/flask/flask.py
--- a/tools/python/xen/util/xsm/flask/flask.py  Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/python/xen/util/xsm/flask/flask.py  Fri Oct 10 12:06:46 2008 +0900
@@ -35,7 +35,10 @@ def calc_dom_ssidref_from_info(info):
     return ssidref
 
 def set_security_label(policy, label):
-    return label
+    if label:
+        return label
+    else:
+        return ""
 
 def ssidref2security_label(ssidref):
     label = ssidref2label(ssidref)
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Oct 10 12:06:46 2008 +0900
@@ -1303,7 +1303,7 @@ class XendDomainInfo:
         t.mkdir()
         t.set_permissions({'dom' : self.domid, 'read' : True})
         t.write('vm', self.vmpath)
-        for i in [ 'device', 'control', 'error' ]:
+        for i in [ 'device', 'control', 'error', 'memory' ]:
             t.mkdir(i)
             t.set_permissions(i, {'dom' : self.domid})
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Oct 10 11:58:03 2008 +0900
+++ b/tools/python/xen/xend/image.py    Fri Oct 10 12:06:46 2008 +0900
@@ -502,7 +502,7 @@ class ImageHandler:
         if fifo_fd >= 0:
             self._openSentinel(sentinel_path_fifo)
             os.close(fifo_fd)
-            self.pid = self.vm._gatherDom(('image/device-model-pid', int))
+            self.pid = self.vm.gatherDom(('image/device-model-pid', int))
             log.debug("%s device model rediscovered, pid %s sentinel fifo %s",
                     name, self.pid, sentinel_path_fifo)
             self.sentinel_thread = 
thread.start_new_thread(self._sentinel_watch,())
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/domain.c     Fri Oct 10 12:06:46 2008 +0900
@@ -459,6 +459,7 @@ void arch_domain_destroy(struct domain *
         hvm_domain_destroy(d);
 
     pci_release_devices(d);
+    free_domain_pirqs(d);
     if ( !is_idle_domain(d) )
         iommu_domain_destroy(d);
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/hvm/svm/intr.c       Fri Oct 10 12:06:46 2008 +0900
@@ -124,9 +124,11 @@ static void svm_dirq_assist(struct vcpu 
         if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
             continue;
 
+        spin_lock(&d->event_lock);
         if ( test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[irq].flags) )
         {
             hvm_pci_msi_assert(d, irq);
+            spin_unlock(&d->event_lock);
             continue;
         }
 
@@ -137,9 +139,7 @@ static void svm_dirq_assist(struct vcpu 
             device = digl->device;
             intx = digl->intx;
             hvm_pci_intx_assert(d, device, intx);
-            spin_lock(&hvm_irq_dpci->dirq_lock);
             hvm_irq_dpci->mirq[irq].pending++;
-            spin_unlock(&hvm_irq_dpci->dirq_lock);
         }
 
         /*
@@ -151,6 +151,7 @@ static void svm_dirq_assist(struct vcpu 
          */
         set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
                   NOW() + PT_IRQ_TIME_OUT);
+        spin_unlock(&d->event_lock);
     }
 }
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/hvm/vmsi.c   Fri Oct 10 12:06:46 2008 +0900
@@ -134,7 +134,7 @@ int vmsi_deliver(struct domain *d, int p
                 "vector=%x trig_mode=%x\n",
                 dest, dest_mode, delivery_mode, vector, trig_mode);
 
-    if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MSI) )
+    if ( !test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[pirq].flags) )
     {
         gdprintk(XENLOG_WARNING, "pirq %x not msi \n", pirq);
         return 0;
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/hvm/vmx/intr.c       Fri Oct 10 12:06:46 2008 +0900
@@ -127,11 +127,13 @@ static void vmx_dirq_assist(struct vcpu 
         if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
             continue;
 
-               if ( test_bit(_HVM_IRQ_DPCI_MSI, 
&hvm_irq_dpci->mirq[irq].flags) )
-               {
-                       hvm_pci_msi_assert(d, irq);
-                       continue;
-               }
+        spin_lock(&d->event_lock);
+        if ( test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[irq].flags) )
+        {
+            hvm_pci_msi_assert(d, irq);
+            spin_unlock(&d->event_lock);
+            continue;
+        }
 
         stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)]);
 
@@ -140,9 +142,7 @@ static void vmx_dirq_assist(struct vcpu 
             device = digl->device;
             intx = digl->intx;
             hvm_pci_intx_assert(d, device, intx);
-            spin_lock(&hvm_irq_dpci->dirq_lock);
             hvm_irq_dpci->mirq[irq].pending++;
-            spin_unlock(&hvm_irq_dpci->dirq_lock);
         }
 
         /*
@@ -154,6 +154,7 @@ static void vmx_dirq_assist(struct vcpu 
          */
         set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
                   NOW() + PT_IRQ_TIME_OUT);
+        spin_unlock(&d->event_lock);
     }
 }
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/i8259.c      Fri Oct 10 12:06:46 2008 +0900
@@ -408,6 +408,10 @@ void __init init_IRQ(void)
         irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type;
     }
 
+    /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
+    vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN;
+    vector_irq[0x80] = NEVER_ASSIGN;
+
     apic_intr_init();
 
     /* Set the clock to HZ Hz */
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/io_apic.c    Fri Oct 10 12:06:46 2008 +0900
@@ -87,7 +87,8 @@ static struct irq_pin_list {
 } irq_2_pin[PIN_MAP_SIZE];
 static int irq_2_pin_free_entry = NR_IRQS;
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
+int vector_irq[NR_VECTORS] __read_mostly = {
+    [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN};
 
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
@@ -666,40 +667,47 @@ static inline int IO_APIC_irq_trigger(in
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
 u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
+int free_irq_vector(int vector)
+{
+    int irq;
+
+    BUG_ON((vector > LAST_DYNAMIC_VECTOR) || (vector < FIRST_DYNAMIC_VECTOR));
+
+    spin_lock(&vector_lock);
+    if ((irq = vector_irq[vector]) == AUTO_ASSIGN)
+        vector_irq[vector] = FREE_TO_ASSIGN;
+    spin_unlock(&vector_lock);
+
+    return (irq == AUTO_ASSIGN) ? 0 : -EINVAL;
+}
+
 int assign_irq_vector(int irq)
 {
-    static unsigned current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+    static unsigned current_vector = FIRST_DYNAMIC_VECTOR;
     unsigned vector;
 
     BUG_ON(irq >= NR_IRQ_VECTORS);
+
     spin_lock(&vector_lock);
 
-    if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+    if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) {
         spin_unlock(&vector_lock);
         return IO_APIC_VECTOR(irq);
     }
 
-next:
-    current_vector += 8;
-
-    /* Skip the hypercall vector. */
-    if (current_vector == HYPERCALL_VECTOR)
-        goto next;
-
-    /* Skip the Linux/BSD fast-trap vector. */
-    if (current_vector == 0x80)
-        goto next;
-
-    if (current_vector > LAST_DYNAMIC_VECTOR) {
-        offset++;
-        if (!(offset%8)) {
+    vector = current_vector;
+    while (vector_irq[vector] != FREE_TO_ASSIGN) {
+        vector += 8;
+        if (vector > LAST_DYNAMIC_VECTOR)
+            vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7);
+
+        if (vector == current_vector) {
             spin_unlock(&vector_lock);
             return -ENOSPC;
         }
-        current_vector = FIRST_DYNAMIC_VECTOR + offset;
-    }
-
-    vector = current_vector;
+    }
+
+    current_vector = vector;
     vector_irq[vector] = irq;
     if (irq != AUTO_ASSIGN)
         IO_APIC_VECTOR(irq) = vector;
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/irq.c        Fri Oct 10 12:06:46 2008 +0900
@@ -14,8 +14,11 @@
 #include <xen/sched.h>
 #include <xen/keyhandler.h>
 #include <xen/compat.h>
+#include <xen/iocap.h>
+#include <xen/iommu.h>
+#include <asm/msi.h>
 #include <asm/current.h>
-#include <xen/iommu.h>
+#include <public/physdev.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
 int opt_noirqbalance = 0;
@@ -282,7 +285,7 @@ static void __do_IRQ_guest(int vector)
  * The descriptor is returned locked. This function is safe against changes
  * to the per-domain irq-to-vector mapping.
  */
-static irq_desc_t *domain_spin_lock_irq_desc(
+irq_desc_t *domain_spin_lock_irq_desc(
     struct domain *d, int irq, unsigned long *pflags)
 {
     unsigned int vector;
@@ -511,7 +514,7 @@ int pirq_guest_bind(struct vcpu *v, int 
     int                 rc = 0;
     cpumask_t           cpumask = CPU_MASK_NONE;
 
-    WARN_ON(!spin_is_locked(&v->domain->evtchn_lock));
+    WARN_ON(!spin_is_locked(&v->domain->event_lock));
     BUG_ON(!local_irq_is_enabled());
 
  retry:
@@ -681,7 +684,7 @@ void pirq_guest_unbind(struct domain *d,
     irq_desc_t *desc;
     int vector;
 
-    WARN_ON(!spin_is_locked(&d->evtchn_lock));
+    WARN_ON(!spin_is_locked(&d->event_lock));
 
     BUG_ON(!local_irq_is_enabled());
     desc = domain_spin_lock_irq_desc(d, irq, NULL);
@@ -708,7 +711,7 @@ int pirq_guest_force_unbind(struct domai
     irq_guest_action_t *action;
     int i, bound = 0;
 
-    WARN_ON(!spin_is_locked(&d->evtchn_lock));
+    WARN_ON(!spin_is_locked(&d->event_lock));
 
     BUG_ON(!local_irq_is_enabled());
     desc = domain_spin_lock_irq_desc(d, irq, NULL);
@@ -729,6 +732,173 @@ int pirq_guest_force_unbind(struct domai
  out:
     spin_unlock_irq(&desc->lock);
     return bound;
+}
+
+int get_free_pirq(struct domain *d, int type, int index)
+{
+    int i;
+
+    ASSERT(spin_is_locked(&d->event_lock));
+
+    if ( type == MAP_PIRQ_TYPE_GSI )
+    {
+        for ( i = 16; i < NR_PIRQS; i++ )
+            if ( !d->arch.pirq_vector[i] )
+                break;
+        if ( i == NR_PIRQS )
+            return -ENOSPC;
+    }
+    else
+    {
+        for ( i = NR_PIRQS - 1; i >= 16; i-- )
+            if ( !d->arch.pirq_vector[i] )
+                break;
+        if ( i == 16 )
+            return -ENOSPC;
+    }
+
+    return i;
+}
+
+int map_domain_pirq(
+    struct domain *d, int pirq, int vector, int type, void *data)
+{
+    int ret = 0;
+    int old_vector, old_pirq;
+    irq_desc_t *desc;
+    unsigned long flags;
+
+    ASSERT(spin_is_locked(&d->event_lock));
+
+    if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( pirq < 0 || pirq >= NR_PIRQS || vector < 0 || vector >= NR_VECTORS )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or vector %d\n",
+                d->domain_id, pirq, vector);
+        return -EINVAL;
+    }
+
+    old_vector = d->arch.pirq_vector[pirq];
+    old_pirq = d->arch.vector_pirq[vector];
+
+    if ( (old_vector && (old_vector != vector) ) ||
+         (old_pirq && (old_pirq != pirq)) )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or vector %d already mapped\n",
+                d->domain_id, pirq, vector);
+        return -EINVAL;
+    }
+
+    ret = irq_permit_access(d, pirq);
+    if ( ret )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n",
+                d->domain_id, pirq);
+        return ret;
+    }
+
+    desc = &irq_desc[vector];
+    spin_lock_irqsave(&desc->lock, flags);
+
+    if ( type == MAP_PIRQ_TYPE_MSI )
+    {
+        struct msi_info *msi = (struct msi_info *)data;
+        if ( desc->handler != &no_irq_type )
+            dprintk(XENLOG_G_ERR, "dom%d: vector %d in use\n",
+                    d->domain_id, vector);
+        desc->handler = &pci_msi_type;
+        ret = pci_enable_msi(msi);
+        if ( ret )
+            goto done;
+    }
+
+    d->arch.pirq_vector[pirq] = vector;
+    d->arch.vector_pirq[vector] = pirq;
+
+done:
+    spin_unlock_irqrestore(&desc->lock, flags);
+    return ret;
+}
+
+/* The pirq should have been unbound before this call. */
+int unmap_domain_pirq(struct domain *d, int pirq)
+{
+    unsigned long flags;
+    irq_desc_t *desc;
+    int vector, ret = 0;
+    bool_t forced_unbind;
+
+    if ( (pirq < 0) || (pirq >= NR_PIRQS) )
+        return -EINVAL;
+
+    if ( !IS_PRIV(current->domain) )
+        return -EINVAL;
+
+    ASSERT(spin_is_locked(&d->event_lock));
+
+    vector = d->arch.pirq_vector[pirq];
+    if ( vector <= 0 )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
+                d->domain_id, pirq);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    forced_unbind = pirq_guest_force_unbind(d, pirq);
+    if ( forced_unbind )
+        dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
+                d->domain_id, pirq);
+
+    desc = &irq_desc[vector];
+    spin_lock_irqsave(&desc->lock, flags);
+
+    BUG_ON(vector != d->arch.pirq_vector[pirq]);
+
+    if ( desc->msi_desc )
+        pci_disable_msi(vector);
+
+    if ( desc->handler == &pci_msi_type )
+    {
+        desc->handler = &no_irq_type;
+        free_irq_vector(vector);
+    }
+
+    if ( !forced_unbind )
+    {
+        d->arch.pirq_vector[pirq] = 0;
+        d->arch.vector_pirq[vector] = 0;
+    }
+    else
+    {
+        d->arch.pirq_vector[pirq] = -vector;
+        d->arch.vector_pirq[vector] = -pirq;
+    }
+
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    ret = irq_deny_access(d, pirq);
+    if ( ret )
+        dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
+                d->domain_id, pirq);
+
+ done:
+    return ret;
+}
+
+void free_domain_pirqs(struct domain *d)
+{
+    int i;
+
+    spin_lock(&d->event_lock);
+
+    for ( i = 0; i < NR_PIRQS; i++ )
+        if ( d->arch.pirq_vector[i] > 0 )
+            unmap_domain_pirq(d, i);
+
+    spin_unlock(&d->event_lock);
 }
 
 extern void dump_ioapic_irq_info(void);
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/mm.c Fri Oct 10 12:06:46 2008 +0900
@@ -3067,7 +3067,7 @@ static int destroy_grant_pte_mapping(
     ol1e = *(l1_pgentry_t *)va;
     
     /* Check that the virtual address supplied is actually mapped to frame. */
-    if ( unlikely((l1e_get_intpte(ol1e) >> PAGE_SHIFT) != frame) )
+    if ( unlikely(l1e_get_pfn(ol1e) != frame) )
     {
         page_unlock(page);
         MEM_LOG("PTE entry %lx for address %"PRIx64" doesn't match frame %lx",
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/pci.c
--- a/xen/arch/x86/pci.c        Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/pci.c        Fri Oct 10 12:06:46 2008 +0900
@@ -1,12 +1,9 @@
 /******************************************************************************
  * pci.c
  * 
- * PCI access functions.
+ * Architecture-dependent PCI access functions.
  */
 
-#include <xen/config.h>
-#include <xen/pci.h>
-#include <xen/pci_regs.h>
 #include <xen/spinlock.h>
 #include <asm/io.h>
 
@@ -118,59 +115,3 @@ void pci_conf_write32(
     pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
 }
 
-int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap)
-{
-    u8 id;
-    int max_cap = 48;
-    u8 pos = PCI_CAPABILITY_LIST;
-    u16 status;
-
-    status = pci_conf_read16(bus, dev, func, PCI_STATUS);
-    if ( (status & PCI_STATUS_CAP_LIST) == 0 )
-        return 0;
-
-    while ( max_cap-- )
-    {
-        pos = pci_conf_read8(bus, dev, func, pos);
-        if ( pos < 0x40 )
-            break;
-
-        pos &= ~3;
-        id = pci_conf_read8(bus, dev, func, pos + PCI_CAP_LIST_ID);
-
-        if ( id == 0xff )
-            break;
-        else if ( id == cap )
-            return pos;
-
-        pos += PCI_CAP_LIST_NEXT;
-    }
-
-    return 0;
-}
-
-int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap)
-{
-    u8 id;
-    int ttl = 48;
-
-    while ( ttl-- )
-    {
-        pos = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
-        if ( pos < 0x40 )
-            break;
-
-        pos &= ~3;
-        id = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pos + PCI_CAP_LIST_ID);
-
-        if ( id == 0xff )
-            break;
-        if ( id == cap )
-            return pos;
-
-        pos += PCI_CAP_LIST_NEXT;
-    }
-    return 0;
-}
-
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/physdev.c    Fri Oct 10 12:06:46 2008 +0900
@@ -26,168 +26,12 @@ ioapic_guest_write(
 ioapic_guest_write(
     unsigned long physbase, unsigned int reg, u32 pval);
 
-static int get_free_pirq(struct domain *d, int type, int index)
-{
-    int i;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    if ( type == MAP_PIRQ_TYPE_GSI )
-    {
-        for ( i = 16; i < NR_PIRQS; i++ )
-            if ( !d->arch.pirq_vector[i] )
-                break;
-        if ( i == NR_PIRQS )
-            return -ENOSPC;
-    }
-    else
-    {
-        for ( i = NR_PIRQS - 1; i >= 16; i-- )
-            if ( !d->arch.pirq_vector[i] )
-                break;
-        if ( i == 16 )
-            return -ENOSPC;
-    }
-
-    return i;
-}
-
-static int map_domain_pirq(struct domain *d, int pirq, int vector,
-                           struct physdev_map_pirq *map)
-{
-    int ret = 0;
-    int old_vector, old_pirq;
-    struct msi_info msi;
-    irq_desc_t *desc;
-    unsigned long flags;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( pirq < 0 || pirq >= NR_PIRQS || vector < 0 || vector >= NR_VECTORS )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or vector %d\n",
-                d->domain_id, pirq, vector);
-        return -EINVAL;
-    }
-
-    old_vector = d->arch.pirq_vector[pirq];
-    old_pirq = d->arch.vector_pirq[vector];
-
-    if ( (old_vector && (old_vector != vector) ) ||
-         (old_pirq && (old_pirq != pirq)) )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or vector %d already mapped\n",
-                d->domain_id, pirq, vector);
-        return -EINVAL;
-    }
-
-    ret = irq_permit_access(d, pirq);
-    if ( ret )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n",
-                d->domain_id, pirq);
-        return ret;
-    }
-
-    desc = &irq_desc[vector];
-    spin_lock_irqsave(&desc->lock, flags);
-
-    if ( map && MAP_PIRQ_TYPE_MSI == map->type )
-    {
-        if ( desc->handler != &no_irq_type )
-            dprintk(XENLOG_G_ERR, "dom%d: vector %d in use\n",
-                    d->domain_id, vector);
-        desc->handler = &pci_msi_type;
-
-        msi.bus = map->bus;
-        msi.devfn = map->devfn;
-        msi.entry_nr = map->entry_nr;
-        msi.table_base = map->table_base;
-        msi.vector = vector;
-
-        ret = pci_enable_msi(&msi);
-        if ( ret )
-            goto done;
-    }
-
-    d->arch.pirq_vector[pirq] = vector;
-    d->arch.vector_pirq[vector] = pirq;
-
-done:
-    spin_unlock_irqrestore(&desc->lock, flags);
-    return ret;
-}
-
-/* The pirq should have been unbound before this call. */
-static int unmap_domain_pirq(struct domain *d, int pirq)
-{
-    unsigned long flags;
-    irq_desc_t *desc;
-    int vector, ret = 0;
-    bool_t forced_unbind;
-
-    if ( (pirq < 0) || (pirq >= NR_PIRQS) )
-        return -EINVAL;
-
-    if ( !IS_PRIV(current->domain) )
-        return -EINVAL;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    vector = d->arch.pirq_vector[pirq];
-    if ( vector <= 0 )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
-                d->domain_id, pirq);
-        ret = -EINVAL;
-        goto done;
-    }
-
-    forced_unbind = pirq_guest_force_unbind(d, pirq);
-    if ( forced_unbind )
-        dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
-                d->domain_id, pirq);
-
-    desc = &irq_desc[vector];
-    spin_lock_irqsave(&desc->lock, flags);
-
-    BUG_ON(vector != d->arch.pirq_vector[pirq]);
-
-    if ( desc->msi_desc )
-        pci_disable_msi(vector);
-
-    if ( desc->handler == &pci_msi_type )
-        desc->handler = &no_irq_type;
-
-    if ( !forced_unbind )
-    {
-        d->arch.pirq_vector[pirq] = 0;
-        d->arch.vector_pirq[vector] = 0;
-    }
-    else
-    {
-        d->arch.pirq_vector[pirq] = -vector;
-        d->arch.vector_pirq[vector] = -pirq;
-    }
-
-    spin_unlock_irqrestore(&desc->lock, flags);
-
-    ret = irq_deny_access(d, pirq);
-    if ( ret )
-        dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
-                d->domain_id, pirq);
-
- done:
-    return ret;
-}
-
 static int physdev_map_pirq(struct physdev_map_pirq *map)
 {
     struct domain *d;
     int vector, pirq, ret = 0;
+    struct msi_info _msi;
+    void *map_data = NULL;
 
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
@@ -206,6 +50,7 @@ static int physdev_map_pirq(struct physd
         goto free_domain;
     }
 
+    /* Verify or get vector. */
     switch ( map->type )
     {
         case MAP_PIRQ_TYPE_GSI:
@@ -220,31 +65,42 @@ static int physdev_map_pirq(struct physd
             if ( !vector )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n",
-                        d->domain_id, map->index);
+                        d->domain_id, vector);
                 ret = -EINVAL;
                 goto free_domain;
             }
             break;
+
         case MAP_PIRQ_TYPE_MSI:
             vector = map->index;
-                       if ( vector == -1 )
-                               vector = assign_irq_vector(AUTO_ASSIGN);
+            if ( vector == -1 )
+                vector = assign_irq_vector(AUTO_ASSIGN);
 
             if ( vector < 0 || vector >= NR_VECTORS )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: map irq with wrong vector %d\n",
-                        d->domain_id, map->index);
+                        d->domain_id, vector);
                 ret = -EINVAL;
                 goto free_domain;
             }
-            break;
+
+            _msi.bus = map->bus;
+            _msi.devfn = map->devfn;
+            _msi.entry_nr = map->entry_nr;
+            _msi.table_base = map->table_base;
+            _msi.vector = vector;
+            map_data = &_msi;
+            break;
+
         default:
-            dprintk(XENLOG_G_ERR, "dom%d: wrong map_pirq type %x\n", 
d->domain_id, map->type);
+            dprintk(XENLOG_G_ERR, "dom%d: wrong map_pirq type %x\n",
+                    d->domain_id, map->type);
             ret = -EINVAL;
             goto free_domain;
     }
 
-    spin_lock(&d->evtchn_lock);
+    /* Verify or get pirq. */
+    spin_lock(&d->event_lock);
     if ( map->pirq < 0 )
     {
         if ( d->arch.vector_pirq[vector] )
@@ -284,13 +140,14 @@ static int physdev_map_pirq(struct physd
             pirq = map->pirq;
     }
 
-
-    ret = map_domain_pirq(d, pirq, vector, map);
-
-    if ( !ret )
+    ret = map_domain_pirq(d, pirq, vector, map->type, map_data);
+    if ( ret == 0 )
         map->pirq = pirq;
+
 done:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
+    if ( (ret != 0) && (map->type == MAP_PIRQ_TYPE_MSI) && (map->index == -1) )
+        free_irq_vector(vector);
 free_domain:
     rcu_unlock_domain(d);
     return ret;
@@ -312,9 +169,9 @@ static int physdev_unmap_pirq(struct phy
     if ( d == NULL )
         return -ESRCH;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
     ret = unmap_domain_pirq(d, unmap->pirq);
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     rcu_unlock_domain(d);
 
@@ -441,9 +298,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
 
         irq_op.vector = assign_irq_vector(irq);
 
-        spin_lock(&dom0->evtchn_lock);
-        ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector, NULL);
-        spin_unlock(&dom0->evtchn_lock);
+        spin_lock(&dom0->event_lock);
+        ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector,
+                              MAP_PIRQ_TYPE_GSI, NULL);
+        spin_unlock(&dom0->event_lock);
 
         if ( copy_to_guest(arg, &irq_op, 1) != 0 )
             ret = -EFAULT;
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/x86_32/xen.lds.S     Fri Oct 10 12:06:46 2008 +0900
@@ -69,6 +69,7 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
+  __per_cpu_shift = PERCPU_SHIFT; /* kdump assist */
   __per_cpu_start = .;
   .data.percpu : { *(.data.percpu) } :text
   __per_cpu_data_end = .;
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/arch/x86/x86_64/xen.lds.S
--- a/xen/arch/x86/x86_64/xen.lds.S     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/arch/x86/x86_64/xen.lds.S     Fri Oct 10 12:06:46 2008 +0900
@@ -67,6 +67,7 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
+  __per_cpu_shift = PERCPU_SHIFT; /* kdump assist */
   __per_cpu_start = .;
   .data.percpu : { *(.data.percpu) } :text
   __per_cpu_data_end = .;
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/common/event_channel.c        Fri Oct 10 12:06:46 2008 +0900
@@ -133,7 +133,7 @@ static long evtchn_alloc_unbound(evtchn_
     if ( rc )
         return rc;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( (port = get_free_port(d)) < 0 )
         ERROR_EXIT_DOM(port, d);
@@ -150,7 +150,7 @@ static long evtchn_alloc_unbound(evtchn_
     alloc->port = port;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
     rcu_unlock_domain(d);
 
     return rc;
@@ -174,14 +174,14 @@ static long evtchn_bind_interdomain(evtc
     /* Avoid deadlock by first acquiring lock of domain with smaller id. */
     if ( ld < rd )
     {
-        spin_lock(&ld->evtchn_lock);
-        spin_lock(&rd->evtchn_lock);
+        spin_lock(&ld->event_lock);
+        spin_lock(&rd->event_lock);
     }
     else
     {
         if ( ld != rd )
-            spin_lock(&rd->evtchn_lock);
-        spin_lock(&ld->evtchn_lock);
+            spin_lock(&rd->event_lock);
+        spin_lock(&ld->event_lock);
     }
 
     if ( (lport = get_free_port(ld)) < 0 )
@@ -216,9 +216,9 @@ static long evtchn_bind_interdomain(evtc
     bind->local_port = lport;
 
  out:
-    spin_unlock(&ld->evtchn_lock);
+    spin_unlock(&ld->event_lock);
     if ( ld != rd )
-        spin_unlock(&rd->evtchn_lock);
+        spin_unlock(&rd->event_lock);
     
     rcu_unlock_domain(rd);
 
@@ -244,7 +244,7 @@ static long evtchn_bind_virq(evtchn_bind
          ((v = d->vcpu[vcpu]) == NULL) )
         return -ENOENT;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( v->virq_to_evtchn[virq] != 0 )
         ERROR_EXIT(-EEXIST);
@@ -260,7 +260,7 @@ static long evtchn_bind_virq(evtchn_bind
     v->virq_to_evtchn[virq] = bind->port = port;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return rc;
 }
@@ -277,7 +277,7 @@ static long evtchn_bind_ipi(evtchn_bind_
          (d->vcpu[vcpu] == NULL) )
         return -ENOENT;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( (port = get_free_port(d)) < 0 )
         ERROR_EXIT(port);
@@ -289,7 +289,7 @@ static long evtchn_bind_ipi(evtchn_bind_
     bind->port = port;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return rc;
 }
@@ -308,7 +308,7 @@ static long evtchn_bind_pirq(evtchn_bind
     if ( !irq_access_permitted(d, pirq) )
         return -EPERM;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( d->pirq_to_evtchn[pirq] != 0 )
         ERROR_EXIT(-EEXIST);
@@ -333,7 +333,7 @@ static long evtchn_bind_pirq(evtchn_bind
     bind->port = port;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return rc;
 }
@@ -348,7 +348,7 @@ static long __evtchn_close(struct domain
     long           rc = 0;
 
  again:
-    spin_lock(&d1->evtchn_lock);
+    spin_lock(&d1->event_lock);
 
     if ( !port_is_valid(d1, port1) )
     {
@@ -404,12 +404,12 @@ static long __evtchn_close(struct domain
 
             if ( d1 < d2 )
             {
-                spin_lock(&d2->evtchn_lock);
+                spin_lock(&d2->event_lock);
             }
             else if ( d1 != d2 )
             {
-                spin_unlock(&d1->evtchn_lock);
-                spin_lock(&d2->evtchn_lock);
+                spin_unlock(&d1->event_lock);
+                spin_lock(&d2->event_lock);
                 goto again;
             }
         }
@@ -454,11 +454,11 @@ static long __evtchn_close(struct domain
     if ( d2 != NULL )
     {
         if ( d1 != d2 )
-            spin_unlock(&d2->evtchn_lock);
+            spin_unlock(&d2->event_lock);
         put_domain(d2);
     }
 
-    spin_unlock(&d1->evtchn_lock);
+    spin_unlock(&d1->event_lock);
 
     return rc;
 }
@@ -476,11 +476,11 @@ int evtchn_send(struct domain *d, unsign
     struct vcpu   *rvcpu;
     int            rport, ret = 0;
 
-    spin_lock(&ld->evtchn_lock);
+    spin_lock(&ld->event_lock);
 
     if ( unlikely(!port_is_valid(ld, lport)) )
     {
-        spin_unlock(&ld->evtchn_lock);
+        spin_unlock(&ld->event_lock);
         return -EINVAL;
     }
 
@@ -489,7 +489,7 @@ int evtchn_send(struct domain *d, unsign
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(lchn->consumer_is_xen) )
     {
-        spin_unlock(&ld->evtchn_lock);
+        spin_unlock(&ld->event_lock);
         return -EINVAL;
     }
 
@@ -527,7 +527,7 @@ int evtchn_send(struct domain *d, unsign
     }
 
 out:
-    spin_unlock(&ld->evtchn_lock);
+    spin_unlock(&ld->event_lock);
 
     return ret;
 }
@@ -656,7 +656,7 @@ static long evtchn_status(evtchn_status_
     if ( rc )
         return rc;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( !port_is_valid(d, port) )
     {
@@ -704,7 +704,7 @@ static long evtchn_status(evtchn_status_
     status->vcpu = chn->notify_vcpu_id;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
     rcu_unlock_domain(d);
 
     return rc;
@@ -720,7 +720,7 @@ long evtchn_bind_vcpu(unsigned int port,
     if ( (vcpu_id >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu_id] == NULL) )
         return -ENOENT;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( !port_is_valid(d, port) )
     {
@@ -756,7 +756,7 @@ long evtchn_bind_vcpu(unsigned int port,
     }
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return rc;
 }
@@ -768,11 +768,11 @@ static long evtchn_unmask(evtchn_unmask_
     int            port = unmask->port;
     struct vcpu   *v;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( unlikely(!port_is_valid(d, port)) )
     {
-        spin_unlock(&d->evtchn_lock);
+        spin_unlock(&d->event_lock);
         return -EINVAL;
     }
 
@@ -790,7 +790,7 @@ static long evtchn_unmask(evtchn_unmask_
         vcpu_mark_events_pending(v);
     }
 
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return 0;
 }
@@ -944,7 +944,7 @@ int alloc_unbound_xen_event_channel(
     struct domain *d = local_vcpu->domain;
     int            port;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( (port = get_free_port(d)) < 0 )
         goto out;
@@ -956,7 +956,7 @@ int alloc_unbound_xen_event_channel(
     chn->u.unbound.remote_domid = remote_domid;
 
  out:
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     return port;
 }
@@ -968,11 +968,11 @@ void free_xen_event_channel(
     struct evtchn *chn;
     struct domain *d = local_vcpu->domain;
 
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
 
     if ( unlikely(d->is_dying) )
     {
-        spin_unlock(&d->evtchn_lock);
+        spin_unlock(&d->event_lock);
         return;
     }
 
@@ -981,7 +981,7 @@ void free_xen_event_channel(
     BUG_ON(!chn->consumer_is_xen);
     chn->consumer_is_xen = 0;
 
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 
     (void)__evtchn_close(d, port);
 }
@@ -993,7 +993,7 @@ void notify_via_xen_event_channel(int lp
     struct domain *ld = current->domain, *rd;
     int            rport;
 
-    spin_lock(&ld->evtchn_lock);
+    spin_lock(&ld->event_lock);
 
     ASSERT(port_is_valid(ld, lport));
     lchn = evtchn_from_port(ld, lport);
@@ -1007,13 +1007,13 @@ void notify_via_xen_event_channel(int lp
         evtchn_set_pending(rd->vcpu[rchn->notify_vcpu_id], rport);
     }
 
-    spin_unlock(&ld->evtchn_lock);
+    spin_unlock(&ld->event_lock);
 }
 
 
 int evtchn_init(struct domain *d)
 {
-    spin_lock_init(&d->evtchn_lock);
+    spin_lock_init(&d->event_lock);
     if ( get_free_port(d) != 0 )
         return -EINVAL;
     evtchn_from_port(d, 0)->state = ECS_RESERVED;
@@ -1027,7 +1027,7 @@ void evtchn_destroy(struct domain *d)
 
     /* After this barrier no new event-channel allocations can occur. */
     BUG_ON(!d->is_dying);
-    spin_barrier(&d->evtchn_lock);
+    spin_barrier(&d->event_lock);
 
     /* Close all existing event channels. */
     for ( i = 0; port_is_valid(d, i); i++ )
@@ -1037,14 +1037,14 @@ void evtchn_destroy(struct domain *d)
     }
 
     /* Free all event-channel buckets. */
-    spin_lock(&d->evtchn_lock);
+    spin_lock(&d->event_lock);
     for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
     {
         xsm_free_security_evtchn(d->evtchn[i]);
         xfree(d->evtchn[i]);
         d->evtchn[i] = NULL;
     }
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 }
 
 static void domain_dump_evtchn_info(struct domain *d)
@@ -1053,7 +1053,7 @@ static void domain_dump_evtchn_info(stru
 
     printk("Domain %d polling vCPUs: %08lx\n", d->domain_id, d->poll_mask[0]);
 
-    if ( !spin_trylock(&d->evtchn_lock) )
+    if ( !spin_trylock(&d->event_lock) )
         return;
 
     printk("Event channel information for domain %d:\n",
@@ -1094,7 +1094,7 @@ static void domain_dump_evtchn_info(stru
         printk(" x=%d\n", chn->consumer_is_xen);
     }
 
-    spin_unlock(&d->evtchn_lock);
+    spin_unlock(&d->event_lock);
 }
 
 static void dump_evtchn_info(unsigned char key)
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/Makefile
--- a/xen/drivers/Makefile      Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/Makefile      Fri Oct 10 12:06:46 2008 +0900
@@ -1,5 +1,6 @@ subdir-y += char
 subdir-y += char
 subdir-y += cpufreq
+subdir-y += pci
 subdir-$(x86) += passthrough
 subdir-$(HAS_ACPI) += acpi
 subdir-$(HAS_VGA) += video
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/passthrough/io.c      Fri Oct 10 12:06:46 2008 +0900
@@ -26,10 +26,14 @@ static void pt_irq_time_out(void *data)
     struct hvm_mirq_dpci_mapping *irq_map = data;
     unsigned int guest_gsi, machine_gsi = 0;
     int vector;
-    struct hvm_irq_dpci *dpci = domain_get_irq_dpci(irq_map->dom);
+    struct hvm_irq_dpci *dpci = NULL;
     struct dev_intx_gsi_link *digl;
     uint32_t device, intx;
 
+    spin_lock(&irq_map->dom->event_lock);
+
+    dpci = domain_get_irq_dpci(irq_map->dom);
+    ASSERT(dpci);
     list_for_each_entry ( digl, &irq_map->digl_list, list )
     {
         guest_gsi = digl->gsi;
@@ -41,55 +45,65 @@ static void pt_irq_time_out(void *data)
 
     clear_bit(machine_gsi, dpci->dirq_mask);
     vector = domain_irq_to_vector(irq_map->dom, machine_gsi);
-    stop_timer(&dpci->hvm_timer[vector]);
-    spin_lock(&dpci->dirq_lock);
     dpci->mirq[machine_gsi].pending = 0;
-    spin_unlock(&dpci->dirq_lock);
+    spin_unlock(&irq_map->dom->event_lock);
     pirq_guest_eoi(irq_map->dom, machine_gsi);
 }
 
 int pt_irq_create_bind_vtd(
     struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
-    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
+    struct hvm_irq_dpci *hvm_irq_dpci = NULL;
     uint32_t machine_gsi, guest_gsi;
     uint32_t device, intx, link;
     struct dev_intx_gsi_link *digl;
-
+    int pirq = pt_irq_bind->machine_irq;
+
+    if ( pirq < 0 || pirq >= NR_PIRQS )
+        return -EINVAL;
+
+    spin_lock(&d->event_lock);
+
+    hvm_irq_dpci = domain_get_irq_dpci(d);
     if ( hvm_irq_dpci == NULL )
     {
         hvm_irq_dpci = xmalloc(struct hvm_irq_dpci);
         if ( hvm_irq_dpci == NULL )
+        {
+            spin_unlock(&d->event_lock);
             return -ENOMEM;
-
+        }
         memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
-        spin_lock_init(&hvm_irq_dpci->dirq_lock);
         for ( int i = 0; i < NR_IRQS; i++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->mirq[i].digl_list);
-
-        if ( domain_set_irq_dpci(d, hvm_irq_dpci) == 0 )
-            xfree(hvm_irq_dpci);
+    }
+
+    if ( domain_set_irq_dpci(d, hvm_irq_dpci) == 0 )
+    {
+        xfree(hvm_irq_dpci);
+        spin_unlock(&d->event_lock);
+        return -EINVAL;
     }
 
     if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI )
     {
-        int pirq = pt_irq_bind->machine_irq;
-
-        if ( pirq < 0 || pirq >= NR_IRQS )
-            return -EINVAL;
-
-        if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_VALID ) )
-        {
-            hvm_irq_dpci->mirq[pirq].flags |= HVM_IRQ_DPCI_VALID |
-                                              HVM_IRQ_DPCI_MSI ;
+
+        if ( !test_and_set_bit(pirq, hvm_irq_dpci->mapping))
+        {
+            set_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[pirq].flags);
+            hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
+            hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
+            hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = pirq;
+            /* bind after hvm_irq_dpci is setup to avoid race with irq 
handler*/
             pirq_guest_bind(d->vcpu[0], pirq, 0);
         }
-
-        hvm_irq_dpci->mirq[pirq].flags |= HVM_IRQ_DPCI_VALID |HVM_IRQ_DPCI_MSI 
;
-        hvm_irq_dpci->mirq[pirq].gmsi.gvec = pt_irq_bind->u.msi.gvec;
-        hvm_irq_dpci->mirq[pirq].gmsi.gflags = pt_irq_bind->u.msi.gflags;
-        hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = pirq;
-
+        else if (hvm_irq_dpci->mirq[pirq].gmsi.gvec != pt_irq_bind->u.msi.gvec
+                ||hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] != pirq)
+
+        {
+            spin_unlock(&d->event_lock);
+            return -EBUSY;
+        }
     }
     else
     {
@@ -102,7 +116,10 @@ int pt_irq_create_bind_vtd(
 
         digl = xmalloc(struct dev_intx_gsi_link);
         if ( !digl )
+        {
+            spin_unlock(&d->event_lock);
             return -ENOMEM;
+        }
 
         digl->device = device;
         digl->intx = intx;
@@ -117,11 +134,11 @@ int pt_irq_create_bind_vtd(
         hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi;
 
         /* Bind the same mirq once in the same domain */
-        if ( !(hvm_irq_dpci->mirq[machine_gsi].flags & HVM_IRQ_DPCI_VALID) )
-        {
-            hvm_irq_dpci->mirq[machine_gsi].flags |= HVM_IRQ_DPCI_VALID;
+        if ( !test_and_set_bit(machine_gsi, hvm_irq_dpci->mapping))
+        {
             hvm_irq_dpci->mirq[machine_gsi].dom = d;
 
+            /* Init timer before binding */
             init_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, 
machine_gsi)],
                        pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
             /* Deal with gsi for legacy devices */
@@ -132,37 +149,45 @@ int pt_irq_create_bind_vtd(
                  "VT-d irq bind: m_irq = %x device = %x intx = %x\n",
                  machine_gsi, device, intx);
     }
+    spin_unlock(&d->event_lock);
     return 0;
 }
 
 int pt_irq_destroy_bind_vtd(
     struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
-    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
+    struct hvm_irq_dpci *hvm_irq_dpci = NULL;
     uint32_t machine_gsi, guest_gsi;
     uint32_t device, intx, link;
     struct list_head *digl_list, *tmp;
     struct dev_intx_gsi_link *digl;
-
-    if ( hvm_irq_dpci == NULL )
-        return 0;
 
     machine_gsi = pt_irq_bind->machine_irq;
     device = pt_irq_bind->u.pci.device;
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
     link = hvm_pci_intx_link(device, intx);
-    hvm_irq_dpci->link_cnt[link]--;
 
     gdprintk(XENLOG_INFO,
              "pt_irq_destroy_bind_vtd: machine_gsi=%d "
              "guest_gsi=%d, device=%d, intx=%d.\n",
              machine_gsi, guest_gsi, device, intx);
+    spin_lock(&d->event_lock);
+
+    hvm_irq_dpci = domain_get_irq_dpci(d);
+
+    if ( hvm_irq_dpci == NULL )
+    {
+        spin_unlock(&d->event_lock);
+        return -EINVAL;
+    }
+
+    hvm_irq_dpci->link_cnt[link]--;
     memset(&hvm_irq_dpci->girq[guest_gsi], 0,
            sizeof(struct hvm_girq_dpci_mapping));
 
     /* clear the mirq info */
-    if ( (hvm_irq_dpci->mirq[machine_gsi].flags & HVM_IRQ_DPCI_VALID) )
+    if ( test_bit(machine_gsi, hvm_irq_dpci->mapping))
     {
         list_for_each_safe ( digl_list, tmp,
                 &hvm_irq_dpci->mirq[machine_gsi].digl_list )
@@ -185,9 +210,10 @@ int pt_irq_destroy_bind_vtd(
             kill_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, 
machine_gsi)]);
             hvm_irq_dpci->mirq[machine_gsi].dom   = NULL;
             hvm_irq_dpci->mirq[machine_gsi].flags = 0;
-        }
-    }
-
+            clear_bit(machine_gsi, hvm_irq_dpci->mapping);
+        }
+    }
+    spin_unlock(&d->event_lock);
     gdprintk(XENLOG_INFO,
              "XEN_DOMCTL_irq_unmapping: m_irq = %x device = %x intx = %x\n",
              machine_gsi, device, intx);
@@ -199,8 +225,9 @@ int hvm_do_IRQ_dpci(struct domain *d, un
 {
     struct hvm_irq_dpci *dpci = domain_get_irq_dpci(d);
 
+    ASSERT(spin_is_locked(&irq_desc[domain_irq_to_vector(d, mirq)].lock));
     if ( !iommu_enabled || (d == dom0) || !dpci ||
-         !dpci->mirq[mirq].flags & HVM_IRQ_DPCI_VALID )
+         !test_bit(mirq, dpci->mapping))
         return 0;
 
     /*
@@ -218,69 +245,82 @@ int hvm_do_IRQ_dpci(struct domain *d, un
     return 1;
 }
 
-
 void hvm_dpci_msi_eoi(struct domain *d, int vector)
 {
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    irq_desc_t *desc;
     int pirq;
-    unsigned long flags;
-    irq_desc_t *desc;
 
     if ( !iommu_enabled || (hvm_irq_dpci == NULL) )
        return;
 
+    spin_lock(&d->event_lock);
     pirq = hvm_irq_dpci->msi_gvec_pirq[vector];
 
     if ( ( pirq >= 0 ) && (pirq < NR_PIRQS) &&
-         (hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_VALID) &&
-         (hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MSI) )
-    {
-        int vec;
-        vec = domain_irq_to_vector(d, pirq);
-        desc = &irq_desc[vec];
-
-        spin_lock_irqsave(&desc->lock, flags);
-        desc->status &= ~IRQ_INPROGRESS;
-        spin_unlock_irqrestore(&desc->lock, flags);
-
-        pirq_guest_eoi(d, pirq);
-    }
+          test_bit(pirq, hvm_irq_dpci->mapping) &&
+         (test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[pirq].flags)))
+     {
+         BUG_ON(!local_irq_is_enabled());
+         desc = domain_spin_lock_irq_desc(d, pirq, NULL);
+         if (!desc)
+         {
+            spin_unlock(&d->event_lock);
+            return;
+         }
+
+         desc->status &= ~IRQ_INPROGRESS;
+         spin_unlock_irq(&desc->lock);
+
+         pirq_guest_eoi(d, pirq);
+     }
+
+    spin_unlock(&d->event_lock);
 }
 
 void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
                   union vioapic_redir_entry *ent)
 {
-    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
+    struct hvm_irq_dpci *hvm_irq_dpci = NULL;
     uint32_t device, intx, machine_gsi;
 
-    if ( !iommu_enabled || (hvm_irq_dpci == NULL) ||
+    if ( !iommu_enabled)
+        return;
+
+    if ( guest_gsi < NR_ISAIRQS )
+    {
+        hvm_dpci_isairq_eoi(d, guest_gsi);
+        return;
+    }
+
+    spin_lock(&d->event_lock);
+    hvm_irq_dpci = domain_get_irq_dpci(d);
+
+    if((hvm_irq_dpci == NULL) ||
          (guest_gsi >= NR_ISAIRQS &&
           !hvm_irq_dpci->girq[guest_gsi].valid) )
+    {
+        spin_unlock(&d->event_lock);
         return;
-
-    if ( guest_gsi < NR_ISAIRQS )
-    {
-        hvm_dpci_isairq_eoi(d, guest_gsi);
-        return;
-    }
-
-    machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
+    }
+
     device = hvm_irq_dpci->girq[guest_gsi].device;
     intx = hvm_irq_dpci->girq[guest_gsi].intx;
     hvm_pci_intx_deassert(d, device, intx);
 
-    spin_lock(&hvm_irq_dpci->dirq_lock);
+    machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
     if ( --hvm_irq_dpci->mirq[machine_gsi].pending == 0 )
     {
-        spin_unlock(&hvm_irq_dpci->dirq_lock);
-
         if ( (ent == NULL) || !ent->fields.mask )
         {
+            /*
+             * No need to get vector lock for timer
+             * since interrupt is still not EOIed
+             */
             stop_timer(&hvm_irq_dpci->hvm_timer[
                 domain_irq_to_vector(d, machine_gsi)]);
             pirq_guest_eoi(d, machine_gsi);
         }
     }
-    else
-        spin_unlock(&hvm_irq_dpci->dirq_lock);
-}
+    spin_unlock(&d->event_lock);
+}
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/passthrough/pci.c     Fri Oct 10 12:06:46 2008 +0900
@@ -154,7 +154,7 @@ int pci_remove_device(u8 bus, u8 devfn)
 
 static void pci_clean_dpci_irqs(struct domain *d)
 {
-    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
+    struct hvm_irq_dpci *hvm_irq_dpci = NULL;
     uint32_t i;
     struct list_head *digl_list, *tmp;
     struct dev_intx_gsi_link *digl;
@@ -165,13 +165,14 @@ static void pci_clean_dpci_irqs(struct d
     if ( !is_hvm_domain(d) && !need_iommu(d) )
         return;
 
+    spin_lock(&d->event_lock);
+    hvm_irq_dpci = domain_get_irq_dpci(d);
     if ( hvm_irq_dpci != NULL )
     {
-        for ( i = 0; i < NR_IRQS; i++ )
-        {
-            if ( !(hvm_irq_dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID) )
-                continue;
-
+        for ( i = find_first_bit(hvm_irq_dpci->mapping, NR_PIRQS);
+              i < NR_PIRQS;
+              i = find_next_bit(hvm_irq_dpci->mapping, NR_PIRQS, i + 1) )
+        {
             pirq_guest_unbind(d, i);
             kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
 
@@ -188,6 +189,7 @@ static void pci_clean_dpci_irqs(struct d
         d->arch.hvm_domain.irq.dpci = NULL;
         xfree(hvm_irq_dpci);
     }
+    spin_unlock(&d->event_lock);
 }
 
 void pci_release_devices(struct domain *d)
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/passthrough/vtd/intremap.c    Fri Oct 10 12:06:46 2008 +0900
@@ -44,7 +44,7 @@ u16 apicid_to_bdf(int apic_id)
 }
 
 static int remap_entry_to_ioapic_rte(
-    struct iommu *iommu, struct IO_APIC_route_entry *old_rte)
+    struct iommu *iommu, struct IO_xAPIC_route_entry *old_rte)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
     struct IO_APIC_route_remap_entry *remap_rte;
@@ -90,13 +90,13 @@ static int remap_entry_to_ioapic_rte(
 }
 
 static int ioapic_rte_to_remap_entry(struct iommu *iommu,
-    int apic_id, struct IO_APIC_route_entry *old_rte,
+    int apic_id, struct IO_xAPIC_route_entry *old_rte,
     unsigned int rte_upper, unsigned int value)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
     struct iremap_entry new_ire;
     struct IO_APIC_route_remap_entry *remap_rte;
-    struct IO_APIC_route_entry new_rte;
+    struct IO_xAPIC_route_entry new_rte;
     int index;
     unsigned long flags;
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
@@ -177,7 +177,7 @@ unsigned int io_apic_read_remap_rte(
 unsigned int io_apic_read_remap_rte(
     unsigned int apic, unsigned int reg)
 {
-    struct IO_APIC_route_entry old_rte = { 0 };
+    struct IO_xAPIC_route_entry old_rte = { 0 };
     struct IO_APIC_route_remap_entry *remap_rte;
     int rte_upper = (reg & 1) ? 1 : 0;
     struct iommu *iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
@@ -222,7 +222,7 @@ void io_apic_write_remap_rte(
 void io_apic_write_remap_rte(
     unsigned int apic, unsigned int reg, unsigned int value)
 {
-    struct IO_APIC_route_entry old_rte = { 0 };
+    struct IO_xAPIC_route_entry old_rte = { 0 };
     struct IO_APIC_route_remap_entry *remap_rte;
     unsigned int rte_upper = (reg & 1) ? 1 : 0;
     struct iommu *iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/passthrough/vtd/vtd.h
--- a/xen/drivers/passthrough/vtd/vtd.h Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/passthrough/vtd/vtd.h Fri Oct 10 12:06:46 2008 +0900
@@ -22,6 +22,43 @@
 #define _VTD_H_
 
 #include <xen/iommu.h>
+
+/* Accomodate both IOAPIC and IOSAPIC. */
+struct IO_xAPIC_route_entry {
+    __u32   vector      :  8,
+        delivery_mode   :  3,   /* 000: FIXED
+                                 * 001: lowest prio
+                                 * 111: ExtINT
+                                 */
+        dest_mode       :  1,   /* 0: physical, 1: logical */
+        delivery_status :  1,
+        polarity        :  1,
+        irr             :  1,
+        trigger         :  1,   /* 0: edge, 1: level */
+        mask            :  1,   /* 0: enabled, 1: disabled */
+        __reserved_2    : 15;
+   
+    union {
+        struct { __u32
+            __reserved_1    : 24,
+            physical_dest   :  4,
+            __reserved_2    :  4;
+        } physical;
+
+        struct { __u32
+            __reserved_1    : 24,
+            logical_dest    :  8;
+        } logical;
+
+#ifdef __ia64__
+        struct { __u32
+            __reserved_1    : 16,
+            dest_id         : 16;
+        };
+#endif
+    } dest;
+
+} __attribute__ ((packed));
 
 struct IO_APIC_route_remap_entry {
     union {
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c     Fri Oct 10 12:06:46 2008 +0900
@@ -85,37 +85,41 @@ void hvm_dpci_isairq_eoi(struct domain *
 void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-    struct hvm_irq_dpci *dpci = domain_get_irq_dpci(d);
+    struct hvm_irq_dpci *dpci = NULL;
     struct dev_intx_gsi_link *digl, *tmp;
     int i;
 
     ASSERT(isairq < NR_ISAIRQS);
-    if ( !vtd_enabled || !dpci ||
-         !test_bit(isairq, dpci->isairq_map) )
+    if ( !vtd_enabled)
         return;
 
+    spin_lock(&d->event_lock);
+
+    dpci = domain_get_irq_dpci(d);
+
+    if ( !dpci || !test_bit(isairq, dpci->isairq_map) )
+    {
+        spin_unlock(&d->event_lock);
+        return;
+    }
     /* Multiple mirq may be mapped to one isa irq */
-    for ( i = 0; i < NR_IRQS; i++ )
+    for ( i = find_first_bit(dpci->mapping, NR_PIRQS);
+          i < NR_PIRQS;
+          i = find_next_bit(dpci->mapping, NR_PIRQS, i + 1) )
     {
-        if ( !dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID )
-            continue;
-
         list_for_each_entry_safe ( digl, tmp,
             &dpci->mirq[i].digl_list, list )
         {
             if ( hvm_irq->pci_link.route[digl->link] == isairq )
             {
                 hvm_pci_intx_deassert(d, digl->device, digl->intx);
-                spin_lock(&dpci->dirq_lock);
                 if ( --dpci->mirq[i].pending == 0 )
                 {
-                    spin_unlock(&dpci->dirq_lock);
                     stop_timer(&dpci->hvm_timer[domain_irq_to_vector(d, i)]);
                     pirq_guest_eoi(d, i);
                 }
-                else
-                    spin_unlock(&dpci->dirq_lock);
             }
         }
     }
+    spin_unlock(&d->event_lock);
 }
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/pci/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/pci/Makefile  Fri Oct 10 12:06:46 2008 +0900
@@ -0,0 +1,1 @@
+obj-y += pci.o
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/drivers/pci/pci.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/pci/pci.c     Fri Oct 10 12:06:46 2008 +0900
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * pci.c
+ *
+ * Architecture-independent PCI access functions.
+ */
+
+#include <xen/pci.h>
+#include <xen/pci_regs.h>
+
+int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap)
+{
+    u8 id;
+    int max_cap = 48;
+    u8 pos = PCI_CAPABILITY_LIST;
+    u16 status;
+
+    status = pci_conf_read16(bus, dev, func, PCI_STATUS);
+    if ( (status & PCI_STATUS_CAP_LIST) == 0 )
+        return 0;
+
+    while ( max_cap-- )
+    {
+        pos = pci_conf_read8(bus, dev, func, pos);
+        if ( pos < 0x40 )
+            break;
+
+        pos &= ~3;
+        id = pci_conf_read8(bus, dev, func, pos + PCI_CAP_LIST_ID);
+
+        if ( id == 0xff )
+            break;
+        else if ( id == cap )
+            return pos;
+
+        pos += PCI_CAP_LIST_NEXT;
+    }
+
+    return 0;
+}
+
+int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap)
+{
+    u8 id;
+    int ttl = 48;
+
+    while ( ttl-- )
+    {
+        pos = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        if ( pos < 0x40 )
+            break;
+
+        pos &= ~3;
+        id = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                            pos + PCI_CAP_LIST_ID);
+
+        if ( id == 0xff )
+            break;
+        if ( id == cap )
+            return pos;
+
+        pos += PCI_CAP_LIST_NEXT;
+    }
+    return 0;
+}
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/asm-x86/domain.h      Fri Oct 10 12:06:46 2008 +0900
@@ -235,7 +235,7 @@ struct arch_domain
     /* Shadow translated domain: P2M mapping */
     pagetable_t phys_table;
 
-    /* NB. protected by d->evtchn_lock and by irq_desc[vector].lock */
+    /* NB. protected by d->event_lock and by irq_desc[vector].lock */
     int vector_pirq[NR_VECTORS];
     int pirq_vector[NR_PIRQS];
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/asm-x86/hvm/irq.h     Fri Oct 10 12:06:46 2008 +0900
@@ -25,6 +25,7 @@
 #include <xen/types.h>
 #include <xen/spinlock.h>
 #include <asm/irq.h>
+#include <asm/pirq.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/vpic.h>
 #include <asm/hvm/vioapic.h>
@@ -38,8 +39,6 @@ struct dev_intx_gsi_link {
     uint8_t link;
 };
 
-#define HVM_IRQ_DPCI_VALID 0x1
-#define HVM_IRQ_DPCI_MSI   0x2
 #define _HVM_IRQ_DPCI_MSI  0x1
 
 struct hvm_gmsi_info {
@@ -64,9 +63,10 @@ struct hvm_girq_dpci_mapping {
 
 #define NR_ISAIRQS  16
 #define NR_LINK     4
+/* Protected by domain's event_lock */
 struct hvm_irq_dpci {
-    spinlock_t dirq_lock;
     /* Machine IRQ to guest device/intx mapping. */
+    DECLARE_BITMAP(mapping, NR_PIRQS);
     struct hvm_mirq_dpci_mapping mirq[NR_IRQS];
     /* Guest IRQ to guest device/intx mapping. */
     struct hvm_girq_dpci_mapping girq[NR_IRQS];
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/asm-x86/io_apic.h     Fri Oct 10 12:06:46 2008 +0900
@@ -190,5 +190,6 @@ static inline int ioapic_resume(void) {r
 #endif
 
 extern int assign_irq_vector(int irq);
+extern int free_irq_vector(int vector);
 
 #endif
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/asm-x86/irq.h Fri Oct 10 12:06:46 2008 +0900
@@ -19,7 +19,9 @@
 
 extern int vector_irq[NR_VECTORS];
 extern u8 irq_vector[NR_IRQ_VECTORS];
-#define AUTO_ASSIGN             -1
+#define AUTO_ASSIGN    -1
+#define NEVER_ASSIGN   -2
+#define FREE_TO_ASSIGN -3
 
 #define platform_legacy_irq(irq)       ((irq) < 16)
 
@@ -52,6 +54,12 @@ int pirq_acktype(struct domain *d, int i
 int pirq_acktype(struct domain *d, int irq);
 int pirq_shared(struct domain *d , int irq);
 
+int map_domain_pirq(struct domain *d, int pirq, int vector, int type,
+                           void *data);
+int unmap_domain_pirq(struct domain *d, int pirq);
+int get_free_pirq(struct domain *d, int type, int index);
+void free_domain_pirqs(struct domain *d);
+
 #define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[(irq)])
 #define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[(vec)])
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/xen/irq.h
--- a/xen/include/xen/irq.h     Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/xen/irq.h     Fri Oct 10 12:06:46 2008 +0900
@@ -78,6 +78,8 @@ extern int pirq_guest_unmask(struct doma
 extern int pirq_guest_unmask(struct domain *d);
 extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share);
 extern void pirq_guest_unbind(struct domain *d, int irq);
+extern irq_desc_t *domain_spin_lock_irq_desc(
+    struct domain *d, int irq, unsigned long *pflags);
 
 static inline void set_native_irq_info(int irq, cpumask_t mask)
 {
diff -r af8eaa3cf782 -r c2fc4d26ef18 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Fri Oct 10 11:58:03 2008 +0900
+++ b/xen/include/xen/sched.h   Fri Oct 10 12:06:46 2008 +0900
@@ -188,7 +188,7 @@ struct domain
 
     /* Event channel information. */
     struct evtchn   *evtchn[NR_EVTCHN_BUCKETS];
-    spinlock_t       evtchn_lock;
+    spinlock_t       event_lock;
 
     struct grant_table *grant_table;
 
diff -r af8eaa3cf782 -r c2fc4d26ef18 
xen/xsm/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/xsm/acm/acm_simple_type_enforcement_hooks.c   Fri Oct 10 11:58:03 
2008 +0900
+++ b/xen/xsm/acm/acm_simple_type_enforcement_hooks.c   Fri Oct 10 12:06:46 
2008 +0900
@@ -248,11 +248,11 @@ ste_init_state(struct acm_sized_buffer *
         /* a) check for event channel conflicts */
         for ( bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++ )
         {
-            spin_lock(&d->evtchn_lock);
+            spin_lock(&d->event_lock);
             ports = d->evtchn[bucket];
             if ( ports == NULL)
             {
-                spin_unlock(&d->evtchn_lock);
+                spin_unlock(&d->event_lock);
                 break;
             }
 
@@ -280,7 +280,7 @@ ste_init_state(struct acm_sized_buffer *
                     printkd("%s: Policy violation in event channel domain "
                             "%x -> domain %x.\n",
                             __func__, d->domain_id, rdomid);
-                    spin_unlock(&d->evtchn_lock);
+                    spin_unlock(&d->event_lock);
 
                     acm_array_append_tuple(errors,
                                            ACM_EVTCHN_SHARING_VIOLATION,
@@ -288,7 +288,7 @@ ste_init_state(struct acm_sized_buffer *
                     goto out;
                 }
             }
-            spin_unlock(&d->evtchn_lock);
+            spin_unlock(&d->event_lock);
         } 
 
 

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

<Prev in Thread] Current Thread [Next in Thread>