* [PATCH 09/10] um: Properly check all process' threads for a live mm
From: Anton Vorontsov @ 2012-03-24 10:31 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
kill_off_processes() might miss a valid process, this is because
checking for process->mm is not enough. Process' main thread may
exit or detach its mm via use_mm(), but other threads may still
have a valid mm.
To catch this we use find_lock_task_mm(), which walks up all
threads and returns an appropriate task (with task lock held).
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/um/kernel/reboot.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 1411f4e..3d15243 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -6,6 +6,7 @@
#include "linux/sched.h"
#include "linux/spinlock.h"
#include "linux/slab.h"
+#include "linux/oom.h"
#include "kern_util.h"
#include "os.h"
#include "skas.h"
@@ -25,13 +26,13 @@ static void kill_off_processes(void)
read_lock(&tasklist_lock);
for_each_process(p) {
- task_lock(p);
- if (!p->mm) {
- task_unlock(p);
+ struct task_struct *t;
+
+ t = find_lock_task_mm(p);
+ if (!t)
continue;
- }
- pid = p->mm->context.id.u.pid;
- task_unlock(p);
+ pid = t->mm->context.id.u.pid;
+ task_unlock(t);
os_kill_ptraced_process(pid, 1);
}
read_unlock(&tasklist_lock);
--
1.7.9.2
^ permalink raw reply related
* [PATCH 08/10] um: Fix possible race on task->mm
From: Anton Vorontsov @ 2012-03-24 10:30 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Checking for task->mm is dangerous as ->mm might disappear (exit_mm()
assigns NULL under task_lock(), so tasklist lock is not enough).
We can't use get_task_mm()/mmput() pair as mmput() might sleep,
so let's take the task lock while we care about its mm.
Note that we should also use find_lock_task_mm() to check all process'
threads for a valid mm, but for uml we'll do it in a separate patch.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/um/kernel/reboot.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 66d754c..1411f4e 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -25,10 +25,13 @@ static void kill_off_processes(void)
read_lock(&tasklist_lock);
for_each_process(p) {
- if (p->mm == NULL)
+ task_lock(p);
+ if (!p->mm) {
+ task_unlock(p);
continue;
-
+ }
pid = p->mm->context.id.u.pid;
+ task_unlock(p);
os_kill_ptraced_process(pid, 1);
}
read_unlock(&tasklist_lock);
--
1.7.9.2
^ permalink raw reply related
* [PATCH 07/10] um: Should hold tasklist_lock while traversing processes
From: Anton Vorontsov @ 2012-03-24 10:30 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Traversing the tasks requires holding tasklist_lock, otherwise it
is unsafe.
p.s. However, I'm not sure that calling os_kill_ptraced_process()
in the atomic context is correct. It seem to work, but please
take a closer look.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/um/kernel/reboot.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 4d93dff..66d754c 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -4,6 +4,7 @@
*/
#include "linux/sched.h"
+#include "linux/spinlock.h"
#include "linux/slab.h"
#include "kern_util.h"
#include "os.h"
@@ -22,6 +23,7 @@ static void kill_off_processes(void)
struct task_struct *p;
int pid;
+ read_lock(&tasklist_lock);
for_each_process(p) {
if (p->mm == NULL)
continue;
@@ -29,6 +31,7 @@ static void kill_off_processes(void)
pid = p->mm->context.id.u.pid;
os_kill_ptraced_process(pid, 1);
}
+ read_unlock(&tasklist_lock);
}
}
--
1.7.9.2
^ permalink raw reply related
* [PATCH 06/10] blackfin: Fix possible deadlock in decode_address()
From: Anton Vorontsov @ 2012-03-24 10:30 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Oleg Nesterov found an interesting deadlock possibility:
> sysrq_showregs_othercpus() does smp_call_function(showacpu)
> and showacpu() show_stack()->decode_address(). Now suppose that IPI
> interrupts the task holding read_lock(tasklist).
To fix this, blackfin should not grab the write_ variant of the
tasklist lock, read_ one is enough.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/blackfin/kernel/trace.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 5102cdf..9cc9302 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -28,7 +28,7 @@ void decode_address(char *buf, unsigned long address)
{
struct task_struct *p;
struct mm_struct *mm;
- unsigned long flags, offset;
+ unsigned long offset;
struct rb_node *n;
#ifdef CONFIG_KALLSYMS
@@ -112,7 +112,7 @@ void decode_address(char *buf, unsigned long address)
* mappings of all our processes and see if we can't be a whee
* bit more specific
*/
- write_lock_irqsave(&tasklist_lock, flags);
+ read_lock(&tasklist_lock);
for_each_process(p) {
struct task_struct *t;
@@ -185,7 +185,7 @@ __continue:
sprintf(buf, "/* kernel dynamic memory */");
done:
- write_unlock_irqrestore(&tasklist_lock, flags);
+ read_unlock(&tasklist_lock);
}
#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
--
1.7.9.2
^ permalink raw reply related
* [PATCH 05/10] blackfin: A couple of task->mm handling fixes
From: Anton Vorontsov @ 2012-03-24 10:29 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
The patch fixes two problems:
1. Working with task->mm w/o getting mm or grabing the task lock is
dangerous as ->mm might disappear (exit_mm() assigns NULL under
task_lock(), so tasklist lock is not enough).
We can't use get_task_mm()/mmput() pair as mmput() might sleep,
so we have to take the task lock while handle its mm.
2. Checking for process->mm is not enough because process' main
thread may exit or detach its mm via use_mm(), but other threads
may still have a valid mm.
To catch this we use find_lock_task_mm(), which walks up all
threads and returns an appropriate task (with task lock held).
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/blackfin/kernel/trace.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 050db44..5102cdf 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -10,6 +10,8 @@
#include <linux/hardirq.h>
#include <linux/thread_info.h>
#include <linux/mm.h>
+#include <linux/oom.h>
+#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
@@ -27,7 +29,6 @@ void decode_address(char *buf, unsigned long address)
struct task_struct *p;
struct mm_struct *mm;
unsigned long flags, offset;
- unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
struct rb_node *n;
#ifdef CONFIG_KALLSYMS
@@ -113,15 +114,15 @@ void decode_address(char *buf, unsigned long address)
*/
write_lock_irqsave(&tasklist_lock, flags);
for_each_process(p) {
- mm = (in_atomic ? p->mm : get_task_mm(p));
- if (!mm)
- continue;
+ struct task_struct *t;
- if (!down_read_trylock(&mm->mmap_sem)) {
- if (!in_atomic)
- mmput(mm);
+ t = find_lock_task_mm(p);
+ if (!t)
continue;
- }
+
+ mm = t->mm;
+ if (!down_read_trylock(&mm->mmap_sem))
+ goto __continue;
for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
struct vm_area_struct *vma;
@@ -130,7 +131,7 @@ void decode_address(char *buf, unsigned long address)
if (address >= vma->vm_start && address < vma->vm_end) {
char _tmpbuf[256];
- char *name = p->comm;
+ char *name = t->comm;
struct file *file = vma->vm_file;
if (file) {
@@ -163,8 +164,7 @@ void decode_address(char *buf, unsigned long address)
name, vma->vm_start, vma->vm_end);
up_read(&mm->mmap_sem);
- if (!in_atomic)
- mmput(mm);
+ task_unlock(t);
if (buf[0] == '\0')
sprintf(buf, "[ %s ] dynamic memory", name);
@@ -174,8 +174,8 @@ void decode_address(char *buf, unsigned long address)
}
up_read(&mm->mmap_sem);
- if (!in_atomic)
- mmput(mm);
+__continue:
+ task_unlock(t);
}
/*
--
1.7.9.2
^ permalink raw reply related
* [PATCH 04/10] sh: Use clear_tasks_mm_cpumask()
From: Anton Vorontsov @ 2012-03-24 10:28 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Current CPU hotplug code has some task->mm handling issues:
1. Working with task->mm w/o getting mm or grabing the task lock is
dangerous as ->mm might disappear (exit_mm() assigns NULL under
task_lock(), so tasklist lock is not enough).
We can't use get_task_mm()/mmput() pair as mmput() might sleep,
so we must take the task lock while handle its mm.
2. Checking for process->mm is not enough because process' main
thread may exit or detach its mm via use_mm(), but other threads
may still have a valid mm.
To fix this we would need to use find_lock_task_mm(), which would
walk up all threads and returns an appropriate task (with task
lock held).
clear_tasks_mm_cpumask() has all the issues fixed, so let's use it.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/sh/kernel/smp.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index f624174..2470c83 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -123,7 +123,6 @@ void native_play_dead(void)
int __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
- struct task_struct *p;
int ret;
ret = mp_ops->cpu_disable(cpu);
@@ -153,11 +152,7 @@ int __cpu_disable(void)
flush_cache_all();
local_flush_tlb_all();
- read_lock(&tasklist_lock);
- for_each_process(p)
- if (p->mm)
- cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
- read_unlock(&tasklist_lock);
+ clear_tasks_mm_cpumask(cpu);
return 0;
}
--
1.7.9.2
^ permalink raw reply related
* [PATCH 03/10] powerpc: Use clear_tasks_mm_cpumask()
From: Anton Vorontsov @ 2012-03-24 10:28 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Current CPU hotplug code has some task->mm handling issues:
1. Working with task->mm w/o getting mm or grabing the task lock is
dangerous as ->mm might disappear (exit_mm() assigns NULL under
task_lock(), so tasklist lock is not enough).
We can't use get_task_mm()/mmput() pair as mmput() might sleep,
so we must take the task lock while handle its mm.
2. Checking for process->mm is not enough because process' main
thread may exit or detach its mm via use_mm(), but other threads
may still have a valid mm.
To fix this we would need to use find_lock_task_mm(), which would
walk up all threads and returns an appropriate task (with task
lock held).
clear_tasks_mm_cpumask() has all the issues fixed, so let's use it.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/powerpc/mm/mmu_context_nohash.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 5b63bd3..e779642 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -333,9 +333,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned int)(long)hcpu;
-#ifdef CONFIG_HOTPLUG_CPU
- struct task_struct *p;
-#endif
+
/* We don't touch CPU 0 map, it's allocated at aboot and kept
* around forever
*/
@@ -358,12 +356,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
stale_map[cpu] = NULL;
/* We also clear the cpu_vm_mask bits of CPUs going away */
- read_lock(&tasklist_lock);
- for_each_process(p) {
- if (p->mm)
- cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
- }
- read_unlock(&tasklist_lock);
+ clear_tasks_mm_cpumask(cpu);
break;
#endif /* CONFIG_HOTPLUG_CPU */
}
--
1.7.9.2
^ permalink raw reply related
* [PATCH 02/10] arm: Use clear_tasks_mm_cpumask()
From: Anton Vorontsov @ 2012-03-24 10:28 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Current CPU hotplug code has some task->mm handling issues:
1. Working with task->mm w/o getting mm or grabing the task lock is
dangerous as ->mm might disappear (exit_mm() assigns NULL under
task_lock(), so tasklist lock is not enough).
We can't use get_task_mm()/mmput() pair as mmput() might sleep,
so we must take the task lock while handle its mm.
2. Checking for process->mm is not enough because process' main
thread may exit or detach its mm via use_mm(), but other threads
may still have a valid mm.
To fix this we would need to use find_lock_task_mm(), which would
walk up all threads and returns an appropriate task (with task
lock held).
clear_tasks_mm_cpumask() has all the issues fixed, so let's use it.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
arch/arm/kernel/smp.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index cdeb727..880b93a 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -136,7 +136,6 @@ static void percpu_timer_stop(void);
int __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
- struct task_struct *p;
int ret;
ret = platform_cpu_disable(cpu);
@@ -166,12 +165,7 @@ int __cpu_disable(void)
flush_cache_all();
local_flush_tlb_all();
- read_lock(&tasklist_lock);
- for_each_process(p) {
- if (p->mm)
- cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
- }
- read_unlock(&tasklist_lock);
+ clear_tasks_mm_cpumask(cpu);
return 0;
}
--
1.7.9.2
^ permalink raw reply related
* [PATCH 01/10] cpu: Introduce clear_tasks_mm_cpumask() helper
From: Anton Vorontsov @ 2012-03-24 10:27 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120324102609.GA28356@lizard>
Many architctures clear tasks' mm_cpumask like this:
read_lock(&tasklist_lock);
for_each_process(p) {
if (p->mm)
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
}
read_unlock(&tasklist_lock);
The code above has several problems, such as:
1. Working with task->mm w/o getting mm or grabing the task lock is
dangerous as ->mm might disappear (exit_mm() assigns NULL under
task_lock(), so tasklist lock is not enough).
2. Checking for process->mm is not enough because process' main
thread may exit or detach its mm via use_mm(), but other threads
may still have a valid mm.
This patch implements a small helper function that does things
correctly, i.e.:
1. We take the task's lock while whe handle its mm (we can't use
get_task_mm()/mmput() pair as mmput() might sleep);
2. To catch exited main thread case, we use find_lock_task_mm(),
which walks up all threads and returns an appropriate task
(with task lock held).
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
---
include/linux/cpu.h | 1 +
kernel/cpu.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1f65875..941e865 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -171,6 +171,7 @@ extern void put_online_cpus(void);
#define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri)
#define register_hotcpu_notifier(nb) register_cpu_notifier(nb)
#define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
+void clear_tasks_mm_cpumask(int cpu);
int cpu_down(unsigned int cpu);
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2060c6e..5255936 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -10,6 +10,7 @@
#include <linux/sched.h>
#include <linux/unistd.h>
#include <linux/cpu.h>
+#include <linux/oom.h>
#include <linux/export.h>
#include <linux/kthread.h>
#include <linux/stop_machine.h>
@@ -171,6 +172,23 @@ void __ref unregister_cpu_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_cpu_notifier);
+void clear_tasks_mm_cpumask(int cpu)
+{
+ struct task_struct *p;
+
+ read_lock(&tasklist_lock);
+ for_each_process(p) {
+ struct task_struct *t;
+
+ t = find_lock_task_mm(p);
+ if (!t)
+ continue;
+ cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
+ task_unlock(t);
+ }
+ read_unlock(&tasklist_lock);
+}
+
static inline void check_for_tasks(int cpu)
{
struct task_struct *p;
--
1.7.9.2
^ permalink raw reply related
* [PATCH v2 0/10] Fixes for common mistakes w/ for_each_process and task->mm
From: Anton Vorontsov @ 2012-03-24 10:26 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov
Cc: Mike Frysinger, Peter Zijlstra, user-mode-linux-devel, linux-sh,
Richard Weinberger, linux-kernel, uclinux-dist-devel, linux-mm,
Paul Mundt, John Stultz, KOSAKI Motohiro, Russell King,
linuxppc-dev, linux-arm-kernel
Hi all,
This is a reincarnation of the task->mm fixes. Several architectures
were traverse the tasklist in an unsafe manner, plus there are a
few cases of unsafe access to task->mm.
In v2 I decided to introduce a small helper in cpu.c: most arches
duplicate the same [buggy] code snippet, so it's better to fix it
and move the logic into a common function.
Thanks!
--
Anton Vorontsov
Email: cbouatmailru@gmail.com
^ permalink raw reply
* [PATCH] Disable /dev/port interface on powerpc systems
From: Haren Myneni @ 2012-03-24 8:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, anton
In-Reply-To: <1332314613.2982.38.camel@pasglop>
Ben, Here it is the updated patch based on your suggestions. Please let
me know if it has any issues.
Thanks
Haren
Some power systems do not have legacy ISA devices. So, /dev/port is not
a valid interface on these systems. User level tools such as kbdrate is
trying to access the device using this interface which is causing the
system crash.
This patch will fix this issue by not creating this interface on these
powerpc systems.
Signed-off-by: Haren Myneni <haren@us.ibm.com>
diff -Naurp linux.orig/arch/powerpc/include/asm/io.h
linux/arch/powerpc/include/asm/io.h
--- linux.orig/arch/powerpc/include/asm/io.h 2012-03-24
00:51:21.619999958 -0700
+++ linux/arch/powerpc/include/asm/io.h 2012-03-24 00:52:50.450000543
-0700
@@ -20,6 +20,14 @@ extern int check_legacy_ioport(unsigned
#define _PNPWRP 0xa79
#define PNPBIOS_BASE 0xf000
+#ifdef CONFIG_PPC64
+extern struct pci_dev *isa_bridge_pcidev;
+/*
+ * has legacy ISA devices ?
+ */
+#define arch_has_dev_port() (isa_bridge_pcidev != NULL)
+#endif
+
#include <linux/device.h>
#include <linux/io.h>
diff -Naurp linux.orig/drivers/char/mem.c linux/drivers/char/mem.c
--- linux.orig/drivers/char/mem.c 2012-03-24 00:50:21.570000660 -0700
+++ linux/drivers/char/mem.c 2012-03-24 00:52:32.080000802 -0700
@@ -35,6 +35,8 @@
# include <linux/efi.h>
#endif
+#define DEVPORT_MINOR 4
+
static inline unsigned long size_inside_page(unsigned long start,
unsigned long size)
{
@@ -930,6 +932,13 @@ static int __init chr_dev_init(void)
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name)
continue;
+
+ /*
+ * Create /dev/port?
+ */
+ if ((minor == DEVPORT_MINOR) && !arch_has_dev_port())
+ continue;
+
device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
NULL, devlist[minor].name);
}
diff -Naurp linux.orig/include/linux/io.h linux/include/linux/io.h
--- linux.orig/include/linux/io.h 2012-03-24 00:54:18.060000449 -0700
+++ linux/include/linux/io.h 2012-03-24 01:12:43.280000840 -0700
@@ -67,4 +67,13 @@ int check_signature(const volatile void
const unsigned char *signature, int length);
void devm_ioremap_release(struct device *dev, void *res);
+/*
+ * Some systems do not have legacy ISA devices.
+ * /dev/port is not a valid interface on these systems.
+ * So for those archs, <asm/io.h> should define the following symbol.
+ */
+#ifndef arch_has_dev_port
+#define arch_has_dev_port() (1)
+#endif
+
#endif /* _LINUX_IO_H */
^ permalink raw reply
* Re: Boot failure with next-20120208
From: Benjamin Herrenschmidt @ 2012-03-23 22:18 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Stephen Rothwell, Michael Neuling, gregkh, LKML, Milton Miller,
linux-next, Andrew Morton, ppc-dev
In-Reply-To: <4F6CCDDC.5000802@linux.intel.com>
On Fri, 2012-03-23 at 12:24 -0700, Arjan van de Ven wrote:
> well yeah, PPC is throwing things in the spanner
>
> we're now working on an x86-only patch with basically the same
> improvement, but done in a way that does not touch the other
> architectures
>
> so by all means drop the patch
Or maybe make an arch flag to enable the behaviour ? I can have a look
at the problem & maybe even fix it next week (it's been under my radar
for some reason so far), but I know at least of a few places where we
have that sort of assumptions about the bringup of boot CPUs.
For example, on Apple G5s, we don't support real hotplug, so the hot
unplug path just puts them in a linux-controlled sleep loop. So the
early boot time bringup is different from the hotplug path.
Among others, it needs access to things like i2c to synchronize the time
bases of the CPUs being brought up and we "release" that resource at the
end of the bringup.
So that needs fixing a way or another (and it's non trivial as other
drivers might try to get a lock on that i2c bus).
I'm sure I have a few other places with similar assumptions. And I
wouldn't be surprised if other architectures do as well :-)
So while your patch is a good / worthwhile idea, I think we need a bit
more time to sort things out before it can be applied.
(BTW. Arjan, can you send me privately your latest version of that
patch, for some reason I don't seem to be able to put my hand on it).
Cheers,
Ben.
^ permalink raw reply
* Re: [GIT PULL] DMA-mapping framework updates for 3.4
From: Linus Torvalds @ 2012-03-23 21:35 UTC (permalink / raw)
To: Marek Szyprowski, Dave Airlie
Cc: linux-mips, linux-ia64, linux-sh, linux-mm, sparclinux,
linux-arch, Jonathan Corbet, x86, Arnd Bergmann,
microblaze-uclinux, linaro-mm-sig, Andrzej Pietrasiewicz,
Thomas Gleixner, linux-arm-kernel, discuss, linux-kernel,
FUJITA Tomonori, Kyungmin Park, linux-alpha, Andrew Morton,
linuxppc-dev
In-Reply-To: <1332228283-29077-1-git-send-email-m.szyprowski@samsung.com>
On Tue, Mar 20, 2012 at 12:24 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
>
> =A0git://git.infradead.org/users/kmpark/linux-samsung dma-mapping-next
>
> Those patches introduce a new alloc method (with support for memory
> attributes) in dma_map_ops structure, which will later replace
> dma_alloc_coherent and dma_alloc_writecombine functions.
So I'm quite unhappy with these patches.
Here's just the few problems I saw from some *very* quick look-through
of the git tree:
- I'm not seeing ack's from the architecture maintainers for the
patches that change some architecture.
- Even more importantly, what I really want is acks and comments from
the people who are expected to *use* this.
- it looks like patches break compilation half-way through the
series. Just one example I noticed: the "x86 adaptation" patch changes
the functions in lib/swiotlb.c, but afaik ia64 *also* uses those. So
now ia64 is broken until a couple of patches later. I suspect there
are other examples like that.
- the sign-off chains are odd. What happened there? Several patches
are signed off by Kyungmin Park, but he doesn't seem to be "in the
chain" at all. Whazzup? (*)
(Btw, I notice the same thing in the tree I pulled from Dave Airlie,
btw - what the F is going on with samsung submissions - those are
marked as committed by Dave Airlie, and don't have Dave in the
sign-off chain at all!)
- Finally, how/why are "dma attributes" different from the per-device
dma limits ("device_dma_parameters")
Hmm?
Linus
(*) Btw, I notice the same thing in the tree I pulled from Dave
Airlie, btw - what the F is going on with samsung submissions - those
are marked as committed by Dave Airlie, and don't have Dave in the
sign-off chain at all! Dave?
^ permalink raw reply
* Re: [git pull] PCI changes (including maintainer change)
From: Yinghai Lu @ 2012-03-23 21:29 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-mips, devicetree-discuss, linuxppc-dev, linux-kernel,
Ralf Baechle, Paul Mackerras, Jesse Barnes, linux-pci,
Bjorn Helgaas, Rob Herring
In-Reply-To: <CA+55aFx+dXoJ=MGmpyzepDjBDv8LpXqdxUBCbdrakMKBsKpmTw@mail.gmail.com>
On Fri, Mar 23, 2012 at 2:10 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Fri, Mar 23, 2012 at 12:58 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>>
>> There are some merge conflicts. Hope attached patch could help Linus a
>> little bit.
>
> Hmm. My merge does not agree with yours at all in the MIPS
> pcibios_fixup_bus() area.
>
> Your patch re-introduces the device resource fixup that Bjorn removed,
> for example.
>
> I think my merge is correct, but hey, people should double-check.
yes, you are right.
Yinghai
^ permalink raw reply
* Re: [git pull] PCI changes (including maintainer change)
From: Linus Torvalds @ 2012-03-23 21:10 UTC (permalink / raw)
To: Yinghai Lu
Cc: linux-mips, devicetree-discuss, linuxppc-dev, linux-kernel,
Ralf Baechle, Paul Mackerras, Jesse Barnes, linux-pci,
Bjorn Helgaas, Rob Herring
In-Reply-To: <CAE9FiQV96Uz9fU=v4=eBbAogOeehuBM3eHgSr0QW_C68ceADcQ@mail.gmail.com>
On Fri, Mar 23, 2012 at 12:58 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>
> There are some merge conflicts. Hope attached patch could help Linus a
> little bit.
Hmm. My merge does not agree with yours at all in the MIPS
pcibios_fixup_bus() area.
Your patch re-introduces the device resource fixup that Bjorn removed,
for example.
I think my merge is correct, but hey, people should double-check.
Linus
^ permalink raw reply
* Re: [git pull] PCI changes (including maintainer change)
From: Yinghai Lu @ 2012-03-23 19:58 UTC (permalink / raw)
To: Jesse Barnes, Ralf Baechle, Linus Torvalds,
Benjamin Herrenschmidt, Paul Mackerras, Bjorn Helgaas,
Grant Likely, Rob Herring
Cc: linux-pci, devicetree-discuss, linuxppc-dev, linux-kernel,
linux-mips
In-Reply-To: <20120322144817.796e3a8a@jbarnes-desktop>
[-- Attachment #1: Type: text/plain, Size: 1488 bytes --]
On Thu, Mar 22, 2012 at 2:48 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> The following changes since commit
> 4f262acfde22b63498b5e4f165e53d3bb4e96400:
>
> Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm (2012-03-07 08:33:03 -0800)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci linux-next
>
> This pull has some good cleanups from Bjorn and Yinghai, as well as
> some more code from Yinghai to better handle resource re-allocation
> when enabled.
>
> There's also a new initcall_debug feature from Arjan which will print
> out quirk timing information to help identify slow quirks for fixing or
> refinement (Yinghai sent in a few patches to do just that once the new
> debug code landed).
>
> Beyond that, I'm handing off PCI maintainership to Bjorn Helgaas. He's
> been a core PCI and Linux contributor for some time now, and has kindly
> volunteered to take over. I just don't feel I have the time for PCI
> review and work that it deserves lately (I've taken on some other
> projects), and haven't been as responsive lately as I'd like, so I
> approached Bjorn asking if he'd like to manage things. He's going to
> give it a try, and I'm confident he'll do at least as well as I have in
> keeping the tree managed, patches flowing, and keeping things stable.
>
There are some merge conflicts. Hope attached patch could help Linus a
little bit.
Yinghai
[-- Attachment #2: pci_linux_next_merge.patch --]
[-- Type: text/x-patch, Size: 26738 bytes --]
---
arch/mips/pci/pci.c | 6
arch/powerpc/include/asm/ppc-pci.h | 3
arch/powerpc/platforms/iseries/pci.c | 919 -----------------------------------
include/linux/pci.h | 4
4 files changed, 932 deletions(-)
Index: linux-2.6/arch/mips/pci/pci.c
===================================================================
--- linux-2.6.orig/arch/mips/pci/pci.c
+++ linux-2.6/arch/mips/pci/pci.c
@@ -250,25 +250,19 @@ int pcibios_enable_device(struct pci_dev
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
-<<<<<<< HEAD
/* Propagate hose info into the subordinate devices. */
-=======
->>>>>>> pci/linux-next
struct pci_dev *dev = bus->self;
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
-<<<<<<< HEAD
pcibios_fixup_device_resources(dev, bus);
}
list_for_each_entry(dev, &bus->devices, bus_list) {
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
pcibios_fixup_device_resources(dev, bus);
-=======
->>>>>>> pci/linux-next
}
}
Index: linux-2.6/arch/powerpc/include/asm/ppc-pci.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/ppc-pci.h
+++ linux-2.6/arch/powerpc/include/asm/ppc-pci.h
@@ -45,12 +45,9 @@ extern void init_pci_config_tokens (void
extern unsigned long get_phb_buid (struct device_node *);
extern int rtas_setup_phb(struct pci_controller *phb);
-<<<<<<< HEAD
extern unsigned long pci_probe_only;
-=======
/* ---- EEH internal-use-only related routines ---- */
->>>>>>> pci/linux-next
#ifdef CONFIG_EEH
void pci_addr_cache_build(void);
Index: linux-2.6/arch/powerpc/platforms/iseries/pci.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/iseries/pci.c
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * Copyright (C) 2001 Allan Trautman, IBM Corporation
- * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp
- *
- * iSeries specific routines for PCI.
- *
- * Based on code from pci.c and iSeries_pci.c 32bit
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#undef DEBUG
-
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/of.h>
-#include <linux/ratelimit.h>
-
-#include <asm/types.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/abs_addr.h>
-#include <asm/firmware.h>
-
-#include <asm/iseries/hv_types.h>
-#include <asm/iseries/hv_call_xm.h>
-#include <asm/iseries/mf.h>
-#include <asm/iseries/iommu.h>
-
-#include <asm/ppc-pci.h>
-
-#include "irq.h"
-#include "pci.h"
-#include "call_pci.h"
-
-#define PCI_RETRY_MAX 3
-static int limit_pci_retries = 1; /* Set Retry Error on. */
-
-/*
- * Table defines
- * Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
- */
-#define IOMM_TABLE_MAX_ENTRIES 1024
-#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL
-#define BASE_IO_MEMORY 0xE000000000000000UL
-#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL
-
-static unsigned long max_io_memory = BASE_IO_MEMORY;
-static long current_iomm_table_entry;
-
-/*
- * Lookup Tables.
- */
-static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
-static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];
-
-static DEFINE_SPINLOCK(iomm_table_lock);
-
-/*
- * Generate a Direct Select Address for the Hypervisor
- */
-static inline u64 iseries_ds_addr(struct device_node *node)
-{
- struct pci_dn *pdn = PCI_DN(node);
- const u32 *sbp = of_get_property(node, "linux,subbus", NULL);
-
- return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)
- + ((u64)0x10 << 32);
-}
-
-/*
- * Size of Bus VPD data
- */
-#define BUS_VPDSIZE 1024
-
-/*
- * Bus Vpd Tags
- */
-#define VPD_END_OF_AREA 0x79
-#define VPD_ID_STRING 0x82
-#define VPD_VENDOR_AREA 0x84
-
-/*
- * Mfg Area Tags
- */
-#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
-#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
-#define VPD_SLOT_MAP 0x534D /* "SM" */
-
-/*
- * Structures of the areas
- */
-struct mfg_vpd_area {
- u16 tag;
- u8 length;
- u8 data1;
- u8 data2;
-};
-#define MFG_ENTRY_SIZE 3
-
-struct slot_map {
- u8 agent;
- u8 secondary_agent;
- u8 phb;
- char card_location[3];
- char parms[8];
- char reserved[2];
-};
-#define SLOT_ENTRY_SIZE 16
-
-/*
- * Parse the Slot Area
- */
-static void __init iseries_parse_slot_area(struct slot_map *map, int len,
- HvAgentId agent, u8 *phb, char card[4])
-{
- /*
- * Parse Slot label until we find the one requested
- */
- while (len > 0) {
- if (map->agent == agent) {
- /*
- * If Phb wasn't found, grab the entry first one found.
- */
- if (*phb == 0xff)
- *phb = map->phb;
- /* Found it, extract the data. */
- if (map->phb == *phb) {
- memcpy(card, &map->card_location, 3);
- card[3] = 0;
- break;
- }
- }
- /* Point to the next Slot */
- map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
- len -= SLOT_ENTRY_SIZE;
- }
-}
-
-/*
- * Parse the Mfg Area
- */
-static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
- HvAgentId agent, u8 *phb, u8 *frame, char card[4])
-{
- u16 slot_map_fmt = 0;
-
- /* Parse Mfg Data */
- while (len > 0) {
- int mfg_tag_len = area->length;
- /* Frame ID (FI 4649020310 ) */
- if (area->tag == VPD_FRU_FRAME_ID)
- *frame = area->data1;
- /* Slot Map Format (MF 4D46020004 ) */
- else if (area->tag == VPD_SLOT_MAP_FORMAT)
- slot_map_fmt = (area->data1 * 256)
- + area->data2;
- /* Slot Map (SM 534D90 */
- else if (area->tag == VPD_SLOT_MAP) {
- struct slot_map *slot_map;
-
- if (slot_map_fmt == 0x1004)
- slot_map = (struct slot_map *)((char *)area
- + MFG_ENTRY_SIZE + 1);
- else
- slot_map = (struct slot_map *)((char *)area
- + MFG_ENTRY_SIZE);
- iseries_parse_slot_area(slot_map, mfg_tag_len,
- agent, phb, card);
- }
- /*
- * Point to the next Mfg Area
- * Use defined size, sizeof give wrong answer
- */
- area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
- + MFG_ENTRY_SIZE);
- len -= (mfg_tag_len + MFG_ENTRY_SIZE);
- }
-}
-
-/*
- * Look for "BUS".. Data is not Null terminated.
- * PHBID of 0xFF indicates PHB was not found in VPD Data.
- */
-static u8 __init iseries_parse_phbid(u8 *area, int len)
-{
- while (len > 0) {
- if ((*area == 'B') && (*(area + 1) == 'U')
- && (*(area + 2) == 'S')) {
- area += 3;
- while (*area == ' ')
- area++;
- return *area & 0x0F;
- }
- area++;
- len--;
- }
- return 0xff;
-}
-
-/*
- * Parse out the VPD Areas
- */
-static void __init iseries_parse_vpd(u8 *data, int data_len,
- HvAgentId agent, u8 *frame, char card[4])
-{
- u8 phb = 0xff;
-
- while (data_len > 0) {
- int len;
- u8 tag = *data;
-
- if (tag == VPD_END_OF_AREA)
- break;
- len = *(data + 1) + (*(data + 2) * 256);
- data += 3;
- data_len -= 3;
- if (tag == VPD_ID_STRING)
- phb = iseries_parse_phbid(data, len);
- else if (tag == VPD_VENDOR_AREA)
- iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
- agent, &phb, frame, card);
- /* Point to next Area. */
- data += len;
- data_len -= len;
- }
-}
-
-static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
- u8 *frame, char card[4])
-{
- int status = 0;
- int bus_vpd_len = 0;
- u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
-
- if (bus_vpd == NULL) {
- printk("PCI: Bus VPD Buffer allocation failure.\n");
- return 0;
- }
- bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
- BUS_VPDSIZE);
- if (bus_vpd_len == 0) {
- printk("PCI: Bus VPD Buffer zero length.\n");
- goto out_free;
- }
- /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
- /* Make sure this is what I think it is */
- if (*bus_vpd != VPD_ID_STRING) {
- printk("PCI: Bus VPD Buffer missing starting tag.\n");
- goto out_free;
- }
- iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
- status = 1;
-out_free:
- kfree(bus_vpd);
- return status;
-}
-
-/*
- * Prints the device information.
- * - Pass in pci_dev* pointer to the device.
- * - Pass in the device count
- *
- * Format:
- * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
- * controller
- */
-static void __init iseries_device_information(struct pci_dev *pdev,
- u16 bus, HvSubBusNumber subbus)
-{
- u8 frame = 0;
- char card[4];
- HvAgentId agent;
-
- agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
- ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
-
- if (iseries_get_location_code(bus, agent, &frame, card)) {
- printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "
- "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor,
- frame, card, (int)(pdev->class >> 8));
- }
-}
-
-/*
- * iomm_table_allocate_entry
- *
- * Adds pci_dev entry in address translation table
- *
- * - Allocates the number of entries required in table base on BAR
- * size.
- * - Allocates starting at BASE_IO_MEMORY and increases.
- * - The size is round up to be a multiple of entry size.
- * - CurrentIndex is incremented to keep track of the last entry.
- * - Builds the resource entry for allocated BARs.
- */
-static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
-{
- struct resource *bar_res = &dev->resource[bar_num];
- long bar_size = pci_resource_len(dev, bar_num);
- struct device_node *dn = pci_device_to_OF_node(dev);
-
- /*
- * No space to allocate, quick exit, skip Allocation.
- */
- if (bar_size == 0)
- return;
- /*
- * Set Resource values.
- */
- spin_lock(&iomm_table_lock);
- bar_res->start = BASE_IO_MEMORY +
- IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
- bar_res->end = bar_res->start + bar_size - 1;
- /*
- * Allocate the number of table entries needed for BAR.
- */
- while (bar_size > 0 ) {
- iomm_table[current_iomm_table_entry] = dn;
- ds_addr_table[current_iomm_table_entry] =
- iseries_ds_addr(dn) | (bar_num << 24);
- bar_size -= IOMM_TABLE_ENTRY_SIZE;
- ++current_iomm_table_entry;
- }
- max_io_memory = BASE_IO_MEMORY +
- IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
- spin_unlock(&iomm_table_lock);
-}
-
-/*
- * allocate_device_bars
- *
- * - Allocates ALL pci_dev BAR's and updates the resources with the
- * BAR value. BARS with zero length will have the resources
- * The HvCallPci_getBarParms is used to get the size of the BAR
- * space. It calls iomm_table_allocate_entry to allocate
- * each entry.
- * - Loops through The Bar resources(0 - 5) including the ROM
- * is resource(6).
- */
-static void __init allocate_device_bars(struct pci_dev *dev)
-{
- int bar_num;
-
- for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num)
- iomm_table_allocate_entry(dev, bar_num);
-}
-
-/*
- * Log error information to system console.
- * Filter out the device not there errors.
- * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
- * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
- * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
- */
-static void pci_log_error(char *error, int bus, int subbus,
- int agent, int hv_res)
-{
- if (hv_res == 0x0302)
- return;
- printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
- error, bus, subbus, agent, hv_res);
-}
-
-/*
- * Look down the chain to find the matching Device Device
- */
-static struct device_node *find_device_node(int bus, int devfn)
-{
- struct device_node *node;
-
- for (node = NULL; (node = of_find_all_nodes(node)); ) {
- struct pci_dn *pdn = PCI_DN(node);
-
- if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn))
- return node;
- }
- return NULL;
-}
-
-/*
- * iSeries_pcibios_fixup_resources
- *
- * Fixes up all resources for devices
- */
-void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
-{
- const u32 *agent;
- const u32 *sub_bus;
- unsigned char bus = pdev->bus->number;
- struct device_node *node;
- int i;
-
- node = pci_device_to_OF_node(pdev);
- pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
- pci_name(pdev), pdev, node);
- if (!node) {
- printk("PCI: %s disabled, device tree entry not found !\n",
- pci_name(pdev));
- for (i = 0; i <= PCI_ROM_RESOURCE; i++)
- pdev->resource[i].flags = 0;
- return;
- }
- sub_bus = of_get_property(node, "linux,subbus", NULL);
- agent = of_get_property(node, "linux,agent-id", NULL);
- if (agent && sub_bus) {
- u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);
- int err;
-
- err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);
- if (err)
- pci_log_error("Connect Bus Unit",
- bus, *sub_bus, *agent, err);
- else {
- err = HvCallPci_configStore8(bus, *sub_bus,
- *agent, PCI_INTERRUPT_LINE, irq);
- if (err)
- pci_log_error("PciCfgStore Irq Failed!",
- bus, *sub_bus, *agent, err);
- else
- pdev->irq = irq;
- }
- }
-
- allocate_device_bars(pdev);
- if (likely(sub_bus))
- iseries_device_information(pdev, bus, *sub_bus);
- else
- printk(KERN_ERR "PCI: Device node %s has missing or invalid "
- "linux,subbus property\n", node->full_name);
-}
-
-/*
- * iSeries_pci_final_fixup(void)
- */
-void __init iSeries_pci_final_fixup(void)
-{
- /* Fix up at the device node and pci_dev relationship */
- mf_display_src(0xC9000100);
- iSeries_activate_IRQs();
- mf_display_src(0xC9000200);
-}
-
-/*
- * Config space read and write functions.
- * For now at least, we look for the device node for the bus and devfn
- * that we are asked to access. It may be possible to translate the devfn
- * to a subbus and deviceid more directly.
- */
-static u64 hv_cfg_read_func[4] = {
- HvCallPciConfigLoad8, HvCallPciConfigLoad16,
- HvCallPciConfigLoad32, HvCallPciConfigLoad32
-};
-
-static u64 hv_cfg_write_func[4] = {
- HvCallPciConfigStore8, HvCallPciConfigStore16,
- HvCallPciConfigStore32, HvCallPciConfigStore32
-};
-
-/*
- * Read PCI config space
- */
-static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int size, u32 *val)
-{
- struct device_node *node = find_device_node(bus->number, devfn);
- u64 fn;
- struct HvCallPci_LoadReturn ret;
-
- if (node == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset > 255) {
- *val = ~0;
- return PCIBIOS_BAD_REGISTER_NUMBER;
- }
-
- fn = hv_cfg_read_func[(size - 1) & 3];
- HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);
-
- if (ret.rc != 0) {
- *val = ~0;
- return PCIBIOS_DEVICE_NOT_FOUND; /* or something */
- }
-
- *val = ret.value;
- return 0;
-}
-
-/*
- * Write PCI config space
- */
-
-static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int size, u32 val)
-{
- struct device_node *node = find_device_node(bus->number, devfn);
- u64 fn;
- u64 ret;
-
- if (node == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset > 255)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- fn = hv_cfg_write_func[(size - 1) & 3];
- ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);
-
- if (ret != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return 0;
-}
-
-static struct pci_ops iSeries_pci_ops = {
- .read = iSeries_pci_read_config,
- .write = iSeries_pci_write_config
-};
-
-/*
- * Check Return Code
- * -> On Failure, print and log information.
- * Increment Retry Count, if exceeds max, panic partition.
- *
- * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
- * PCI: Device 23.90 ReadL Retry( 1)
- * PCI: Device 23.90 ReadL Retry Successful(1)
- */
-static int check_return_code(char *type, struct device_node *dn,
- int *retry, u64 ret)
-{
- if (ret != 0) {
- struct pci_dn *pdn = PCI_DN(dn);
-
- (*retry)++;
- printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
- type, pdn->busno, pdn->devfn,
- *retry, (int)ret);
- /*
- * Bump the retry and check for retry count exceeded.
- * If, Exceeded, panic the system.
- */
- if (((*retry) > PCI_RETRY_MAX) &&
- (limit_pci_retries > 0)) {
- mf_display_src(0xB6000103);
- panic_timeout = 0;
- panic("PCI: Hardware I/O Error, SRC B6000103, "
- "Automatic Reboot Disabled.\n");
- }
- return -1; /* Retry Try */
- }
- return 0;
-}
-
-/*
- * Translate the I/O Address into a device node, bar, and bar offset.
- * Note: Make sure the passed variable end up on the stack to avoid
- * the exposure of being device global.
- */
-static inline struct device_node *xlate_iomm_address(
- const volatile void __iomem *addr,
- u64 *dsaptr, u64 *bar_offset, const char *func)
-{
- unsigned long orig_addr;
- unsigned long base_addr;
- unsigned long ind;
- struct device_node *dn;
-
- orig_addr = (unsigned long __force)addr;
- if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
- static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10);
-
- if (__ratelimit(&ratelimit))
- printk(KERN_ERR
- "iSeries_%s: invalid access at IO address %p\n",
- func, addr);
- return NULL;
- }
- base_addr = orig_addr - BASE_IO_MEMORY;
- ind = base_addr / IOMM_TABLE_ENTRY_SIZE;
- dn = iomm_table[ind];
-
- if (dn != NULL) {
- *dsaptr = ds_addr_table[ind];
- *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
- } else
- panic("PCI: Invalid PCI IO address detected!\n");
- return dn;
-}
-
-/*
- * Read MM I/O Instructions for the iSeries
- * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
- * else, data is returned in Big Endian format.
- */
-static u8 iseries_readb(const volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- struct HvCallPci_LoadReturn ret;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");
-
- if (dn == NULL)
- return 0xff;
- do {
- HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);
- } while (check_return_code("RDB", dn, &retry, ret.rc) != 0);
-
- return ret.value;
-}
-
-static u16 iseries_readw_be(const volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- struct HvCallPci_LoadReturn ret;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");
-
- if (dn == NULL)
- return 0xffff;
- do {
- HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
- bar_offset, 0);
- } while (check_return_code("RDW", dn, &retry, ret.rc) != 0);
-
- return ret.value;
-}
-
-static u32 iseries_readl_be(const volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- struct HvCallPci_LoadReturn ret;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");
-
- if (dn == NULL)
- return 0xffffffff;
- do {
- HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
- bar_offset, 0);
- } while (check_return_code("RDL", dn, &retry, ret.rc) != 0);
-
- return ret.value;
-}
-
-/*
- * Write MM I/O Instructions for the iSeries
- *
- */
-static void iseries_writeb(u8 data, volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- u64 rc;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");
-
- if (dn == NULL)
- return;
- do {
- rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);
- } while (check_return_code("WWB", dn, &retry, rc) != 0);
-}
-
-static void iseries_writew_be(u16 data, volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- u64 rc;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");
-
- if (dn == NULL)
- return;
- do {
- rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);
- } while (check_return_code("WWW", dn, &retry, rc) != 0);
-}
-
-static void iseries_writel_be(u32 data, volatile void __iomem *addr)
-{
- u64 bar_offset;
- u64 dsa;
- int retry = 0;
- u64 rc;
- struct device_node *dn =
- xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");
-
- if (dn == NULL)
- return;
- do {
- rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);
- } while (check_return_code("WWL", dn, &retry, rc) != 0);
-}
-
-static u16 iseries_readw(const volatile void __iomem *addr)
-{
- return le16_to_cpu(iseries_readw_be(addr));
-}
-
-static u32 iseries_readl(const volatile void __iomem *addr)
-{
- return le32_to_cpu(iseries_readl_be(addr));
-}
-
-static void iseries_writew(u16 data, volatile void __iomem *addr)
-{
- iseries_writew_be(cpu_to_le16(data), addr);
-}
-
-static void iseries_writel(u32 data, volatile void __iomem *addr)
-{
- iseries_writel(cpu_to_le32(data), addr);
-}
-
-static void iseries_readsb(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- u8 *dst = buf;
- while(count-- > 0)
- *(dst++) = iseries_readb(addr);
-}
-
-static void iseries_readsw(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- u16 *dst = buf;
- while(count-- > 0)
- *(dst++) = iseries_readw_be(addr);
-}
-
-static void iseries_readsl(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- u32 *dst = buf;
- while(count-- > 0)
- *(dst++) = iseries_readl_be(addr);
-}
-
-static void iseries_writesb(volatile void __iomem *addr, const void *buf,
- unsigned long count)
-{
- const u8 *src = buf;
- while(count-- > 0)
- iseries_writeb(*(src++), addr);
-}
-
-static void iseries_writesw(volatile void __iomem *addr, const void *buf,
- unsigned long count)
-{
- const u16 *src = buf;
- while(count-- > 0)
- iseries_writew_be(*(src++), addr);
-}
-
-static void iseries_writesl(volatile void __iomem *addr, const void *buf,
- unsigned long count)
-{
- const u32 *src = buf;
- while(count-- > 0)
- iseries_writel_be(*(src++), addr);
-}
-
-static void iseries_memset_io(volatile void __iomem *addr, int c,
- unsigned long n)
-{
- volatile char __iomem *d = addr;
-
- while (n-- > 0)
- iseries_writeb(c, d++);
-}
-
-static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
- unsigned long n)
-{
- char *d = dest;
- const volatile char __iomem *s = src;
-
- while (n-- > 0)
- *d++ = iseries_readb(s++);
-}
-
-static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
- unsigned long n)
-{
- const char *s = src;
- volatile char __iomem *d = dest;
-
- while (n-- > 0)
- iseries_writeb(*s++, d++);
-}
-
-/* We only set MMIO ops. The default PIO ops will be default
- * to the MMIO ops + pci_io_base which is 0 on iSeries as
- * expected so both should work.
- *
- * Note that we don't implement the readq/writeq versions as
- * I don't know of an HV call for doing so. Thus, the default
- * operation will be used instead, which will fault a the value
- * return by iSeries for MMIO addresses always hits a non mapped
- * area. This is as good as the BUG() we used to have there.
- */
-static struct ppc_pci_io __initdata iseries_pci_io = {
- .readb = iseries_readb,
- .readw = iseries_readw,
- .readl = iseries_readl,
- .readw_be = iseries_readw_be,
- .readl_be = iseries_readl_be,
- .writeb = iseries_writeb,
- .writew = iseries_writew,
- .writel = iseries_writel,
- .writew_be = iseries_writew_be,
- .writel_be = iseries_writel_be,
- .readsb = iseries_readsb,
- .readsw = iseries_readsw,
- .readsl = iseries_readsl,
- .writesb = iseries_writesb,
- .writesw = iseries_writesw,
- .writesl = iseries_writesl,
- .memset_io = iseries_memset_io,
- .memcpy_fromio = iseries_memcpy_fromio,
- .memcpy_toio = iseries_memcpy_toio,
-};
-
-/*
- * iSeries_pcibios_init
- *
- * Description:
- * This function checks for all possible system PCI host bridges that connect
- * PCI buses. The system hypervisor is queried as to the guest partition
- * ownership status. A pci_controller is built for any bus which is partially
- * owned or fully owned by this guest partition.
- */
-void __init iSeries_pcibios_init(void)
-{
- struct pci_controller *phb;
- struct device_node *root = of_find_node_by_path("/");
- struct device_node *node = NULL;
-
- /* Install IO hooks */
- ppc_pci_io = iseries_pci_io;
-
- pci_add_flags(PCI_PROBE_ONLY);
-
- /* iSeries has no IO space in the common sense, it needs to set
- * the IO base to 0
- */
- pci_io_base = 0;
-
- if (root == NULL) {
- printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
- "of device tree\n");
- return;
- }
- while ((node = of_get_next_child(root, node)) != NULL) {
- HvBusNumber bus;
- const u32 *busp;
-
- if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
- continue;
-
- busp = of_get_property(node, "bus-range", NULL);
- if (busp == NULL)
- continue;
- bus = *busp;
- printk("bus %d appears to exist\n", bus);
- phb = pcibios_alloc_controller(node);
- if (phb == NULL)
- continue;
- /* All legacy iSeries PHBs are in domain zero */
- phb->global_number = 0;
-
- phb->first_busno = bus;
- phb->last_busno = bus;
- phb->ops = &iSeries_pci_ops;
- phb->io_base_virt = (void __iomem *)_IO_BASE;
- phb->io_resource.flags = IORESOURCE_IO;
- phb->io_resource.start = BASE_IO_MEMORY;
- phb->io_resource.end = END_IO_MEMORY;
- phb->io_resource.name = "iSeries PCI IO";
- phb->mem_resources[0].flags = IORESOURCE_MEM;
- phb->mem_resources[0].start = BASE_IO_MEMORY;
- phb->mem_resources[0].end = END_IO_MEMORY;
- phb->mem_resources[0].name = "Series PCI MEM";
- }
-
- of_node_put(root);
-
- pci_devs_phb_init();
-}
-
Index: linux-2.6/include/linux/pci.h
===================================================================
--- linux-2.6.orig/include/linux/pci.h
+++ linux-2.6/include/linux/pci.h
@@ -947,7 +947,6 @@ int __must_check __pci_register_driver(s
__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
void pci_unregister_driver(struct pci_driver *dev);
-<<<<<<< HEAD
/**
* module_pci_driver() - Helper macro for registering a PCI driver
@@ -961,10 +960,7 @@ void pci_unregister_driver(struct pci_dr
module_driver(__pci_driver, pci_register_driver, \
pci_unregister_driver)
-void pci_remove_behind_bridge(struct pci_dev *dev);
-=======
void pci_stop_and_remove_behind_bridge(struct pci_dev *dev);
->>>>>>> pci/linux-next
struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
int pci_add_dynid(struct pci_driver *drv,
unsigned int vendor, unsigned int device,
^ permalink raw reply
* Re: Boot failure with next-20120208
From: Arjan van de Ven @ 2012-03-23 19:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Stephen Rothwell, Michael Neuling, gregkh, LKML, Milton Miller,
linux-next, ppc-dev
In-Reply-To: <20120323122244.132198e3.akpm@linux-foundation.org>
On 3/23/2012 12:22 PM, Andrew Morton wrote:
> On Mon, 13 Feb 2012 12:16:41 -0800
> Arjan van de Ven <arjan@linux.intel.com> wrote:
>
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>>> The bug looks pretty generic, nothing very PPC-specific there. It
>>> might affect other architectures - we won't know until we find out
>>> wht caused it.
>>
>> well one half of the race looks pretty generic...
>> ..... doesn't mean the other half of the race is though....
>>
>>
>>>
>>> Ho hum, I suppose I should pull the patch out of linux-next, to
>>> avoid disrupting other testing. This means it's going to be hard
>>> to get the bug fixed.
>>
>> it means losing this one big PPC machine indeed.... until they hit
>> that same race some other way with regular real cpu hotplug ;-(
>
> So we're kinda stuck with this. As I can't merge it, I guess I'll make
> smp-start-up-non-boot-cpus-asynchronously.patch disappear.
well yeah, PPC is throwing things in the spanner
we're now working on an x86-only patch with basically the same
improvement, but done in a way that does not touch the other architectures
so by all means drop the patch
^ permalink raw reply
* Re: Boot failure with next-20120208
From: Andrew Morton @ 2012-03-23 19:22 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Stephen Rothwell, Michael Neuling, gregkh, LKML, Milton Miller,
linux-next, ppc-dev
In-Reply-To: <4F396FA9.90606@linux.intel.com>
On Mon, 13 Feb 2012 12:16:41 -0800
Arjan van de Ven <arjan@linux.intel.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> > The bug looks pretty generic, nothing very PPC-specific there. It
> > might affect other architectures - we won't know until we find out
> > wht caused it.
>
> well one half of the race looks pretty generic...
> ..... doesn't mean the other half of the race is though....
>
>
> >
> > Ho hum, I suppose I should pull the patch out of linux-next, to
> > avoid disrupting other testing. This means it's going to be hard
> > to get the bug fixed.
>
> it means losing this one big PPC machine indeed.... until they hit
> that same race some other way with regular real cpu hotplug ;-(
So we're kinda stuck with this. As I can't merge it, I guess I'll make
smp-start-up-non-boot-cpus-asynchronously.patch disappear.
^ permalink raw reply
* Re: [PATCH 00/17] Platform Facilities Option and crypto accelerator driver
From: Kumar Gala @ 2012-03-23 16:06 UTC (permalink / raw)
To: Kent Yoder; +Cc: rcj, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1332443286.3858.70.camel@key-ThinkPad-W510>
On Mar 22, 2012, at 2:08 PM, Kent Yoder wrote:
> Hi Kumar,
>=20
>> Is there a reason this isn't in drivers/crypto/
>=20
> Other arch-specific dirs have their crypto subdir as well such as
> arch/s390. I was just matching that.
>=20
> Kent
>=20
>> - k
>=20
=46rom what I can tell this isn't ISA level instructions and thus should =
NOT be in arch/powerpc. This should be moved into drivers/crypto
- k=
^ permalink raw reply
* Re: [PATCH 00/17] Platform Facilities Option and crypto accelerator driver
From: Kent Yoder @ 2012-03-22 19:08 UTC (permalink / raw)
To: Kumar Gala; +Cc: rcj, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <C23F031B-1431-4E98-92DC-3EB7E31D2776@kernel.crashing.org>
Hi Kumar,
> Is there a reason this isn't in drivers/crypto/
Other arch-specific dirs have their crypto subdir as well such as
arch/s390. I was just matching that.
Kent
> - k
^ permalink raw reply
* Re: [PATCH 00/17] Platform Facilities Option and crypto accelerator driver
From: Kumar Gala @ 2012-03-22 17:17 UTC (permalink / raw)
To: Kent Yoder; +Cc: rcj, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1332365297.3858.5.camel@key-ThinkPad-W510>
On Mar 21, 2012, at 4:28 PM, Kent Yoder wrote:
> arch/powerpc/crypto/nx/Makefile | 11 +
> arch/powerpc/crypto/nx/nx-aes-cbc.c | 135 +++++
> arch/powerpc/crypto/nx/nx-aes-ccm.c | 466 ++++++++++++++++++
> arch/powerpc/crypto/nx/nx-aes-ctr.c | 175 +++++++
> arch/powerpc/crypto/nx/nx-aes-ecb.c | 133 +++++
> arch/powerpc/crypto/nx/nx-aes-gcm.c | 352 +++++++++++++
> arch/powerpc/crypto/nx/nx-aes-xcbc.c | 230 +++++++++
> arch/powerpc/crypto/nx/nx-sha256.c | 240 +++++++++
> arch/powerpc/crypto/nx/nx-sha512.c | 259 ++++++++++
> arch/powerpc/crypto/nx/nx.c | 710 =
+++++++++++++++++++++++++++
> arch/powerpc/crypto/nx/nx.h | 190 +++++++
> arch/powerpc/crypto/nx/nx_csbcpb.h | 246 +++++++++
> arch/powerpc/crypto/nx/nx_sysfs.c | 194 ++++++++
Is there a reason this isn't in drivers/crypto/
- k=
^ permalink raw reply
* [PATCH v5 1/2] dmaengine: Add context parameter to prep_dma_sg and prep_interleaved_dma
From: Ravi Kumar V @ 2012-03-22 14:22 UTC (permalink / raw)
To: Vinod Koul
Cc: tsoni, Russell King, Ravi Kumar V, Srinidhi Kasagar,
Ira W. Snyder, linux-arm-msm, linux-kernel, Zhang Wei,
Bryan Huntsman, Al Viro, Barry Song, Daniel Walker, Dan Williams,
linuxppc-dev, David Brown, linux-arm-kernel
Add new context parameter to DMA SG and Interleaveid mode for passing
per transfer specific private data, using this it enables the
dma devices which needs to pass the parameters which changes per
each transfer
Signed-off-by: Ravi Kumar V <kumarrav@codeaurora.org>
---
drivers/dma/fsldma.c | 2 +-
drivers/dma/sirf-dma.c | 2 +-
drivers/dma/ste_dma40.c | 2 +-
drivers/misc/carma/carma-fpga-program.c | 2 +-
drivers/misc/carma/carma-fpga.c | 7 +++----
include/linux/dmaengine.h | 22 ++++++++++++++++++++--
6 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index b98070c..f9f77db 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -645,7 +645,7 @@ fail:
static struct dma_async_tx_descriptor *fsl_dma_prep_sg(struct dma_chan *dchan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long flags)
+ unsigned long flags, void *context)
{
struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
struct fsldma_chan *chan = to_fsl_chan(dchan);
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 2333810..ff4d344 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -428,7 +428,7 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved(
struct dma_chan *chan, struct dma_interleaved_template *xt,
- unsigned long flags)
+ unsigned long flags, void *context)
{
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cc5ecbc..2f58ba9 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2287,7 +2287,7 @@ static struct dma_async_tx_descriptor *
d40_prep_memcpy_sg(struct dma_chan *chan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long dma_flags)
+ unsigned long dma_flags, void *context)
{
if (dst_nents != src_nents)
return NULL;
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c
index a2d25e4..3739a12 100644
--- a/drivers/misc/carma/carma-fpga-program.c
+++ b/drivers/misc/carma/carma-fpga-program.c
@@ -530,7 +530,7 @@ static noinline int fpga_program_dma(struct fpga_dev *priv)
}
/* setup and submit the DMA transaction */
- tx = chan->device->device_prep_dma_sg(chan,
+ tx = chan->device->dmaengine_prep_dma_sg(chan,
table.sgl, num_pages,
vb->sglist, vb->sglen, 0);
if (!tx) {
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 14e974b2..be0baf6 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -638,10 +638,9 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
*/
/* setup the scatterlist to scatterlist transfer */
- tx = chan->device->device_prep_dma_sg(chan,
- dst_sg, dst_nents,
- src_sg, src_nents,
- 0);
+ tx = dmaengine_prep_dma_sg(chan, dst_sg, dst_nents,
+ src_sg, src_nents,
+ 0);
if (!tx) {
dev_err(priv->dev, "unable to prep scatterlist DMA\n");
return -ENOMEM;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 679b349..68a57da 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -570,7 +570,7 @@ struct dma_device {
struct dma_chan *chan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long flags);
+ unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
@@ -581,7 +581,7 @@ struct dma_device {
size_t period_len, enum dma_transfer_direction direction);
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
- unsigned long flags);
+ unsigned long flags, void *context);
int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
unsigned long arg);
@@ -615,6 +615,24 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
}
+static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
+ struct dma_chan *chan, struct scatterlist *dst_sg,
+ unsigned int dst_nents, struct scatterlist *src_sg,
+ unsigned int src_nents, unsigned long flags)
+{
+ return chan->device->device_prep_dma_sg(chan, dst_sg, dst_nents,
+ src_sg, src_nents, flags, NULL);
+}
+
+static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
+ struct dma_chan *chan,
+ struct dma_interleaved_template *xt,
+ unsigned long flags)
+{
+ return chan->device->device_prep_interleaved_dma(chan, xt,
+ flags, NULL);
+}
+
static inline int dmaengine_terminate_all(struct dma_chan *chan)
{
return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH v4 1/2] dmaengine: Add context parameter to prep_dma_sg and prep_interleaved_dma
From: Ravi Kumar V @ 2012-03-22 10:54 UTC (permalink / raw)
To: Vinod Koul
Cc: tsoni, Russell King, Ravi Kumar V, Srinidhi Kasagar,
Ira W. Snyder, linux-arm-msm, linux-kernel, Zhang Wei,
Bryan Huntsman, Al Viro, Barry Song, Daniel Walker, Dan Williams,
linuxppc-dev, David Brown, linux-arm-kernel
Add new context parameter to DMA SG and Interleaveid mode for passing
per transfer specific private data, using this it enables the
dma devices which needs to pass the parameters which changes per
each transfer
Change-Id: Ia9ee19f2c253e68b8e5ff254a57478dcc51014ca
Signed-off-by: Ravi Kumar V <kumarrav@codeaurora.org>
---
drivers/dma/fsldma.c | 2 +-
drivers/dma/sirf-dma.c | 2 +-
drivers/dma/ste_dma40.c | 2 +-
drivers/misc/carma/carma-fpga-program.c | 2 +-
drivers/misc/carma/carma-fpga.c | 7 +++----
include/linux/dmaengine.h | 22 ++++++++++++++++++++--
6 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index b98070c..f9f77db 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -645,7 +645,7 @@ fail:
static struct dma_async_tx_descriptor *fsl_dma_prep_sg(struct dma_chan *dchan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long flags)
+ unsigned long flags, void *context)
{
struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
struct fsldma_chan *chan = to_fsl_chan(dchan);
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 2333810..ff4d344 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -428,7 +428,7 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved(
struct dma_chan *chan, struct dma_interleaved_template *xt,
- unsigned long flags)
+ unsigned long flags, void *context)
{
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cc5ecbc..2f58ba9 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2287,7 +2287,7 @@ static struct dma_async_tx_descriptor *
d40_prep_memcpy_sg(struct dma_chan *chan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long dma_flags)
+ unsigned long dma_flags, void *context)
{
if (dst_nents != src_nents)
return NULL;
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c
index a2d25e4..3739a12 100644
--- a/drivers/misc/carma/carma-fpga-program.c
+++ b/drivers/misc/carma/carma-fpga-program.c
@@ -530,7 +530,7 @@ static noinline int fpga_program_dma(struct fpga_dev *priv)
}
/* setup and submit the DMA transaction */
- tx = chan->device->device_prep_dma_sg(chan,
+ tx = chan->device->dmaengine_prep_dma_sg(chan,
table.sgl, num_pages,
vb->sglist, vb->sglen, 0);
if (!tx) {
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 14e974b2..be0baf6 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -638,10 +638,9 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
*/
/* setup the scatterlist to scatterlist transfer */
- tx = chan->device->device_prep_dma_sg(chan,
- dst_sg, dst_nents,
- src_sg, src_nents,
- 0);
+ tx = dmaengine_prep_dma_sg(chan, dst_sg, dst_nents,
+ src_sg, src_nents,
+ 0);
if (!tx) {
dev_err(priv->dev, "unable to prep scatterlist DMA\n");
return -ENOMEM;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 679b349..68a57da 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -570,7 +570,7 @@ struct dma_device {
struct dma_chan *chan,
struct scatterlist *dst_sg, unsigned int dst_nents,
struct scatterlist *src_sg, unsigned int src_nents,
- unsigned long flags);
+ unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
@@ -581,7 +581,7 @@ struct dma_device {
size_t period_len, enum dma_transfer_direction direction);
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
- unsigned long flags);
+ unsigned long flags, void *context);
int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
unsigned long arg);
@@ -615,6 +615,24 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
}
+static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
+ struct dma_chan *chan, struct scatterlist *dst_sg,
+ unsigned int dst_nents, struct scatterlist *src_sg,
+ unsigned int src_nents, unsigned long flags)
+{
+ return chan->device->device_prep_dma_sg(chan, dst_sg, dst_nents,
+ src_sg, src_nents, flags, NULL);
+}
+
+static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
+ struct dma_chan *chan,
+ struct dma_interleaved_template *xt,
+ unsigned long flags)
+{
+ return chan->device->device_prep_interleaved_dma(chan, xt,
+ flags, NULL);
+}
+
static inline int dmaengine_terminate_all(struct dma_chan *chan)
{
return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* Re: [PATCH 05/17] pseries: Enabled the PFO-based RNG accelerator
From: Anton Blanchard @ 2012-03-22 9:55 UTC (permalink / raw)
To: Kent Yoder; +Cc: rcj, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1332365949.3858.32.camel@key-ThinkPad-W510>
Hi,
+#if defined(CONFIG_HW_RANDOM_PSERIES) || \
+ defined(CONFIG_HW_RANDOM_PSERIES_MODULE)
+#define OV5_PFO_HW_RNG 0x80 /* PFO Random Number
Generator */ +#else
+#define OV5_PFO_HW_RNG 0x00
+#endif
Milton tipped me off about this. We really don't want to be doing
ibm,client-architecture reboots every time a config option is changed.
Let's just hardwire it on.
Anton
^ permalink raw reply
* Re: [PATCH 14/17] powerpc: crypto: nx driver code supporting nx encryption
From: Benjamin Herrenschmidt @ 2012-03-22 5:39 UTC (permalink / raw)
To: Greg KH
Cc: rcj, linux-kernel, linux-crypto, Kent Yoder, linuxppc-dev,
David Miller
In-Reply-To: <20120322033957.GA16914@kroah.com>
On Wed, 2012-03-21 at 20:39 -0700, Greg KH wrote:
> On Thu, Mar 22, 2012 at 01:57:30PM +1100, Benjamin Herrenschmidt wrote:
> > +int __vio_register_driver(struct vio_driver *viodrv, struct module *owner,
> > + const char *mod_name)
> > {
> > viodrv->driver.bus = &vio_bus_type;
> > + viodrv->driver.name = viodrv->name;
> > + viodrv->driver.bus = &vio_bus_type;
> > + viodrv->driver.owner = owner;
> > + viodrv->driver.mod_name = mod_name;
>
> Any reason you set .bus twice?
Nope, just a typo. I'll fix it up, when I have feedback from Dave.
Cheers,
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox