LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc: Add VDSO version of getcpu
From: Anton Blanchard @ 2012-06-25  1:55 UTC (permalink / raw)
  To: benh, paulus; +Cc: linuxppc-dev


We had a request for a fast method of getting CPU and NUMA node IDs
from userspace. Ben suggested we use SPRG3 which is userspace
readable. This is a quick hack to try that out.

I have a glibc patch to implement sched_getcpu using this. Testing
on a POWER7:

baseline: 538 cycles 
vdso:      30 cycles

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Outstanding issues:

- Do we have any KVM issues?

- This will only work with 64 bit kernels for now, do we need to come up
  with a scheme for 32 bit?

- Implement 32 bit userspace version (running on 64 bit kernels)

Index: linux-build/arch/powerpc/include/asm/reg.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/reg.h	2012-06-25 10:05:52.193076424 +1000
+++ linux-build/arch/powerpc/include/asm/reg.h	2012-06-25 10:09:02.932316659 +1000
@@ -491,6 +491,7 @@
 #define SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
 #define SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
 #define SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
+#define SPRN_USPRG3	0x103	/* SPRG3 userspace read */
 #define SPRN_SPRG4	0x114	/* Special Purpose Register General 4 */
 #define SPRN_SPRG5	0x115	/* Special Purpose Register General 5 */
 #define SPRN_SPRG6	0x116	/* Special Purpose Register General 6 */
@@ -753,14 +754,14 @@
  * 64-bit server:
  *	- SPRG0 unused (reserved for HV on Power4)
  *	- SPRG2 scratch for exception vectors
- *	- SPRG3 unused (user visible)
+ *	- SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
  *      - HSPRG0 stores PACA in HV mode
  *      - HSPRG1 scratch for "HV" exceptions
  *
  * 64-bit embedded
  *	- SPRG0 generic exception scratch
  *	- SPRG2 TLB exception stack
- *	- SPRG3 unused (user visible)
+ *	- SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
  *	- SPRG4 unused (user visible)
  *	- SPRG6 TLB miss scratch (user visible, sorry !)
  *	- SPRG7 critical exception scratch
Index: linux-build/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso.c	2012-06-25 10:05:52.229077036 +1000
+++ linux-build/arch/powerpc/kernel/vdso.c	2012-06-25 10:12:50.256171890 +1000
@@ -706,6 +706,25 @@ static void __init vdso_setup_syscall_ma
 	}
 }
 
+#ifdef CONFIG_PPC64
+int __cpuinit vdso_getcpu_init(void)
+{
+	unsigned long cpu, node;
+
+	/*
+	 * SPRG3 contains the CPU in the bottom 32 bits and the NUMA node in the
+	 * top 32 bits.
+	 */
+	cpu = get_cpu();
+	node = cpu_to_node(cpu);
+	mtspr(SPRN_SPRG3, cpu | (node << 32));
+	put_cpu();
+
+	return 0;
+}
+/* We need to call this before SMP init */
+early_initcall(vdso_getcpu_init);
+#endif
 
 static int __init vdso_init(void)
 {
Index: linux-build/arch/powerpc/kernel/vdso64/Makefile
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/Makefile	2012-06-25 10:05:52.209076696 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/Makefile	2012-06-25 10:05:53.737102674 +1000
@@ -1,6 +1,6 @@
 # List of files in the vdso, has to be asm only for now
 
-obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
+obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
 
 # Build rules
 
Index: linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S
===================================================================
--- linux-build.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S	2012-06-25 10:05:52.217076832 +1000
+++ linux-build/arch/powerpc/kernel/vdso64/vdso64.lds.S	2012-06-25 10:05:53.737102674 +1000
@@ -146,6 +146,7 @@ VERSION
 		__kernel_sync_dicache;
 		__kernel_sync_dicache_p5;
 		__kernel_sigtramp_rt64;
+		__kernel_getcpu;
 
 	local: *;
 	};
Index: linux-build/arch/powerpc/kernel/vdso64/getcpu.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-build/arch/powerpc/kernel/vdso64/getcpu.S	2012-06-25 10:09:11.796467121 +1000
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/ppc_asm.h>
+#include <asm/vdso.h>
+
+	.text
+/*
+ * Exact prototype of getcpu
+ *
+ * int __kernel_getcpu(unsigned *cpu, unsigned *node);
+ *
+ */
+V_FUNCTION_BEGIN(__kernel_getcpu)
+  .cfi_startproc
+	mfspr	r5,SPRN_USPRG3
+	cmpdi	cr0,r3,0
+	cmpdi	cr1,r4,0
+	srdi	r6,r5,32
+	beq	cr0,1f
+	stw	r5,0(r3)
+1:	beq	cr1,2f
+	stw	r6,0(r4)
+2:	crclr	cr0*4+so
+	li	r3,0			/* always success */
+	blr
+  .cfi_endproc
+V_FUNCTION_END(__kernel_getcpu)
Index: linux-build/arch/powerpc/kernel/smp.c
===================================================================
--- linux-build.orig/arch/powerpc/kernel/smp.c	2012-06-25 10:05:52.197076492 +1000
+++ linux-build/arch/powerpc/kernel/smp.c	2012-06-25 10:13:54.897266908 +1000
@@ -48,6 +48,7 @@
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #endif
+#include <asm/vdso.h>
 #include <asm/debug.h>
 
 #ifdef DEBUG
@@ -570,6 +571,8 @@ void __devinit start_secondary(void *unu
 #ifdef CONFIG_PPC64
 	if (system_state == SYSTEM_RUNNING)
 		vdso_data->processorCount++;
+
+	vdso_getcpu_init();
 #endif
 	ipi_call_lock();
 	notify_cpu_starting(cpu);
Index: linux-build/arch/powerpc/include/asm/vdso.h
===================================================================
--- linux-build.orig/arch/powerpc/include/asm/vdso.h	2012-06-25 10:05:52.181076220 +1000
+++ linux-build/arch/powerpc/include/asm/vdso.h	2012-06-25 10:05:53.737102674 +1000
@@ -22,6 +22,8 @@ extern unsigned long vdso64_rt_sigtramp;
 extern unsigned long vdso32_sigtramp;
 extern unsigned long vdso32_rt_sigtramp;
 
+int __cpuinit vdso_getcpu_init(void);
+
 #else /* __ASSEMBLY__ */
 
 #ifdef __VDSO64__

^ permalink raw reply

* [PATCH -v4 6/6] fault-injection: add notifier error injection testing scripts
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
	Paul Mackerras, Pavel Machek, Américo Wang, linux-pm,
	linuxppc-dev
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>

This adds two testing scripts with notifier error injection

* tools/testing/fault-injection/cpu-notifier.sh is testing script for
CPU notifier error handling by using cpu-notifier-error-inject.ko.

1. Offline all hot-pluggable CPUs in preparation for testing
2. Test CPU hot-add error handling by injecting notifier errors
3. Online all hot-pluggable CPUs in preparation for testing
4. Test CPU hot-remove error handling by injecting notifier errors

* tools/testing/fault-injection/memory-notifier.sh is doing the similar
thing for memory hotplug notifier.

1. Offline 10% of hot-pluggable memory in preparation for testing
2. Test memory hot-add error handling by injecting notifier errors
3. Online all hot-pluggable memory in preparation for testing
4. Test memory hot-remove error handling by injecting notifier errors

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang <xiyou.wangcong@gmail.com>
---
* v4
- add -r option for memory-notifier.sh to specify percent of offlining
  memory blocks

 tools/testing/fault-injection/cpu-notifier.sh    |  169 +++++++++++++++++++++
 tools/testing/fault-injection/memory-notifier.sh |  176 ++++++++++++++++++++++
 2 files changed, 345 insertions(+)
 create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
 create mode 100755 tools/testing/fault-injection/memory-notifier.sh

diff --git a/tools/testing/fault-injection/cpu-notifier.sh b/tools/testing/fault-injection/cpu-notifier.sh
new file mode 100755
index 0000000..af93630
--- /dev/null
+++ b/tools/testing/fault-injection/cpu-notifier.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable CPUs
+#
+hotpluggable_cpus()
+{
+	local state=${1:-.\*}
+
+	for cpu in /sys/devices/system/cpu/cpu*; do
+		if [ -f $cpu/online ] && grep -q $state $cpu/online; then
+			echo ${cpu##/*/cpu}
+		fi
+	done
+}
+
+hotplaggable_offline_cpus()
+{
+	hotpluggable_cpus 0
+}
+
+hotpluggable_online_cpus()
+{
+	hotpluggable_cpus 1
+}
+
+cpu_is_online()
+{
+	grep -q 1 /sys/devices/system/cpu/cpu$1/online
+}
+
+cpu_is_offline()
+{
+	grep -q 0 /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu()
+{
+	echo 1 > /sys/devices/system/cpu/cpu$1/online
+}
+
+remove_cpu()
+{
+	echo 0 > /sys/devices/system/cpu/cpu$1/online
+}
+
+add_cpu_expect_success()
+{
+	local cpu=$1
+
+	if ! add_cpu $cpu; then
+		echo $FUNCNAME $cpu: unexpected fail >&2
+	elif ! cpu_is_online $cpu; then
+		echo $FUNCNAME $cpu: unexpected offline >&2
+	fi
+}
+
+add_cpu_expect_fail()
+{
+	local cpu=$1
+
+	if add_cpu $cpu 2> /dev/null; then
+		echo $FUNCNAME $cpu: unexpected success >&2
+	elif ! cpu_is_offline $cpu; then
+		echo $FUNCNAME $cpu: unexpected online >&2
+	fi
+}
+
+remove_cpu_expect_success()
+{
+	local cpu=$1
+
+	if ! remove_cpu $cpu; then
+		echo $FUNCNAME $cpu: unexpected fail >&2
+	elif ! cpu_is_offline $cpu; then
+		echo $FUNCNAME $cpu: unexpected offline >&2
+	fi
+}
+
+remove_cpu_expect_fail()
+{
+	local cpu=$1
+
+	if remove_cpu $cpu 2> /dev/null; then
+		echo $FUNCNAME $cpu: unexpected success >&2
+	elif ! cpu_is_online $cpu; then
+		echo $FUNCNAME $cpu: unexpected offline >&2
+	fi
+}
+
+if [ $UID != 0 ]; then
+	echo must be run as root >&2
+	exit 1
+fi
+
+error=-12
+priority=0
+
+while getopts e:hp: opt; do
+	case $opt in
+	e)
+		error=$OPTARG
+		;;
+	h)
+		echo "Usage $0 [ -e errno ] [ -p notifier-priority ]"
+		exit
+		;;
+	p)
+		priority=$OPTARG
+		;;
+	esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+	echo "error code must be -4095 <= errno < 0" >&2
+	exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+	echo debugfs is not mounted >&2
+	exit 1
+fi
+
+/sbin/modprobe -r cpu-notifier-error-inject
+/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+
+NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
+
+if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+	echo cpu-notifier-error-inject module is not available >&2
+	exit 1
+fi
+
+#
+# Offline all hot-pluggable CPUs
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+for cpu in `hotpluggable_online_cpus`; do
+	remove_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-add error handling (offline => online)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+for cpu in `hotplaggable_offline_cpus`; do
+	add_cpu_expect_fail $cpu
+done
+
+#
+# Online all hot-pluggable CPUs
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+for cpu in `hotplaggable_offline_cpus`; do
+	add_cpu_expect_success $cpu
+done
+
+#
+# Test CPU hot-remove error handling (online => offline)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+for cpu in `hotpluggable_online_cpus`; do
+	remove_cpu_expect_fail $cpu
+done
+
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+/sbin/modprobe -r cpu-notifier-error-inject
diff --git a/tools/testing/fault-injection/memory-notifier.sh b/tools/testing/fault-injection/memory-notifier.sh
new file mode 100755
index 0000000..843cba7
--- /dev/null
+++ b/tools/testing/fault-injection/memory-notifier.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+#
+# list all hot-pluggable memory
+#
+hotpluggable_memory()
+{
+	local state=${1:-.\*}
+
+	for memory in /sys/devices/system/memory/memory*; do
+		if grep -q 1 $memory/removable &&
+		   grep -q $state $memory/state; then
+			echo ${memory##/*/memory}
+		fi
+	done
+}
+
+hotplaggable_offline_memory()
+{
+	hotpluggable_memory offline
+}
+
+hotpluggable_online_memory()
+{
+	hotpluggable_memory online
+}
+
+memory_is_online()
+{
+	grep -q online /sys/devices/system/memory/memory$1/state
+}
+
+memory_is_offline()
+{
+	grep -q offline /sys/devices/system/memory/memory$1/state
+}
+
+add_memory()
+{
+	echo online > /sys/devices/system/memory/memory$1/state
+}
+
+remove_memory()
+{
+	echo offline > /sys/devices/system/memory/memory$1/state
+}
+
+add_memory_expect_success()
+{
+	local memory=$1
+
+	if ! add_memory $memory; then
+		echo $FUNCNAME $memory: unexpected fail >&2
+	elif ! memory_is_online $memory; then
+		echo $FUNCNAME $memory: unexpected offline >&2
+	fi
+}
+
+add_memory_expect_fail()
+{
+	local memory=$1
+
+	if add_memory $memory 2> /dev/null; then
+		echo $FUNCNAME $memory: unexpected success >&2
+	elif ! memory_is_offline $memory; then
+		echo $FUNCNAME $memory: unexpected online >&2
+	fi
+}
+
+remove_memory_expect_success()
+{
+	local memory=$1
+
+	if ! remove_memory $memory; then
+		echo $FUNCNAME $memory: unexpected fail >&2
+	elif ! memory_is_offline $memory; then
+		echo $FUNCNAME $memory: unexpected offline >&2
+	fi
+}
+
+remove_memory_expect_fail()
+{
+	local memory=$1
+
+	if remove_memory $memory 2> /dev/null; then
+		echo $FUNCNAME $memory: unexpected success >&2
+	elif ! memory_is_online $memory; then
+		echo $FUNCNAME $memory: unexpected offline >&2
+	fi
+}
+
+if [ $UID != 0 ]; then
+	echo must be run as root >&2
+	exit 1
+fi
+
+error=-12
+priority=0
+ratio=10
+
+while getopts e:hp:r: opt; do
+	case $opt in
+	e)
+		error=$OPTARG
+		;;
+	h)
+		echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
+		exit
+		;;
+	p)
+		priority=$OPTARG
+		;;
+	r)
+		ratio=$OPTARG
+		;;
+	esac
+done
+
+if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+	echo "error code must be -4095 <= errno < 0" >&2
+	exit 1
+fi
+
+DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+
+if [ ! -d "$DEBUGFS" ]; then
+	echo debugfs is not mounted >&2
+	exit 1
+fi
+
+/sbin/modprobe -r memory-notifier-error-inject
+/sbin/modprobe -q memory-notifier-error-inject priority=$priority
+
+NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory
+
+if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+	echo memory-notifier-error-inject module is not available >&2
+	exit 1
+fi
+
+#
+# Offline $ratio percent of hot-pluggable memory
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+for memory in `hotpluggable_online_memory`; do
+	if [ $((RANDOM % 100)) -lt $ratio ]; then
+		remove_memory_expect_success $memory
+	fi
+done
+
+#
+# Test memory hot-add error handling (offline => online)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
+for memory in `hotplaggable_offline_memory`; do
+	add_memory_expect_fail $memory
+done
+
+#
+# Online all hot-pluggable memory
+#
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
+for memory in `hotplaggable_offline_memory`; do
+	add_memory_expect_success $memory
+done
+
+#
+# Test memory hot-remove error handling (online => offline)
+#
+echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+for memory in `hotpluggable_online_memory`; do
+	remove_memory_expect_fail $memory
+done
+
+echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
+/sbin/modprobe -r memory-notifier-error-inject
-- 
1.7.10.2

^ permalink raw reply related

* [PATCH -v4 5/6] powerpc: pSeries reconfig notifier error injection module
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
  To: linux-kernel, akpm; +Cc: linuxppc-dev, Paul Mackerras, Akinobu Mita
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>

This provides the ability to inject artifical errors to pSeries reconfig
notifier chain callbacks.  It is controlled through debugfs interface
under /sys/kernel/debug/notifier-error-inject/pSeries-reconfig

If the notifier call chain should be failed with some events
notified, write the error code to "actions/<notifier event>/error".

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
* v4
- update modules to follow new interface

 lib/Kconfig.debug                            |   17 +++++++++
 lib/Makefile                                 |    2 +
 lib/pSeries-reconfig-notifier-error-inject.c |   51 ++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7cceddc..8f8e226 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1166,6 +1166,23 @@ config MEMORY_NOTIFIER_ERROR_INJECT
 
 	  If unsure, say N.
 
+config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
+	tristate "pSeries reconfig notifier error injection module"
+	depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+	help
+	  This option provides the ability to inject artifical errors to
+	  pSeries reconfig notifier chain callbacks.  It is controlled
+	  through debugfs interface under
+	  /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/
+
+	  If the notifier call chain should be failed with some events
+	  notified, write the error code to "actions/<notifier event>/error".
+
+	  To compile this code as a module, choose M here: the module will
+	  be called memory-notifier-error-inject.
+
+	  If unsure, say N.
+
 config FAULT_INJECTION
 	bool "Fault-injection framework"
 	depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index a867aa5..d055cb1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o
 obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o
+obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \
+	pSeries-reconfig-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
 
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c b/lib/pSeries-reconfig-notifier-error-inject.c
new file mode 100644
index 0000000..7f7c98d
--- /dev/null
+++ b/lib/pSeries-reconfig-notifier-error-inject.c
@@ -0,0 +1,51 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/pSeries_reconfig.h>
+
+#include "notifier-error-inject.h"
+
+static int priority;
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
+
+static struct notifier_err_inject reconfig_err_inject = {
+	.actions = {
+		{ NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) },
+		{ NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) },
+		{ NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) },
+		{ NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) },
+		{}
+	}
+};
+
+static struct dentry *dir;
+
+static int err_inject_init(void)
+{
+	int err;
+
+	dir = notifier_err_inject_init("pSeries-reconfig",
+		notifier_err_inject_dir, &reconfig_err_inject, priority);
+	if (IS_ERR(dir))
+		return PTR_ERR(dir);
+
+	err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb);
+	if (err)
+		debugfs_remove_recursive(dir);
+
+	return err;
+}
+
+static void err_inject_exit(void)
+{
+	pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb);
+	debugfs_remove_recursive(dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("pSeries reconfig notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
-- 
1.7.10.2

^ permalink raw reply related

* [PATCH -v4 1/6] fault-injection: notifier error injection
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
	Paul Mackerras, Pavel Machek, linux-pm, linuxppc-dev
In-Reply-To: <1340463502-15341-1-git-send-email-akinobu.mita@gmail.com>

The notifier error injection provides the ability to inject artifical
errors to specified notifier chain callbacks.  It is useful to test the
error handling of notifier call chain failures.

This adds common basic functions to define which type of events can be
fail and to initialize the debugfs interface to control what error code
should be returned and which event should be failed.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <michael@ellerman.id.au>
---
* v4
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
  (e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
        $DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)

 lib/Kconfig.debug           |   11 +++++
 lib/Makefile                |    1 +
 lib/notifier-error-inject.c |  112 +++++++++++++++++++++++++++++++++++++++++++
 lib/notifier-error-inject.h |   24 ++++++++++
 4 files changed, 148 insertions(+)
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ff5bdee..c848758 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1084,6 +1084,17 @@ config LKDTM
 	Documentation on how to use the module can be found in
 	Documentation/fault-injection/provoke-crashes.txt
 
+config NOTIFIER_ERROR_INJECTION
+	tristate "Notifier error injection"
+	depends on DEBUG_KERNEL
+	select DEBUG_FS
+	help
+	  This option provides the ability to inject artifical errors to
+	  specified notifier chain callbacks. It is useful to test the error
+	  handling of notifier call chain failures.
+
+	  Say N if unsure.
+
 config CPU_NOTIFIER_ERROR_INJECT
 	tristate "CPU notifier error injection module"
 	depends on HOTPLUG_CPU && DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 8c31a0c..23fba9e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
 obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
+obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o
 obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o
 
 lib-$(CONFIG_GENERIC_BUG) += bug.o
diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
new file mode 100644
index 0000000..44b92cb
--- /dev/null
+++ b/lib/notifier-error-inject.c
@@ -0,0 +1,112 @@
+#include <linux/module.h>
+
+#include "notifier-error-inject.h"
+
+static int debugfs_errno_set(void *data, u64 val)
+{
+	*(int *)data = clamp_t(int, val, -MAX_ERRNO, 0);
+	return 0;
+}
+
+static int debugfs_errno_get(void *data, u64 *val)
+{
+	*val = *(int *)data;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
+			"%lld\n");
+
+static struct dentry *debugfs_create_errno(const char *name, mode_t mode,
+				struct dentry *parent, int *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_errno);
+}
+
+static int notifier_err_inject_callback(struct notifier_block *nb,
+				unsigned long val, void *p)
+{
+	int err = 0;
+	struct notifier_err_inject *err_inject =
+		container_of(nb, struct notifier_err_inject, nb);
+	struct notifier_err_inject_action *action;
+
+	for (action = err_inject->actions; action->name; action++) {
+		if (action->val == val) {
+			err = action->error;
+			break;
+		}
+	}
+	if (err)
+		pr_info("Injecting error (%d) to %s\n", err, action->name);
+
+	return notifier_from_errno(err);
+}
+
+struct dentry *notifier_err_inject_dir;
+EXPORT_SYMBOL_GPL(notifier_err_inject_dir);
+
+struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent,
+			struct notifier_err_inject *err_inject, int priority)
+{
+	struct notifier_err_inject_action *action;
+	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+	struct dentry *dir;
+	struct dentry *actions_dir;
+
+	err_inject->nb.notifier_call = notifier_err_inject_callback;
+	err_inject->nb.priority = priority;
+
+	dir = debugfs_create_dir(name, parent);
+	if (!dir)
+		return ERR_PTR(-ENOMEM);
+
+	actions_dir = debugfs_create_dir("actions", dir);
+	if (!actions_dir)
+		goto fail;
+
+	for (action = err_inject->actions; action->name; action++) {
+		struct dentry *action_dir;
+
+		action_dir = debugfs_create_dir(action->name, actions_dir);
+		if (!action_dir)
+			goto fail;
+
+		/*
+		 * Create debugfs r/w file containing action->error. If
+		 * notifier call chain is called with action->val, it will
+		 * fail with the error code
+		 */
+		if (!debugfs_create_errno("error", mode, action_dir,
+					&action->error))
+			goto fail;
+	}
+	return dir;
+fail:
+	debugfs_remove_recursive(dir);
+	return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL_GPL(notifier_err_inject_init);
+
+static int __init err_inject_init(void)
+{
+	notifier_err_inject_dir =
+		debugfs_create_dir("notifier-error-inject", NULL);
+
+	if (!notifier_err_inject_dir)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void __exit err_inject_exit(void)
+{
+	debugfs_remove_recursive(notifier_err_inject_dir);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_DESCRIPTION("Notifier error injection module");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
diff --git a/lib/notifier-error-inject.h b/lib/notifier-error-inject.h
new file mode 100644
index 0000000..99b3b6f
--- /dev/null
+++ b/lib/notifier-error-inject.h
@@ -0,0 +1,24 @@
+#include <linux/atomic.h>
+#include <linux/debugfs.h>
+#include <linux/notifier.h>
+
+struct notifier_err_inject_action {
+	unsigned long val;
+	int error;
+	const char *name;
+};
+
+#define NOTIFIER_ERR_INJECT_ACTION(action)	\
+	.name = #action, .val = (action),
+
+struct notifier_err_inject {
+	struct notifier_block nb;
+	struct notifier_err_inject_action actions[];
+	/* The last slot must be terminated with zero sentinel */
+};
+
+extern struct dentry *notifier_err_inject_dir;
+
+extern struct dentry *notifier_err_inject_init(const char *name,
+		struct dentry *parent, struct notifier_err_inject *err_inject,
+		int priority);
-- 
1.7.10.2

^ permalink raw reply related

* [PATCH -v4 0/6] notifier error injection
From: Akinobu Mita @ 2012-06-23 14:58 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Greg KH, Akinobu Mita, Rafael J. Wysocki, linux-mm,
	Paul Mackerras, Pavel Machek, Américo Wang, linux-pm,
	linuxppc-dev

This provides kernel modules that can be used to test the error handling
of notifier call chain failures by injecting artifical errors to the
following notifier chain callbacks.

 * CPU notifier
 * PM notifier
 * memory hotplug notifier
 * powerpc pSeries reconfig notifier

Example: Inject CPU offline error (-1 == -EPERM)

	# cd /sys/kernel/debug/notifier-error-inject/cpu
	# echo -1 > actions/CPU_DOWN_PREPARE/error
	# echo 0 > /sys/devices/system/cpu/cpu1/online
	bash: echo: write error: Operation not permitted

There are also handy shell scripts to test CPU and memory hotplug notifier.
Note that these tests didn't detect error handling bugs on my machine but
I still think this feature is usefull to test the code path which is rarely
executed.

Changelog:

* v4 (It is about 11 months since v3)
- prefix all APIs with notifier_err_inject_*
- rearrange debugfs interface
  (e.g. $DEBUGFS/cpu-notifier-error-inject/CPU_DOWN_PREPARE -->
        $DEBUGFS/notifier-error-inject/cpu/actions/CPU_DOWN_PREPARE/error)
- update modules to follow new interface
- add -r option for memory-notifier.sh to specify percent of offlining
  memory blocks

* v3
- rewrite to be kernel modules instead of initializing at late_initcall()s
  (it makes the diffstat look different but most code remains unchanged)
- export err_inject_notifier_block_{init,cleanup} for modules
- export pSeries_reconfig_notifier_{,un}register symbols for a module
- notifier priority can be specified as a module parameter
- add testing scripts in tools/testing/fault-injection

* v2
- "PM: Improve error code of pm_notifier_call_chain()" is now in -next
- "debugfs: add debugfs_create_int" is dropped
- put a comment in err_inject_notifier_block_init()
- only allow valid errno to be injected (-MAX_ERRNO <= errno <= 0)
- improve Kconfig help text
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION visible even if PM_DEBUG is disabled
- make CONFIG_PM_NOTIFIER_ERROR_INJECTION default if PM_DEBUG is enabled

Akinobu Mita (6):
  fault-injection: notifier error injection
  cpu: rewrite cpu-notifier-error-inject module
  PM: PM notifier error injection module
  memory: memory notifier error injection module
  powerpc: pSeries reconfig notifier error injection module
  fault-injection: add notifier error injection testing scripts

 lib/Kconfig.debug                                |   91 ++++++++++-
 lib/Makefile                                     |    5 +
 lib/cpu-notifier-error-inject.c                  |   63 +++-----
 lib/memory-notifier-error-inject.c               |   48 ++++++
 lib/notifier-error-inject.c                      |  112 ++++++++++++++
 lib/notifier-error-inject.h                      |   24 +++
 lib/pSeries-reconfig-notifier-error-inject.c     |   51 +++++++
 lib/pm-notifier-error-inject.c                   |   49 ++++++
 tools/testing/fault-injection/cpu-notifier.sh    |  169 +++++++++++++++++++++
 tools/testing/fault-injection/memory-notifier.sh |  176 ++++++++++++++++++++++
 10 files changed, 748 insertions(+), 40 deletions(-)
 create mode 100644 lib/memory-notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.c
 create mode 100644 lib/notifier-error-inject.h
 create mode 100644 lib/pSeries-reconfig-notifier-error-inject.c
 create mode 100644 lib/pm-notifier-error-inject.c
 create mode 100755 tools/testing/fault-injection/cpu-notifier.sh
 create mode 100755 tools/testing/fault-injection/memory-notifier.sh

Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
Cc: Greg KH <greg@kroah.com>
Cc: linux-mm@kvack.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Américo Wang <xiyou.wangcong@gmail.com>
Cc: Michael Ellerman <michael@ellerman.id.au>

-- 
1.7.10.2

^ permalink raw reply

* [PATCH 03/12] powerpc: remove km_type definitions
From: Cong Wang @ 2012-06-23 10:04 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, linuxppc-dev, Paul Mackerras, Cong Wang
In-Reply-To: <1340445863-16111-1-git-send-email-amwang@redhat.com>

Signed-off-by: Cong Wang <amwang@redhat.com>
---
 arch/powerpc/include/asm/kmap_types.h |   31 +------------------------------
 1 files changed, 1 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h
index bca8fdc..5acabbd 100644
--- a/arch/powerpc/include/asm/kmap_types.h
+++ b/arch/powerpc/include/asm/kmap_types.h
@@ -10,36 +10,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BIO_SRC_IRQ,
-	KM_BIO_DST_IRQ,
-	KM_PTE0,
-	KM_PTE1,
-	KM_IRQ0,
-	KM_IRQ1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_PPC_SYNC_PAGE,
-	KM_PPC_SYNC_ICACHE,
-	KM_KDB,
-	KM_TYPE_NR
-};
-
-/*
- * This is a temporary build fix that (so they say on lkml....) should no longer
- * be required after 2.6.33, because of changes planned to the kmap code.
- * Let's try to remove this cruft then.
- */
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define KM_NMI		(-1)
-#define KM_NMI_PTE	(-1)
-#define KM_IRQ_PTE	(-1)
-#endif
+#define KM_TYPE_NR 16
 
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_KMAP_TYPES_H */
-- 
1.7.7.6

^ permalink raw reply related

* Help with Freescale QE ATM driver (FUA)
From: Bill F @ 2012-06-22 19:14 UTC (permalink / raw)
  To: linuxppc-dev

Hi,
Have you used the Freescale QUICC Engine (QE) ATM mode with a Linux
based product ?

I am currently using the "fua" driver obtained from Freescale
MPC8360E_PB_K26_20081112-LTIB.iso CDROM image.  The "fua" driver was
written for kernel 2.6.22 (2007) and I have ported it forward to
kernel 3.3 (2012).  My board has an MPC8358 and SUNI PHY.  I am
testing the fua driver with the atm-tools and aburst, and using a
loopback cable.

The ported fua driver is able to open an ATM connection and send and
receive messages.  I can use awrite and aread to send and receive
ascii characters.

Problems:
  * If I open three or more ATM connections, all ATM transfers stop,
and the ethernet driver (ucc_geth) also stops working.  To recover I
have to reboot. Urg.
  * UBR transfers seem to be treated as if they are a 100 Mbps CBR
connection.  I was expecting UBR to fill all of the unused bandwidth.
  * I'm finding and fixing a lot of minor bugs that crash the driver.

My other reference is the mpc8360 SAR driver
(http://mpc8360sar.sourceforge.net) which is even older (patches
against kernel 2.6.11).

If someone on this list is sitting on an updated fua driver or similar
QE ATM driver, could you send me the code.  Better yet, can I help you
push it out to a github or similar repo ?

Thanks,
Bill

^ permalink raw reply

* Re: [PATCH] MIPS: fix bug.h MIPS build regression
From: David Daney @ 2012-06-22 17:54 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: Linux MIPS Mailing List, Linux-sh list, linux-kernel,
	Linuxppc-dev, Paul Mundt, Geert Uytterhoeven, Chris Zankel,
	Yoichi Yuasa
In-Reply-To: <20120620161249.GB29196@linux-mips.org>

On 06/20/2012 09:12 AM, Ralf Baechle wrote:
> On Wed, Jun 20, 2012 at 03:27:59PM +0900, Yoichi Yuasa wrote:
>
>> Commit: 3777808873b0c49c5cf27e44c948dfb02675d578 breaks all MIPS builds.
>
> Thanks, fix applied.
>

Where was it applied?

It doesn't show up in linux-next for 20120622, which is where it is needed.

David Daney

^ permalink raw reply

* Re: [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: matt @ 2012-06-22  9:01 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, amodra
In-Reply-To: <1340337027-22110-1-git-send-email-michael@ellerman.id.au>

Whee!  Let's try that again with MUA configured better...

On 2012-06-22 04:50, Michael Ellerman wrote:
> If the kernel is big enough (eg. allyesconfig), the linker may need 
> to
> switch TOCs when calling from the BPF JIT code out to the external
> helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).
>
> In order to do that we need to leave space after the bl for the 
> linker
> to insert a reload of our TOC pointer.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

Oops, x2, and

Acked-by: Matt Evans <matt@ozlabs.org>

:-)


> ---
>  arch/powerpc/net/bpf_jit_64.S |    2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/net/bpf_jit_64.S 
> b/arch/powerpc/net/bpf_jit_64.S
> index 55ba385..7d3a3b5 100644
> --- a/arch/powerpc/net/bpf_jit_64.S
> +++ b/arch/powerpc/net/bpf_jit_64.S
> @@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
>  	mr	r4, r_addr;					\
>  	li	r6, SIZE;					\
>  	bl	skb_copy_bits;					\
> +	nop;							\
>  	/* R3 = 0 on success */					\
>  	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
>  	ld	r0, 16(r1);					\
> @@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
>  	mr	r4, r_addr;					\
>  	li	r5, SIZE;					\
>  	bl	bpf_internal_load_pointer_neg_helper;		\
> +	nop;							\
>  	/* R3 != 0 on success */				\
>  	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
>  	ld	r0, 16(r1);					\

^ permalink raw reply

* Re: [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: matt @ 2012-06-22  8:58 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, matt, amodra
In-Reply-To: <1340337027-22110-1-git-send-email-michael@ellerman.id.au>

On 2012-06-22 04:50, Michael Ellerman wrote:
> If the kernel is big enough (eg. allyesconfig), the linker may need 
> to
> switch TOCs when calling from the BPF JIT code out to the external
> helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).
>
> In order to do that we need to leave space after the bl for the 
> linker
> to insert a reload of our TOC pointer.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

Oops..!

Acked-by: Matt Evans <matt@ozlabs.org>


> ---
>  arch/powerpc/net/bpf_jit_64.S |    2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/net/bpf_jit_64.S 
> b/arch/powerpc/net/bpf_jit_64.S
> index 55ba385..7d3a3b5 100644
> --- a/arch/powerpc/net/bpf_jit_64.S
> +++ b/arch/powerpc/net/bpf_jit_64.S
> @@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
>  	mr	r4, r_addr;					\
>  	li	r6, SIZE;					\
>  	bl	skb_copy_bits;					\
> +	nop;							\
>  	/* R3 = 0 on success */					\
>  	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
>  	ld	r0, 16(r1);					\
> @@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
>  	mr	r4, r_addr;					\
>  	li	r5, SIZE;					\
>  	bl	bpf_internal_load_pointer_neg_helper;		\
> +	nop;							\
>  	/* R3 != 0 on success */				\
>  	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
>  	ld	r0, 16(r1);					\

^ permalink raw reply

* [PATCH] powerpc: Turn on BPF_JIT in ppc64_defconfig
From: Michael Ellerman @ 2012-06-22  3:52 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: matt, amodra

Matt added BPF_JIT support in commit 0ca87f05, but currently none of our
defconfigs build it. Turn that sucker on.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/configs/ppc64_defconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index c1442a3..a637ee7 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -489,3 +489,4 @@ CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
 CONFIG_VHOST_NET=m
+CONFIG_BPF_JIT=y
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH] powerpc: Fix BPF_JIT code to link with multiple TOCs
From: Michael Ellerman @ 2012-06-22  3:50 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: matt, amodra

If the kernel is big enough (eg. allyesconfig), the linker may need to
switch TOCs when calling from the BPF JIT code out to the external
helpers (skb_copy_bits() & bpf_internal_load_pointer_neg_helper()).

In order to do that we need to leave space after the bl for the linker
to insert a reload of our TOC pointer.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/net/bpf_jit_64.S |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
index 55ba385..7d3a3b5 100644
--- a/arch/powerpc/net/bpf_jit_64.S
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -105,6 +105,7 @@ sk_load_byte_msh_positive_offset:
 	mr	r4, r_addr;					\
 	li	r6, SIZE;					\
 	bl	skb_copy_bits;					\
+	nop;							\
 	/* R3 = 0 on success */					\
 	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
 	ld	r0, 16(r1);					\
@@ -156,6 +157,7 @@ bpf_slow_path_byte_msh:
 	mr	r4, r_addr;					\
 	li	r5, SIZE;					\
 	bl	bpf_internal_load_pointer_neg_helper;		\
+	nop;							\
 	/* R3 != 0 on success */				\
 	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
 	ld	r0, 16(r1);					\
-- 
1.7.9.5

^ permalink raw reply related

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-22  0:39 UTC (permalink / raw)
  To: Alan Modra; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <20120621114354.GG20973@bubble.grove.modra.org>

On Thu, 2012-06-21 at 21:13 +0930, Alan Modra wrote:
> On Thu, Jun 21, 2012 at 08:18:39PM +0930, Alan Modra wrote:
> > Linker bug.  That's not a sibling call, but a normal function return
> > via an out-of-line register restore function.
> 
> I couldn't see how this might be occurring, then I remembered the
> kernel has this horrible practise of using ld -r to package object
> files.  So linker generated functions might be munged together with
> other functions.  Does this help?  (It won't if the kernel is
> providing its own save/restore functions.)

The kernel does provide its own AIUI.

cheers

^ permalink raw reply

* Re: [PATCH] kernel panic during kernel module load (powerpc specific part)
From: roger blofeld @ 2012-06-21 15:27 UTC (permalink / raw)
  To: ext Benjamin Herrenschmidt, paulus, Steffen Rumler
  Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4FCF6B1D.50009@nsn.com>

--- On Wed, 6/6/12, Steffen Rumler <steffen.rumler.ext@nsn.com> wrote:=0A=
=0A> From: Steffen Rumler <steffen.rumler.ext@nsn.com>=0A> Subject: [PATCH]=
 kernel panic during kernel module load (powerpc specific part)=0A> To: "ex=
t Benjamin Herrenschmidt" <benh@kernel.crashing.org>, paulus@samba.org=0A> =
Cc: "Wrobel Heinz-R39252" <r39252@freescale.com>, "Michael Ellerman" <micha=
el@ellerman.id.au>, "linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozl=
abs.org>=0A> Date: Wednesday, June 6, 2012, 7:37 AM=0A> Hi,=0A> =0A> The pa=
tch below is intended to fix the following problem.=0A> =0A> According to t=
he PowerPC EABI specification, the GPR r11 is=0A> assigned=0A> the dedicate=
d function to point to the previous stack=0A> frame.=0A> In the powerpc-spe=
cific kernel module loader, do_plt_call()=0A> (in arch/powerpc/kernel/modul=
e_32.c), the GPR r11 is also=0A> used=0A> to generate trampoline code.=0A> =
=0A> This combination crashes the kernel, in the following case:=0A> =0A> =
=A0 + The compiler has been generated the prologue and=0A> epilogue,=0A> =
=A0 =A0 which is part of the .text section.=0A> =A0 + The compiler has been=
 generated the code for the=0A> module init entry point,=0A> =A0 =A0 part o=
f the .init.text section (in the case it=0A> is marked with __init).=0A> =
=A0 + By returning from the module init entry point, the=0A> epilogue is ca=
lled by doing=0A> =A0 =A0 a branch instruction.=0A> =A0 + If the epilogue i=
s too far away, a relative branch=0A> instruction cannot be applied.=0A> =
=A0 =A0 Instead trampoline code is generated in=0A> do_plt_call(), in order=
 to jump via register.=0A> =A0 =A0 Unfortunately the code generated by=0A> =
do_plt_call() destroys the content of GPR r11.=0A> =A0 + Because GPR r11 do=
es not more keep the right stack=0A> frame pointer,=0A> =A0 =A0 the kernel =
crashes right after the epilogue.=0A> =0A> The fix just uses GPR r12 instea=
d of GPR r11 for generating=0A> the trampoline code.=0A> According to the s=
tatements from Freescale, this is also=0A> save from EABI perspective.=0A> =
=0A> I've tested the fix for kernel 2.6.33 on MPC8541.=0A> =0A> Signed-off-=
by: Steffen Rumler <steffen.rumler.ext@nsn.com>=0A> ---=0A> =0A> --- orig/a=
rch/powerpc/kernel/module_32.c=A0=A0=A0=0A> 2012-06-06 16:04:28.956446788 +=
0200=0A> +++ new/arch/powerpc/kernel/module_32.c=A0=A0=A0=0A> =A0=A0=A0 201=
2-06-06 16:04:17.746290683 +0200=0A> @@ -187,8 +187,8 @@=0A> =0A>  static i=
nline int entry_matches(struct ppc_plt_entry=0A> *entry, Elf32_Addr val)=0A=
>  {=0A> -=A0=A0=A0 if (entry->jump[0] =3D=3D 0x3d600000 +=0A> ((val + 0x80=
00) >> 16)=0A> -=A0=A0=A0 =A0 =A0 &&=0A> entry->jump[1] =3D=3D 0x396b0000 +=
 (val & 0xffff))=0A> +=A0=A0=A0 if (entry->jump[0] =3D=3D 0x3d800000 +=0A> =
((val + 0x8000) >> 16)=0A> +=A0=A0=A0 =A0 =A0 &&=0A> entry->jump[1] =3D=3D =
0x398c0000 + (val & 0xffff))=0A>  =A0=A0=A0 =A0=A0=A0 return 1;=0A>  =A0=A0=
=A0 return 0;=0A>  }=0A> @@ -215,10 +215,9 @@=0A>  =A0=A0=A0 =A0=A0=A0 entr=
y++;=0A>  =A0=A0=A0 }=0A> =0A> -=A0=A0=A0 /* Stolen from Paul Mackerras as =
well...=0A> */=0A> -=A0=A0=A0 entry->jump[0] =3D=0A> 0x3d600000+((val+0x800=
0)>>16);=A0=A0=A0 /*=0A> lis r11,sym@ha */=0A> -=A0=A0=A0 entry->jump[1] =
=3D 0x396b0000 +=0A> (val&0xffff);=A0=A0=A0 /* addi r11,r11,sym@l*/=0A> -=
=A0=A0=A0 entry->jump[2] =3D=0A> 0x7d6903a6;=A0=A0=A0 =A0=A0=A0=0A> =A0=A0=
=A0 /* mtctr r11 */=0A> +=A0=A0=A0 entry->jump[0] =3D=0A> 0x3d800000+((val+=
0x8000)>>16); /* lis r12,sym@ha */=0A> +=A0=A0=A0 entry->jump[1] =3D 0x398c=
0000 +=0A> (val&0xffff);=A0 =A0=A0=A0/* addi=0A> r12,r12,sym@l*/=0A> +=A0=
=A0=A0 entry->jump[2] =3D 0x7d8903a6;=A0=0A> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0=0A> =A0 /* mtctr r12 */=0A>  =A0=A0=A0 entry->jump[3] =3D=0A> 0x4e80042=
0;=A0=A0=A0 =A0=A0=A0=0A> =A0=A0=A0 /* bctr */=0A> =0A>  =A0=A0=A0 DEBUGP("=
Initialized plt for 0x%x at=0A> %p\n", val, entry);=0A> ___________________=
____________________________=0A> Linuxppc-dev mailing list=0A> Linuxppc-dev=
@lists.ozlabs.org=0A> https://lists.ozlabs.org/listinfo/linuxppc-dev=0A> =
=0A=0AHi,=0A=0AShouldn't the corresponding ftrace code be updated to match?=
 Perhaps like the following (untested) patch:=0A=0ASigned-off-by: Roger Blo=
feld <blofeldus@yahoo.com>=0A---=0A=0A--- a/arch/powerpc/kernel/ftrace.c=0A=
+++ b/arch/powerpc/kernel/ftrace.c=0A@@ -245,9 +245,9 @@ __ftrace_make_nop(=
struct module *mod,=0A =0A =09/*=0A =09 * On PPC32 the trampoline looks lik=
e:=0A-=09 *  0x3d, 0x60, 0x00, 0x00  lis r11,sym@ha=0A-=09 *  0x39, 0x6b, 0=
x00, 0x00  addi r11,r11,sym@l=0A-=09 *  0x7d, 0x69, 0x03, 0xa6  mtctr r11=
=0A+=09 *  0x3d, 0x80, 0x00, 0x00  lis r12,sym@ha=0A+=09 *  0x39, 0x8c, 0x0=
0, 0x00  addi r12,r12,sym@l=0A+=09 *  0x7d, 0x89, 0x03, 0xa6  mtctr r12=0A =
=09 *  0x4e, 0x80, 0x04, 0x20  bctr=0A =09 */=0A =0A@@ -262,9 +262,9 @@ __f=
trace_make_nop(struct module *mod,=0A =09pr_devel(" %08x %08x ", jmp[0], jm=
p[1]);=0A =0A =09/* verify that this is what we expect it to be */=0A-=09if=
 (((jmp[0] & 0xffff0000) !=3D 0x3d600000) ||=0A-=09    ((jmp[1] & 0xffff000=
0) !=3D 0x396b0000) ||=0A-=09    (jmp[2] !=3D 0x7d6903a6) ||=0A+=09if (((jm=
p[0] & 0xffff0000) !=3D 0x3d800000) ||=0A+=09    ((jmp[1] & 0xffff0000) !=
=3D 0x398c0000) ||=0A+=09    (jmp[2] !=3D 0x7d8903a6) ||=0A =09    (jmp[3] =
!=3D 0x4e800420)) {=0A =09=09printk(KERN_ERR "Not a trampoline\n");=0A =09=
=09return -EINVAL;=0A

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Alan Modra @ 2012-06-21 11:43 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <20120621104839.GE20973@bubble.grove.modra.org>

On Thu, Jun 21, 2012 at 08:18:39PM +0930, Alan Modra wrote:
> Linker bug.  That's not a sibling call, but a normal function return
> via an out-of-line register restore function.

I couldn't see how this might be occurring, then I remembered the
kernel has this horrible practise of using ld -r to package object
files.  So linker generated functions might be munged together with
other functions.  Does this help?  (It won't if the kernel is
providing its own save/restore functions.)

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.387
diff -u -p -r1.387 elf64-ppc.c
@@ -6494,9 +6494,10 @@ ppc64_elf_func_desc_adjust (bfd *obfd AT
 
   /* Provide any missing _save* and _rest* functions.  */
   htab->sfpr->size = 0;
-  for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
-    if (!sfpr_define (info, &funcs[i]))
-      return FALSE;
+  if (!info->relocatable)
+    for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
+      if (!sfpr_define (info, &funcs[i]))
+	return FALSE;
 
   elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
 


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Alan Modra @ 2012-06-21 10:48 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linux-next, ppc-dev, linux-kernel, Stephen Rothwell
In-Reply-To: <1340264307.1998.20.camel@concordia>

On Thu, Jun 21, 2012 at 05:38:27PM +1000, Michael Ellerman wrote:
> On Thu, 2012-06-21 at 17:07 +1000, Michael Ellerman wrote:
> > On Thu, 2012-06-21 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> > > On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> > > > 
> > > > powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990): 
> > > >         sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
> > > >         recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern
> > > > 

Linker bug.  That's not a sibling call, but a normal function return
via an out-of-line register restore function.  Will fix.  I'm a bit
surprised to see this with gcc-4.6 though.  Or does this gcc-4.6 have
some of my recent mainline gcc patches enabling out-of-line
save/restore functions for -Os?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-21  7:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, amodra
In-Reply-To: <1340262473.1998.19.camel@concordia>

On Thu, 2012-06-21 at 17:07 +1000, Michael Ellerman wrote:
> On Thu, 2012-06-21 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> > On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> > >=20
> > > powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.te=
xt+0x89b990):=20
> > >         sibling call optimization to `_restgpr0_28' does not allow au=
tomatic multiple TOCs;
> > >         recompile with -mminimal-toc or -fno-optimize-sibling-calls, =
or make `_restgpr0_28' extern
> > >=20
> > Can you show the full build command that triggers the above ?
>=20
> Well that would be a few MBs of log, but here's an excerpt:
>=20
> make -f scripts/Makefile.build obj=3Dnet/openvswitch
>   /opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc -m64 =
-Wp,-MD,net/openvswitch/.vport-netdev.o.d  -nostdinc -isystem /opt/cross/gc=
c-4.6.3-nolibc/powerpc64-linux/lib/gcc/powerpc64-linux/4.6.3/include -I/hom=
e/michael/src/kmk/next/arch/powerpc/include -Iarch/powerpc/include/generate=
d -Iinclude  -include /home/michael/src/kmk/next/include/linux/kconfig.h -D=
__KERNEL__ -Iarch/powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs =
-fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno=
-format-security -fno-delete-null-pointer-checks -Os -msoft-float -pipe -Ia=
rch/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=3Dpower7 -=
mtune=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at-a-time -fn=
o-dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -fno-reorder-b=
locks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-than=3D2048 -f=
no-stack-protector -Wno-unused-but-set-variable -g -femit-struct-debug-base=
only -pg -fno-inline-functions-called-once -Wdeclaration-after-statement -W=
no-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO  -=
fprofile-arcs -ftest-coverage    -D"KBUILD_STR(s)=3D#s" -D"KBUILD_BASENAME=
=3DKBUILD_STR(vport_netdev)"  -D"KBUILD_MODNAME=3DKBUILD_STR(openvswitch)" =
-c -o net/openvswitch/.tmp_vport-netdev.o net/openvswitch/vport-netdev.c
>   if [ "-pg" =3D "-pg" ]; then set -e ; perl /home/michael/src/kmk/next/s=
cripts/recordmcount.pl "powerpc" "little" "64" "/opt/cross/gcc-4.6-nolibc/p=
owerpc64-linux/bin/powerpc64-linux-objdump" "/opt/cross/gcc-4.6-nolibc/powe=
rpc64-linux/bin/powerpc64-linux-objcopy" "/opt/cross/gcc-4.6-nolibc/powerpc=
64-linux/bin/powerpc64-linux-gcc -m64 -Wall -Wundef -Wstrict-prototypes -Wn=
o-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-decl=
aration -Wno-format-security -fno-delete-null-pointer-checks -Os -msoft-flo=
at -pipe -Iarch/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtun=
e=3Dpower7 -mtune=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-a=
t-a-time -fno-dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -f=
no-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-th=
an=3D2048  -fno-stack-protector -Wno-unused-but-set-variable -g  -femit-str=
uct-debug-baseonly -pg  -fno-inline-functions-called-once -Wdeclaration-aft=
er-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_H=
AVE_ASM_GOTO" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linu=
x-ld -m elf64ppc" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-=
linux-nm --synthetic" "" "" "0" "net/openvswitch/vport-netdev.o"; fi;

Just for the record it's not the FTRACE stuff (-pg):

  /opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc -m64 -W=
p,-MD,net/openvswitch/.vport-netdev.o.d  -nostdinc -isystem /opt/cross/gcc-=
4.6.3-nolibc/powerpc64-linux/lib/gcc/powerpc64-linux/4.6.3/include -I/home/=
michael/src/kmk/next/arch/powerpc/include -Iarch/powerpc/include/generated =
-Iinclude  -include /home/michael/src/kmk/next/include/linux/kconfig.h -D__=
KERNEL__ -Iarch/powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -f=
no-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-f=
ormat-security -fno-delete-null-pointer-checks -Os -msoft-float -pipe -Iarc=
h/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=3Dpower7 -mt=
une=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at-a-time -fno-=
dwarf2-cfi-asm -mno-string -Wa,-maltivec -fno-reorder-blocks -fno-ipa-cp-cl=
one -fno-partial-inlining -Wframe-larger-than=3D2048 -fno-stack-protector -=
Wno-unused-but-set-variable -fomit-frame-pointer -g -femit-struct-debug-bas=
eonly -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-=
pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO  -fpr=
ofile-arcs -ftest-coverage    -D"KBUILD_STR(s)=3D#s" -D"KBUILD_BASENAME=3DK=
BUILD_STR(vport_netdev)"  -D"KBUILD_MODNAME=3DKBUILD_STR(openvswitch)" -c -=
o net/openvswitch/.tmp_vport-netdev.o net/openvswitch/vport-netdev.c


And same error.

cheers

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Gabriel Paubert @ 2012-06-21  7:29 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, Alan Modra
In-Reply-To: <1340256961.1998.11.camel@concordia>

On Thu, Jun 21, 2012 at 03:36:01PM +1000, Michael Ellerman wrote:
> On Wed, 2012-06-20 at 17:50 +1000, Stephen Rothwell wrote:
> > Hi all,
> > 
> > After merging the final tree, today's linux-next build (powerpc
> > allyesconfig) failed like this:
> > 
> > powerpc64-linux-ld: arch/powerpc/net/built-in.o: In function `bpf_slow_path_word':
> > (.text+0x90): sibling call optimization to `skb_copy_bits' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `skb_copy_bits' extern
> 
> 
> Those seem to be caused because we don't have a nop after the call,
> meaning we can't patch the TOC pointer on the way back. Adding a nop
> fixes those.
> 
> But, then I get 32,410 variants of this:
> 
> powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990): 
> 	sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
> 	recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern
> 
> 

These functions should not need a TOC in the first place. There is
code in the linker (for 64 bit only: bfd/elf64-ppc.c) to automatically 
generate them whenever they are needed.

I suspect you compile with -Os. But I don't think you can use
these functions when doing a sibling call since restgpr0_nn
implies a return to the caller. restgpr1_nn would be different...

> And those are generated calls so I don't see how we can fix them.
> 
> > I started building with gcc 4.6.3/binutils 2.22 today.  gcc
> > 4.6.0/binutils 2.21 do not produce this error, it produces this instead
> > (which has been happening for a long time):
> > 
> > powerpc64-linux-ld: TOC section size exceeds 64k
> 
> 
> So presumably there's some new error checking that we're hitting, I
> imagine it was always broken, but now it's being more explicit.

I'm not so sure. I suspect gcc, but upgrading gcc and binutils at the
same time may not be the wisest...

	Gabriel

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-21  7:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, amodra
In-Reply-To: <1340259896.3942.2.camel@pasglop>

On Thu, 2012-06-21 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> >=20
> > powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text=
+0x89b990):=20
> >         sibling call optimization to `_restgpr0_28' does not allow auto=
matic multiple TOCs;
> >         recompile with -mminimal-toc or -fno-optimize-sibling-calls, or=
 make `_restgpr0_28' extern
> >=20
> >=20
> > And those are generated calls so I don't see how we can fix them.
>=20
> Is this a module ? We should really be linking that stuff directly with t=
he module....

No, it's builtin.

> The interesting thing is that we do build everything except a handful of
> files with -mminimal-toc unless something's wrong with our main Makefile.=
...

Yeah, the top arch Makefile sets it, though we do override it in a few
places. I tried removing those overrides and it didn't seem to make any
difference.

> Can you show the full build command that triggers the above ?

Well that would be a few MBs of log, but here's an excerpt:

make -f scripts/Makefile.build obj=3Dnet/openvswitch
  /opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc -m64 -W=
p,-MD,net/openvswitch/.vport-netdev.o.d  -nostdinc -isystem /opt/cross/gcc-=
4.6.3-nolibc/powerpc64-linux/lib/gcc/powerpc64-linux/4.6.3/include -I/home/=
michael/src/kmk/next/arch/powerpc/include -Iarch/powerpc/include/generated =
-Iinclude  -include /home/michael/src/kmk/next/include/linux/kconfig.h -D__=
KERNEL__ -Iarch/powerpc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -f=
no-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-f=
ormat-security -fno-delete-null-pointer-checks -Os -msoft-float -pipe -Iarc=
h/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=3Dpower7 -mt=
une=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at-a-time -fno-=
dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -fno-reorder-blo=
cks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-than=3D2048 -fno=
-stack-protector -Wno-unused-but-set-variable -g -femit-struct-debug-baseon=
ly -pg -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno=
-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO  -fp=
rofile-arcs -ftest-coverage    -D"KBUILD_STR(s)=3D#s" -D"KBUILD_BASENAME=3D=
KBUILD_STR(vport_netdev)"  -D"KBUILD_MODNAME=3DKBUILD_STR(openvswitch)" -c =
-o net/openvswitch/.tmp_vport-netdev.o net/openvswitch/vport-netdev.c
  if [ "-pg" =3D "-pg" ]; then set -e ; perl /home/michael/src/kmk/next/scr=
ipts/recordmcount.pl "powerpc" "little" "64" "/opt/cross/gcc-4.6-nolibc/pow=
erpc64-linux/bin/powerpc64-linux-objdump" "/opt/cross/gcc-4.6-nolibc/powerp=
c64-linux/bin/powerpc64-linux-objcopy" "/opt/cross/gcc-4.6-nolibc/powerpc64=
-linux/bin/powerpc64-linux-gcc -m64 -Wall -Wundef -Wstrict-prototypes -Wno-=
trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declar=
ation -Wno-format-security -fno-delete-null-pointer-checks -Os -msoft-float=
 -pipe -Iarch/powerpc -mminimal-toc -mtraceback=3Dno -mcall-aixdesc -mtune=
=3Dpower7 -mtune=3Dcell -mno-altivec -mno-vsx -mno-spe -mspe=3Dno -funit-at=
-a-time -fno-dwarf2-cfi-asm -mno-string -mno-sched-epilog -Wa,-maltivec -fn=
o-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-tha=
n=3D2048  -fno-stack-protector -Wno-unused-but-set-variable -g  -femit-stru=
ct-debug-baseonly -pg  -fno-inline-functions-called-once -Wdeclaration-afte=
r-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HA=
VE_ASM_GOTO" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-linux=
-ld -m elf64ppc" "/opt/cross/gcc-4.6-nolibc/powerpc64-linux/bin/powerpc64-l=
inux-nm --synthetic" "" "" "0" "net/openvswitch/vport-netdev.o"; fi;

And then a whole bunch of calls to ld.

So we are at least building that file with -mminimal-toc.

cheers

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Benjamin Herrenschmidt @ 2012-06-21  6:24 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Stephen Rothwell, linux-next, ppc-dev, linux-kernel, Alan Modra
In-Reply-To: <1340256961.1998.11.camel@concordia>

On Thu, 2012-06-21 at 15:36 +1000, Michael Ellerman wrote:
> 
> powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990): 
>         sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
>         recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern
> 
> 
> And those are generated calls so I don't see how we can fix them.

Is this a module ? We should really be linking that stuff directly with the module....

The interesting thing is that we do build everything except a handful of
files with -mminimal-toc unless something's wrong with our main Makefile....

Can you show the full build command that triggers the above ?

Cheers,
Ben.

^ permalink raw reply

* Re: linux-next: build failure after merge of the final tree (powerpc related)
From: Michael Ellerman @ 2012-06-21  5:36 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linux-next, ppc-dev, linux-kernel, Alan Modra
In-Reply-To: <20120620175014.a822a766e0f91f7b44f48fa0@canb.auug.org.au>

On Wed, 2012-06-20 at 17:50 +1000, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the final tree, today's linux-next build (powerpc
> allyesconfig) failed like this:
> 
> powerpc64-linux-ld: arch/powerpc/net/built-in.o: In function `bpf_slow_path_word':
> (.text+0x90): sibling call optimization to `skb_copy_bits' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `skb_copy_bits' extern


Those seem to be caused because we don't have a nop after the call,
meaning we can't patch the TOC pointer on the way back. Adding a nop
fixes those.

But, then I get 32,410 variants of this:

powerpc64-linux-ld: /src/next/net/openvswitch/vport-netdev.c:189:(.text+0x89b990): 
	sibling call optimization to `_restgpr0_28' does not allow automatic multiple TOCs;
	recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `_restgpr0_28' extern


And those are generated calls so I don't see how we can fix them.

> I started building with gcc 4.6.3/binutils 2.22 today.  gcc
> 4.6.0/binutils 2.21 do not produce this error, it produces this instead
> (which has been happening for a long time):
> 
> powerpc64-linux-ld: TOC section size exceeds 64k


So presumably there's some new error checking that we're hitting, I
imagine it was always broken, but now it's being more explicit.

I think we need some help from the toolchain experts, hi Alan :)

cheers

^ permalink raw reply

* Re: [PATCH] PPC: PCI: Fix pcibios_io_space_offset() so it works for 32-bit ptr/64-bit rsrcs
From: Benjamin Herrenschmidt @ 2012-06-21  2:46 UTC (permalink / raw)
  To: Ben Collins, Bjorn Helgaas; +Cc: linuxppc-dev
In-Reply-To: <4DC27253-67FC-4A55-8C78-7782D9D0CF53@servergy.com>

(Bjorn, added you back because I ended up digging a shitload
of issues including some generic ... see below)

On Tue, 2012-06-05 at 23:50 -0400, Ben Collins wrote:
> The commit introducing pcibios_io_space_offset() was ignoring 32-bit to
> 64-bit sign extention, which is the case on ppc32 with 64-bit resource
> addresses. This only seems to have shown up while running under QEMU for
> e500mc target. It may or may be suboptimal that QEMU has an IO base
> address > 32-bits for the e500-pci implementation, but 1) it's still a
> regression and 2) it's more correct to handle things this way.

So I came to the conclusion that this isn't the right fix... what we
have is an "interesting" combinations of issues here and I'll have to
dig with Bjorn to sort them all out.

In the meantime, let me know if the "quick fix" below works for you
as a workaround:

@@ -734,7 +740,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_contr
                        hose->io_base_virt = ioremap(cpu_addr, size);
 
                        /* Expect trouble if pci_addr is not 0 */
-                       if (primary)
+                       if (primary || !isa_io_base)
                                isa_io_base =
                                        (unsigned long)hose->io_base_virt;

(Note: The root of the qemu issue seems to be that qemu doesn't accept
an IO BAR with a value of 0 as a valid IO BAR... which is arguably a
qemu bug. However, we shouldn't have assigned that if it wasn't for
a bunch of other nasties)

Now, we have a combination of problems here Bjorn. A bunch of them are
powerpc specific and I'll fix them, but I'm hitting a couple of nasties
in the generic resource allocation code:

 * I'm not too happy with our pcibios_io_space_offset() sign extension,
but that's no biggie, I will fix that

 * It triggers a bunch of other problems where quite a bit of code
in pci-common.c seems to be assuming 32-bit arithmetic when messing
around with the port remapping, so I have fixes for all of that

 * Additionally, we end up with a crazy offset for IO because our
isa_io_base is only set if we mark a host bridge as "primary" and it
looks like the FSL code doesn't mark any. So our isa_io_base is 0
instead of the virt base of the first bridge, and thus our resource
offsets are equal to the virt base of the IO space of the bridge :-)
This isn't wrong per-se, ie, it -should- still work, but it then
trigger interesting problems. The patch above "corrects" that by making
isa_io_base default to the first bridge IO base if there's no primary.

 * PCIBIOS_IO_MIN (and MEM_MIN) are bogus... On most architectures
they represent a bus address, but the generic code uses them as a
resource address. So they don't work and we end up handing out
an IO resource equal to 0 (bus) instead of 0x1000 (bus) because the
offset'ed resource address isn't smaller than the min. Now I do have a
patch to fix that in the generic code, but I suspect that will break
a couple of archs:

arch/mn10300/include/asm/pci.h:#define PCIBIOS_MIN_IO           0xBE000004
arch/alpha/include/asm/pci.h:#define PCIBIOS_MIN_IO             alpha_mv.min_io_address

and maybe some mips stuff, I'm not sure. Do those archs do any
offsetting ? If they do we might want to change those defines
along with my patch:

diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index eea85da..ec429f3 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -131,10 +131,20 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
                int resno, resource_size_t size, resource_size_t align)
 {
        struct resource *res = dev->resource + resno;
+       struct resource min_res;
+       struct pci_bus_region min_reg;
        resource_size_t min;
        int ret;
 
-       min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+       /*
+        * We convert PCIBIOS_MIN_IO/MEM from bus addresses to
+        * resources before passing them to pci_bus_alloc_resource
+        */
+       min_res.flags = res->flags;
+       min_reg.start =  (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+       min_reg.end = min_reg.start;
+       pcibios_bus_to_resource(dev, &min_res, &min_reg);
+       min = min_res.start;
 
        /* First, try exact prefetching match.. */
        ret = pci_bus_alloc_resource(bus, res, size, align, min,

 * Additionally, there's another problem inside pci_bus_alloc_resource()
itself:

		/* Ok, try it out.. */
		ret = allocate_resource(r, res, size,
					r->start ? : min,
					max, align,
					alignf, alignf_data);

See the r->start ? : min ?

It only applies the "min" if r->start is 0.... now we have a hack in arch/powerpc
to clear out resources we think are unassigned. Unfortunately that hack got broken
when moving the offett'ing to generic code because it now tests the resource start
rather than the bus address (but thinks it tests the bus address).

So with a fix for that hack, I set r->start to 0 for anything that originally had
a "bus address" of 0, and the above passes, I get min, and things work. Pfiew !

Maybe a better thing to do would be to test if r->start < min ? That would work
but maybe it subtly breaks some x86 stuff where we want BIOS assigned addresses
< min to remain in place ?

What do you reckon ?

Cheers,
Ben.
	

> Signed-off-by: Ben Collins <bcollins@ubuntu.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  arch/powerpc/kernel/pci-common.c |    8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index 8e78e93..be9ced7 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -1477,9 +1477,15 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
>  	return pci_enable_resources(dev, mask);
>  }
>  
> +/* Before assuming too much here, take care to realize that we need sign
> + * extension from 32-bit pointers to 64-bit resource addresses to work.
> + */
>  resource_size_t pcibios_io_space_offset(struct pci_controller *hose)
>  {
> -	return (unsigned long) hose->io_base_virt - _IO_BASE;
> +	long vbase = (long)hose->io_base_virt;
> +	long io_base = _IO_BASE;
> +
> +	return (resource_size_t)(vbase - io_base);
>  }
>  
>  static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources)

^ permalink raw reply related

* [PATCH 18/18] powerpc: enforce usage of RA 0-R31 where possible
From: Michael Neuling @ 2012-06-21  2:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: mikey, linuxppc-dev, schwab, Anton Blanchard, Olof Johannsson
In-Reply-To: <1340244266.960241.475925824909.qpush@ale>

Some macros use RA where when RA=R0 the values is 0, so make this
the enforced mnemonic in the macro.

Idea suggested by Andreas Schwab.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---

 arch/powerpc/include/asm/ppc-opcode.h |   14 +++++++-------
 arch/powerpc/kernel/cpu_setup_a2.S    |    2 +-
 arch/powerpc/kernel/exceptions-64e.S  |    8 ++++----
 arch/powerpc/mm/tlb_low_64e.S         |   10 +++++-----
 arch/powerpc/mm/tlb_nohash_low.S      |   16 ++++++++--------
 5 files changed, 25 insertions(+), 25 deletions(-)

Index: powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc-test.orig/arch/powerpc/include/asm/ppc-opcode.h
+++ powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
@@ -198,7 +198,7 @@
 #define PPC_RFDI		stringify_in_c(.long PPC_INST_RFDI)
 #define PPC_RFMCI		stringify_in_c(.long PPC_INST_RFMCI)
 #define PPC_TLBILX(t, a, b)	stringify_in_c(.long PPC_INST_TLBILX | \
-					__PPC_T_TLB(t) | __PPC_RA(a) | __PPC_RB(b))
+					__PPC_T_TLB(t) | __PPC_RA0(a) | __PPC_RB(b))
 #define PPC_TLBILX_ALL(a, b)	PPC_TLBILX(0, a, b)
 #define PPC_TLBILX_PID(a, b)	PPC_TLBILX(1, a, b)
 #define PPC_TLBILX_VA(a, b)	PPC_TLBILX(3, a, b)
@@ -207,23 +207,23 @@
 #define PPC_TLBIE(lp,a) 	stringify_in_c(.long PPC_INST_TLBIE | \
 					       ___PPC_RB(a) | ___PPC_RS(lp))
 #define PPC_TLBSRX_DOT(a,b)	stringify_in_c(.long PPC_INST_TLBSRX_DOT | \
-					__PPC_RA(a) | __PPC_RB(b))
+					__PPC_RA0(a) | __PPC_RB(b))
 #define PPC_TLBIVAX(a,b)	stringify_in_c(.long PPC_INST_TLBIVAX | \
-					__PPC_RA(a) | __PPC_RB(b))
+					__PPC_RA0(a) | __PPC_RB(b))
 
 #define PPC_ERATWE(s, a, w)	stringify_in_c(.long PPC_INST_ERATWE | \
 					__PPC_RS(s) | __PPC_RA(a) | __PPC_WS(w))
 #define PPC_ERATRE(s, a, w)	stringify_in_c(.long PPC_INST_ERATRE | \
 					__PPC_RS(s) | __PPC_RA(a) | __PPC_WS(w))
 #define PPC_ERATILX(t, a, b)	stringify_in_c(.long PPC_INST_ERATILX | \
-					__PPC_T_TLB(t) | __PPC_RA(a) | \
+					__PPC_T_TLB(t) | __PPC_RA0(a) | \
 					__PPC_RB(b))
 #define PPC_ERATIVAX(s, a, b)	stringify_in_c(.long PPC_INST_ERATIVAX | \
-					__PPC_RS(s) | __PPC_RA(a) | __PPC_RB(b))
+					__PPC_RS(s) | __PPC_RA0(a) | __PPC_RB(b))
 #define PPC_ERATSX(t, a, w)	stringify_in_c(.long PPC_INST_ERATSX | \
-					__PPC_RS(t) | __PPC_RA(a) | __PPC_RB(b))
+					__PPC_RS(t) | __PPC_RA0(a) | __PPC_RB(b))
 #define PPC_ERATSX_DOT(t, a, w)	stringify_in_c(.long PPC_INST_ERATSX_DOT | \
-					__PPC_RS(t) | __PPC_RA(a) | __PPC_RB(b))
+					__PPC_RS(t) | __PPC_RA0(a) | __PPC_RB(b))
 #define PPC_SLBFEE_DOT(t, b)	stringify_in_c(.long PPC_INST_SLBFEE | \
 					__PPC_RT(t) | __PPC_RB(b))
 /* PASemi instructions */
Index: powerpc-test/arch/powerpc/kernel/cpu_setup_a2.S
===================================================================
--- powerpc-test.orig/arch/powerpc/kernel/cpu_setup_a2.S
+++ powerpc-test/arch/powerpc/kernel/cpu_setup_a2.S
@@ -112,7 +112,7 @@ _icswx_skip_guest:
 	 * a bolted entry though it will be in LRU and so will go away eventually
 	 * but let's not bother for now
 	 */
-	PPC_ERATILX(0,R0,R0)
+	PPC_ERATILX(0,0,R0)
 1:
 	blr
 
Index: powerpc-test/arch/powerpc/kernel/exceptions-64e.S
===================================================================
--- powerpc-test.orig/arch/powerpc/kernel/exceptions-64e.S
+++ powerpc-test/arch/powerpc/kernel/exceptions-64e.S
@@ -903,7 +903,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	bne	1b				/* If not, repeat */
 
 	/* Invalidate all TLBs */
-	PPC_TLBILX_ALL(R0,R0)
+	PPC_TLBILX_ALL(0,R0)
 	sync
 	isync
 
@@ -961,7 +961,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	tlbwe
 
 	/* Invalidate TLB1 */
-	PPC_TLBILX_ALL(R0,R0)
+	PPC_TLBILX_ALL(0,R0)
 	sync
 	isync
 
@@ -1020,7 +1020,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	tlbwe
 
 	/* Invalidate TLB1 */
-	PPC_TLBILX_ALL(R0,R0)
+	PPC_TLBILX_ALL(0,R0)
 	sync
 	isync
 
@@ -1138,7 +1138,7 @@ a2_tlbinit_after_iprot_flush:
 	tlbwe
 #endif /* CONFIG_PPC_EARLY_DEBUG_WSP */
 
-	PPC_TLBILX(0,R0,R0)
+	PPC_TLBILX(0,0,R0)
 	sync
 	isync
 
Index: powerpc-test/arch/powerpc/mm/tlb_low_64e.S
===================================================================
--- powerpc-test.orig/arch/powerpc/mm/tlb_low_64e.S
+++ powerpc-test/arch/powerpc/mm/tlb_low_64e.S
@@ -126,7 +126,7 @@ BEGIN_MMU_FTR_SECTION
 	/* Set the TLB reservation and search for existing entry. Then load
 	 * the entry.
 	 */
-	PPC_TLBSRX_DOT(R0,R16)
+	PPC_TLBSRX_DOT(0,R16)
 	ldx	r14,r14,r15		/* grab pgd entry */
 	beq	normal_tlb_miss_done	/* tlb exists already, bail */
 MMU_FTR_SECTION_ELSE
@@ -395,7 +395,7 @@ BEGIN_MMU_FTR_SECTION
 	/* Set the TLB reservation and search for existing entry. Then load
 	 * the entry.
 	 */
-	PPC_TLBSRX_DOT(R0,R16)
+	PPC_TLBSRX_DOT(0,R16)
 	ld	r14,0(r10)
 	beq	normal_tlb_miss_done
 MMU_FTR_SECTION_ELSE
@@ -528,7 +528,7 @@ BEGIN_MMU_FTR_SECTION
 	/* Search if we already have a TLB entry for that virtual address, and
 	 * if we do, bail out.
 	 */
-	PPC_TLBSRX_DOT(R0,R16)
+	PPC_TLBSRX_DOT(0,R16)
 	beq	virt_page_table_tlb_miss_done
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
 
@@ -779,7 +779,7 @@ htw_tlb_miss:
 	 *
 	 * MAS1:IND should be already set based on MAS4
 	 */
-	PPC_TLBSRX_DOT(R0,R16)
+	PPC_TLBSRX_DOT(0,R16)
 	beq	htw_tlb_miss_done
 
 	/* Now, we need to walk the page tables. First check if we are in
@@ -919,7 +919,7 @@ tlb_load_linear:
 	mtspr	SPRN_MAS1,r15
 
 	/* Already somebody there ? */
-	PPC_TLBSRX_DOT(R0,R16)
+	PPC_TLBSRX_DOT(0,R16)
 	beq	tlb_load_linear_done
 
 	/* Now we build the remaining MAS. MAS0 and 2 should be fine
Index: powerpc-test/arch/powerpc/mm/tlb_nohash_low.S
===================================================================
--- powerpc-test.orig/arch/powerpc/mm/tlb_nohash_low.S
+++ powerpc-test/arch/powerpc/mm/tlb_nohash_low.S
@@ -266,7 +266,7 @@ BEGIN_MMU_FTR_SECTION
 	andi.	r3,r3,MMUCSR0_TLBFI@l
 	bne	1b
 MMU_FTR_SECTION_ELSE
-	PPC_TLBILX_ALL(R0,R0)
+	PPC_TLBILX_ALL(0,R0)
 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
 	msync
 	isync
@@ -279,7 +279,7 @@ BEGIN_MMU_FTR_SECTION
 	wrteei	0
 	mfspr	r4,SPRN_MAS6	/* save MAS6 */
 	mtspr	SPRN_MAS6,r3
-	PPC_TLBILX_PID(R0,R0)
+	PPC_TLBILX_PID(0,R0)
 	mtspr	SPRN_MAS6,r4	/* restore MAS6 */
 	wrtee	r10
 MMU_FTR_SECTION_ELSE
@@ -313,7 +313,7 @@ BEGIN_MMU_FTR_SECTION
 	mtspr	SPRN_MAS1,r4
 	tlbwe
 MMU_FTR_SECTION_ELSE
-	PPC_TLBILX_VA(R0,R3)
+	PPC_TLBILX_VA(0,R3)
 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
 	msync
 	isync
@@ -331,7 +331,7 @@ _GLOBAL(_tlbil_pid)
 	mfmsr	r10
 	wrteei	0
 	mtspr	SPRN_MAS6,r4
-	PPC_TLBILX_PID(R0,R0)
+	PPC_TLBILX_PID(0,R0)
 	wrtee	r10
 	msync
 	isync
@@ -343,14 +343,14 @@ _GLOBAL(_tlbil_pid_noind)
 	ori	r4,r4,MAS6_SIND
 	wrteei	0
 	mtspr	SPRN_MAS6,r4
-	PPC_TLBILX_PID(R0,R0)
+	PPC_TLBILX_PID(0,R0)
 	wrtee	r10
 	msync
 	isync
 	blr
 
 _GLOBAL(_tlbil_all)
-	PPC_TLBILX_ALL(R0,R0)
+	PPC_TLBILX_ALL(0,R0)
 	msync
 	isync
 	blr
@@ -364,7 +364,7 @@ _GLOBAL(_tlbil_va)
 	beq	1f
 	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
 1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
-	PPC_TLBILX_VA(R0,R3)
+	PPC_TLBILX_VA(0,R3)
 	msync
 	isync
 	wrtee	r10
@@ -379,7 +379,7 @@ _GLOBAL(_tlbivax_bcast)
 	beq	1f
 	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
 1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
-	PPC_TLBIVAX(R0,R3)
+	PPC_TLBIVAX(0,R3)
 	eieio
 	tlbsync
 	sync

^ permalink raw reply

* [PATCH 17/18] powerpc: Add defines for RA 0-R31
From: Michael Neuling @ 2012-06-21  2:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: mikey, linuxppc-dev, schwab, Anton Blanchard, Olof Johannsson
In-Reply-To: <1340244266.960241.475925824909.qpush@ale>

R0 is special since it'll be 0.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---

 arch/powerpc/include/asm/ppc-opcode.h |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

Index: powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc-test.orig/arch/powerpc/include/asm/ppc-opcode.h
+++ powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
@@ -48,6 +48,39 @@
 #define	__REG_R30	30
 #define	__REG_R31	31
 
+#define	__REGA0_0	0
+#define	__REGA0_R1	1
+#define	__REGA0_R2	2
+#define	__REGA0_R3	3
+#define	__REGA0_R4	4
+#define	__REGA0_R5	5
+#define	__REGA0_R6	6
+#define	__REGA0_R7	7
+#define	__REGA0_R8	8
+#define	__REGA0_R9	9
+#define	__REGA0_R10	10
+#define	__REGA0_R11	11
+#define	__REGA0_R12	12
+#define	__REGA0_R13	13
+#define	__REGA0_R14	14
+#define	__REGA0_R15	15
+#define	__REGA0_R16	16
+#define	__REGA0_R17	17
+#define	__REGA0_R18	18
+#define	__REGA0_R19	19
+#define	__REGA0_R20	20
+#define	__REGA0_R21	21
+#define	__REGA0_R22	22
+#define	__REGA0_R23	23
+#define	__REGA0_R24	24
+#define	__REGA0_R25	25
+#define	__REGA0_R26	26
+#define	__REGA0_R27	27
+#define	__REGA0_R28	28
+#define	__REGA0_R29	29
+#define	__REGA0_R30	30
+#define	__REGA0_R31	31
+
 /* sorted alphabetically */
 #define PPC_INST_DCBA			0x7c0005ec
 #define PPC_INST_DCBA_MASK		0xfc0007fe
@@ -149,6 +182,7 @@
 #define ___PPC_RS(s)	(((s) & 0x1f) << 21)
 #define ___PPC_RT(t)	___PPC_RS(t)
 #define __PPC_RA(a)	___PPC_RA(__REG_##a)
+#define __PPC_RA0(a)	___PPC_RA(__REGA0_##a)
 #define __PPC_RB(b)	___PPC_RB(__REG_##b)
 #define __PPC_RS(s)	___PPC_RS(__REG_##s)
 #define __PPC_RT(t)	___PPC_RT(__REG_##t)

^ permalink raw reply

* [PATCH 16/18] powerpc: enforce usage of R0-R31 where possible
From: Michael Neuling @ 2012-06-21  2:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: mikey, linuxppc-dev, schwab, Anton Blanchard, Olof Johannsson
In-Reply-To: <1340244266.960241.475925824909.qpush@ale>

Enforce the use of R0-R31 in macros where possible now we have all the
fixes in.

R0-R31 macros are removed here so that can't be used anymore.  They
should not be defined anywhere.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---

 arch/powerpc/include/asm/ppc-opcode.h |   41 +++-------------------------------
 arch/powerpc/include/asm/ppc_asm.h    |   17 ++++++++------
 arch/powerpc/kernel/fpu.S             |   12 +++++----
 arch/powerpc/kvm/booke_interrupts.S   |    3 +-
 4 files changed, 23 insertions(+), 50 deletions(-)

Index: powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
===================================================================
--- powerpc-test.orig/arch/powerpc/include/asm/ppc-opcode.h
+++ powerpc-test/arch/powerpc/include/asm/ppc-opcode.h
@@ -15,39 +15,6 @@
 #include <linux/stringify.h>
 #include <asm/asm-compat.h>
 
-#define	R0	0
-#define	R1	1
-#define	R2	2
-#define	R3	3
-#define	R4	4
-#define	R5	5
-#define	R6	6
-#define	R7	7
-#define	R8	8
-#define	R9	9
-#define	R10	10
-#define	R11	11
-#define	R12	12
-#define	R13	13
-#define	R14	14
-#define	R15	15
-#define	R16	16
-#define	R17	17
-#define	R18	18
-#define	R19	19
-#define	R20	20
-#define	R21	21
-#define	R22	22
-#define	R23	23
-#define	R24	24
-#define	R25	25
-#define	R26	26
-#define	R27	27
-#define	R28	28
-#define	R29	29
-#define	R30	30
-#define	R31	31
-
 #define	__REG_R0	0
 #define	__REG_R1	1
 #define	__REG_R2	2
@@ -181,10 +148,10 @@
 #define ___PPC_RB(b)	(((b) & 0x1f) << 11)
 #define ___PPC_RS(s)	(((s) & 0x1f) << 21)
 #define ___PPC_RT(t)	___PPC_RS(t)
-#define __PPC_RA(a)	(((a) & 0x1f) << 16)
-#define __PPC_RB(b)	(((b) & 0x1f) << 11)
-#define __PPC_RS(s)	(((s) & 0x1f) << 21)
-#define __PPC_RT(s)	__PPC_RS(s)
+#define __PPC_RA(a)	___PPC_RA(__REG_##a)
+#define __PPC_RB(b)	___PPC_RB(__REG_##b)
+#define __PPC_RS(s)	___PPC_RS(__REG_##s)
+#define __PPC_RT(t)	___PPC_RT(__REG_##t)
 #define __PPC_XA(a)	((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3))
 #define __PPC_XB(b)	((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4))
 #define __PPC_XS(s)	((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
Index: powerpc-test/arch/powerpc/include/asm/ppc_asm.h
===================================================================
--- powerpc-test.orig/arch/powerpc/include/asm/ppc_asm.h
+++ powerpc-test/arch/powerpc/include/asm/ppc_asm.h
@@ -126,26 +126,26 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLP
 #define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
 /* Save the lower 32 VSRs in the thread VSR region */
-#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,base,b)
+#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,R##base,R##b)
 #define SAVE_2VSRS(n,b,base)	SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
 #define SAVE_4VSRS(n,b,base)	SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
 #define SAVE_8VSRS(n,b,base)	SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
 #define SAVE_16VSRS(n,b,base)	SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
 #define SAVE_32VSRS(n,b,base)	SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
-#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,base,b)
+#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,R##base,R##b)
 #define REST_2VSRS(n,b,base)	REST_VSR(n,b,base); REST_VSR(n+1,b,base)
 #define REST_4VSRS(n,b,base)	REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
 #define REST_8VSRS(n,b,base)	REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
 #define REST_16VSRS(n,b,base)	REST_8VSRS(n,b,base); REST_8VSRS(n+8,b,base)
 #define REST_32VSRS(n,b,base)	REST_16VSRS(n,b,base); REST_16VSRS(n+16,b,base)
 /* Save the upper 32 VSRs (32-63) in the thread VSX region (0-31) */
-#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,base,b)
+#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,R##base,R##b)
 #define SAVE_2VSRSU(n,b,base)	SAVE_VSRU(n,b,base); SAVE_VSRU(n+1,b,base)
 #define SAVE_4VSRSU(n,b,base)	SAVE_2VSRSU(n,b,base); SAVE_2VSRSU(n+2,b,base)
 #define SAVE_8VSRSU(n,b,base)	SAVE_4VSRSU(n,b,base); SAVE_4VSRSU(n+4,b,base)
 #define SAVE_16VSRSU(n,b,base)	SAVE_8VSRSU(n,b,base); SAVE_8VSRSU(n+8,b,base)
 #define SAVE_32VSRSU(n,b,base)	SAVE_16VSRSU(n,b,base); SAVE_16VSRSU(n+16,b,base)
-#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,base,b)
+#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,R##base,R##b)
 #define REST_2VSRSU(n,b,base)	REST_VSRU(n,b,base); REST_VSRU(n+1,b,base)
 #define REST_4VSRSU(n,b,base)	REST_2VSRSU(n,b,base); REST_2VSRSU(n+2,b,base)
 #define REST_8VSRSU(n,b,base)	REST_4VSRSU(n,b,base); REST_4VSRSU(n+4,b,base)
@@ -183,15 +183,18 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLP
 #else
 #define ULONG_SIZE	4
 #endif
-#define VCPU_GPR(n)	(VCPU_GPRS + (n * ULONG_SIZE))
+#define __VCPU_GPR(n)	(VCPU_GPRS + (n * ULONG_SIZE))
+#define VCPU_GPR(n)	__VCPU_GPR(__REG_##n)
 
 #ifdef __KERNEL__
 #ifdef CONFIG_PPC64
 
 #define STACKFRAMESIZE 256
-#define STK_REG(i)     (112 + ((i)-14)*8)
+#define __STK_REG(i)   (112 + ((i)-14)*8)
+#define STK_REG(i)     __STK_REG(__REG_##i)
 
-#define STK_PARAM(i)	(48 + ((i)-3)*8)
+#define __STK_PARAM(i)	(48 + ((i)-3)*8)
+#define STK_PARAM(i)	__STK_PARAM(__REG_##i)
 
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
Index: powerpc-test/arch/powerpc/kernel/fpu.S
===================================================================
--- powerpc-test.orig/arch/powerpc/kernel/fpu.S
+++ powerpc-test/arch/powerpc/kernel/fpu.S
@@ -26,7 +26,7 @@
 #include <asm/ptrace.h>
 
 #ifdef CONFIG_VSX
-#define REST_32FPVSRS(n,c,base)						\
+#define __REST_32FPVSRS(n,c,base)					\
 BEGIN_FTR_SECTION							\
 	b	2f;							\
 END_FTR_SECTION_IFSET(CPU_FTR_VSX);					\
@@ -35,7 +35,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);
 2:	REST_32VSRS(n,c,base);						\
 3:
 
-#define SAVE_32FPVSRS(n,c,base)						\
+#define __SAVE_32FPVSRS(n,c,base)					\
 BEGIN_FTR_SECTION							\
 	b	2f;							\
 END_FTR_SECTION_IFSET(CPU_FTR_VSX);					\
@@ -44,9 +44,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);
 2:	SAVE_32VSRS(n,c,base);						\
 3:
 #else
-#define REST_32FPVSRS(n,b,base)	REST_32FPRS(n, base)
-#define SAVE_32FPVSRS(n,b,base)	SAVE_32FPRS(n, base)
+#define __REST_32FPVSRS(n,b,base)	REST_32FPRS(n, base)
+#define __SAVE_32FPVSRS(n,b,base)	SAVE_32FPRS(n, base)
 #endif
+#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
+#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
 
 /*
  * This task wants to use the FPU now.
@@ -79,7 +81,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 	beq	1f
 	toreal(r4)
 	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
-	SAVE_32FPVSRS(0, r5, r4)
+	SAVE_32FPVSRS(0, R5, R4)
 	mffs	fr0
 	stfd	fr0,THREAD_FPSCR(r4)
 	PPC_LL	r5,PT_REGS(r4)
Index: powerpc-test/arch/powerpc/kvm/booke_interrupts.S
===================================================================
--- powerpc-test.orig/arch/powerpc/kvm/booke_interrupts.S
+++ powerpc-test/arch/powerpc/kvm/booke_interrupts.S
@@ -34,7 +34,8 @@
 #define HOST_R2         12
 #define HOST_CR         16
 #define HOST_NV_GPRS    20
-#define HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * 4))
+#define __HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * 4))
+#define HOST_NV_GPR(n)  __HOST_NV_GPR(__REG_##n)
 #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4)
 #define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
 #define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox