ia64/linux-2.6.18-xen.hg

changeset 753:17adc5c344fe

merge with linux-2.6.18-xen.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Thu Dec 04 11:02:17 2008 +0900 (2008-12-04)
parents 6743af9fffc6 ca213a56dba1
children 82ce2e69bb5b
files
line diff
     1.1 --- a/arch/i386/kernel/io_apic-xen.c	Wed Dec 03 11:38:32 2008 +0900
     1.2 +++ b/arch/i386/kernel/io_apic-xen.c	Thu Dec 04 11:02:17 2008 +0900
     1.3 @@ -87,8 +87,10 @@ static inline void xen_io_apic_write(uns
     1.4  int (*ioapic_renumber_irq)(int ioapic, int irq);
     1.5  atomic_t irq_mis_count;
     1.6  
     1.7 +#ifndef CONFIG_XEN
     1.8  /* Where if anywhere is the i8259 connect in external int mode */
     1.9  static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
    1.10 +#endif
    1.11  
    1.12  static DEFINE_SPINLOCK(ioapic_lock);
    1.13  static DEFINE_SPINLOCK(vector_lock);
    1.14 @@ -793,6 +795,7 @@ static int find_irq_entry(int apic, int 
    1.15  	return -1;
    1.16  }
    1.17  
    1.18 +#ifndef CONFIG_XEN
    1.19  /*
    1.20   * Find the pin to which IRQ[irq] (ISA) is connected
    1.21   */
    1.22 @@ -842,6 +845,7 @@ static int __init find_isa_irq_apic(int 
    1.23  
    1.24  	return -1;
    1.25  }
    1.26 +#endif
    1.27  
    1.28  /*
    1.29   * Find a specific PCI IRQ entry.
    1.30 @@ -1687,7 +1691,9 @@ void /*__init*/ print_PIC(void)
    1.31  static void __init enable_IO_APIC(void)
    1.32  {
    1.33  	union IO_APIC_reg_01 reg_01;
    1.34 +#ifndef CONFIG_XEN
    1.35  	int i8259_apic, i8259_pin;
    1.36 +#endif
    1.37  	int i, apic;
    1.38  	unsigned long flags;
    1.39  
    1.40 @@ -1708,6 +1714,7 @@ static void __init enable_IO_APIC(void)
    1.41  		spin_unlock_irqrestore(&ioapic_lock, flags);
    1.42  		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
    1.43  	}
    1.44 +#ifndef CONFIG_XEN
    1.45  	for(apic = 0; apic < nr_ioapics; apic++) {
    1.46  		int pin;
    1.47  		/* See if any of the pins is in ExtINT mode */
    1.48 @@ -1749,6 +1756,7 @@ static void __init enable_IO_APIC(void)
    1.49  	{
    1.50  		printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
    1.51  	}
    1.52 +#endif
    1.53  
    1.54  	/*
    1.55  	 * Do not trust the IO-APIC being empty at bootup
    1.56 @@ -2517,6 +2525,8 @@ static int __init io_apic_bug_finalize(v
    1.57  
    1.58  late_initcall(io_apic_bug_finalize);
    1.59  
    1.60 +#ifndef CONFIG_XEN
    1.61 +
    1.62  struct sysfs_ioapic_data {
    1.63  	struct sys_device dev;
    1.64  	struct IO_APIC_route_entry entry[0];
    1.65 @@ -2570,10 +2580,8 @@ static int ioapic_resume(struct sys_devi
    1.66  
    1.67  static struct sysdev_class ioapic_sysdev_class = {
    1.68  	set_kset_name("ioapic"),
    1.69 -#ifndef CONFIG_XEN
    1.70  	.suspend = ioapic_suspend,
    1.71  	.resume = ioapic_resume,
    1.72 -#endif
    1.73  };
    1.74  
    1.75  static int __init ioapic_init_sysfs(void)
    1.76 @@ -2611,6 +2619,8 @@ static int __init ioapic_init_sysfs(void
    1.77  
    1.78  device_initcall(ioapic_init_sysfs);
    1.79  
    1.80 +#endif /* CONFIG_XEN */
    1.81 +
    1.82  /* --------------------------------------------------------------------------
    1.83                            ACPI-based IOAPIC Configuration
    1.84     -------------------------------------------------------------------------- */
     2.1 --- a/arch/i386/mm/hypervisor.c	Wed Dec 03 11:38:32 2008 +0900
     2.2 +++ b/arch/i386/mm/hypervisor.c	Thu Dec 04 11:02:17 2008 +0900
     2.3 @@ -374,6 +374,15 @@ void xen_destroy_contiguous_region(unsig
     2.4  }
     2.5  EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
     2.6  
     2.7 +static void undo_limit_pages(struct page *pages, unsigned int order)
     2.8 +{
     2.9 +	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
    2.10 +	BUG_ON(order > MAX_CONTIG_ORDER);
    2.11 +	xen_limit_pages_to_max_mfn(pages, order, 0);
    2.12 +	ClearPageForeign(pages);
    2.13 +	__free_pages(pages, order);
    2.14 +}
    2.15 +
    2.16  int xen_limit_pages_to_max_mfn(
    2.17  	struct page *pages, unsigned int order, unsigned int address_bits)
    2.18  {
    2.19 @@ -402,16 +411,28 @@ int xen_limit_pages_to_max_mfn(
    2.20  	if (unlikely(order > MAX_CONTIG_ORDER))
    2.21  		return -ENOMEM;
    2.22  
    2.23 -	bitmap_zero(limit_map, 1U << order);
    2.24 +	if (address_bits) {
    2.25 +		if (address_bits < PAGE_SHIFT)
    2.26 +			return -EINVAL;
    2.27 +		bitmap_zero(limit_map, 1U << order);
    2.28 +	} else if (order) {
    2.29 +		BUILD_BUG_ON(sizeof(pages->index) != sizeof(*limit_map));
    2.30 +		for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
    2.31 +			limit_map[i] = pages[i + 1].index;
    2.32 +	} else
    2.33 +		__set_bit(0, limit_map);
    2.34 +
    2.35  	set_xen_guest_handle(exchange.in.extent_start, in_frames);
    2.36  	set_xen_guest_handle(exchange.out.extent_start, out_frames);
    2.37  
    2.38  	/* 0. Scrub the pages. */
    2.39  	for (i = 0, n = 0; i < 1U<<order ; i++) {
    2.40  		page = &pages[i];
    2.41 -		if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - PAGE_SHIFT)))
    2.42 -			continue;
    2.43 -		__set_bit(i, limit_map);
    2.44 +		if (address_bits) {
    2.45 +			if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - PAGE_SHIFT)))
    2.46 +				continue;
    2.47 +			__set_bit(i, limit_map);
    2.48 +		}
    2.49  
    2.50  		if (!PageHighMem(page))
    2.51  			scrub_pages(page_address(page), 1);
    2.52 @@ -497,7 +518,19 @@ int xen_limit_pages_to_max_mfn(
    2.53  
    2.54  	balloon_unlock(flags);
    2.55  
    2.56 -	return success ? 0 : -ENOMEM;
    2.57 +	if (!success)
    2.58 +		return -ENOMEM;
    2.59 +
    2.60 +	if (address_bits) {
    2.61 +		if (order) {
    2.62 +			BUILD_BUG_ON(sizeof(*limit_map) != sizeof(pages->index));
    2.63 +			for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
    2.64 +				pages[i + 1].index = limit_map[i];
    2.65 +		}
    2.66 +		SetPageForeign(pages, undo_limit_pages);
    2.67 +	}
    2.68 +
    2.69 +	return 0;
    2.70  }
    2.71  EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);
    2.72  
     3.1 --- a/arch/i386/mm/pgtable-xen.c	Wed Dec 03 11:38:32 2008 +0900
     3.2 +++ b/arch/i386/mm/pgtable-xen.c	Thu Dec 04 11:02:17 2008 +0900
     3.3 @@ -152,6 +152,12 @@ pte_t *pte_alloc_one_kernel(struct mm_st
     3.4  	return pte;
     3.5  }
     3.6  
     3.7 +static void _pte_free(struct page *page, unsigned int order)
     3.8 +{
     3.9 +	BUG_ON(order);
    3.10 +	pte_free(page);
    3.11 +}
    3.12 +
    3.13  struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
    3.14  {
    3.15  	struct page *pte;
    3.16 @@ -162,7 +168,7 @@ struct page *pte_alloc_one(struct mm_str
    3.17  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
    3.18  #endif
    3.19  	if (pte) {
    3.20 -		SetPageForeign(pte, pte_free);
    3.21 +		SetPageForeign(pte, _pte_free);
    3.22  		init_page_count(pte);
    3.23  	}
    3.24  	return pte;
     4.1 --- a/arch/x86_64/kernel/io_apic-xen.c	Wed Dec 03 11:38:32 2008 +0900
     4.2 +++ b/arch/x86_64/kernel/io_apic-xen.c	Thu Dec 04 11:02:17 2008 +0900
     4.3 @@ -2054,6 +2054,8 @@ void __init setup_IO_APIC(void)
     4.4  		print_IO_APIC();
     4.5  }
     4.6  
     4.7 +#ifndef CONFIG_XEN
     4.8 +
     4.9  struct sysfs_ioapic_data {
    4.10  	struct sys_device dev;
    4.11  	struct IO_APIC_route_entry entry[0];
    4.12 @@ -2107,10 +2109,8 @@ static int ioapic_resume(struct sys_devi
    4.13  
    4.14  static struct sysdev_class ioapic_sysdev_class = {
    4.15  	set_kset_name("ioapic"),
    4.16 -#ifndef CONFIG_XEN
    4.17  	.suspend = ioapic_suspend,
    4.18  	.resume = ioapic_resume,
    4.19 -#endif
    4.20  };
    4.21  
    4.22  static int __init ioapic_init_sysfs(void)
    4.23 @@ -2148,6 +2148,8 @@ static int __init ioapic_init_sysfs(void
    4.24  
    4.25  device_initcall(ioapic_init_sysfs);
    4.26  
    4.27 +#endif /* CONFIG_XEN */
    4.28 +
    4.29  /* --------------------------------------------------------------------------
    4.30                            ACPI-based IOAPIC Configuration
    4.31     -------------------------------------------------------------------------- */
     5.1 --- a/arch/x86_64/mm/pageattr-xen.c	Wed Dec 03 11:38:32 2008 +0900
     5.2 +++ b/arch/x86_64/mm/pageattr-xen.c	Thu Dec 04 11:02:17 2008 +0900
     5.3 @@ -248,13 +248,19 @@ void _arch_exit_mmap(struct mm_struct *m
     5.4  		mm_unpin(mm);
     5.5  }
     5.6  
     5.7 +static void _pte_free(struct page *page, unsigned int order)
     5.8 +{
     5.9 +	BUG_ON(order);
    5.10 +	pte_free(page);
    5.11 +}
    5.12 +
    5.13  struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
    5.14  {
    5.15  	struct page *pte;
    5.16  
    5.17  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
    5.18  	if (pte) {
    5.19 -		SetPageForeign(pte, pte_free);
    5.20 +		SetPageForeign(pte, _pte_free);
    5.21  		init_page_count(pte);
    5.22  	}
    5.23  	return pte;
     6.1 --- a/drivers/pci/msi-xen.c	Wed Dec 03 11:38:32 2008 +0900
     6.2 +++ b/drivers/pci/msi-xen.c	Thu Dec 04 11:02:17 2008 +0900
     6.3 @@ -42,6 +42,8 @@ struct msi_dev_list {
     6.4  	struct list_head list;
     6.5  	spinlock_t pirq_list_lock;
     6.6  	struct list_head pirq_list_head;
     6.7 +	/* Used for saving/restoring MSI-X tables */
     6.8 +	void __iomem *mask_base;
     6.9  };
    6.10  
    6.11  struct msi_pirq_entry {
    6.12 @@ -50,7 +52,6 @@ struct msi_pirq_entry {
    6.13  	int entry_nr;
    6.14  #ifdef CONFIG_PM
    6.15  	/* PM save area for MSIX address/data */
    6.16 -	void __iomem *mask_base;
    6.17  	u32	address_hi_save;
    6.18  	u32	address_lo_save;
    6.19  	u32	data_save;
    6.20 @@ -90,7 +91,7 @@ static struct msi_dev_list *get_msi_dev_
    6.21  	return ret;
    6.22  }
    6.23  
    6.24 -static int attach_pirq_entry(int pirq, int entry_nr, u64 table_base,
    6.25 +static int attach_pirq_entry(int pirq, int entry_nr,
    6.26                               struct msi_dev_list *msi_dev_entry)
    6.27  {
    6.28  	struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
    6.29 @@ -100,9 +101,6 @@ static int attach_pirq_entry(int pirq, i
    6.30  		return -ENOMEM;
    6.31  	entry->pirq = pirq;
    6.32  	entry->entry_nr = entry_nr;
    6.33 -#ifdef COMFIG_PM
    6.34 -	entry->mask_base = table_base;
    6.35 -#endif
    6.36  	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
    6.37  	list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
    6.38  	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
    6.39 @@ -381,17 +379,24 @@ int pci_save_msix_state(struct pci_dev *
    6.40  	unsigned long flags;
    6.41  	struct msi_dev_list *msi_dev_entry;
    6.42  	struct msi_pirq_entry *pirq_entry;
    6.43 +	void __iomem *base;
    6.44  
    6.45  	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
    6.46  	if (pos <= 0 || dev->no_msi)
    6.47  		return 0;
    6.48  
    6.49 -	printk(KERN_CRIT "Saving MSIX cap\n");
    6.50 -
    6.51  	/* save the capability */
    6.52  	pci_read_config_word(dev, msi_control_reg(pos), &control);
    6.53  	if (!(control & PCI_MSIX_FLAGS_ENABLE))
    6.54  		return 0;
    6.55 +
    6.56 +	msi_dev_entry = get_msi_dev_pirq_list(dev);
    6.57 +	/* If we failed to map the MSI-X table at pci_enable_msix,
    6.58 +	 * We could not support saving them here.
    6.59 +	 */
    6.60 +	if (!(base = msi_dev_entry->mask_base))
    6.61 +		return -ENOMEM;
    6.62 +
    6.63  	save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
    6.64  		GFP_KERNEL);
    6.65  	if (!save_state) {
    6.66 @@ -400,19 +405,12 @@ int pci_save_msix_state(struct pci_dev *
    6.67  	}
    6.68  	*((u16 *)&save_state->data[0]) = control;
    6.69  
    6.70 -	msi_dev_entry = get_msi_dev_pirq_list(dev);
    6.71 -
    6.72  	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
    6.73  	list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
    6.74  		int j;
    6.75 -		void __iomem *base;
    6.76  
    6.77  		/* save the table */
    6.78 -		base = pirq_entry->mask_base;
    6.79  		j = pirq_entry->entry_nr;
    6.80 -		printk(KERN_CRIT "Save msix table entry %d pirq %x base %p\n",
    6.81 -		       j, pirq_entry->pirq, base);
    6.82 -
    6.83  		pirq_entry->address_lo_save =
    6.84  			readl(base + j * PCI_MSIX_ENTRY_SIZE +
    6.85  			      PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
    6.86 @@ -443,7 +441,6 @@ void pci_restore_msix_state(struct pci_d
    6.87  	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
    6.88  	if (!save_state)
    6.89  		return;
    6.90 -	printk(KERN_CRIT "Restoring MSIX cap\n");
    6.91  
    6.92  	save = *((u16 *)&save_state->data[0]);
    6.93  	pci_remove_saved_cap(save_state);
    6.94 @@ -454,15 +451,12 @@ void pci_restore_msix_state(struct pci_d
    6.95  		return;
    6.96  
    6.97  	msi_dev_entry = get_msi_dev_pirq_list(dev);
    6.98 +	base = msi_dev_entry->mask_base;
    6.99  
   6.100  	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
   6.101  	list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
   6.102  		/* route the table */
   6.103 -		base = pirq_entry->mask_base;
   6.104  		j = pirq_entry->entry_nr;
   6.105 -
   6.106 -		printk(KERN_CRIT "Restore msix table entry %d pirq %x base %p\n",
   6.107 -		       j, pirq_entry->pirq, base);
   6.108  		writel(pirq_entry->address_lo_save,
   6.109  			base + j * PCI_MSIX_ENTRY_SIZE +
   6.110  			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
   6.111 @@ -523,7 +517,8 @@ static int msix_capability_init(struct p
   6.112  				struct msix_entry *entries, int nvec)
   6.113  {
   6.114  	u64 table_base;
   6.115 -	int pirq, i, j, mapped, pos;
   6.116 +	u16 control;
   6.117 +	int pirq, i, j, mapped, pos, nr_entries;
   6.118  	struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
   6.119  	struct msi_pirq_entry *pirq_entry;
   6.120  
   6.121 @@ -535,6 +530,12 @@ static int msix_capability_init(struct p
   6.122  	if (!table_base)
   6.123  		return -ENODEV;
   6.124  
   6.125 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
   6.126 +	nr_entries = multi_msix_capable(control);
   6.127 +	if (!msi_dev_entry->mask_base)
   6.128 +		msi_dev_entry->mask_base = 
   6.129 +			ioremap_nocache(table_base, nr_entries * PCI_MSIX_ENTRY_SIZE);
   6.130 +
   6.131  	/* MSI-X Table Initialization */
   6.132  	for (i = 0; i < nvec; i++) {
   6.133  		mapped = 0;
   6.134 @@ -554,7 +555,7 @@ static int msix_capability_init(struct p
   6.135  		pirq = msi_map_vector(dev, entries[i].entry, table_base);
   6.136  		if (pirq < 0)
   6.137  			break;
   6.138 -		attach_pirq_entry(pirq, entries[i].entry, table_base, msi_dev_entry);
   6.139 +		attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
   6.140  		(entries + i)->vector = pirq;
   6.141  	}
   6.142  
   6.143 @@ -739,7 +740,7 @@ int pci_enable_msix(struct pci_dev* dev,
   6.144  			if (mapped)
   6.145  				continue;
   6.146  			irq = evtchn_map_pirq(-1, entries[i].vector);
   6.147 -			attach_pirq_entry(irq, entries[i].entry, 0, msi_dev_entry);
   6.148 +			attach_pirq_entry(irq, entries[i].entry, msi_dev_entry);
   6.149  			entries[i].vector = irq;
   6.150  		}
   6.151          return 0;
   6.152 @@ -857,18 +858,15 @@ void msi_remove_pci_irq_vectors(struct p
   6.153  
   6.154  	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
   6.155  	if (!list_empty(&msi_dev_entry->pirq_list_head))
   6.156 -	{
   6.157 -		printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not freed \
   6.158 -		       before acquire again.\n", dev->bus->number, PCI_SLOT(dev->devfn),
   6.159 -			   PCI_FUNC(dev->devfn));
   6.160  		list_for_each_entry_safe(pirq_entry, tmp,
   6.161  		                         &msi_dev_entry->pirq_list_head, list) {
   6.162  			msi_unmap_pirq(dev, pirq_entry->pirq);
   6.163  			list_del(&pirq_entry->list);
   6.164  			kfree(pirq_entry);
   6.165  		}
   6.166 -	}
   6.167  	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
   6.168 +	iounmap(msi_dev_entry->mask_base);
   6.169 +	msi_dev_entry->mask_base = NULL;
   6.170  	dev->irq = dev->irq_old;
   6.171  }
   6.172  
     7.1 --- a/drivers/pci/pci.h	Wed Dec 03 11:38:32 2008 +0900
     7.2 +++ b/drivers/pci/pci.h	Thu Dec 04 11:02:17 2008 +0900
     7.3 @@ -104,5 +104,4 @@ extern int is_reassigndev(struct pci_dev
     7.4  extern void pci_disable_bridge_window(struct pci_dev *dev);
     7.5  #else
     7.6  #define is_reassigndev(dev) 0
     7.7 -static inline void pci_disable_bridge_window(struct pci_dev *dev) {}
     7.8  #endif
     8.1 --- a/drivers/pci/quirks.c	Wed Dec 03 11:38:32 2008 +0900
     8.2 +++ b/drivers/pci/quirks.c	Thu Dec 04 11:02:17 2008 +0900
     8.3 @@ -24,6 +24,7 @@
     8.4  #include "pci.h"
     8.5  
     8.6  
     8.7 +#ifdef CONFIG_PCI_REASSIGN
     8.8  /*
     8.9   * This quirk function disables the device and releases resources
    8.10   * which is specified by kernel's boot parameter 'reassigndev'.
    8.11 @@ -66,10 +67,10 @@ static void __devinit quirk_release_reso
    8.12  		    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
    8.13  			pci_disable_bridge_window(dev);
    8.14  		}
    8.15 -		return;
    8.16  	}
    8.17  }
    8.18  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_release_resources);
    8.19 +#endif  /* CONFIG_PCI_REASSIGN */
    8.20  
    8.21  /* The Mellanox Tavor device gives false positive parity errors
    8.22   * Mark this device with a broken_parity_status, to allow
     9.1 --- a/drivers/pci/setup-bus.c	Wed Dec 03 11:38:32 2008 +0900
     9.2 +++ b/drivers/pci/setup-bus.c	Thu Dec 04 11:02:17 2008 +0900
     9.3 @@ -355,7 +355,7 @@ pbus_size_mem(struct pci_bus *bus, unsig
     9.4  				continue;
     9.5  			r_size = r->end - r->start + 1;
     9.6  
     9.7 -			if (reassign)
     9.8 +			if ((i < PCI_BRIDGE_RESOURCES) && reassign)
     9.9  				r_size = ALIGN(r_size, PAGE_SIZE);
    9.10  
    9.11  			/* For bridges size != alignment */
    10.1 --- a/drivers/pci/setup-res.c	Wed Dec 03 11:38:32 2008 +0900
    10.2 +++ b/drivers/pci/setup-res.c	Thu Dec 04 11:02:17 2008 +0900
    10.3 @@ -234,6 +234,7 @@ void __devinit
    10.4  pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
    10.5  {
    10.6  	int i;
    10.7 +	int reassigndev = is_reassigndev(dev);
    10.8  
    10.9  	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
   10.10  		struct resource *r;
   10.11 @@ -245,6 +246,11 @@ pdev_sort_resources(struct pci_dev *dev,
   10.12  		
   10.13  		if (!(r->flags) || r->parent)
   10.14  			continue;
   10.15 +		
   10.16 +		if (i < PCI_BRIDGE_RESOURCES && (r->flags & IORESOURCE_MEM) &&
   10.17 +		    reassigndev)
   10.18 +			r_align = ALIGN(r_align, PAGE_SIZE);
   10.19 +
   10.20  		if (!r_align) {
   10.21  			printk(KERN_WARNING "PCI: Ignore bogus resource %d "
   10.22  				"[%llx:%llx] of %s\n",
   10.23 @@ -263,6 +269,10 @@ pdev_sort_resources(struct pci_dev *dev,
   10.24  				align = (idx < PCI_BRIDGE_RESOURCES) ?
   10.25  					ln->res->end - ln->res->start + 1 :
   10.26  					ln->res->start;
   10.27 +				if ((idx < PCI_BRIDGE_RESOURCES) &&
   10.28 +				    (ln->res->flags & IORESOURCE_MEM) &&
   10.29 +				    is_reassigndev(ln->dev))
   10.30 +					align = ALIGN(align, PAGE_SIZE);
   10.31  			}
   10.32  			if (r_align > align) {
   10.33  				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
    11.1 --- a/drivers/xen/blkback/blkback.c	Wed Dec 03 11:38:32 2008 +0900
    11.2 +++ b/drivers/xen/blkback/blkback.c	Thu Dec 04 11:02:17 2008 +0900
    11.3 @@ -317,14 +317,14 @@ static int do_block_io_op(blkif_t *blkif
    11.4  		if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
    11.5  			break;
    11.6  
    11.7 -		pending_req = alloc_req();
    11.8 -		if (NULL == pending_req) {
    11.9 -			blkif->st_oo_req++;
   11.10 +		if (kthread_should_stop()) {
   11.11  			more_to_do = 1;
   11.12  			break;
   11.13  		}
   11.14  
   11.15 -		if (kthread_should_stop()) {
   11.16 +		pending_req = alloc_req();
   11.17 +		if (NULL == pending_req) {
   11.18 +			blkif->st_oo_req++;
   11.19  			more_to_do = 1;
   11.20  			break;
   11.21  		}
    12.1 --- a/drivers/xen/blktap/blktap.c	Wed Dec 03 11:38:32 2008 +0900
    12.2 +++ b/drivers/xen/blktap/blktap.c	Thu Dec 04 11:02:17 2008 +0900
    12.3 @@ -1286,14 +1286,14 @@ static int do_block_io_op(blkif_t *blkif
    12.4  			break;		
    12.5  		}
    12.6  
    12.7 -		pending_req = alloc_req();
    12.8 -		if (NULL == pending_req) {
    12.9 -			blkif->st_oo_req++;
   12.10 +		if (kthread_should_stop()) {
   12.11  			more_to_do = 1;
   12.12  			break;
   12.13  		}
   12.14  
   12.15 -		if (kthread_should_stop()) {
   12.16 +		pending_req = alloc_req();
   12.17 +		if (NULL == pending_req) {
   12.18 +			blkif->st_oo_req++;
   12.19  			more_to_do = 1;
   12.20  			break;
   12.21  		}
    13.1 --- a/drivers/xen/core/evtchn.c	Wed Dec 03 11:38:32 2008 +0900
    13.2 +++ b/drivers/xen/core/evtchn.c	Thu Dec 04 11:02:17 2008 +0900
    13.3 @@ -123,9 +123,6 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
    13.4  /* Reference counts for bindings to IRQs. */
    13.5  static int irq_bindcount[NR_IRQS];
    13.6  
    13.7 -/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
    13.8 -static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
    13.9 -
   13.10  #ifdef CONFIG_SMP
   13.11  
   13.12  static u8 cpu_evtchn[NR_EVENT_CHANNELS];
   13.13 @@ -756,16 +753,48 @@ static struct hw_interrupt_type dynirq_t
   13.14  	.retrigger = resend_irq_on_evtchn,
   13.15  };
   13.16  
   13.17 -static inline void pirq_unmask_notify(int irq)
   13.18 +/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
   13.19 +static int pirq_eoi_does_unmask;
   13.20 +static DECLARE_BITMAP(pirq_needs_eoi, ALIGN(NR_PIRQS, PAGE_SIZE * 8))
   13.21 +	__attribute__ ((__section__(".bss.page_aligned"), __aligned__(PAGE_SIZE)));
   13.22 +
   13.23 +static void pirq_unmask_and_notify(unsigned int evtchn, unsigned int irq)
   13.24  {
   13.25  	struct physdev_eoi eoi = { .irq = evtchn_get_xen_pirq(irq) };
   13.26 -	if (unlikely(test_bit(irq - PIRQ_BASE, pirq_needs_eoi)))
   13.27 -		VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
   13.28 +
   13.29 +	if (pirq_eoi_does_unmask) {
   13.30 +		if (test_bit(eoi.irq, pirq_needs_eoi))
   13.31 +			VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
   13.32 +		else
   13.33 +			unmask_evtchn(evtchn);
   13.34 +	} else if (test_bit(irq - PIRQ_BASE, pirq_needs_eoi)) {
   13.35 +		if (smp_processor_id() != cpu_from_evtchn(evtchn)) {
   13.36 +			struct evtchn_unmask unmask = { .port = evtchn };
   13.37 +			struct multicall_entry mcl[2];
   13.38 +
   13.39 +			mcl[0].op = __HYPERVISOR_event_channel_op;
   13.40 +			mcl[0].args[0] = EVTCHNOP_unmask;
   13.41 +			mcl[0].args[1] = (unsigned long)&unmask;
   13.42 +			mcl[1].op = __HYPERVISOR_physdev_op;
   13.43 +			mcl[1].args[0] = PHYSDEVOP_eoi;
   13.44 +			mcl[1].args[1] = (unsigned long)&eoi;
   13.45 +
   13.46 +			if (HYPERVISOR_multicall(mcl, 2))
   13.47 +				BUG();
   13.48 +		} else {
   13.49 +			unmask_evtchn(evtchn);
   13.50 +			VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
   13.51 +		}
   13.52 +	} else
   13.53 +		unmask_evtchn(evtchn);
   13.54  }
   13.55  
   13.56  static inline void pirq_query_unmask(int irq)
   13.57  {
   13.58  	struct physdev_irq_status_query irq_status;
   13.59 +
   13.60 +	if (pirq_eoi_does_unmask)
   13.61 +		return;
   13.62  	irq_status.irq = evtchn_get_xen_pirq(irq);
   13.63  	if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
   13.64  		irq_status.flags = 0;
   13.65 @@ -806,8 +835,7 @@ static unsigned int startup_pirq(unsigne
   13.66  	irq_info[irq] = mk_irq_info(IRQT_PIRQ, bind_pirq.pirq, evtchn);
   13.67  
   13.68   out:
   13.69 -	unmask_evtchn(evtchn);
   13.70 -	pirq_unmask_notify(irq);
   13.71 +	pirq_unmask_and_notify(evtchn, irq);
   13.72  
   13.73  	return 0;
   13.74  }
   13.75 @@ -859,10 +887,8 @@ static void end_pirq(unsigned int irq)
   13.76  	if ((irq_desc[irq].status & (IRQ_DISABLED|IRQ_PENDING)) ==
   13.77  	    (IRQ_DISABLED|IRQ_PENDING)) {
   13.78  		shutdown_pirq(irq);
   13.79 -	} else if (VALID_EVTCHN(evtchn)) {
   13.80 -		unmask_evtchn(evtchn);
   13.81 -		pirq_unmask_notify(irq);
   13.82 -	}
   13.83 +	} else if (VALID_EVTCHN(evtchn))
   13.84 +		pirq_unmask_and_notify(evtchn, irq);
   13.85  }
   13.86  
   13.87  static struct hw_interrupt_type pirq_type = {
   13.88 @@ -1012,6 +1038,15 @@ void irq_resume(void)
   13.89  
   13.90  	init_evtchn_cpu_bindings();
   13.91  
   13.92 +	if (pirq_eoi_does_unmask) {
   13.93 +		struct physdev_pirq_eoi_gmfn eoi_gmfn;
   13.94 +
   13.95 +		eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
   13.96 +			>> PAGE_SHIFT;
   13.97 +		if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn))
   13.98 +			BUG();
   13.99 +	}
  13.100 +
  13.101  	/* New event-channel space is not 'live' yet. */
  13.102  	for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
  13.103  		mask_evtchn(evtchn);
  13.104 @@ -1098,9 +1133,16 @@ int evtchn_get_xen_pirq(int irq)
  13.105  void __init xen_init_IRQ(void)
  13.106  {
  13.107  	unsigned int i;
  13.108 +	struct physdev_pirq_eoi_gmfn eoi_gmfn;
  13.109  
  13.110  	init_evtchn_cpu_bindings();
  13.111  
  13.112 +	BUG_ON(!bitmap_empty(pirq_needs_eoi, PAGE_SIZE * 8));
  13.113 +	eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
  13.114 +		>> PAGE_SHIFT;
  13.115 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn) == 0)
  13.116 +		pirq_eoi_does_unmask = 1;
  13.117 +
  13.118  	/* No event channels are 'live' right now. */
  13.119  	for (i = 0; i < NR_EVENT_CHANNELS; i++)
  13.120  		mask_evtchn(i);
    14.1 --- a/drivers/xen/core/gnttab.c	Wed Dec 03 11:38:32 2008 +0900
    14.2 +++ b/drivers/xen/core/gnttab.c	Thu Dec 04 11:02:17 2008 +0900
    14.3 @@ -505,8 +505,9 @@ static int gnttab_map(unsigned int start
    14.4  	return 0;
    14.5  }
    14.6  
    14.7 -static void gnttab_page_free(struct page *page)
    14.8 +static void gnttab_page_free(struct page *page, unsigned int order)
    14.9  {
   14.10 +	BUG_ON(order);
   14.11  	ClearPageForeign(page);
   14.12  	gnttab_reset_grant_page(page);
   14.13  	put_page(page);
    15.1 --- a/drivers/xen/netback/netback.c	Wed Dec 03 11:38:32 2008 +0900
    15.2 +++ b/drivers/xen/netback/netback.c	Thu Dec 04 11:02:17 2008 +0900
    15.3 @@ -55,7 +55,6 @@ struct netbk_tx_pending_inuse {
    15.4  };
    15.5  
    15.6  static void netif_idx_release(u16 pending_idx);
    15.7 -static void netif_page_release(struct page *page);
    15.8  static void make_tx_response(netif_t *netif, 
    15.9  			     netif_tx_request_t *txp,
   15.10  			     s8       st);
   15.11 @@ -1436,8 +1435,9 @@ static void netif_idx_release(u16 pendin
   15.12  	tasklet_schedule(&net_tx_tasklet);
   15.13  }
   15.14  
   15.15 -static void netif_page_release(struct page *page)
   15.16 +static void netif_page_release(struct page *page, unsigned int order)
   15.17  {
   15.18 +	BUG_ON(order);
   15.19  	netif_idx_release(netif_page_index(page));
   15.20  }
   15.21  
    16.1 --- a/include/asm-ia64/maddr.h	Wed Dec 03 11:38:32 2008 +0900
    16.2 +++ b/include/asm-ia64/maddr.h	Thu Dec 04 11:02:17 2008 +0900
    16.3 @@ -99,6 +99,7 @@ mfn_to_local_pfn(unsigned long mfn)
    16.4  #define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
    16.5  #define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
    16.6  #define virt_to_machine(virt) __pa(virt) /* for tpmfront.c */
    16.7 +#define arbitrary_virt_to_machine(virt) virt_to_machine(ia64_imva(virt))
    16.8  
    16.9  #define set_phys_to_machine(pfn, mfn) do { } while (0)
   16.10  
    17.1 --- a/include/linux/page-flags.h	Wed Dec 03 11:38:32 2008 +0900
    17.2 +++ b/include/linux/page-flags.h	Thu Dec 04 11:02:17 2008 +0900
    17.3 @@ -252,15 +252,15 @@
    17.4  #define PageForeign(page)	test_bit(PG_foreign, &(page)->flags)
    17.5  #define SetPageForeign(_page, dtor) do {		\
    17.6  	set_bit(PG_foreign, &(_page)->flags);		\
    17.7 -	BUG_ON((dtor) == (void (*)(struct page *))0);	\
    17.8 +	BUG_ON((dtor) == (void (*)(struct page *, unsigned int))0); \
    17.9  	(_page)->index = (long)(dtor);			\
   17.10  } while (0)
   17.11  #define ClearPageForeign(page) do {			\
   17.12  	clear_bit(PG_foreign, &(page)->flags);		\
   17.13  	(page)->index = 0;				\
   17.14  } while (0)
   17.15 -#define PageForeignDestructor(_page)			\
   17.16 -	((void (*)(struct page *))(_page)->index)(_page)
   17.17 +#define PageForeignDestructor(_page, order)		\
   17.18 +	((void (*)(struct page *, unsigned int))(_page)->index)(_page, order)
   17.19  
   17.20  struct page;	/* forward declaration */
   17.21  
    18.1 --- a/include/xen/interface/physdev.h	Wed Dec 03 11:38:32 2008 +0900
    18.2 +++ b/include/xen/interface/physdev.h	Thu Dec 04 11:02:17 2008 +0900
    18.3 @@ -41,6 +41,21 @@ typedef struct physdev_eoi physdev_eoi_t
    18.4  DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
    18.5  
    18.6  /*
    18.7 + * Register a shared page for the hypervisor to indicate whether the guest
    18.8 + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
    18.9 + * once the guest used this function in that the associated event channel
   18.10 + * will automatically get unmasked. The page registered is used as a bit
   18.11 + * array indexed by Xen's PIRQ value.
   18.12 + */
   18.13 +#define PHYSDEVOP_pirq_eoi_gmfn         17
   18.14 +struct physdev_pirq_eoi_gmfn {
   18.15 +    /* IN */
   18.16 +    xen_pfn_t gmfn;
   18.17 +};
   18.18 +typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
   18.19 +DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
   18.20 +
   18.21 +/*
   18.22   * Query the status of an IRQ line.
   18.23   * @arg == pointer to physdev_irq_status_query structure.
   18.24   */
    19.1 --- a/mm/page_alloc.c	Wed Dec 03 11:38:32 2008 +0900
    19.2 +++ b/mm/page_alloc.c	Thu Dec 04 11:02:17 2008 +0900
    19.3 @@ -453,7 +453,7 @@ static void __free_pages_ok(struct page 
    19.4  
    19.5  #ifdef CONFIG_XEN
    19.6  	if (PageForeign(page)) {
    19.7 -		PageForeignDestructor(page);
    19.8 +		PageForeignDestructor(page, order);
    19.9  		return;
   19.10  	}
   19.11  #endif
   19.12 @@ -737,7 +737,7 @@ static void fastcall free_hot_cold_page(
   19.13  
   19.14  #ifdef CONFIG_XEN
   19.15  	if (PageForeign(page)) {
   19.16 -		PageForeignDestructor(page);
   19.17 +		PageForeignDestructor(page, 0);
   19.18  		return;
   19.19  	}
   19.20  #endif