diff options
-rw-r--r-- | arch/ia64/kernel/entry.S | 7 | ||||
-rw-r--r-- | arch/ia64/kernel/patch.c | 20 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 7 | ||||
-rw-r--r-- | arch/ia64/kernel/vmlinux.lds.S | 7 | ||||
-rw-r--r-- | include/asm-ia64/asmmacro.h | 10 | ||||
-rw-r--r-- | include/asm-ia64/patch.h | 1 | ||||
-rw-r--r-- | include/asm-ia64/processor.h | 1 | ||||
-rw-r--r-- | include/asm-ia64/sections.h | 1 |
8 files changed, 47 insertions, 7 deletions
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 15234ed3a341..ac4b304bea30 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -767,7 +767,7 @@ ENTRY(ia64_leave_syscall) | |||
767 | ld8.fill r15=[r3] // M0|1 restore r15 | 767 | ld8.fill r15=[r3] // M0|1 restore r15 |
768 | mov b6=r18 // I0 restore b6 | 768 | mov b6=r18 // I0 restore b6 |
769 | 769 | ||
770 | addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A | 770 | LOAD_PHYS_STACK_REG_SIZE(r17) |
771 | mov f9=f0 // F clear f9 | 771 | mov f9=f0 // F clear f9 |
772 | (pKStk) br.cond.dpnt.many skip_rbs_switch // B | 772 | (pKStk) br.cond.dpnt.many skip_rbs_switch // B |
773 | 773 | ||
@@ -775,7 +775,6 @@ ENTRY(ia64_leave_syscall) | |||
775 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | 775 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition |
776 | cover // B add current frame into dirty partition & set cr.ifs | 776 | cover // B add current frame into dirty partition & set cr.ifs |
777 | ;; | 777 | ;; |
778 | (pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 | ||
779 | mov r19=ar.bsp // M2 get new backing store pointer | 778 | mov r19=ar.bsp // M2 get new backing store pointer |
780 | mov f10=f0 // F clear f10 | 779 | mov f10=f0 // F clear f10 |
781 | 780 | ||
@@ -953,9 +952,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) | |||
953 | shr.u r18=r19,16 // get byte size of existing "dirty" partition | 952 | shr.u r18=r19,16 // get byte size of existing "dirty" partition |
954 | ;; | 953 | ;; |
955 | mov r16=ar.bsp // get existing backing store pointer | 954 | mov r16=ar.bsp // get existing backing store pointer |
956 | addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 | 955 | LOAD_PHYS_STACK_REG_SIZE(r17) |
957 | ;; | ||
958 | ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 | ||
959 | (pKStk) br.cond.dpnt skip_rbs_switch | 956 | (pKStk) br.cond.dpnt skip_rbs_switch |
960 | 957 | ||
961 | /* | 958 | /* |
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index bc11bb096f58..e796e29f8e15 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c | |||
@@ -195,3 +195,23 @@ ia64_patch_gate (void) | |||
195 | ia64_patch_vtop(START(vtop), END(vtop)); | 195 | ia64_patch_vtop(START(vtop), END(vtop)); |
196 | ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); | 196 | ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); |
197 | } | 197 | } |
198 | |||
199 | void ia64_patch_phys_stack_reg(unsigned long val) | ||
200 | { | ||
201 | s32 * offp = (s32 *) __start___phys_stack_reg_patchlist; | ||
202 | s32 * end = (s32 *) __end___phys_stack_reg_patchlist; | ||
203 | u64 ip, mask, imm; | ||
204 | |||
205 | /* see instruction format A4: adds r1 = imm13, r3 */ | ||
206 | mask = (0x3fUL << 27) | (0x7f << 13); | ||
207 | imm = (((val >> 7) & 0x3f) << 27) | (val & 0x7f) << 13; | ||
208 | |||
209 | while (offp < end) { | ||
210 | ip = (u64) offp + *offp; | ||
211 | ia64_patch(ip, mask, imm); | ||
212 | ia64_fc(ip); | ||
213 | ++offp; | ||
214 | } | ||
215 | ia64_sync_i(); | ||
216 | ia64_srlz_i(); | ||
217 | } | ||
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index ad567b8d432e..f167b89f24eb 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -75,7 +75,6 @@ extern void ia64_setup_printk_clock(void); | |||
75 | 75 | ||
76 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); | 76 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); |
77 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); | 77 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); |
78 | DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); | ||
79 | unsigned long ia64_cycles_per_usec; | 78 | unsigned long ia64_cycles_per_usec; |
80 | struct ia64_boot_param *ia64_boot_param; | 79 | struct ia64_boot_param *ia64_boot_param; |
81 | struct screen_info screen_info; | 80 | struct screen_info screen_info; |
@@ -836,6 +835,7 @@ void __cpuinit | |||
836 | cpu_init (void) | 835 | cpu_init (void) |
837 | { | 836 | { |
838 | extern void __cpuinit ia64_mmu_init (void *); | 837 | extern void __cpuinit ia64_mmu_init (void *); |
838 | static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG; | ||
839 | unsigned long num_phys_stacked; | 839 | unsigned long num_phys_stacked; |
840 | pal_vm_info_2_u_t vmi; | 840 | pal_vm_info_2_u_t vmi; |
841 | unsigned int max_ctx; | 841 | unsigned int max_ctx; |
@@ -949,7 +949,10 @@ cpu_init (void) | |||
949 | num_phys_stacked = 96; | 949 | num_phys_stacked = 96; |
950 | } | 950 | } |
951 | /* size of physical stacked register partition plus 8 bytes: */ | 951 | /* size of physical stacked register partition plus 8 bytes: */ |
952 | __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; | 952 | if (num_phys_stacked > max_num_phys_stacked) { |
953 | ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8); | ||
954 | max_num_phys_stacked = num_phys_stacked; | ||
955 | } | ||
953 | platform_cpu_init(); | 956 | platform_cpu_init(); |
954 | pm_idle = default_idle; | 957 | pm_idle = default_idle; |
955 | } | 958 | } |
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index d6083a0936f4..d9599dcac787 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S | |||
@@ -78,6 +78,13 @@ SECTIONS | |||
78 | __stop___mca_table = .; | 78 | __stop___mca_table = .; |
79 | } | 79 | } |
80 | 80 | ||
81 | .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) | ||
82 | { | ||
83 | __start___phys_stack_reg_patchlist = .; | ||
84 | *(.data.patch.phys_stack_reg) | ||
85 | __end___phys_stack_reg_patchlist = .; | ||
86 | } | ||
87 | |||
81 | /* Global data */ | 88 | /* Global data */ |
82 | _data = .; | 89 | _data = .; |
83 | 90 | ||
diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h index c22b4658fc61..c1642fd64029 100644 --- a/include/asm-ia64/asmmacro.h +++ b/include/asm-ia64/asmmacro.h | |||
@@ -104,6 +104,16 @@ name: | |||
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * If physical stack register size is different from DEF_NUM_STACK_REG, | ||
108 | * dynamically patch the kernel for correct size. | ||
109 | */ | ||
110 | .section ".data.patch.phys_stack_reg", "a" | ||
111 | .previous | ||
112 | #define LOAD_PHYS_STACK_REG_SIZE(reg) \ | ||
113 | [1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \ | ||
114 | .xdata4 ".data.patch.phys_stack_reg", 1b-. | ||
115 | |||
116 | /* | ||
107 | * Up until early 2004, use of .align within a function caused bad unwind info. | 117 | * Up until early 2004, use of .align within a function caused bad unwind info. |
108 | * TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing | 118 | * TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing |
109 | * otherwise. | 119 | * otherwise. |
diff --git a/include/asm-ia64/patch.h b/include/asm-ia64/patch.h index 4797f3535e6d..a71543084fb4 100644 --- a/include/asm-ia64/patch.h +++ b/include/asm-ia64/patch.h | |||
@@ -20,6 +20,7 @@ extern void ia64_patch_imm60 (u64 insn_addr, u64 val); /* patch "brl" w/ip-rel | |||
20 | 20 | ||
21 | extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end); | 21 | extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end); |
22 | extern void ia64_patch_vtop (unsigned long start, unsigned long end); | 22 | extern void ia64_patch_vtop (unsigned long start, unsigned long end); |
23 | extern void ia64_patch_phys_stack_reg(unsigned long val); | ||
23 | extern void ia64_patch_gate (void); | 24 | extern void ia64_patch_gate (void); |
24 | 25 | ||
25 | #endif /* _ASM_IA64_PATCH_H */ | 26 | #endif /* _ASM_IA64_PATCH_H */ |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 5830d36fd8e6..88c728b9ff45 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
20 | #include <asm/ustack.h> | 20 | #include <asm/ustack.h> |
21 | 21 | ||
22 | #define IA64_NUM_PHYS_STACK_REG 96 | ||
22 | #define IA64_NUM_DBG_REGS 8 | 23 | #define IA64_NUM_DBG_REGS 8 |
23 | 24 | ||
24 | #define DEFAULT_MAP_BASE __IA64_UL_CONST(0x2000000000000000) | 25 | #define DEFAULT_MAP_BASE __IA64_UL_CONST(0x2000000000000000) |
diff --git a/include/asm-ia64/sections.h b/include/asm-ia64/sections.h index e9eb7f62d32b..dc42a359894f 100644 --- a/include/asm-ia64/sections.h +++ b/include/asm-ia64/sections.h | |||
@@ -11,6 +11,7 @@ | |||
11 | extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; | 11 | extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; |
12 | extern char __start___vtop_patchlist[], __end___vtop_patchlist[]; | 12 | extern char __start___vtop_patchlist[], __end___vtop_patchlist[]; |
13 | extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[]; | 13 | extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[]; |
14 | extern char __start___phys_stack_reg_patchlist[], __end___phys_stack_reg_patchlist[]; | ||
14 | extern char __start_gate_section[]; | 15 | extern char __start_gate_section[]; |
15 | extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchlist[]; | 16 | extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchlist[]; |
16 | extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[]; | 17 | extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[]; |