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] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 05 Dec 2008 10:10:12 -0800
Delivery-date: Fri, 05 Dec 2008 10:09:59 -0800
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 1228356137 -32400
# Node ID 17adc5c344fe10169ad00b4e9a78ea4dcf8b041e
# Parent  6743af9fffc6f531a73af66a86738aa3ab4a2366
# Parent  ca213a56dba1f15a86d6edddf1aae39bf9b4a2a5
merge with linux-2.6.18-xen.hg
---
 arch/i386/kernel/io_apic-xen.c   |   14 +++++++-
 arch/i386/mm/hypervisor.c        |   43 ++++++++++++++++++++++---
 arch/i386/mm/pgtable-xen.c       |    8 ++++
 arch/x86_64/kernel/io_apic-xen.c |    6 ++-
 arch/x86_64/mm/pageattr-xen.c    |    8 ++++
 drivers/pci/msi-xen.c            |   52 ++++++++++++++----------------
 drivers/pci/pci.h                |    1 
 drivers/pci/quirks.c             |    3 +
 drivers/pci/setup-bus.c          |    2 -
 drivers/pci/setup-res.c          |   10 +++++
 drivers/xen/blkback/blkback.c    |   10 ++---
 drivers/xen/blktap/blktap.c      |   10 ++---
 drivers/xen/core/evtchn.c        |   66 +++++++++++++++++++++++++++++++--------
 drivers/xen/core/gnttab.c        |    5 +-
 drivers/xen/netback/netback.c    |    6 +--
 include/asm-ia64/maddr.h         |    1 
 include/linux/page-flags.h       |    6 +--
 include/xen/interface/physdev.h  |   15 ++++++++
 mm/page_alloc.c                  |    4 +-
 19 files changed, 197 insertions(+), 73 deletions(-)

diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/kernel/io_apic-xen.c
--- a/arch/i386/kernel/io_apic-xen.c    Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/kernel/io_apic-xen.c    Thu Dec 04 11:02:17 2008 +0900
@@ -87,8 +87,10 @@ int (*ioapic_renumber_irq)(int ioapic, i
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 atomic_t irq_mis_count;
 
+#ifndef CONFIG_XEN
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+#endif
 
 static DEFINE_SPINLOCK(ioapic_lock);
 static DEFINE_SPINLOCK(vector_lock);
@@ -793,6 +795,7 @@ static int find_irq_entry(int apic, int 
        return -1;
 }
 
+#ifndef CONFIG_XEN
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
@@ -842,6 +845,7 @@ static int __init find_isa_irq_apic(int 
 
        return -1;
 }
+#endif
 
 /*
  * Find a specific PCI IRQ entry.
@@ -1687,7 +1691,9 @@ static void __init enable_IO_APIC(void)
 static void __init enable_IO_APIC(void)
 {
        union IO_APIC_reg_01 reg_01;
+#ifndef CONFIG_XEN
        int i8259_apic, i8259_pin;
+#endif
        int i, apic;
        unsigned long flags;
 
@@ -1708,6 +1714,7 @@ static void __init enable_IO_APIC(void)
                spin_unlock_irqrestore(&ioapic_lock, flags);
                nr_ioapic_registers[apic] = reg_01.bits.entries+1;
        }
+#ifndef CONFIG_XEN
        for(apic = 0; apic < nr_ioapics; apic++) {
                int pin;
                /* See if any of the pins is in ExtINT mode */
@@ -1749,6 +1756,7 @@ static void __init enable_IO_APIC(void)
        {
                printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
        }
+#endif
 
        /*
         * Do not trust the IO-APIC being empty at bootup
@@ -2517,6 +2525,8 @@ static int __init io_apic_bug_finalize(v
 
 late_initcall(io_apic_bug_finalize);
 
+#ifndef CONFIG_XEN
+
 struct sysfs_ioapic_data {
        struct sys_device dev;
        struct IO_APIC_route_entry entry[0];
@@ -2570,10 +2580,8 @@ static int ioapic_resume(struct sys_devi
 
 static struct sysdev_class ioapic_sysdev_class = {
        set_kset_name("ioapic"),
-#ifndef CONFIG_XEN
        .suspend = ioapic_suspend,
        .resume = ioapic_resume,
-#endif
 };
 
 static int __init ioapic_init_sysfs(void)
@@ -2611,6 +2619,8 @@ static int __init ioapic_init_sysfs(void
 
 device_initcall(ioapic_init_sysfs);
 
+#endif /* CONFIG_XEN */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- 
*/
diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/mm/hypervisor.c
--- a/arch/i386/mm/hypervisor.c Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/mm/hypervisor.c Thu Dec 04 11:02:17 2008 +0900
@@ -374,6 +374,15 @@ void xen_destroy_contiguous_region(unsig
 }
 EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
 
+static void undo_limit_pages(struct page *pages, unsigned int order)
+{
+       BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
+       BUG_ON(order > MAX_CONTIG_ORDER);
+       xen_limit_pages_to_max_mfn(pages, order, 0);
+       ClearPageForeign(pages);
+       __free_pages(pages, order);
+}
+
 int xen_limit_pages_to_max_mfn(
        struct page *pages, unsigned int order, unsigned int address_bits)
 {
@@ -402,16 +411,28 @@ int xen_limit_pages_to_max_mfn(
        if (unlikely(order > MAX_CONTIG_ORDER))
                return -ENOMEM;
 
-       bitmap_zero(limit_map, 1U << order);
+       if (address_bits) {
+               if (address_bits < PAGE_SHIFT)
+                       return -EINVAL;
+               bitmap_zero(limit_map, 1U << order);
+       } else if (order) {
+               BUILD_BUG_ON(sizeof(pages->index) != sizeof(*limit_map));
+               for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+                       limit_map[i] = pages[i + 1].index;
+       } else
+               __set_bit(0, limit_map);
+
        set_xen_guest_handle(exchange.in.extent_start, in_frames);
        set_xen_guest_handle(exchange.out.extent_start, out_frames);
 
        /* 0. Scrub the pages. */
        for (i = 0, n = 0; i < 1U<<order ; i++) {
                page = &pages[i];
-               if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - 
PAGE_SHIFT)))
-                       continue;
-               __set_bit(i, limit_map);
+               if (address_bits) {
+                       if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - 
PAGE_SHIFT)))
+                               continue;
+                       __set_bit(i, limit_map);
+               }
 
                if (!PageHighMem(page))
                        scrub_pages(page_address(page), 1);
@@ -497,7 +518,19 @@ int xen_limit_pages_to_max_mfn(
 
        balloon_unlock(flags);
 
-       return success ? 0 : -ENOMEM;
+       if (!success)
+               return -ENOMEM;
+
+       if (address_bits) {
+               if (order) {
+                       BUILD_BUG_ON(sizeof(*limit_map) != 
sizeof(pages->index));
+                       for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+                               pages[i + 1].index = limit_map[i];
+               }
+               SetPageForeign(pages, undo_limit_pages);
+       }
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);
 
diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/mm/pgtable-xen.c
--- a/arch/i386/mm/pgtable-xen.c        Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/mm/pgtable-xen.c        Thu Dec 04 11:02:17 2008 +0900
@@ -152,6 +152,12 @@ pte_t *pte_alloc_one_kernel(struct mm_st
        return pte;
 }
 
+static void _pte_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
+       pte_free(page);
+}
+
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
        struct page *pte;
@@ -162,7 +168,7 @@ struct page *pte_alloc_one(struct mm_str
        pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 #endif
        if (pte) {
-               SetPageForeign(pte, pte_free);
+               SetPageForeign(pte, _pte_free);
                init_page_count(pte);
        }
        return pte;
diff -r 6743af9fffc6 -r 17adc5c344fe arch/x86_64/kernel/io_apic-xen.c
--- a/arch/x86_64/kernel/io_apic-xen.c  Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/x86_64/kernel/io_apic-xen.c  Thu Dec 04 11:02:17 2008 +0900
@@ -2054,6 +2054,8 @@ void __init setup_IO_APIC(void)
                print_IO_APIC();
 }
 
+#ifndef CONFIG_XEN
+
 struct sysfs_ioapic_data {
        struct sys_device dev;
        struct IO_APIC_route_entry entry[0];
@@ -2107,10 +2109,8 @@ static int ioapic_resume(struct sys_devi
 
 static struct sysdev_class ioapic_sysdev_class = {
        set_kset_name("ioapic"),
-#ifndef CONFIG_XEN
        .suspend = ioapic_suspend,
        .resume = ioapic_resume,
-#endif
 };
 
 static int __init ioapic_init_sysfs(void)
@@ -2148,6 +2148,8 @@ static int __init ioapic_init_sysfs(void
 
 device_initcall(ioapic_init_sysfs);
 
+#endif /* CONFIG_XEN */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- 
*/
diff -r 6743af9fffc6 -r 17adc5c344fe arch/x86_64/mm/pageattr-xen.c
--- a/arch/x86_64/mm/pageattr-xen.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/x86_64/mm/pageattr-xen.c     Thu Dec 04 11:02:17 2008 +0900
@@ -248,13 +248,19 @@ void _arch_exit_mmap(struct mm_struct *m
                mm_unpin(mm);
 }
 
+static void _pte_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
+       pte_free(page);
+}
+
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
        struct page *pte;
 
        pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
        if (pte) {
-               SetPageForeign(pte, pte_free);
+               SetPageForeign(pte, _pte_free);
                init_page_count(pte);
        }
        return pte;
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/msi-xen.c
--- a/drivers/pci/msi-xen.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/msi-xen.c     Thu Dec 04 11:02:17 2008 +0900
@@ -42,6 +42,8 @@ struct msi_dev_list {
        struct list_head list;
        spinlock_t pirq_list_lock;
        struct list_head pirq_list_head;
+       /* Used for saving/restoring MSI-X tables */
+       void __iomem *mask_base;
 };
 
 struct msi_pirq_entry {
@@ -50,7 +52,6 @@ struct msi_pirq_entry {
        int entry_nr;
 #ifdef CONFIG_PM
        /* PM save area for MSIX address/data */
-       void __iomem *mask_base;
        u32     address_hi_save;
        u32     address_lo_save;
        u32     data_save;
@@ -90,7 +91,7 @@ static struct msi_dev_list *get_msi_dev_
        return ret;
 }
 
-static int attach_pirq_entry(int pirq, int entry_nr, u64 table_base,
+static int attach_pirq_entry(int pirq, int entry_nr,
                              struct msi_dev_list *msi_dev_entry)
 {
        struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
@@ -100,9 +101,6 @@ static int attach_pirq_entry(int pirq, i
                return -ENOMEM;
        entry->pirq = pirq;
        entry->entry_nr = entry_nr;
-#ifdef COMFIG_PM
-       entry->mask_base = table_base;
-#endif
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
@@ -381,17 +379,24 @@ int pci_save_msix_state(struct pci_dev *
        unsigned long flags;
        struct msi_dev_list *msi_dev_entry;
        struct msi_pirq_entry *pirq_entry;
+       void __iomem *base;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
        if (pos <= 0 || dev->no_msi)
                return 0;
-
-       printk(KERN_CRIT "Saving MSIX cap\n");
 
        /* save the capability */
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        if (!(control & PCI_MSIX_FLAGS_ENABLE))
                return 0;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+       /* If we failed to map the MSI-X table at pci_enable_msix,
+        * We could not support saving them here.
+        */
+       if (!(base = msi_dev_entry->mask_base))
+               return -ENOMEM;
+
        save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
                GFP_KERNEL);
        if (!save_state) {
@@ -400,19 +405,12 @@ int pci_save_msix_state(struct pci_dev *
        }
        *((u16 *)&save_state->data[0]) = control;
 
-       msi_dev_entry = get_msi_dev_pirq_list(dev);
-
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                int j;
-               void __iomem *base;
 
                /* save the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-               printk(KERN_CRIT "Save msix table entry %d pirq %x base %p\n",
-                      j, pirq_entry->pirq, base);
-
                pirq_entry->address_lo_save =
                        readl(base + j * PCI_MSIX_ENTRY_SIZE +
                              PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -443,7 +441,6 @@ void pci_restore_msix_state(struct pci_d
        save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
        if (!save_state)
                return;
-       printk(KERN_CRIT "Restoring MSIX cap\n");
 
        save = *((u16 *)&save_state->data[0]);
        pci_remove_saved_cap(save_state);
@@ -454,15 +451,12 @@ void pci_restore_msix_state(struct pci_d
                return;
 
        msi_dev_entry = get_msi_dev_pirq_list(dev);
+       base = msi_dev_entry->mask_base;
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                /* route the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-
-               printk(KERN_CRIT "Restore msix table entry %d pirq %x base 
%p\n",
-                      j, pirq_entry->pirq, base);
                writel(pirq_entry->address_lo_save,
                        base + j * PCI_MSIX_ENTRY_SIZE +
                        PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -523,7 +517,8 @@ static int msix_capability_init(struct p
                                struct msix_entry *entries, int nvec)
 {
        u64 table_base;
-       int pirq, i, j, mapped, pos;
+       u16 control;
+       int pirq, i, j, mapped, pos, nr_entries;
        struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
        struct msi_pirq_entry *pirq_entry;
 
@@ -534,6 +529,12 @@ static int msix_capability_init(struct p
        table_base = find_table_base(dev, pos);
        if (!table_base)
                return -ENODEV;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       nr_entries = multi_msix_capable(control);
+       if (!msi_dev_entry->mask_base)
+               msi_dev_entry->mask_base = 
+                       ioremap_nocache(table_base, nr_entries * 
PCI_MSIX_ENTRY_SIZE);
 
        /* MSI-X Table Initialization */
        for (i = 0; i < nvec; i++) {
@@ -554,7 +555,7 @@ static int msix_capability_init(struct p
                pirq = msi_map_vector(dev, entries[i].entry, table_base);
                if (pirq < 0)
                        break;
-               attach_pirq_entry(pirq, entries[i].entry, table_base, 
msi_dev_entry);
+               attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
                (entries + i)->vector = pirq;
        }
 
@@ -739,7 +740,7 @@ int pci_enable_msix(struct pci_dev* dev,
                        if (mapped)
                                continue;
                        irq = evtchn_map_pirq(-1, entries[i].vector);
-                       attach_pirq_entry(irq, entries[i].entry, 0, 
msi_dev_entry);
+                       attach_pirq_entry(irq, entries[i].entry, msi_dev_entry);
                        entries[i].vector = irq;
                }
         return 0;
@@ -857,18 +858,15 @@ void msi_remove_pci_irq_vectors(struct p
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        if (!list_empty(&msi_dev_entry->pirq_list_head))
-       {
-               printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not 
freed \
-                      before acquire again.\n", dev->bus->number, 
PCI_SLOT(dev->devfn),
-                          PCI_FUNC(dev->devfn));
                list_for_each_entry_safe(pirq_entry, tmp,
                                         &msi_dev_entry->pirq_list_head, list) {
                        msi_unmap_pirq(dev, pirq_entry->pirq);
                        list_del(&pirq_entry->list);
                        kfree(pirq_entry);
                }
-       }
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+       iounmap(msi_dev_entry->mask_base);
+       msi_dev_entry->mask_base = NULL;
        dev->irq = dev->irq_old;
 }
 
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/pci.h
--- a/drivers/pci/pci.h Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/pci.h Thu Dec 04 11:02:17 2008 +0900
@@ -104,5 +104,4 @@ extern void pci_disable_bridge_window(st
 extern void pci_disable_bridge_window(struct pci_dev *dev);
 #else
 #define is_reassigndev(dev) 0
-static inline void pci_disable_bridge_window(struct pci_dev *dev) {}
 #endif
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/quirks.c
--- a/drivers/pci/quirks.c      Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/quirks.c      Thu Dec 04 11:02:17 2008 +0900
@@ -24,6 +24,7 @@
 #include "pci.h"
 
 
+#ifdef CONFIG_PCI_REASSIGN
 /*
  * This quirk function disables the device and releases resources
  * which is specified by kernel's boot parameter 'reassigndev'.
@@ -66,10 +67,10 @@ static void __devinit quirk_release_reso
                    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
                        pci_disable_bridge_window(dev);
                }
-               return;
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_release_resources);
+#endif  /* CONFIG_PCI_REASSIGN */
 
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/setup-bus.c   Thu Dec 04 11:02:17 2008 +0900
@@ -355,7 +355,7 @@ pbus_size_mem(struct pci_bus *bus, unsig
                                continue;
                        r_size = r->end - r->start + 1;
 
-                       if (reassign)
+                       if ((i < PCI_BRIDGE_RESOURCES) && reassign)
                                r_size = ALIGN(r_size, PAGE_SIZE);
 
                        /* For bridges size != alignment */
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/setup-res.c   Thu Dec 04 11:02:17 2008 +0900
@@ -234,6 +234,7 @@ pdev_sort_resources(struct pci_dev *dev,
 pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
 {
        int i;
+       int reassigndev = is_reassigndev(dev);
 
        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
                struct resource *r;
@@ -245,6 +246,11 @@ pdev_sort_resources(struct pci_dev *dev,
                
                if (!(r->flags) || r->parent)
                        continue;
+               
+               if (i < PCI_BRIDGE_RESOURCES && (r->flags & IORESOURCE_MEM) &&
+                   reassigndev)
+                       r_align = ALIGN(r_align, PAGE_SIZE);
+
                if (!r_align) {
                        printk(KERN_WARNING "PCI: Ignore bogus resource %d "
                                "[%llx:%llx] of %s\n",
@@ -263,6 +269,10 @@ pdev_sort_resources(struct pci_dev *dev,
                                align = (idx < PCI_BRIDGE_RESOURCES) ?
                                        ln->res->end - ln->res->start + 1 :
                                        ln->res->start;
+                               if ((idx < PCI_BRIDGE_RESOURCES) &&
+                                   (ln->res->flags & IORESOURCE_MEM) &&
+                                   is_reassigndev(ln->dev))
+                                       align = ALIGN(align, PAGE_SIZE);
                        }
                        if (r_align > align) {
                                tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/blkback/blkback.c
--- a/drivers/xen/blkback/blkback.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/blkback/blkback.c     Thu Dec 04 11:02:17 2008 +0900
@@ -317,14 +317,14 @@ static int do_block_io_op(blkif_t *blkif
                if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
                        break;
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                pending_req = alloc_req();
                if (NULL == pending_req) {
                        blkif->st_oo_req++;
-                       more_to_do = 1;
-                       break;
-               }
-
-               if (kthread_should_stop()) {
                        more_to_do = 1;
                        break;
                }
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/blktap/blktap.c       Thu Dec 04 11:02:17 2008 +0900
@@ -1286,14 +1286,14 @@ static int do_block_io_op(blkif_t *blkif
                        break;          
                }
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                pending_req = alloc_req();
                if (NULL == pending_req) {
                        blkif->st_oo_req++;
-                       more_to_do = 1;
-                       break;
-               }
-
-               if (kthread_should_stop()) {
                        more_to_do = 1;
                        break;
                }
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/core/evtchn.c Thu Dec 04 11:02:17 2008 +0900
@@ -123,9 +123,6 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
 /* Reference counts for bindings to IRQs. */
 static int irq_bindcount[NR_IRQS];
 
-/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
-
 #ifdef CONFIG_SMP
 
 static u8 cpu_evtchn[NR_EVENT_CHANNELS];
@@ -756,16 +753,48 @@ static struct hw_interrupt_type dynirq_t
        .retrigger = resend_irq_on_evtchn,
 };
 
-static inline void pirq_unmask_notify(int irq)
+/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
+static int pirq_eoi_does_unmask;
+static DECLARE_BITMAP(pirq_needs_eoi, ALIGN(NR_PIRQS, PAGE_SIZE * 8))
+       __attribute__ ((__section__(".bss.page_aligned"), 
__aligned__(PAGE_SIZE)));
+
+static void pirq_unmask_and_notify(unsigned int evtchn, unsigned int irq)
 {
        struct physdev_eoi eoi = { .irq = evtchn_get_xen_pirq(irq) };
-       if (unlikely(test_bit(irq - PIRQ_BASE, pirq_needs_eoi)))
-               VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+
+       if (pirq_eoi_does_unmask) {
+               if (test_bit(eoi.irq, pirq_needs_eoi))
+                       VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+               else
+                       unmask_evtchn(evtchn);
+       } else if (test_bit(irq - PIRQ_BASE, pirq_needs_eoi)) {
+               if (smp_processor_id() != cpu_from_evtchn(evtchn)) {
+                       struct evtchn_unmask unmask = { .port = evtchn };
+                       struct multicall_entry mcl[2];
+
+                       mcl[0].op = __HYPERVISOR_event_channel_op;
+                       mcl[0].args[0] = EVTCHNOP_unmask;
+                       mcl[0].args[1] = (unsigned long)&unmask;
+                       mcl[1].op = __HYPERVISOR_physdev_op;
+                       mcl[1].args[0] = PHYSDEVOP_eoi;
+                       mcl[1].args[1] = (unsigned long)&eoi;
+
+                       if (HYPERVISOR_multicall(mcl, 2))
+                               BUG();
+               } else {
+                       unmask_evtchn(evtchn);
+                       VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+               }
+       } else
+               unmask_evtchn(evtchn);
 }
 
 static inline void pirq_query_unmask(int irq)
 {
        struct physdev_irq_status_query irq_status;
+
+       if (pirq_eoi_does_unmask)
+               return;
        irq_status.irq = evtchn_get_xen_pirq(irq);
        if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
                irq_status.flags = 0;
@@ -806,8 +835,7 @@ static unsigned int startup_pirq(unsigne
        irq_info[irq] = mk_irq_info(IRQT_PIRQ, bind_pirq.pirq, evtchn);
 
  out:
-       unmask_evtchn(evtchn);
-       pirq_unmask_notify(irq);
+       pirq_unmask_and_notify(evtchn, irq);
 
        return 0;
 }
@@ -859,10 +887,8 @@ static void end_pirq(unsigned int irq)
        if ((irq_desc[irq].status & (IRQ_DISABLED|IRQ_PENDING)) ==
            (IRQ_DISABLED|IRQ_PENDING)) {
                shutdown_pirq(irq);
-       } else if (VALID_EVTCHN(evtchn)) {
-               unmask_evtchn(evtchn);
-               pirq_unmask_notify(irq);
-       }
+       } else if (VALID_EVTCHN(evtchn))
+               pirq_unmask_and_notify(evtchn, irq);
 }
 
 static struct hw_interrupt_type pirq_type = {
@@ -1011,6 +1037,15 @@ void irq_resume(void)
        unsigned int cpu, irq, evtchn;
 
        init_evtchn_cpu_bindings();
+
+       if (pirq_eoi_does_unmask) {
+               struct physdev_pirq_eoi_gmfn eoi_gmfn;
+
+               eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
+                       >> PAGE_SHIFT;
+               if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn))
+                       BUG();
+       }
 
        /* New event-channel space is not 'live' yet. */
        for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
@@ -1098,8 +1133,15 @@ void __init xen_init_IRQ(void)
 void __init xen_init_IRQ(void)
 {
        unsigned int i;
+       struct physdev_pirq_eoi_gmfn eoi_gmfn;
 
        init_evtchn_cpu_bindings();
+
+       BUG_ON(!bitmap_empty(pirq_needs_eoi, PAGE_SIZE * 8));
+       eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
+               >> PAGE_SHIFT;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn) == 0)
+               pirq_eoi_does_unmask = 1;
 
        /* No event channels are 'live' right now. */
        for (i = 0; i < NR_EVENT_CHANNELS; i++)
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/core/gnttab.c
--- a/drivers/xen/core/gnttab.c Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/core/gnttab.c Thu Dec 04 11:02:17 2008 +0900
@@ -505,8 +505,9 @@ static int gnttab_map(unsigned int start
        return 0;
 }
 
-static void gnttab_page_free(struct page *page)
-{
+static void gnttab_page_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
        ClearPageForeign(page);
        gnttab_reset_grant_page(page);
        put_page(page);
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/netback/netback.c     Thu Dec 04 11:02:17 2008 +0900
@@ -55,7 +55,6 @@ struct netbk_tx_pending_inuse {
 };
 
 static void netif_idx_release(u16 pending_idx);
-static void netif_page_release(struct page *page);
 static void make_tx_response(netif_t *netif, 
                             netif_tx_request_t *txp,
                             s8       st);
@@ -1436,8 +1435,9 @@ static void netif_idx_release(u16 pendin
        tasklet_schedule(&net_tx_tasklet);
 }
 
-static void netif_page_release(struct page *page)
-{
+static void netif_page_release(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
        netif_idx_release(netif_page_index(page));
 }
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/asm-ia64/maddr.h
--- a/include/asm-ia64/maddr.h  Wed Dec 03 11:38:32 2008 +0900
+++ b/include/asm-ia64/maddr.h  Thu Dec 04 11:02:17 2008 +0900
@@ -99,6 +99,7 @@ mfn_to_local_pfn(unsigned long mfn)
 #define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
 #define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
 #define virt_to_machine(virt) __pa(virt) /* for tpmfront.c */
+#define arbitrary_virt_to_machine(virt) virt_to_machine(ia64_imva(virt))
 
 #define set_phys_to_machine(pfn, mfn) do { } while (0)
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/linux/page-flags.h
--- a/include/linux/page-flags.h        Wed Dec 03 11:38:32 2008 +0900
+++ b/include/linux/page-flags.h        Thu Dec 04 11:02:17 2008 +0900
@@ -252,15 +252,15 @@
 #define PageForeign(page)      test_bit(PG_foreign, &(page)->flags)
 #define SetPageForeign(_page, dtor) do {               \
        set_bit(PG_foreign, &(_page)->flags);           \
-       BUG_ON((dtor) == (void (*)(struct page *))0);   \
+       BUG_ON((dtor) == (void (*)(struct page *, unsigned int))0); \
        (_page)->index = (long)(dtor);                  \
 } while (0)
 #define ClearPageForeign(page) do {                    \
        clear_bit(PG_foreign, &(page)->flags);          \
        (page)->index = 0;                              \
 } while (0)
-#define PageForeignDestructor(_page)                   \
-       ((void (*)(struct page *))(_page)->index)(_page)
+#define PageForeignDestructor(_page, order)            \
+       ((void (*)(struct page *, unsigned int))(_page)->index)(_page, order)
 
 struct page;   /* forward declaration */
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/xen/interface/physdev.h
--- a/include/xen/interface/physdev.h   Wed Dec 03 11:38:32 2008 +0900
+++ b/include/xen/interface/physdev.h   Thu Dec 04 11:02:17 2008 +0900
@@ -41,6 +41,21 @@ DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 
 /*
+ * Register a shared page for the hypervisor to indicate whether the guest
+ * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
+ * once the guest used this function in that the associated event channel
+ * will automatically get unmasked. The page registered is used as a bit
+ * array indexed by Xen's PIRQ value.
+ */
+#define PHYSDEVOP_pirq_eoi_gmfn         17
+struct physdev_pirq_eoi_gmfn {
+    /* IN */
+    xen_pfn_t gmfn;
+};
+typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
+
+/*
  * Query the status of an IRQ line.
  * @arg == pointer to physdev_irq_status_query structure.
  */
diff -r 6743af9fffc6 -r 17adc5c344fe mm/page_alloc.c
--- a/mm/page_alloc.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/mm/page_alloc.c   Thu Dec 04 11:02:17 2008 +0900
@@ -453,7 +453,7 @@ static void __free_pages_ok(struct page 
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, order);
                return;
        }
 #endif
@@ -737,7 +737,7 @@ static void fastcall free_hot_cold_page(
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, 0);
                return;
        }
 #endif

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg, Xen patchbot-linux-2.6.18-xen <=