From: Greg Kroah-Hartman Subject: Linux 2.6.32.10 Patch-mainline: 2.6.32.10 Signed-off-by: Greg Kroah-Hartman Automatically created from "patches.kernel.org/patch-2.6.32.9-10" by xen-port-patches.py --- sle11sp1-2010-03-22.orig/arch/x86/include/mach-xen/asm/pgalloc.h 2009-11-06 10:52:09.000000000 +0100 +++ sle11sp1-2010-03-22/arch/x86/include/mach-xen/asm/pgalloc.h 2010-03-22 12:47:01.000000000 +0100 @@ -27,6 +27,11 @@ pmd_t *early_get_pmd(unsigned long va); #endif /* + * Flags to use when allocating a user page table page. + */ +extern gfp_t __userpte_alloc_gfp; + +/* * Allocate and free page tables. */ extern pgd_t *pgd_alloc(struct mm_struct *); --- sle11sp1-2010-03-22.orig/arch/x86/kernel/apic/io_apic-xen.c 2010-03-01 14:44:43.000000000 +0100 +++ sle11sp1-2010-03-22/arch/x86/kernel/apic/io_apic-xen.c 2010-03-22 12:47:01.000000000 +0100 @@ -1626,6 +1626,60 @@ static void __init setup_IO_APIC_irqs(vo " (apicid-pin) not connected\n"); } +/* + * for the gsit that is not in first ioapic + * but could not use acpi_register_gsi() + * like some special sci in IBM x3330 + */ +void setup_IO_APIC_irq_extra(u32 gsi) +{ + int apic_id = 0, pin, idx, irq; + int node = cpu_to_node(boot_cpu_id); + struct irq_desc *desc; + struct irq_cfg *cfg; + + /* + * Convert 'gsi' to 'ioapic.pin'. + */ + apic_id = mp_find_ioapic(gsi); + if (apic_id < 0) + return; + + pin = mp_find_ioapic_pin(apic_id, gsi); + idx = find_irq_entry(apic_id, pin, mp_INT); + if (idx == -1) + return; + + irq = pin_2_irq(idx, apic_id, pin); +#ifdef CONFIG_XEN + if (irq < PIRQ_BASE || irq >= PIRQ_BASE + nr_pirqs) + return; +#endif +#ifdef CONFIG_SPARSE_IRQ + desc = irq_to_desc(irq); + if (desc) + return; +#endif + desc = irq_to_desc_alloc_node(irq, node); + if (!desc) { + printk(KERN_INFO "can not get irq_desc for %d\n", irq); + return; + } + + cfg = desc->chip_data; + add_pin_to_irq_node(cfg, node, apic_id, pin); + + if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { + pr_debug("Pin %d-%d already programmed\n", + mp_ioapics[apic_id].apicid, pin); + return; + } + set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); + + setup_IO_APIC_irq(apic_id, pin, irq, desc, + irq_trigger(idx), irq_polarity(idx)); +} + #ifndef CONFIG_XEN /* * Set up the timer pin, possibly with the 8259A-master behind. @@ -3275,12 +3329,9 @@ unsigned int create_irq_nr(unsigned int } spin_unlock_irqrestore(&vector_lock, flags); - if (irq > 0) { - dynamic_irq_init(irq); - /* restore it, in case dynamic_irq_init clear it */ - if (desc_new) - desc_new->chip_data = cfg_new; - } + if (irq > 0) + dynamic_irq_init_keep_chip_data(irq); + return irq; } @@ -3303,17 +3354,12 @@ void destroy_irq(unsigned int irq) { unsigned long flags; struct irq_cfg *cfg; - struct irq_desc *desc; - /* store it, in case dynamic_irq_cleanup clear it */ - desc = irq_to_desc(irq); - cfg = desc->chip_data; - dynamic_irq_cleanup(irq); - /* connect back irq_cfg */ - desc->chip_data = cfg; + dynamic_irq_cleanup_keep_chip_data(irq); free_irte(irq); spin_lock_irqsave(&vector_lock, flags); + cfg = irq_to_desc(irq)->chip_data; __clear_irq_vector(irq, cfg); spin_unlock_irqrestore(&vector_lock, flags); } --- sle11sp1-2010-03-22.orig/arch/x86/mm/pgtable-xen.c 2009-11-06 10:52:23.000000000 +0100 +++ sle11sp1-2010-03-22/arch/x86/mm/pgtable-xen.c 2010-03-22 12:50:44.000000000 +0100 @@ -10,6 +10,14 @@ #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO +#ifdef CONFIG_HIGHPTE +#define PGALLOC_USER_GFP __GFP_HIGHMEM +#else +#define PGALLOC_USER_GFP 0 +#endif + +gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP; + pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { pte_t *pte = (pte_t *)__get_free_page(PGALLOC_GFP); @@ -28,11 +36,7 @@ pgtable_t pte_alloc_one(struct mm_struct { struct page *pte; -#ifdef CONFIG_HIGHPTE - pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); -#else - pte = alloc_pages(PGALLOC_GFP, 0); -#endif + pte = alloc_pages(__userpte_alloc_gfp, 0); if (pte) { pgtable_page_ctor(pte); SetPageForeign(pte, _pte_free); @@ -41,6 +45,23 @@ pgtable_t pte_alloc_one(struct mm_struct return pte; } +static int __init setup_userpte(char *arg) +{ + if (!arg) + return -EINVAL; + + /* + * "userpte=nohigh" disables allocation of user pagetables in + * high memory. + */ + if (strcmp(arg, "nohigh") == 0) + __userpte_alloc_gfp &= ~__GFP_HIGHMEM; + else + return -EINVAL; + return 0; +} +early_param("userpte", setup_userpte); + void __pte_free(pgtable_t pte) { if (!PageHighMem(pte)) {