diff options
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/acpi.c | 28 | ||||
-rw-r--r-- | arch/ia64/kernel/cyclone.c | 14 | ||||
-rw-r--r-- | arch/ia64/kernel/head.S | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/init_task.c | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 19 | ||||
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 48 | ||||
-rw-r--r-- | arch/ia64/kernel/machvec.c | 27 | ||||
-rw-r--r-- | arch/ia64/kernel/mca.c | 17 | ||||
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/ia64/kernel/smp.c | 10 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 6 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 20 | ||||
-rw-r--r-- | arch/ia64/kernel/vmlinux.lds.S | 2 |
15 files changed, 137 insertions, 82 deletions
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 103dd8edda71..3d45d24a9d61 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -67,6 +67,8 @@ EXPORT_SYMBOL(pm_power_off); unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; +unsigned long acpi_wakeup_address = 0; + const char __init * acpi_get_sysname(void) { @@ -739,16 +741,15 @@ int __init acpi_boot_init(void) int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) { - int vector; + int tmp; if (has_8259 && gsi < 16) *irq = isa_irq_to_vector(gsi); else { - vector = gsi_to_vector(gsi); - if (vector == -1) + tmp = gsi_to_irq(gsi); + if (tmp == -1) return -1; - - *irq = vector; + *irq = tmp; } return 0; } @@ -986,4 +987,21 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) EXPORT_SYMBOL(acpi_unregister_ioapic); +/* + * acpi_save_state_mem() - save kernel state + * + * TBD when when IA64 starts to support suspend... + */ +int acpi_save_state_mem(void) { return 0; } + +/* + * acpi_restore_state() + */ +void acpi_restore_state_mem(void) {} + +/* + * do_suspend_lowlevel() + */ +void do_suspend_lowlevel(void) {} + #endif /* CONFIG_ACPI */ diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index 2fd96d9062a1..790ef0d87e12 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c @@ -38,11 +38,11 @@ static struct clocksource clocksource_cyclone = { int __init init_cyclone_clock(void) { - u64* reg; + u64 __iomem *reg; u64 base; /* saved cyclone base address */ u64 offset; /* offset from pageaddr to cyclone_timer register */ int i; - u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ + u32 __iomem *cyclone_timer; /* Cyclone MPMC0 register */ if (!use_cyclone) return 0; @@ -51,7 +51,7 @@ int __init init_cyclone_clock(void) /* find base address */ offset = (CYCLONE_CBAR_ADDR); - reg = (u64*)ioremap_nocache(offset, sizeof(u64)); + reg = ioremap_nocache(offset, sizeof(u64)); if(!reg){ printk(KERN_ERR "Summit chipset: Could not find valid CBAR" " register.\n"); @@ -69,7 +69,7 @@ int __init init_cyclone_clock(void) /* setup PMCC */ offset = (base + CYCLONE_PMCC_OFFSET); - reg = (u64*)ioremap_nocache(offset, sizeof(u64)); + reg = ioremap_nocache(offset, sizeof(u64)); if(!reg){ printk(KERN_ERR "Summit chipset: Could not find valid PMCC" " register.\n"); @@ -81,7 +81,7 @@ int __init init_cyclone_clock(void) /* setup MPCS */ offset = (base + CYCLONE_MPCS_OFFSET); - reg = (u64*)ioremap_nocache(offset, sizeof(u64)); + reg = ioremap_nocache(offset, sizeof(u64)); if(!reg){ printk(KERN_ERR "Summit chipset: Could not find valid MPCS" " register.\n"); @@ -93,7 +93,7 @@ int __init init_cyclone_clock(void) /* map in cyclone_timer */ offset = (base + CYCLONE_MPMC_OFFSET); - cyclone_timer = (u32*)ioremap_nocache(offset, sizeof(u32)); + cyclone_timer = ioremap_nocache(offset, sizeof(u32)); if(!cyclone_timer){ printk(KERN_ERR "Summit chipset: Could not find valid MPMC" " register.\n"); @@ -110,7 +110,7 @@ int __init init_cyclone_clock(void) printk(KERN_ERR "Summit chipset: Counter not counting!" " DISABLED\n"); iounmap(cyclone_timer); - cyclone_timer = 0; + cyclone_timer = NULL; use_cyclone = 0; return -ENODEV; } diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 44d540efa6d1..4e5e27540e27 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -178,7 +178,7 @@ swapper_pg_dir: halt_msg: stringz "Halting kernel\n" - .text + .section .text.head,"ax" .global start_ap @@ -392,6 +392,8 @@ self: hint @pause br.sptk.many self // endless loop END(_start) + .text + GLOBAL_ENTRY(ia64_save_debug_regs) alloc r16=ar.pfs,1,0,0,0 mov r20=ar.lc // preserve ar.lc diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c index b69c397ed1bf..bc8efcad28b8 100644 --- a/arch/ia64/kernel/init_task.c +++ b/arch/ia64/kernel/init_task.c @@ -8,6 +8,7 @@ #include <linux/init.h> #include <linux/mm.h> +#include <linux/fs.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/init_task.h> diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 91e6dc1e7baf..cfe4654838f4 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -142,7 +142,7 @@ struct iosapic_rte_info { static struct iosapic_intr_info { struct list_head rtes; /* RTEs using this vector (empty => * not an IOSAPIC interrupt) */ - int count; /* # of RTEs that shares this vector */ + int count; /* # of registered RTEs */ u32 low32; /* current value of low word of * Redirection table entry */ unsigned int dest; /* destination CPU physical ID */ @@ -313,7 +313,7 @@ mask_irq (unsigned int irq) int rte_index; struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt! */ /* set only the mask bit */ @@ -331,7 +331,7 @@ unmask_irq (unsigned int irq) int rte_index; struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt! */ low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; @@ -363,7 +363,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) dest = cpu_physical_id(first_cpu(mask)); - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt */ set_irq_affinity_info(irq, dest, redir); @@ -542,7 +542,7 @@ iosapic_reassign_vector (int irq) { int new_irq; - if (!list_empty(&iosapic_intr_info[irq].rtes)) { + if (iosapic_intr_info[irq].count) { new_irq = create_irq(); if (new_irq < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); @@ -560,7 +560,7 @@ iosapic_reassign_vector (int irq) } } -static struct iosapic_rte_info *iosapic_alloc_rte (void) +static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void) { int i; struct iosapic_rte_info *rte; @@ -677,7 +677,7 @@ get_target_cpu (unsigned int gsi, int irq) * In case of vector shared by multiple RTEs, all RTEs that * share the vector need to use the same destination CPU. */ - if (!list_empty(&iosapic_intr_info[irq].rtes)) + if (iosapic_intr_info[irq].count) return iosapic_intr_info[irq].dest; /* @@ -794,8 +794,9 @@ iosapic_register_intr (unsigned int gsi, err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); if (err < 0) { + spin_unlock(&irq_desc[irq].lock); irq = err; - goto unlock_all; + goto unlock_iosapic_lock; } /* @@ -811,7 +812,7 @@ iosapic_register_intr (unsigned int gsi, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, irq_to_vector(irq)); - unlock_all: + spin_unlock(&irq_desc[irq].lock); unlock_iosapic_lock: spin_unlock_irqrestore(&iosapic_lock, flags); diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 91797c111162..c47c8acc96e3 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -85,8 +85,8 @@ DEFINE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq) = { [0 ... IA64_NUM_VECTORS - 1] = IA64_SPURIOUS_INT_VECTOR }; -static cpumask_t vector_table[IA64_MAX_DEVICE_VECTORS] = { - [0 ... IA64_MAX_DEVICE_VECTORS - 1] = CPU_MASK_NONE +static cpumask_t vector_table[IA64_NUM_VECTORS] = { + [0 ... IA64_NUM_VECTORS - 1] = CPU_MASK_NONE }; static int irq_status[NR_IRQS] = { @@ -101,15 +101,6 @@ int check_irq_used(int irq) return -1; } -static void reserve_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - irq_status[irq] = IRQ_RSVD; - spin_unlock_irqrestore(&vector_lock, flags); -} - static inline int find_unassigned_irq(void) { int irq; @@ -123,17 +114,18 @@ static inline int find_unassigned_irq(void) static inline int find_unassigned_vector(cpumask_t domain) { cpumask_t mask; - int pos; + int pos, vector; cpus_and(mask, domain, cpu_online_map); if (cpus_empty(mask)) return -EINVAL; for (pos = 0; pos < IA64_NUM_DEVICE_VECTORS; pos++) { - cpus_and(mask, domain, vector_table[pos]); + vector = IA64_FIRST_DEVICE_VECTOR + pos; + cpus_and(mask, domain, vector_table[vector]); if (!cpus_empty(mask)) continue; - return IA64_FIRST_DEVICE_VECTOR + pos; + return vector; } return -ENOSPC; } @@ -141,9 +133,12 @@ static inline int find_unassigned_vector(cpumask_t domain) static int __bind_irq_vector(int irq, int vector, cpumask_t domain) { cpumask_t mask; - int cpu, pos; + int cpu; struct irq_cfg *cfg = &irq_cfg[irq]; + BUG_ON((unsigned)irq >= NR_IRQS); + BUG_ON((unsigned)vector >= IA64_NUM_VECTORS); + cpus_and(mask, domain, cpu_online_map); if (cpus_empty(mask)) return -EINVAL; @@ -156,8 +151,7 @@ static int __bind_irq_vector(int irq, int vector, cpumask_t domain) cfg->vector = vector; cfg->domain = domain; irq_status[irq] = IRQ_USED; - pos = vector - IA64_FIRST_DEVICE_VECTOR; - cpus_or(vector_table[pos], vector_table[pos], domain); + cpus_or(vector_table[vector], vector_table[vector], domain); return 0; } @@ -174,7 +168,7 @@ int bind_irq_vector(int irq, int vector, cpumask_t domain) static void __clear_irq_vector(int irq) { - int vector, cpu, pos; + int vector, cpu; cpumask_t mask; cpumask_t domain; struct irq_cfg *cfg = &irq_cfg[irq]; @@ -189,8 +183,7 @@ static void __clear_irq_vector(int irq) cfg->vector = IRQ_VECTOR_UNASSIGNED; cfg->domain = CPU_MASK_NONE; irq_status[irq] = IRQ_UNUSED; - pos = vector - IA64_FIRST_DEVICE_VECTOR; - cpus_andnot(vector_table[pos], vector_table[pos], domain); + cpus_andnot(vector_table[vector], vector_table[vector], domain); } static void clear_irq_vector(int irq) @@ -212,9 +205,6 @@ assign_irq_vector (int irq) vector = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); - if (irq < 0) { - goto out; - } for_each_online_cpu(cpu) { domain = vector_allocation_domain(cpu); vector = find_unassigned_vector(domain); @@ -223,6 +213,8 @@ assign_irq_vector (int irq) } if (vector < 0) goto out; + if (irq == AUTO_ASSIGN) + irq = vector; BUG_ON(__bind_irq_vector(irq, vector, domain)); out: spin_unlock_irqrestore(&vector_lock, flags); @@ -288,7 +280,7 @@ static int __init parse_vector_domain(char *arg) vector_domain_type = VECTOR_DOMAIN_PERCPU; no_int_routing = 1; } - return 1; + return 0; } early_param("vector", parse_vector_domain); #else @@ -301,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu) void destroy_and_reserve_irq(unsigned int irq) { + unsigned long flags; + dynamic_irq_cleanup(irq); - clear_irq_vector(irq); - reserve_irq(irq); + spin_lock_irqsave(&vector_lock, flags); + __clear_irq_vector(irq); + irq_status[irq] = IRQ_RSVD; + spin_unlock_irqrestore(&vector_lock, flags); } static int __reassign_irq_vector(int irq, int cpu) diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c index 13df337508e7..7ccb228ceedc 100644 --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -13,14 +13,6 @@ struct ia64_machine_vector ia64_mv; EXPORT_SYMBOL(ia64_mv); -static __initdata const char *mvec_name; -static __init int setup_mvec(char *s) -{ - mvec_name = s; - return 0; -} -early_param("machvec", setup_mvec); - static struct ia64_machine_vector * __init lookup_machvec (const char *name) { @@ -41,7 +33,7 @@ machvec_init (const char *name) struct ia64_machine_vector *mv; if (!name) - name = mvec_name ? mvec_name : acpi_get_sysname(); + name = acpi_get_sysname(); mv = lookup_machvec(name); if (!mv) panic("generic kernel failed to find machine vector for" @@ -51,6 +43,23 @@ machvec_init (const char *name) printk(KERN_INFO "booting generic kernel on platform %s\n", name); } +void __init +machvec_init_from_cmdline(const char *cmdline) +{ + char str[64]; + const char *start; + char *end; + + if (! (start = strstr(cmdline, "machvec=")) ) + return machvec_init(NULL); + + strlcpy(str, start + strlen("machvec="), sizeof(str)); + if ( (end = strchr(str, ' ')) ) + *end = '\0'; + + return machvec_init(str); +} + #endif /* CONFIG_IA64_GENERIC */ void diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4b5daa3cc0fe..ff28620cb992 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1750,8 +1750,17 @@ format_mca_init_stack(void *mca_data, unsigned long offset, strncpy(p->comm, type, sizeof(p->comm)-1); } -/* Do per-CPU MCA-related initialization. */ +/* Caller prevents this from being called after init */ +static void * __init_refok mca_bootmem(void) +{ + void *p; + p = alloc_bootmem(sizeof(struct ia64_mca_cpu) * NR_CPUS + + KERNEL_STACK_SIZE); + return (void *)ALIGN((unsigned long)p, KERNEL_STACK_SIZE); +} + +/* Do per-CPU MCA-related initialization. */ void __cpuinit ia64_mca_cpu_init(void *cpu_data) { @@ -1763,11 +1772,7 @@ ia64_mca_cpu_init(void *cpu_data) int cpu; first_time = 0; - mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu) - * NR_CPUS + KERNEL_STACK_SIZE); - mca_data = (void *)(((unsigned long)mca_data + - KERNEL_STACK_SIZE - 1) & - (-KERNEL_STACK_SIZE)); + mca_data = mca_bootmem(); for (cpu = 0; cpu < NR_CPUS; cpu++) { format_mca_init_stack(mca_data, offsetof(struct ia64_mca_cpu, mca_stack), diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index b7133cabdbea..14b8e5a6222b 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -591,13 +591,13 @@ pfm_set_task_notify(struct task_struct *task) struct thread_info *info; info = (struct thread_info *) ((char *) task + IA64_TASK_SIZE); - set_bit(TIF_NOTIFY_RESUME, &info->flags); + set_bit(TIF_PERFMON_WORK, &info->flags); } static inline void pfm_clear_task_notify(void) { - clear_thread_flag(TIF_NOTIFY_RESUME); + clear_thread_flag(TIF_PERFMON_WORK); } static inline void diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index fa40cba43350..4158906c45aa 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -499,7 +499,8 @@ copy_thread (int nr, unsigned long clone_flags, /* Copy partially mapped page list */ if (!retval) - retval = ia32_copy_partial_page_list(p, clone_flags); + retval = ia32_copy_ia64_partial_page_list(p, + clone_flags); } #endif @@ -728,7 +729,7 @@ flush_thread (void) ia64_drop_fpu(current); #ifdef CONFIG_IA32_SUPPORT if (IS_IA32_PROCESS(task_pt_regs(current))) { - ia32_drop_partial_page_list(current); + ia32_drop_ia64_partial_page_list(current); current->thread.task_size = IA32_PAGE_OFFSET; set_fs(USER_DS); } @@ -754,7 +755,7 @@ exit_thread (void) pfm_release_debug_registers(current); #endif if (IS_IA32_PROCESS(task_pt_regs(current))) - ia32_drop_partial_page_list(current); + ia32_drop_ia64_partial_page_list(current); } unsigned long diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index cf06fe799041..cd9a37a552c3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -60,7 +60,6 @@ #include <asm/smp.h> #include <asm/system.h> #include <asm/unistd.h> -#include <asm/system.h> #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) # error "struct cpuinfo_ia64 too big!" @@ -491,12 +490,17 @@ setup_arch (char **cmdline_p) efi_init(); io_port_init(); - parse_early_param(); - #ifdef CONFIG_IA64_GENERIC - machvec_init(NULL); + /* machvec needs to be parsed from the command line + * before parse_early_param() is called to ensure + * that ia64_mv is initialised before any command line + * settings may cause console setup to occur + */ + machvec_init_from_cmdline(*cmdline_p); #endif + parse_early_param(); + if (early_console_setup(*cmdline_p) == 0) mark_bsp_online(); diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 9f72838db26e..4e446aa5f4ac 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -346,7 +346,7 @@ smp_flush_tlb_mm (struct mm_struct *mm) } /* - * Run a function on another CPU + * Run a function on a specific CPU * <func> The function to run. This must be fast and non-blocking. * <info> An arbitrary pointer to pass to the function. * <nonatomic> Currently unused. @@ -366,9 +366,11 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int int me = get_cpu(); /* prevent preemption and reschedule on another processor */ if (cpuid == me) { - printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__); + local_irq_disable(); + func(info); + local_irq_enable(); put_cpu(); - return -EBUSY; + return 0; } data.func = func; @@ -468,7 +470,7 @@ smp_send_stop (void) send_IPI_allbutself(IPI_CPU_STOP); } -int __init +int setup_profiling_timer (unsigned int multiplier) { return -EINVAL; diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 9f5c90b594b9..62209dcf06d3 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -487,7 +487,7 @@ struct create_idle { int cpu; }; -void +void __cpuinit do_fork_idle(struct work_struct *work) { struct create_idle *c_idle = @@ -497,7 +497,7 @@ do_fork_idle(struct work_struct *work) complete(&c_idle->done); } -static int __devinit +static int __cpuinit do_boot_cpu (int sapicid, int cpu) { int timeout; @@ -808,7 +808,7 @@ set_cpu_sibling_map(int cpu) } } -int __devinit +int __cpuinit __cpu_up (unsigned int cpu) { int ret; diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 627785c48ea9..98cfc90cab1d 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -52,7 +52,7 @@ static struct clocksource clocksource_itc = { .name = "itc", .rating = 350, .read = itc_get_cycles, - .mask = 0xffffffffffffffff, + .mask = CLOCKSOURCE_MASK(64), .mult = 0, /*to be caluclated*/ .shift = 16, .flags = CLOCK_SOURCE_IS_CONTINUOUS, @@ -240,7 +240,21 @@ ia64_init_itm (void) if (!nojitter) itc_jitter_data.itc_jitter = 1; #endif - } + } else + /* + * ITC is drifty and we have not synchronized the ITCs in smpboot.c. + * ITC values may fluctuate significantly between processors. + * Clock should not be used for hrtimers. Mark itc as only + * useful for boot and testing. + * + * Note that jitter compensation is off! There is no point of + * synchronizing ITCs since they may be large differentials + * that change over time. + * + * The only way to fix this would be to repeatedly sync the + * ITCs. Until that time we have to avoid ITC. + */ + clocksource_itc.rating = 50; /* Setup the CPU local timer tick */ ia64_cpu_local_tick(); @@ -255,7 +269,7 @@ ia64_init_itm (void) } } -static cycle_t itc_get_cycles() +static cycle_t itc_get_cycles(void) { u64 lcycle, now, ret; diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 860f251d2fc2..83e80677de70 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -50,6 +50,8 @@ SECTIONS KPROBES_TEXT *(.gnu.linkonce.t*) } + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) + { *(.text.head) } .text2 : AT(ADDR(.text2) - LOAD_OFFSET) { *(.text2) } #ifdef CONFIG_SMP |