diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-08 14:06:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-08 14:06:01 -0400 |
commit | 3e9ca0224152bac6ea812e3ccfe933d3932c21bd (patch) | |
tree | 968c57dd7b9dc33c0a689413e6e392e588d2af78 | |
parent | e72643088f576032d0d30c1d62c8fc077f383edc (diff) | |
parent | 3c75296562f43e6fbc6cddd3de948a7b3e4e9bcf (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
-rw-r--r-- | arch/powerpc/kernel/module_32.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 14 |
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 | ||
177 | static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) | 177 | static 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 */ |