From 4b9c876a812fd3e2b17e2d1c94082ee4cf31608f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 22 Sep 2006 09:23:53 +0100 Subject: [POWERPC] Fix audit syscall success/failure reporting on PowerPC Due to my stupidity, we were checking for the wrong bit in CCR when attempting to determine whether a syscall succeeded or not. Remedy the symptom, if not the cause. Signed-off-by: David Woodhouse Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index dea75d73f98..cf1d1bc4926 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -553,7 +553,7 @@ void do_syscall_trace_leave(struct pt_regs *regs) #endif if (unlikely(current->audit_context)) - audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, + audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, regs->result); if ((test_thread_flag(TIF_SYSCALL_TRACE) -- cgit v1.2.3 From 94983cb7881dff760d724759105a6f67935b571d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 22 Sep 2006 09:32:45 +0100 Subject: [POWERPC] Fix PPC32 SECCOMP, unexport do_syscall_trace_{enter,leave} The secure_computing() call which automatically aborts a process if it tries to execute a syscall it shouldn't is much more useful if we actually do it _before_ the syscall, rather than afterwards. PPC64 got this right, but the original incorrect behaviour inherited from arch/ppc was preserved by ifdefs. Make it the same on PPC32 too. Also, I see no need to export do_syscall_trace_{leave,enter} on ppc32 -- they were only exported because the old do_syscall_trace() (which they replaced) used to be. Signed-off-by: David Woodhouse Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/ptrace.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index cf1d1bc4926..975102a020d 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -526,9 +526,7 @@ static void do_syscall_trace(void) void do_syscall_trace_enter(struct pt_regs *regs) { -#ifdef CONFIG_PPC64 secure_computing(regs->gpr[0]); -#endif if (test_thread_flag(TIF_SYSCALL_TRACE) && (current->ptrace & PT_PTRACED)) @@ -548,10 +546,6 @@ void do_syscall_trace_enter(struct pt_regs *regs) void do_syscall_trace_leave(struct pt_regs *regs) { -#ifdef CONFIG_PPC32 - secure_computing(regs->gpr[0]); -#endif - if (unlikely(current->audit_context)) audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, regs->result); @@ -561,8 +555,3 @@ void do_syscall_trace_leave(struct pt_regs *regs) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); } - -#ifdef CONFIG_PPC32 -EXPORT_SYMBOL(do_syscall_trace_enter); -EXPORT_SYMBOL(do_syscall_trace_leave); -#endif -- cgit v1.2.3 From e12514650b167f48e952d50315fd492d01d42988 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 2 Aug 2006 10:48:50 +1000 Subject: [POWERPC] Fix loop logic in irq_alloc_virt() There's a bug in irq_alloc_virt() if it's asked for more than 1 interrupt, if it can't find a slot it might look past the end of the irq_map. To be clear: the bug is that the continue affects the inner for loop, not the outer one, so i becomes j + 1 and then we continue the inner loop without checking if i is still <= limit. This fixes it. No one in the kernel actually calls this with count > 1, so it's not critical. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index b4432332341..c3f58f2f9f5 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -777,7 +777,6 @@ unsigned int irq_alloc_virt(struct irq_host *host, { unsigned long flags; unsigned int i, j, found = NO_IRQ; - unsigned int limit = irq_virq_count - count; if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) return NO_IRQ; @@ -794,14 +793,16 @@ unsigned int irq_alloc_virt(struct irq_host *host, /* Look for count consecutive numbers in the allocatable * (non-legacy) space */ - for (i = NUM_ISA_INTERRUPTS; i <= limit; ) { - for (j = i; j < (i + count); j++) - if (irq_map[j].host != NULL) { - i = j + 1; - continue; - } - found = i; - break; + for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) { + if (irq_map[i].host != NULL) + j = 0; + else + j++; + + if (j == count) { + found = i - count + 1; + break; + } } if (found == NO_IRQ) { spin_unlock_irqrestore(&irq_big_lock, flags); -- cgit v1.2.3 From 0ddd3e7d07d6adc4e905ee869a85db5184a02c17 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 22 Sep 2006 20:30:14 +1000 Subject: [POWERPC] Always call cede in pseries dedicated idle loop The smt_snooze_delay logic changed a bit when the idle loops were consolidated. A value of 0 used to mean we always polled, now it means we always sleep. Instead of restoring the old behaviour, lets put a reasonable default in smt_snooze_delay. This means we spin for a bit (in case an external interrupt comes in) and then sleep. Also the pseries dedicated idle loop currently does not cede both threads in an SMT pair. The hypervisor wants us to call in so it can power manage, so lets do that. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 406f308ddea..d45a168bdac 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); /* SMT stuff */ #ifdef CONFIG_PPC_MULTIPLATFORM -/* default to snooze disabled */ -DEFINE_PER_CPU(unsigned long, smt_snooze_delay); +/* Time in microseconds we delay before sleeping in the idle loop */ +DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 }; static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, size_t count) -- cgit v1.2.3 From 7a69af63e788a324d162201a0b23df41bcf158dd Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 26 Sep 2006 17:46:37 -0500 Subject: [POWERPC] Add powerpc get/set_rtc_time interface to new generic rtc class Add powerpc get/set_rtc_time interface to new generic rtc class. This abstracts rtc chip specific code from the platform code for rtc-over-i2c platforms. Specific RTC chip support is now configured under Device Drivers -> Real Time Clock. Setting time of day from the RTC on startup is also configurable. this time without the potentially platform breaking initcall. Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 7a3c3f791ad..b4ed362c457 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -1048,6 +1048,48 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); } +#ifdef CONFIG_RTC_CLASS +static int set_rtc_class_time(struct rtc_time *tm) +{ + int err; + struct class_device *class_dev = + rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + + if (class_dev == NULL) + return -ENODEV; + + err = rtc_set_time(class_dev, tm); + + rtc_class_close(class_dev); + + return 0; +} + +static void get_rtc_class_time(struct rtc_time *tm) +{ + int err; + struct class_device *class_dev = + rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + + if (class_dev == NULL) + return; + + err = rtc_read_time(class_dev, tm); + + rtc_class_close(class_dev); + + return; +} + +int __init rtc_class_hookup(void) +{ + ppc_md.get_rtc_time = get_rtc_class_time; + ppc_md.set_rtc_time = set_rtc_class_time; + + return 0; +} +#endif /* CONFIG_RTC_CLASS */ + #define FEBRUARY 2 #define STARTOFTIME 1970 -- cgit v1.2.3