aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-08 14:06:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-08 14:06:01 -0400
commit3e9ca0224152bac6ea812e3ccfe933d3932c21bd (patch)
tree968c57dd7b9dc33c0a689413e6e392e588d2af78 /arch
parente72643088f576032d0d30c1d62c8fc077f383edc (diff)
parent3c75296562f43e6fbc6cddd3de948a7b3e4e9bcf (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
Pull powerpc fixes from Paul Mackerras: "Two small fixes for powerpc: - a fix for a regression since 3.2 that causes 4-second (or longer) pauses - a fix for a potential oops when loading kernel modules on 32-bit embedded systems." * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: powerpc: Fix kernel panic during kernel module load powerpc/time: Sanity check of decrementer expiration is necessary
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/module_32.c11
-rw-r--r--arch/powerpc/kernel/time.c14
2 files changed, 16 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index 0b6d79617d7b..2e3200ca485f 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -176,8 +176,8 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr,
176 176
177static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) 177static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val)
178{ 178{
179 if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) 179 if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16)
180 && entry->jump[1] == 0x396b0000 + (val & 0xffff)) 180 && entry->jump[1] == 0x398c0000 + (val & 0xffff))
181 return 1; 181 return 1;
182 return 0; 182 return 0;
183} 183}
@@ -204,10 +204,9 @@ static uint32_t do_plt_call(void *location,
204 entry++; 204 entry++;
205 } 205 }
206 206
207 /* Stolen from Paul Mackerras as well... */ 207 entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */
208 entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ 208 entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/
209 entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ 209 entry->jump[2] = 0x7d8903a6; /* mtctr r12 */
210 entry->jump[2] = 0x7d6903a6; /* mtctr r11 */
211 entry->jump[3] = 0x4e800420; /* bctr */ 210 entry->jump[3] = 0x4e800420; /* bctr */
212 211
213 DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); 212 DEBUGP("Initialized plt for 0x%x at %p\n", val, entry);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 99a995c2a3f2..be171ee73bf8 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -475,6 +475,7 @@ void timer_interrupt(struct pt_regs * regs)
475 struct pt_regs *old_regs; 475 struct pt_regs *old_regs;
476 u64 *next_tb = &__get_cpu_var(decrementers_next_tb); 476 u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
477 struct clock_event_device *evt = &__get_cpu_var(decrementers); 477 struct clock_event_device *evt = &__get_cpu_var(decrementers);
478 u64 now;
478 479
479 /* Ensure a positive value is written to the decrementer, or else 480 /* Ensure a positive value is written to the decrementer, or else
480 * some CPUs will continue to take decrementer exceptions. 481 * some CPUs will continue to take decrementer exceptions.
@@ -509,9 +510,16 @@ void timer_interrupt(struct pt_regs * regs)
509 irq_work_run(); 510 irq_work_run();
510 } 511 }
511 512
512 *next_tb = ~(u64)0; 513 now = get_tb_or_rtc();
513 if (evt->event_handler) 514 if (now >= *next_tb) {
514 evt->event_handler(evt); 515 *next_tb = ~(u64)0;
516 if (evt->event_handler)
517 evt->event_handler(evt);
518 } else {
519 now = *next_tb - now;
520 if (now <= DECREMENTER_MAX)
521 set_dec((int)now);
522 }
515 523
516#ifdef CONFIG_PPC64 524#ifdef CONFIG_PPC64
517 /* collect purr register values often, for accurate calculations */ 525 /* collect purr register values often, for accurate calculations */