[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.