Merge branch 'restart-cleanup' into restart

Conflicts:
	arch/arm/kernel/setup.c
This commit is contained in:
Russell King
2012-01-05 12:56:44 +00:00
1597 changed files with 20903 additions and 17484 deletions

View File

@@ -385,6 +385,8 @@
CALL(sys_syncfs)
CALL(sys_sendmmsg)
/* 375 */ CALL(sys_setns)
CALL(sys_process_vm_readv)
CALL(sys_process_vm_writev)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted

View File

@@ -497,7 +497,7 @@ ENDPROC(__und_usr)
.popsection
.pushsection __ex_table,"a"
.long 1b, 4b
#if __LINUX_ARM_ARCH__ >= 7
#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
.long 2b, 4b
.long 3b, 4b
#endif

View File

@@ -360,7 +360,7 @@ __secondary_data:
* r13 = *virtual* address to jump to upon completion
*/
__enable_mmu:
#ifdef CONFIG_ALIGNMENT_TRAP
#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
orr r0, r0, #CR_A
#else
bic r0, r0, #CR_A

View File

@@ -519,10 +519,12 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
static const union decode_item arm_cccc_0001_____1001_table[] = {
/* Synchronization primitives */
#if __LINUX_ARM_ARCH__ < 6
/* Deprecated on ARMv6 and may be UNDEFINED on v7 */
/* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
REGS(NOPC, NOPC, 0, 0, NOPC)),
#endif
/* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
/* And unallocated instructions... */
DECODE_END

View File

@@ -427,18 +427,25 @@ void kprobe_arm_test_cases(void)
TEST_GROUP("Synchronization primitives")
/*
* Use hard coded constants for SWP instructions to avoid warnings
* about deprecated instructions.
*/
TEST_RP( ".word 0xe108e097 @ swp lr, r",7,VAL2,", [r",8,0,"]")
TEST_R( ".word 0x610d0091 @ swpvs r0, r",1,VAL1,", [sp]")
TEST_RP( ".word 0xe10cd09e @ swp sp, r",14,VAL2,", [r",12,13*4,"]")
#if __LINUX_ARM_ARCH__ < 6
TEST_RP("swp lr, r",7,VAL2,", [r",8,0,"]")
TEST_R( "swpvs r0, r",1,VAL1,", [sp]")
TEST_RP("swp sp, r",14,VAL2,", [r",12,13*4,"]")
#else
TEST_UNSUPPORTED(".word 0xe108e097 @ swp lr, r7, [r8]")
TEST_UNSUPPORTED(".word 0x610d0091 @ swpvs r0, r1, [sp]")
TEST_UNSUPPORTED(".word 0xe10cd09e @ swp sp, r14 [r12]")
#endif
TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]")
TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]")
TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]")
TEST_RP( ".word 0xe148e097 @ swpb lr, r",7,VAL2,", [r",8,0,"]")
TEST_R( ".word 0x614d0091 @ swpvsb r0, r",1,VAL1,", [sp]")
#if __LINUX_ARM_ARCH__ < 6
TEST_RP("swpb lr, r",7,VAL2,", [r",8,0,"]")
TEST_R( "swpvsb r0, r",1,VAL1,", [sp]")
#else
TEST_UNSUPPORTED(".word 0xe148e097 @ swpb lr, r7, [r8]")
TEST_UNSUPPORTED(".word 0x614d0091 @ swpvsb r0, r1, [sp]")
#endif
TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]")
TEST_UNSUPPORTED(".word 0xe1100090") /* Unallocated space */
@@ -550,7 +557,7 @@ void kprobe_arm_test_cases(void)
TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]")
TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
TEST_RPR( "strd r",2, VAL1,", [r",3, 24,"], r",4,48,"")
TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
TEST_RPR( "strd r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
TEST_UNSUPPORTED(".word 0xe1afc0fa @ strd r12, [pc, r10]!")

View File

@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
DONT_TEST_IN_ITBLOCK(
TEST_BF_R( "cbnz r",0,0, ", 2f")
TEST_BF_R( "cbz r",2,-1,", 2f")
TEST_BF_RX( "cbnz r",4,1, ", 2f",0x20)
TEST_BF_RX( "cbz r",7,0, ", 2f",0x40)
TEST_BF_RX( "cbnz r",4,1, ", 2f", SPACE_0x20)
TEST_BF_RX( "cbz r",7,0, ", 2f", SPACE_0x40)
)
TEST_R("sxth r0, r",7, HH1,"")
TEST_R("sxth r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
TESTCASE_START(code) \
TEST_ARG_PTR(13, offset) \
TEST_ARG_END("") \
TEST_BRANCH_F(code,0) \
TEST_BRANCH_F(code) \
TESTCASE_END
TEST("push {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
TEST_BF( "b 2f")
TEST_BB( "b 2b")
TEST_BF_X("b 2f", 0x400)
TEST_BB_X("b 2b", 0x400)
TEST_BF_X("b 2f", SPACE_0x400)
TEST_BB_X("b 2b", SPACE_0x400)
TEST_GROUP("Testing instructions in IT blocks")
@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
TEST_BB("bne.w 2b")
TEST_BF("bgt.w 2f")
TEST_BB("blt.w 2b")
TEST_BF_X("bpl.w 2f",0x1000)
TEST_BF_X("bpl.w 2f", SPACE_0x1000)
)
TEST_UNSUPPORTED("msr cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
TEST_BF( "b.w 2f")
TEST_BB( "b.w 2b")
TEST_BF_X("b.w 2f", 0x1000)
TEST_BF_X("b.w 2f", SPACE_0x1000)
TEST_BF( "bl.w 2f")
TEST_BB( "bl.w 2b")
TEST_BB_X("bl.w 2b", 0x1000)
TEST_BB_X("bl.w 2b", SPACE_0x1000)
TEST_X( "blx __dummy_arm_subroutine",
".arm \n\t"

View File

@@ -149,23 +149,31 @@ struct test_arg_end {
"1: "instruction" \n\t" \
" nop \n\t"
#define TEST_BRANCH_F(instruction, xtra_dist) \
#define TEST_BRANCH_F(instruction) \
TEST_INSTRUCTION(instruction) \
".if "#xtra_dist" \n\t" \
" b 99f \n\t" \
".space "#xtra_dist" \n\t" \
".endif \n\t" \
" b 99f \n\t" \
"2: nop \n\t"
#define TEST_BRANCH_B(instruction, xtra_dist) \
#define TEST_BRANCH_B(instruction) \
" b 50f \n\t" \
" b 99f \n\t" \
"2: nop \n\t" \
" b 99f \n\t" \
".if "#xtra_dist" \n\t" \
".space "#xtra_dist" \n\t" \
".endif \n\t" \
TEST_INSTRUCTION(instruction)
#define TEST_BRANCH_FX(instruction, codex) \
TEST_INSTRUCTION(instruction) \
" b 99f \n\t" \
codex" \n\t" \
" b 99f \n\t" \
"2: nop \n\t"
#define TEST_BRANCH_BX(instruction, codex) \
" b 50f \n\t" \
" b 99f \n\t" \
"2: nop \n\t" \
" b 99f \n\t" \
codex" \n\t" \
TEST_INSTRUCTION(instruction)
#define TESTCASE_END \
@@ -301,47 +309,60 @@ struct test_arg_end {
TESTCASE_START(code1 #reg1 code2) \
TEST_ARG_PTR(reg1, val1) \
TEST_ARG_END("") \
TEST_BRANCH_F(code1 #reg1 code2, 0) \
TEST_BRANCH_F(code1 #reg1 code2) \
TESTCASE_END
#define TEST_BF_X(code, xtra_dist) \
#define TEST_BF(code) \
TESTCASE_START(code) \
TEST_ARG_END("") \
TEST_BRANCH_F(code, xtra_dist) \
TEST_BRANCH_F(code) \
TESTCASE_END
#define TEST_BB_X(code, xtra_dist) \
#define TEST_BB(code) \
TESTCASE_START(code) \
TEST_ARG_END("") \
TEST_BRANCH_B(code, xtra_dist) \
TEST_BRANCH_B(code) \
TESTCASE_END
#define TEST_BF_RX(code1, reg, val, code2, xtra_dist) \
TESTCASE_START(code1 #reg code2) \
TEST_ARG_REG(reg, val) \
TEST_ARG_END("") \
TEST_BRANCH_F(code1 #reg code2, xtra_dist) \
#define TEST_BF_R(code1, reg, val, code2) \
TESTCASE_START(code1 #reg code2) \
TEST_ARG_REG(reg, val) \
TEST_ARG_END("") \
TEST_BRANCH_F(code1 #reg code2) \
TESTCASE_END
#define TEST_BB_RX(code1, reg, val, code2, xtra_dist) \
TESTCASE_START(code1 #reg code2) \
TEST_ARG_REG(reg, val) \
TEST_ARG_END("") \
TEST_BRANCH_B(code1 #reg code2, xtra_dist) \
#define TEST_BB_R(code1, reg, val, code2) \
TESTCASE_START(code1 #reg code2) \
TEST_ARG_REG(reg, val) \
TEST_ARG_END("") \
TEST_BRANCH_B(code1 #reg code2) \
TESTCASE_END
#define TEST_BF(code) TEST_BF_X(code, 0)
#define TEST_BB(code) TEST_BB_X(code, 0)
#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0)
#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0)
#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3) \
TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
TEST_ARG_REG(reg1, val1) \
TEST_ARG_REG(reg2, val2) \
TEST_ARG_END("") \
TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0) \
TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3) \
TESTCASE_END
#define TEST_BF_X(code, codex) \
TESTCASE_START(code) \
TEST_ARG_END("") \
TEST_BRANCH_FX(code, codex) \
TESTCASE_END
#define TEST_BB_X(code, codex) \
TESTCASE_START(code) \
TEST_ARG_END("") \
TEST_BRANCH_BX(code, codex) \
TESTCASE_END
#define TEST_BF_RX(code1, reg, val, code2, codex) \
TESTCASE_START(code1 #reg code2) \
TEST_ARG_REG(reg, val) \
TEST_ARG_END("") \
TEST_BRANCH_FX(code1 #reg code2, codex) \
TESTCASE_END
#define TEST_X(code, codex) \
@@ -372,6 +393,25 @@ struct test_arg_end {
TESTCASE_END
/*
* Macros for defining space directives spread over multiple lines.
* These are required so the compiler guesses better the length of inline asm
* code and will spill the literal pool early enough to avoid generating PC
* relative loads with out of range offsets.
*/
#define TWICE(x) x x
#define SPACE_0x8 TWICE(".space 4\n\t")
#define SPACE_0x10 TWICE(SPACE_0x8)
#define SPACE_0x20 TWICE(SPACE_0x10)
#define SPACE_0x40 TWICE(SPACE_0x20)
#define SPACE_0x80 TWICE(SPACE_0x40)
#define SPACE_0x100 TWICE(SPACE_0x80)
#define SPACE_0x200 TWICE(SPACE_0x100)
#define SPACE_0x400 TWICE(SPACE_0x200)
#define SPACE_0x800 TWICE(SPACE_0x400)
#define SPACE_0x1000 TWICE(SPACE_0x800)
/* Various values used in test cases... */
#define N(val) (val ^ 0xffffffff)
#define VAL1 0x12345678

View File

@@ -32,24 +32,6 @@ static atomic_t waiting_for_crash_ipi;
int machine_kexec_prepare(struct kimage *image)
{
unsigned long page_list;
void *reboot_code_buffer;
page_list = image->head & PAGE_MASK;
reboot_code_buffer = page_address(image->control_code_page);
/* Prepare parameters for reboot_code_buffer*/
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
/* copy our kernel relocation code to the control code page */
memcpy(reboot_code_buffer,
relocate_new_kernel, relocate_new_kernel_size);
flush_icache_range((unsigned long) reboot_code_buffer,
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
return 0;
}
@@ -100,14 +82,31 @@ void (*kexec_reinit)(void);
void machine_kexec(struct kimage *image)
{
unsigned long page_list;
unsigned long reboot_code_buffer_phys;
void *reboot_code_buffer;
page_list = image->head & PAGE_MASK;
/* we need both effective and real address here */
reboot_code_buffer_phys =
page_to_pfn(image->control_code_page) << PAGE_SHIFT;
reboot_code_buffer = page_address(image->control_code_page);
/* Prepare parameters for reboot_code_buffer*/
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
/* copy our kernel relocation code to the control code page */
memcpy(reboot_code_buffer,
relocate_new_kernel, relocate_new_kernel_size);
flush_icache_range((unsigned long) reboot_code_buffer,
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
printk(KERN_INFO "Bye!\n");
if (kexec_reinit)

View File

@@ -343,19 +343,25 @@ validate_group(struct perf_event *event)
{
struct perf_event *sibling, *leader = event->group_leader;
struct pmu_hw_events fake_pmu;
DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
memset(&fake_pmu, 0, sizeof(fake_pmu));
/*
* Initialise the fake PMU. We only need to populate the
* used_mask for the purposes of validation.
*/
memset(fake_used_mask, 0, sizeof(fake_used_mask));
fake_pmu.used_mask = fake_used_mask;
if (!validate_event(&fake_pmu, leader))
return -ENOSPC;
return -EINVAL;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
if (!validate_event(&fake_pmu, sibling))
return -ENOSPC;
return -EINVAL;
}
if (!validate_event(&fake_pmu, event))
return -ENOSPC;
return -EINVAL;
return 0;
}
@@ -396,6 +402,9 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
int i, err, irq, irqs;
struct platform_device *pmu_device = armpmu->plat_device;
if (!pmu_device)
return -ENODEV;
err = reserve_pmu(armpmu->type);
if (err) {
pr_warning("unable to reserve pmu\n");
@@ -631,6 +640,9 @@ static struct platform_device_id armpmu_plat_device_ids[] = {
static int __devinit armpmu_device_probe(struct platform_device *pdev)
{
if (!cpu_pmu)
return -ENODEV;
cpu_pmu->plat_device = pdev;
return 0;
}

View File

@@ -33,3 +33,4 @@ release_pmu(enum arm_pmu_type type)
{
clear_bit_unlock(type, pmu_lock);
}
EXPORT_SYMBOL_GPL(release_pmu);

View File

@@ -191,6 +191,9 @@ void cpu_idle(void)
#endif
local_irq_disable();
#ifdef CONFIG_PL310_ERRATA_769419
wmb();
#endif
if (hlt_counter) {
local_irq_enable();
cpu_relax();

View File

@@ -461,8 +461,10 @@ static void __init setup_processor(void)
cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
proc_arch[cpu_architecture()], cr_alignment);
sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
list->arch_name, ENDIANNESS);
snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
list->elf_name, ENDIANNESS);
elf_hwcap = list->elf_hwcap;
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~HWCAP_THUMB;
@@ -893,8 +895,6 @@ void __init setup_arch(char **cmdline_p)
{
struct machine_desc *mdesc;
unwind_init();
setup_processor();
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
@@ -902,6 +902,12 @@ void __init setup_arch(char **cmdline_p)
machine_desc = mdesc;
machine_name = mdesc->name;
#ifdef CONFIG_ZONE_DMA
if (mdesc->dma_zone_size) {
extern unsigned long arm_dma_zone_size;
arm_dma_zone_size = mdesc->dma_zone_size;
}
#endif
if (mdesc->restart_mode)
reboot_setup(&mdesc->restart_mode);
@@ -935,12 +941,6 @@ void __init setup_arch(char **cmdline_p)
tcm_init();
#ifdef CONFIG_ZONE_DMA
if (mdesc->dma_zone_size) {
extern unsigned long arm_dma_zone_size;
arm_dma_zone_size = mdesc->dma_zone_size;
}
#endif
#ifdef CONFIG_MULTI_IRQ_HANDLER
handle_arch_irq = mdesc->handle_irq;
#endif

View File

@@ -43,7 +43,7 @@
struct cputopo_arm cpu_topology[NR_CPUS];
const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
const struct cpumask *cpu_coregroup_mask(int cpu)
{
return &cpu_topology[cpu].core_sibling;
}

View File

@@ -67,7 +67,7 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
struct unwind_ctrl_block {
unsigned long vrs[16]; /* virtual register set */
unsigned long *insn; /* pointer to the current instructions word */
const unsigned long *insn; /* pointer to the current instructions word */
int entries; /* number of entries left to interpret */
int byte; /* current byte number in the instructions word */
};
@@ -83,8 +83,9 @@ enum regs {
PC = 15
};
extern struct unwind_idx __start_unwind_idx[];
extern struct unwind_idx __stop_unwind_idx[];
extern const struct unwind_idx __start_unwind_idx[];
static const struct unwind_idx *__origin_unwind_idx;
extern const struct unwind_idx __stop_unwind_idx[];
static DEFINE_SPINLOCK(unwind_lock);
static LIST_HEAD(unwind_tables);
@@ -98,45 +99,99 @@ static LIST_HEAD(unwind_tables);
})
/*
* Binary search in the unwind index. The entries entries are
* Binary search in the unwind index. The entries are
* guaranteed to be sorted in ascending order by the linker.
*
* start = first entry
* origin = first entry with positive offset (or stop if there is no such entry)
* stop - 1 = last entry
*/
static struct unwind_idx *search_index(unsigned long addr,
struct unwind_idx *first,
struct unwind_idx *last)
static const struct unwind_idx *search_index(unsigned long addr,
const struct unwind_idx *start,
const struct unwind_idx *origin,
const struct unwind_idx *stop)
{
pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
unsigned long addr_prel31;
if (addr < first->addr) {
pr_warning("unwind: Unknown symbol address %08lx\n", addr);
return NULL;
} else if (addr >= last->addr)
return last;
pr_debug("%s(%08lx, %p, %p, %p)\n",
__func__, addr, start, origin, stop);
while (first < last - 1) {
struct unwind_idx *mid = first + ((last - first + 1) >> 1);
/*
* only search in the section with the matching sign. This way the
* prel31 numbers can be compared as unsigned longs.
*/
if (addr < (unsigned long)start)
/* negative offsets: [start; origin) */
stop = origin;
else
/* positive offsets: [origin; stop) */
start = origin;
if (addr < mid->addr)
last = mid;
else
first = mid;
/* prel31 for address relavive to start */
addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff;
while (start < stop - 1) {
const struct unwind_idx *mid = start + ((stop - start) >> 1);
/*
* As addr_prel31 is relative to start an offset is needed to
* make it relative to mid.
*/
if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) <
mid->addr_offset)
stop = mid;
else {
/* keep addr_prel31 relative to start */
addr_prel31 -= ((unsigned long)mid -
(unsigned long)start);
start = mid;
}
}
return first;
if (likely(start->addr_offset <= addr_prel31))
return start;
else {
pr_warning("unwind: Unknown symbol address %08lx\n", addr);
return NULL;
}
}
static struct unwind_idx *unwind_find_idx(unsigned long addr)
static const struct unwind_idx *unwind_find_origin(
const struct unwind_idx *start, const struct unwind_idx *stop)
{
struct unwind_idx *idx = NULL;
pr_debug("%s(%p, %p)\n", __func__, start, stop);
while (start < stop) {
const struct unwind_idx *mid = start + ((stop - start) >> 1);
if (mid->addr_offset >= 0x40000000)
/* negative offset */
start = mid + 1;
else
/* positive offset */
stop = mid;
}
pr_debug("%s -> %p\n", __func__, stop);
return stop;
}
static const struct unwind_idx *unwind_find_idx(unsigned long addr)
{
const struct unwind_idx *idx = NULL;
unsigned long flags;
pr_debug("%s(%08lx)\n", __func__, addr);
if (core_kernel_text(addr))
if (core_kernel_text(addr)) {
if (unlikely(!__origin_unwind_idx))
__origin_unwind_idx =
unwind_find_origin(__start_unwind_idx,
__stop_unwind_idx);
/* main unwind table */
idx = search_index(addr, __start_unwind_idx,
__stop_unwind_idx - 1);
else {
__origin_unwind_idx,
__stop_unwind_idx);
} else {
/* module unwind tables */
struct unwind_table *table;
@@ -145,7 +200,8 @@ static struct unwind_idx *unwind_find_idx(unsigned long addr)
if (addr >= table->begin_addr &&
addr < table->end_addr) {
idx = search_index(addr, table->start,
table->stop - 1);
table->origin,
table->stop);
/* Move-to-front to exploit common traces */
list_move(&table->list, &unwind_tables);
break;
@@ -274,7 +330,7 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
int unwind_frame(struct stackframe *frame)
{
unsigned long high, low;
struct unwind_idx *idx;
const struct unwind_idx *idx;
struct unwind_ctrl_block ctrl;
/* only go to a higher address on the stack */
@@ -399,7 +455,6 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
unsigned long text_size)
{
unsigned long flags;
struct unwind_idx *idx;
struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL);
pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
@@ -408,15 +463,12 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
if (!tab)
return tab;
tab->start = (struct unwind_idx *)start;
tab->stop = (struct unwind_idx *)(start + size);
tab->start = (const struct unwind_idx *)start;
tab->stop = (const struct unwind_idx *)(start + size);
tab->origin = unwind_find_origin(tab->start, tab->stop);
tab->begin_addr = text_addr;
tab->end_addr = text_addr + text_size;
/* Convert the symbol addresses to absolute values */
for (idx = tab->start; idx < tab->stop; idx++)
idx->addr = prel31_to_addr(&idx->addr);
spin_lock_irqsave(&unwind_lock, flags);
list_add_tail(&tab->list, &unwind_tables);
spin_unlock_irqrestore(&unwind_lock, flags);
@@ -437,16 +489,3 @@ void unwind_table_del(struct unwind_table *tab)
kfree(tab);
}
int __init unwind_init(void)
{
struct unwind_idx *idx;
/* Convert the symbol addresses to absolute values */
for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
idx->addr = prel31_to_addr(&idx->addr);
pr_debug("unwind: ARM stack unwinding initialised\n");
return 0;
}