[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |