From: garloff@xxxxxxx Subject: Adapt Xen to 2.6.11rc1bk8 Mostly PageHighMem() instead of highmem_start_page comparison; noexec_setup is void now (and called earlier), ioremap stores passed flags, some __change_page_attr() changes and us __GFP_ZERO rather than calling clear_page ourselves, multi_core and detect_ht() adaptions. Signed-off-by: Kurt Garloff diff -uNrp linux-2.6.10/arch/xen/i386/mm/highmem.c linux-2.6.10.bk8/arch/xen/i386/mm/highmem.c --- linux-2.6.10/arch/xen/i386/mm/highmem.c 2005-01-22 13:57:42.040463792 +0100 +++ linux-2.6.10.bk8/arch/xen/i386/mm/highmem.c 2005-01-22 14:01:48.586564906 +0100 @@ -3,7 +3,7 @@ void *kmap(struct page *page) { might_sleep(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return page_address(page); return kmap_high(page); } @@ -12,7 +12,7 @@ void kunmap(struct page *page) { if (in_interrupt()) BUG(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return; kunmap_high(page); } @@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enu /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ inc_preempt_count(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return page_address(page); idx = type + KM_TYPE_NR*smp_processor_id(); @@ -55,7 +55,7 @@ void *kmap_atomic_pte(struct page *page, /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ inc_preempt_count(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return page_address(page); idx = type + KM_TYPE_NR*smp_processor_id(); diff -uNrp linux-2.6.10/arch/xen/i386/mm/init.c linux-2.6.10.bk8/arch/xen/i386/mm/init.c --- linux-2.6.10/arch/xen/i386/mm/init.c 2005-01-22 13:57:42.197411020 +0100 +++ linux-2.6.10.bk8/arch/xen/i386/mm/init.c 2005-01-22 14:01:48.587564570 +0100 @@ -133,7 +133,7 @@ static void __init page_table_range_init static inline int is_kernel_text(unsigned long addr) { - if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end) + if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end) return 1; return 0; } @@ -471,7 +471,7 @@ u64 __supported_pte_mask = ~_PAGE_NX; * on Enable * off Disable */ -static int __init noexec_setup(char *str) +void __init noexec_setup(const char *str) { if (!strncmp(str, "on",2) && cpu_has_nx) { __supported_pte_mask |= _PAGE_NX; @@ -480,11 +480,8 @@ static int __init noexec_setup(char *str disable_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 1; } -__setup("noexec=", noexec_setup); - int nx_enabled = 0; #ifdef CONFIG_X86_PAE @@ -614,7 +611,6 @@ void __init test_wp_bit(void) static void __init set_max_mapnr_init(void) { #ifdef CONFIG_HIGHMEM - highmem_start_page = pfn_to_page(highstart_pfn); max_mapnr = num_physpages = highend_pfn; #else max_mapnr = num_physpages = max_low_pfn; diff -uNrp linux-2.6.10/arch/xen/i386/mm/ioremap.c linux-2.6.10.bk8/arch/xen/i386/mm/ioremap.c --- linux-2.6.10/arch/xen/i386/mm/ioremap.c 2005-01-22 13:57:42.198410684 +0100 +++ linux-2.6.10.bk8/arch/xen/i386/mm/ioremap.c 2005-01-22 14:01:48.588564234 +0100 @@ -118,7 +118,7 @@ void __iomem * __ioremap(unsigned long p /* * Ok, go for it.. */ - area = get_vm_area(size, VM_IOREMAP); + area = get_vm_area(size, VM_IOREMAP | (flags << 20)); if (!area) return NULL; area->phys_addr = phys_addr; @@ -205,7 +205,7 @@ void iounmap(volatile void __iomem *addr return; } - if (p->flags && is_local_lowmem(p->phys_addr)) { + if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) { change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)), p->size >> PAGE_SHIFT, PAGE_KERNEL); diff -uNrp linux-2.6.10/arch/xen/i386/mm/pageattr.c linux-2.6.10.bk8/arch/xen/i386/mm/pageattr.c --- linux-2.6.10/arch/xen/i386/mm/pageattr.c 2005-01-22 13:57:42.198410684 +0100 +++ linux-2.6.10.bk8/arch/xen/i386/mm/pageattr.c 2005-01-22 14:01:48.588564234 +0100 @@ -111,10 +111,7 @@ __change_page_attr(struct page *page, pg unsigned long address; struct page *kpte_page; -#ifdef CONFIG_HIGHMEM - if (page >= highmem_start_page) - BUG(); -#endif + BUG_ON(PageHighMem(page)); address = (unsigned long)page_address(page); kpte = lookup_address(address); @@ -123,27 +120,35 @@ __change_page_attr(struct page *page, pg kpte_page = virt_to_page(kpte); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((pte_val(*kpte) & _PAGE_PSE) == 0) { - pte_t old = *kpte; - pte_t standard = mk_pte(page, PAGE_KERNEL); set_pte_batched(kpte, mk_pte(page, prot)); - if (pte_same(old,standard)) - get_page(kpte_page); } else { struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; - get_page(kpte_page); set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL)); - } + kpte_page = split; + } + get_page(kpte_page); } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte_batched(kpte, mk_pte(page, PAGE_KERNEL)); __put_page(kpte_page); - } + } else + BUG(); - if (cpu_has_pse && (page_count(kpte_page) == 1)) { - list_add(&kpte_page->lru, &df_list); - revert_page(kpte_page, address); - } + /* + * If the pte was reserved, it means it was created at boot + * time (not via split_large_page) and in turn we must not + * replace it with a largepage. + */ + if (!PageReserved(kpte_page)) { + /* memleak and potential failed 2M page regeneration */ + BUG_ON(!page_count(kpte_page)); + + if (cpu_has_pse && (page_count(kpte_page) == 1)) { + list_add(&kpte_page->lru, &df_list); + revert_page(kpte_page, address); + } + } return 0; } diff -uNrp linux-2.6.10/arch/xen/i386/mm/pgtable.c linux-2.6.10.bk8/arch/xen/i386/mm/pgtable.c --- linux-2.6.10/arch/xen/i386/mm/pgtable.c 2005-01-22 13:57:42.199410348 +0100 +++ linux-2.6.10.bk8/arch/xen/i386/mm/pgtable.c 2005-01-22 14:04:04.073008862 +0100 @@ -192,9 +192,9 @@ void __set_fixmap_ma (enum fixed_address pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); if (pte) { - clear_page(pte); + //clear_page(pte); make_page_readonly(pte); xen_flush_page_update_queue(); } @@ -230,11 +230,11 @@ struct page *pte_alloc_one(struct mm_str #ifdef CONFIG_HIGHPTE struct page *pte; - pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0); + pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); if (pte == NULL) return pte; - if (pte >= highmem_start_page) { - clear_highpage(pte); + if (PageHighMem(pte)) { + //clear_highpage(pte); return pte; } /* not a highmem page -- free page and grab one from the cache */ @@ -250,7 +250,7 @@ void pte_free(struct page *pte) { set_page_count(pte, 1); #ifdef CONFIG_HIGHPTE - if (pte < highmem_start_page) + if (!PageHighMem(pte)) #endif kmem_cache_free(pte_cache, phys_to_virt(page_to_pseudophys(pte))); diff -uNrp linux-2.6.10/include/asm-xen/asm-i386/pgtable.h linux-2.6.10.bk8/include/asm-xen/asm-i386/pgtable.h --- linux-2.6.10/include/asm-xen/asm-i386/pgtable.h 2005-01-22 13:57:42.203409003 +0100 +++ linux-2.6.10.bk8/include/asm-xen/asm-i386/pgtable.h 2005-01-22 14:01:48.590563562 +0100 @@ -385,6 +385,7 @@ extern pte_t *lookup_address(unsigned lo static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;} #endif +extern void noexec_setup(const char *str); #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + \ diff -uNrp linux-2.6.10/include/asm-xen/asm-i386/processor.h linux-2.6.10.bk8/include/asm-xen/asm-i386/processor.h --- linux-2.6.10/include/asm-xen/asm-i386/processor.h 2005-01-22 13:57:42.090446986 +0100 +++ linux-2.6.10.bk8/include/asm-xen/asm-i386/processor.h 2005-01-22 14:01:48.591563226 +0100 @@ -65,6 +65,7 @@ struct cpuinfo_x86 { int f00f_bug; int coma_bug; unsigned long loops_per_jiffy; + unsigned char x86_num_cores; } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -104,6 +105,12 @@ extern void print_cpu_info(struct cpuinf extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern void dodgy_tsc(void); +#ifdef CONFIG_X86_HT +extern void detect_ht(struct cpuinfo_x86 *c); +#else +static inline void detect_ht(struct cpuinfo_x86 *c) {} +#endif + /* * EFLAGS bits */ @@ -270,11 +277,6 @@ static inline void clear_in_cr4 (unsigne outb((data), 0x23); \ } while (0) -/* - * Bus types (default is ISA, but people can check others with these..) - */ -extern int MCA_bus; - static inline void __monitor(const void *eax, unsigned long ecx, unsigned long edx) { diff -Nru a/arch/xen/i386/kernel/setup.c b/arch/xen/i386/kernel/setup.c --- a/arch/xen/i386/kernel/setup.c 2005-01-11 20:02:54 -08:00 +++ b/arch/xen/i386/kernel/setup.c 2005-01-11 20:02:54 -08:00 @@ -737,6 +740,10 @@ } } + else if (!memcmp(from, "noexec=", 7)) + noexec_setup(from + 7); + +