Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm

* 'fixes' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm:
ARM: 7204/1: arch/arm/kernel/setup.c: initialize arm_dma_zone_size earlier
ARM: 7185/1: perf: don't assign platform_device on unsupported CPUs
ARM: 7187/1: fix unwinding for XIP kernels
ARM: 7186/1: fix Kconfig issue with PHYS_OFFSET and !MMU

+101 -68
+2 -1
arch/arm/Kconfig
··· 220 220 be avoided when possible. 221 221 222 222 config PHYS_OFFSET 223 - hex "Physical address of main memory" 223 + hex "Physical address of main memory" if MMU 224 224 depends on !ARM_PATCH_PHYS_VIRT && !NEED_MACH_MEMORY_H 225 + default DRAM_BASE if !MMU 225 226 help 226 227 Please provide the physical address corresponding to the 227 228 location of main memory in your system.
+4 -12
arch/arm/include/asm/unwind.h
··· 30 30 }; 31 31 32 32 struct unwind_idx { 33 - unsigned long addr; 33 + unsigned long addr_offset; 34 34 unsigned long insn; 35 35 }; 36 36 37 37 struct unwind_table { 38 38 struct list_head list; 39 - struct unwind_idx *start; 40 - struct unwind_idx *stop; 39 + const struct unwind_idx *start; 40 + const struct unwind_idx *origin; 41 + const struct unwind_idx *stop; 41 42 unsigned long begin_addr; 42 43 unsigned long end_addr; 43 44 }; ··· 49 48 unsigned long text_size); 50 49 extern void unwind_table_del(struct unwind_table *tab); 51 50 extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk); 52 - 53 - #ifdef CONFIG_ARM_UNWIND 54 - extern int __init unwind_init(void); 55 - #else 56 - static inline int __init unwind_init(void) 57 - { 58 - return 0; 59 - } 60 - #endif 61 51 62 52 #endif /* !__ASSEMBLY__ */ 63 53
+3
arch/arm/kernel/perf_event.c
··· 640 640 641 641 static int __devinit armpmu_device_probe(struct platform_device *pdev) 642 642 { 643 + if (!cpu_pmu) 644 + return -ENODEV; 645 + 643 646 cpu_pmu->plat_device = pdev; 644 647 return 0; 645 648 }
+6 -8
arch/arm/kernel/setup.c
··· 895 895 { 896 896 struct machine_desc *mdesc; 897 897 898 - unwind_init(); 899 - 900 898 setup_processor(); 901 899 mdesc = setup_machine_fdt(__atags_pointer); 902 900 if (!mdesc) ··· 902 904 machine_desc = mdesc; 903 905 machine_name = mdesc->name; 904 906 907 + #ifdef CONFIG_ZONE_DMA 908 + if (mdesc->dma_zone_size) { 909 + extern unsigned long arm_dma_zone_size; 910 + arm_dma_zone_size = mdesc->dma_zone_size; 911 + } 912 + #endif 905 913 if (mdesc->soft_reboot) 906 914 reboot_setup("s"); 907 915 ··· 938 934 939 935 tcm_init(); 940 936 941 - #ifdef CONFIG_ZONE_DMA 942 - if (mdesc->dma_zone_size) { 943 - extern unsigned long arm_dma_zone_size; 944 - arm_dma_zone_size = mdesc->dma_zone_size; 945 - } 946 - #endif 947 937 #ifdef CONFIG_MULTI_IRQ_HANDLER 948 938 handle_arch_irq = mdesc->handle_irq; 949 939 #endif
+86 -47
arch/arm/kernel/unwind.c
··· 67 67 68 68 struct unwind_ctrl_block { 69 69 unsigned long vrs[16]; /* virtual register set */ 70 - unsigned long *insn; /* pointer to the current instructions word */ 70 + const unsigned long *insn; /* pointer to the current instructions word */ 71 71 int entries; /* number of entries left to interpret */ 72 72 int byte; /* current byte number in the instructions word */ 73 73 }; ··· 83 83 PC = 15 84 84 }; 85 85 86 - extern struct unwind_idx __start_unwind_idx[]; 87 - extern struct unwind_idx __stop_unwind_idx[]; 86 + extern const struct unwind_idx __start_unwind_idx[]; 87 + static const struct unwind_idx *__origin_unwind_idx; 88 + extern const struct unwind_idx __stop_unwind_idx[]; 88 89 89 90 static DEFINE_SPINLOCK(unwind_lock); 90 91 static LIST_HEAD(unwind_tables); ··· 99 98 }) 100 99 101 100 /* 102 - * Binary search in the unwind index. The entries entries are 101 + * Binary search in the unwind index. The entries are 103 102 * guaranteed to be sorted in ascending order by the linker. 103 + * 104 + * start = first entry 105 + * origin = first entry with positive offset (or stop if there is no such entry) 106 + * stop - 1 = last entry 104 107 */ 105 - static struct unwind_idx *search_index(unsigned long addr, 106 - struct unwind_idx *first, 107 - struct unwind_idx *last) 108 + static const struct unwind_idx *search_index(unsigned long addr, 109 + const struct unwind_idx *start, 110 + const struct unwind_idx *origin, 111 + const struct unwind_idx *stop) 108 112 { 109 - pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last); 113 + unsigned long addr_prel31; 110 114 111 - if (addr < first->addr) { 112 - pr_warning("unwind: Unknown symbol address %08lx\n", addr); 113 - return NULL; 114 - } else if (addr >= last->addr) 115 - return last; 115 + pr_debug("%s(%08lx, %p, %p, %p)\n", 116 + __func__, addr, start, origin, stop); 116 117 117 - while (first < last - 1) { 118 - struct unwind_idx *mid = first + ((last - first + 1) >> 1); 118 + /* 119 + * only search in the section with the matching sign. This way the 120 + * prel31 numbers can be compared as unsigned longs. 121 + */ 122 + if (addr < (unsigned long)start) 123 + /* negative offsets: [start; origin) */ 124 + stop = origin; 125 + else 126 + /* positive offsets: [origin; stop) */ 127 + start = origin; 119 128 120 - if (addr < mid->addr) 121 - last = mid; 122 - else 123 - first = mid; 129 + /* prel31 for address relavive to start */ 130 + addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff; 131 + 132 + while (start < stop - 1) { 133 + const struct unwind_idx *mid = start + ((stop - start) >> 1); 134 + 135 + /* 136 + * As addr_prel31 is relative to start an offset is needed to 137 + * make it relative to mid. 138 + */ 139 + if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) < 140 + mid->addr_offset) 141 + stop = mid; 142 + else { 143 + /* keep addr_prel31 relative to start */ 144 + addr_prel31 -= ((unsigned long)mid - 145 + (unsigned long)start); 146 + start = mid; 147 + } 124 148 } 125 149 126 - return first; 150 + if (likely(start->addr_offset <= addr_prel31)) 151 + return start; 152 + else { 153 + pr_warning("unwind: Unknown symbol address %08lx\n", addr); 154 + return NULL; 155 + } 127 156 } 128 157 129 - static struct unwind_idx *unwind_find_idx(unsigned long addr) 158 + static const struct unwind_idx *unwind_find_origin( 159 + const struct unwind_idx *start, const struct unwind_idx *stop) 130 160 { 131 - struct unwind_idx *idx = NULL; 161 + pr_debug("%s(%p, %p)\n", __func__, start, stop); 162 + while (start < stop - 1) { 163 + const struct unwind_idx *mid = start + ((stop - start) >> 1); 164 + 165 + if (mid->addr_offset >= 0x40000000) 166 + /* negative offset */ 167 + start = mid; 168 + else 169 + /* positive offset */ 170 + stop = mid; 171 + } 172 + pr_debug("%s -> %p\n", __func__, stop); 173 + return stop; 174 + } 175 + 176 + static const struct unwind_idx *unwind_find_idx(unsigned long addr) 177 + { 178 + const struct unwind_idx *idx = NULL; 132 179 unsigned long flags; 133 180 134 181 pr_debug("%s(%08lx)\n", __func__, addr); 135 182 136 - if (core_kernel_text(addr)) 183 + if (core_kernel_text(addr)) { 184 + if (unlikely(!__origin_unwind_idx)) 185 + __origin_unwind_idx = 186 + unwind_find_origin(__start_unwind_idx, 187 + __stop_unwind_idx); 188 + 137 189 /* main unwind table */ 138 190 idx = search_index(addr, __start_unwind_idx, 139 - __stop_unwind_idx - 1); 140 - else { 191 + __origin_unwind_idx, 192 + __stop_unwind_idx); 193 + } else { 141 194 /* module unwind tables */ 142 195 struct unwind_table *table; 143 196 ··· 200 145 if (addr >= table->begin_addr && 201 146 addr < table->end_addr) { 202 147 idx = search_index(addr, table->start, 203 - table->stop - 1); 148 + table->origin, 149 + table->stop); 204 150 /* Move-to-front to exploit common traces */ 205 151 list_move(&table->list, &unwind_tables); 206 152 break; ··· 330 274 int unwind_frame(struct stackframe *frame) 331 275 { 332 276 unsigned long high, low; 333 - struct unwind_idx *idx; 277 + const struct unwind_idx *idx; 334 278 struct unwind_ctrl_block ctrl; 335 279 336 280 /* only go to a higher address on the stack */ ··· 455 399 unsigned long text_size) 456 400 { 457 401 unsigned long flags; 458 - struct unwind_idx *idx; 459 402 struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL); 460 403 461 404 pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size, ··· 463 408 if (!tab) 464 409 return tab; 465 410 466 - tab->start = (struct unwind_idx *)start; 467 - tab->stop = (struct unwind_idx *)(start + size); 411 + tab->start = (const struct unwind_idx *)start; 412 + tab->stop = (const struct unwind_idx *)(start + size); 413 + tab->origin = unwind_find_origin(tab->start, tab->stop); 468 414 tab->begin_addr = text_addr; 469 415 tab->end_addr = text_addr + text_size; 470 - 471 - /* Convert the symbol addresses to absolute values */ 472 - for (idx = tab->start; idx < tab->stop; idx++) 473 - idx->addr = prel31_to_addr(&idx->addr); 474 416 475 417 spin_lock_irqsave(&unwind_lock, flags); 476 418 list_add_tail(&tab->list, &unwind_tables); ··· 488 436 spin_unlock_irqrestore(&unwind_lock, flags); 489 437 490 438 kfree(tab); 491 - } 492 - 493 - int __init unwind_init(void) 494 - { 495 - struct unwind_idx *idx; 496 - 497 - /* Convert the symbol addresses to absolute values */ 498 - for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++) 499 - idx->addr = prel31_to_addr(&idx->addr); 500 - 501 - pr_debug("unwind: ARM stack unwinding initialised\n"); 502 - 503 - return 0; 504 439 }