LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5/7] jump_label: relax branch hinting restrictions
From: Radim Krčmář @ 2013-10-17 10:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mips, x86, Radim Krčmář, linux-doc,
	Heiko Carstens, sparclinux, Paul Mackerras, H. Peter Anvin,
	Masami Hiramatsu, linux-s390, Russell King, Raghavendra K T,
	Ingo Molnar, Andrew Jones, Konrad Rzeszutek Wilk, Steven Rostedt,
	Thomas Gleixner, linux-arm-kernel, Richard Henderson, Jiri Kosina,
	Ralf Baechle, Rob Landley, Martin Schwidefsky, linux390,
	linuxppc-dev, David S. Miller
In-Reply-To: <1382004631-25895-1-git-send-email-rkrcmar@redhat.com>

We implemented the optimized branch selection in higher levels of api.
That made static_keys very unintuitive, so this patch introduces another
element to jump_table, carrying one bit that tells the underlying code
which branch to optimize.

It is now possible to select optimized branch for every jump_entry.

Current side effect is 1/3 increase increase in space, we could:
* use bitmasks and selectors on 2+ aligned code/struct.
  - aligning jump target is easy, but because it is not done by default
    and few bytes in .text are much worse that few kilos in .data,
    I chose not to
  - data is probably aligned by default on all current architectures,
    but programmer can force misalignment of static_key
* optimize each architecture independently
  - I can't test everything and this patch shouldn't break anything, so
    others can contribute in the future
* choose something worse, like packing or splitting
* ignore

proof: example & x86_64 disassembly: (F = ffffffff)

  struct static_key flexible_feature;
  noinline void jump_label_experiment(void) {
  	if ( static_key_false(&flexible_feature))
  	     asm ("push 0xa1");
  	else asm ("push 0xa0");
  	if (!static_key_false(&flexible_feature))
  	     asm ("push 0xb0");
  	else asm ("push 0xb1");
  	if ( static_key_true(&flexible_feature))
  	     asm ("push 0xc1");
  	else asm ("push 0xc0");
  	if (!static_key_true(&flexible_feature))
  	     asm ("push 0xd0");
  	else asm ("push 0xd1");
  }

  Disassembly of section .text: (push marked by "->")

  F81002000 <jump_label_experiment>:
  F81002000:       e8 7b 29 75 00          callq  F81754980 <__fentry__>
  F81002005:       55                      push   %rbp
  F81002006:       48 89 e5                mov    %rsp,%rbp
  F81002009:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  F8100200e: ->    ff 34 25 a0 00 00 00    pushq  0xa0
  F81002015:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  F8100201a: ->    ff 34 25 b0 00 00 00    pushq  0xb0
  F81002021:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  F81002026: ->    ff 34 25 c1 00 00 00    pushq  0xc1
  F8100202d:       0f 1f 00                nopl   (%rax)
  F81002030:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  F81002035: ->    ff 34 25 d1 00 00 00    pushq  0xd1
  F8100203c:       5d                      pop    %rbp
  F8100203d:       0f 1f 00                nopl   (%rax)
  F81002040:       c3                      retq
  F81002041:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  F81002048: ->    ff 34 25 d0 00 00 00    pushq  0xd0
  F8100204f:       5d                      pop    %rbp
  F81002050:       c3                      retq
  F81002051:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  F81002058: ->    ff 34 25 c0 00 00 00    pushq  0xc0
  F8100205f:       90                      nop
  F81002060:       eb cb                   jmp    F8100202d <[...]+0x2d>
  F81002062:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  F81002068: ->    ff 34 25 b1 00 00 00    pushq  0xb1
  F8100206f:       90                      nop
  F81002070:       eb af                   jmp    F81002021 <[...]+0x21>
  F81002072:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  F81002078: ->    ff 34 25 a1 00 00 00    pushq  0xa1
  F8100207f:       90                      nop
  F81002080:       eb 93                   jmp    F81002015 <[...]+0x15>
  F81002082:       66 66 66 66 66 2e 0f    [...]
  F81002089:       1f 84 00 00 00 00 00

  Contents of section .data: (relevant part of embedded __jump_table)
    F81d26a40 09200081 ffffffff 78200081 ffffffff
    F81d26a50 20600f82 ffffffff 00000000 00000000
    F81d26a60 15200081 ffffffff 68200081 ffffffff
    F81d26a70 20600f82 ffffffff 00000000 00000000
    F81d26a80 21200081 ffffffff 58200081 ffffffff
    F81d26a90 20600f82 ffffffff 01000000 00000000
    F81d26aa0 30200081 ffffffff 48200081 ffffffff
    F81d26ab0 20600f82 ffffffff 01000000 00000000

  (I've also compiled for s390x, blocks were placed correctly,
   jump table looked ok too;
   I hope the least significant bit is correct everywhere)

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 Documentation/static-keys.txt         |  6 ----
 arch/arm/include/asm/jump_label.h     | 19 ++++++++----
 arch/arm/kernel/jump_label.c          |  2 +-
 arch/mips/include/asm/jump_label.h    | 19 ++++++++----
 arch/mips/kernel/jump_label.c         |  2 +-
 arch/powerpc/include/asm/jump_label.h | 19 ++++++++----
 arch/powerpc/kernel/jump_label.c      |  2 +-
 arch/s390/include/asm/jump_label.h    | 19 ++++++++----
 arch/s390/kernel/jump_label.c         |  2 +-
 arch/sparc/include/asm/jump_label.h   | 19 ++++++++----
 arch/sparc/kernel/jump_label.c        |  2 +-
 arch/x86/include/asm/jump_label.h     | 19 ++++++++----
 arch/x86/kernel/jump_label.c          | 32 ++++----------------
 include/linux/jump_label.h            | 55 ++++++++++++-----------------------
 kernel/jump_label.c                   | 29 ++++--------------
 15 files changed, 119 insertions(+), 127 deletions(-)

diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt
index 9f5263d..57c040e 100644
--- a/Documentation/static-keys.txt
+++ b/Documentation/static-keys.txt
@@ -103,12 +103,6 @@ Or:
         else
                 do unlikely code
 
-A key that is initialized via 'STATIC_KEY_INIT_FALSE', must be used in a
-'static_key_false()' construct. Likewise, a key initialized via
-'STATIC_KEY_INIT_TRUE' must be used in a 'static_key_true()' construct. A
-single key can be used in many branches, but all the branches must match the
-way that the key has been initialized.
-
 The branch(es) can then be switched via:
 
 	static_key_slow_inc(&key);
diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h
index 863c892..f4ec3af 100644
--- a/arch/arm/include/asm/jump_label.h
+++ b/arch/arm/include/asm/jump_label.h
@@ -14,18 +14,21 @@
 #define JUMP_LABEL_NOP	"nop"
 #endif
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 	asm_volatile_goto("1:\n\t"
 		 JUMP_LABEL_NOP "\n\t"
 		 ".pushsection __jump_table,  \"aw\"\n\t"
-		 ".word 1b, %l[l_yes], %c0\n\t"
+		 ".word 1b, %l[l_yes], %c0, %c1\n\t"
 		 ".popsection\n\t"
-		 : :  "i" (key) :  : l_yes);
+		 : :  "i" (key), "i" (default_branch) :  : l_yes);
 
-	return false;
+	return default_branch;
 l_yes:
-	return true;
+	return !default_branch;
 }
 
 #endif /* __KERNEL__ */
@@ -36,6 +39,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
index 4ce4f78..b02c531 100644
--- a/arch/arm/kernel/jump_label.c
+++ b/arch/arm/kernel/jump_label.c
@@ -13,7 +13,7 @@ static void __arch_jump_label_transform(struct jump_entry *entry,
 	void *addr = (void *)entry->code;
 	unsigned int insn;
 
-	if (type == JUMP_LABEL_ENABLE)
+	if (type != jump_label_default_branch(entry))
 		insn = arm_gen_branch(entry->code, entry->target);
 	else
 		insn = arm_gen_nop();
diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h
index e194f95..2c065ec 100644
--- a/arch/mips/include/asm/jump_label.h
+++ b/arch/mips/include/asm/jump_label.h
@@ -20,17 +20,20 @@
 #define WORD_INSN ".word"
 #endif
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 	asm_volatile_goto("1:\tnop\n\t"
 		"nop\n\t"
 		".pushsection __jump_table,  \"aw\"\n\t"
-		WORD_INSN " 1b, %l[l_yes], %0\n\t"
+		WORD_INSN " 1b, %l[l_yes], %0, %1\n\t"
 		".popsection\n\t"
-		: :  "i" (key) : : l_yes);
-	return false;
+		: :  "i" (key), "i" (default_branch) : : l_yes);
+	return default_branch;
 l_yes:
-	return true;
+	return !default_branch;
 }
 
 #endif /* __KERNEL__ */
@@ -45,6 +48,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif /* _ASM_MIPS_JUMP_LABEL_H */
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
index 6001610..e5b17ee 100644
--- a/arch/mips/kernel/jump_label.c
+++ b/arch/mips/kernel/jump_label.c
@@ -33,7 +33,7 @@ void arch_jump_label_transform(struct jump_entry *e,
 	/* Target must have 4 byte alignment. */
 	BUG_ON((e->target & 3) != 0);
 
-	if (type == JUMP_LABEL_ENABLE) {
+	if (type != jump_label_default_branch(entry)) {
 		insn.j_format.opcode = j_op;
 		insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
 	} else {
diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h
index f016bb6..463c03d 100644
--- a/arch/powerpc/include/asm/jump_label.h
+++ b/arch/powerpc/include/asm/jump_label.h
@@ -17,17 +17,20 @@
 #define JUMP_ENTRY_TYPE		stringify_in_c(FTR_ENTRY_LONG)
 #define JUMP_LABEL_NOP_SIZE	4
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 	asm_volatile_goto("1:\n\t"
 		 "nop\n\t"
 		 ".pushsection __jump_table,  \"aw\"\n\t"
-		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
+		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0, %c1\n\t"
 		 ".popsection \n\t"
-		 : :  "i" (key) : : l_yes);
-	return false;
+		 : :  "i" (key), "i" (default_branch) : : l_yes);
+	return default_branch;
 l_yes:
-	return true;
+	return !default_branch;
 }
 
 #ifdef CONFIG_PPC64
@@ -40,6 +43,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif /* _ASM_POWERPC_JUMP_LABEL_H */
diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c
index a1ed8a8..ebf148b 100644
--- a/arch/powerpc/kernel/jump_label.c
+++ b/arch/powerpc/kernel/jump_label.c
@@ -17,7 +17,7 @@ void arch_jump_label_transform(struct jump_entry *entry,
 {
 	u32 *addr = (u32 *)(unsigned long)entry->code;
 
-	if (type == JUMP_LABEL_ENABLE)
+	if (type != jump_label_default_branch(entry))
 		patch_branch(addr, entry->target, 0);
 	else
 		patch_instruction(addr, PPC_INST_NOP);
diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h
index 346b1c8..5259b49 100644
--- a/arch/s390/include/asm/jump_label.h
+++ b/arch/s390/include/asm/jump_label.h
@@ -13,17 +13,20 @@
 #define ASM_ALIGN ".balign 4"
 #endif
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 	asm_volatile_goto("0:	brcl 0,0\n"
 		".pushsection __jump_table, \"aw\"\n"
 		ASM_ALIGN "\n"
-		ASM_PTR " 0b, %l[label], %0\n"
+		ASM_PTR " 0b, %l[label], %0, %1\n"
 		".popsection\n"
-		: : "X" (key) : : label);
-	return false;
+		: : "X" (key), "X" (default_branch) : : label);
+	return default_branch;
 label:
-	return true;
+	return !default_branch;
 }
 
 typedef unsigned long jump_label_t;
@@ -32,6 +35,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c
index b987ab2..95958c5 100644
--- a/arch/s390/kernel/jump_label.c
+++ b/arch/s390/kernel/jump_label.c
@@ -28,7 +28,7 @@ static void __jump_label_transform(struct jump_entry *entry,
 	struct insn insn;
 	int rc;
 
-	if (type == JUMP_LABEL_ENABLE) {
+	if (type != jump_label_default_branch(entry)) {
 		/* brcl 15,offset */
 		insn.opcode = 0xc0f4;
 		insn.offset = (entry->target - entry->code) >> 1;
diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h
index ec2e2e2..67b763d 100644
--- a/arch/sparc/include/asm/jump_label.h
+++ b/arch/sparc/include/asm/jump_label.h
@@ -7,19 +7,22 @@
 
 #define JUMP_LABEL_NOP_SIZE 4
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 		asm_volatile_goto("1:\n\t"
 			 "nop\n\t"
 			 "nop\n\t"
 			 ".pushsection __jump_table,  \"aw\"\n\t"
 			 ".align 4\n\t"
-			 ".word 1b, %l[l_yes], %c0\n\t"
+			 ".word 1b, %l[l_yes], %c0, %c1\n\t"
 			 ".popsection \n\t"
-			 : :  "i" (key) : : l_yes);
-	return false;
+			 : :  "i" (key), "i" (default_branch) : : l_yes);
+	return default_branch;
 l_yes:
-	return true;
+	return !default_branch;
 }
 
 #endif /* __KERNEL__ */
@@ -30,6 +33,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif
diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c
index 48565c1..c963a9c 100644
--- a/arch/sparc/kernel/jump_label.c
+++ b/arch/sparc/kernel/jump_label.c
@@ -16,7 +16,7 @@ void arch_jump_label_transform(struct jump_entry *entry,
 	u32 val;
 	u32 *insn = (u32 *) (unsigned long) entry->code;
 
-	if (type == JUMP_LABEL_ENABLE) {
+	if (type != jump_label_default_branch(entry)) {
 		s32 off = (s32)entry->target - (s32)entry->code;
 
 #ifdef CONFIG_SPARC64
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 6a2cefb..18e192e 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -16,18 +16,21 @@
 # define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC
 #endif
 
-static __always_inline bool arch_static_branch(struct static_key *key)
+struct static_key;
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+		const bool default_branch)
 {
 	asm_volatile_goto("1:"
 		".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t"
 		".pushsection __jump_table,  \"aw\" \n\t"
 		_ASM_ALIGN "\n\t"
-		_ASM_PTR "1b, %l[l_yes], %c0 \n\t"
+		_ASM_PTR "1b, %l[l_yes], %c0, %c1 \n\t"
 		".popsection \n\t"
-		: :  "i" (key) : : l_yes);
-	return false;
+		: :  "i" (key), "i" (default_branch) : : l_yes);
+	return default_branch;
 l_yes:
-	return true;
+	return !default_branch;
 }
 
 #endif /* __KERNEL__ */
@@ -42,6 +45,12 @@ struct jump_entry {
 	jump_label_t code;
 	jump_label_t target;
 	jump_label_t key;
+	union {
+		jump_label_t flags;
+		struct {
+			unsigned default_branch:1; /* lsb */
+		};
+	};
 };
 
 #endif
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
index ee11b7d..8b66855 100644
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -43,13 +43,15 @@ static void __jump_label_transform(struct jump_entry *entry,
 {
 	union jump_code_union code;
 	const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
+	const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
 
-	if (type == JUMP_LABEL_ENABLE) {
+	if (type != jump_label_default_branch(entry)) {
 		/*
 		 * We are enabling this jump label. If it is not a nop
 		 * then something must have gone wrong.
 		 */
-		if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) != 0))
+		if (unlikely(memcmp((void *)entry->code,
+		                    init ? default_nop : ideal_nop, 5) != 0))
 			bug_at((void *)entry->code, __LINE__);
 
 		code.jump = 0xe9;
@@ -63,7 +65,6 @@ static void __jump_label_transform(struct jump_entry *entry,
 		 * are converting the default nop to the ideal nop.
 		 */
 		if (init) {
-			const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
 			if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0))
 				bug_at((void *)entry->code, __LINE__);
 		} else {
@@ -101,33 +102,10 @@ void arch_jump_label_transform(struct jump_entry *entry,
 	put_online_cpus();
 }
 
-static enum {
-	JL_STATE_START,
-	JL_STATE_NO_UPDATE,
-	JL_STATE_UPDATE,
-} jlstate __initdata_or_module = JL_STATE_START;
-
 __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
 				      enum jump_label_type type)
 {
-	/*
-	 * This function is called at boot up and when modules are
-	 * first loaded. Check if the default nop, the one that is
-	 * inserted at compile time, is the ideal nop. If it is, then
-	 * we do not need to update the nop, and we can leave it as is.
-	 * If it is not, then we need to update the nop to the ideal nop.
-	 */
-	if (jlstate == JL_STATE_START) {
-		const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
-		const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
-
-		if (memcmp(ideal_nop, default_nop, 5) != 0)
-			jlstate = JL_STATE_UPDATE;
-		else
-			jlstate = JL_STATE_NO_UPDATE;
-	}
-	if (jlstate == JL_STATE_UPDATE)
-		__jump_label_transform(entry, type, text_poke_early, 1);
+	__jump_label_transform(entry, type, text_poke_early, 1);
 }
 
 #endif
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 848bd15..a06791c 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -10,7 +10,8 @@
  * Jump labels provide an interface to generate dynamic branches using
  * self-modifying code. Assuming toolchain and architecture support the result
  * of a "if (static_key_false(&key))" statement is a unconditional branch (which
- * defaults to false - and the true block is placed out of line).
+ * defaults to false - and the true block is placed out of line,
+ * static_key_true(&key) has default to true)
  *
  * However at runtime we can change the branch target using
  * static_key_slow_{inc,dec}(). These function as a 'reference' count on the key
@@ -32,17 +33,9 @@
  * Lacking toolchain and or architecture support, it falls back to a simple
  * conditional branch.
  *
- * struct static_key my_key = STATIC_KEY_INIT_TRUE;
- *
- *   if (static_key_true(&my_key)) {
- *   }
- *
- * will result in the true case being in-line and starts the key with a single
- * reference. Mixing static_key_true() and static_key_false() on the same key is not
- * allowed.
- *
- * Not initializing the key (static data is initialized to 0s anyway) is the
- * same as using STATIC_KEY_INIT_FALSE.
+ * Initial count can be set by STATIC_KEY_INIT(x), defaults to 0, but it takes
+ * effect after jump_label_init() has finished, so static_key_enabled() must be
+ * used instead of static_key_{true,false} before.
  *
 */
 
@@ -53,7 +46,6 @@
 
 struct static_key {
 	atomic_t enabled;
-/* Set lsb bit to 1 if branch is default true, 0 ot */
 	struct jump_entry *entries;
 #ifdef CONFIG_MODULES
 	struct static_key_mod *next;
@@ -75,30 +67,20 @@ struct module;
 #include <linux/atomic.h>
 #ifdef HAVE_JUMP_LABEL
 
-#define JUMP_LABEL_TRUE_BRANCH 1UL
-
 static
 inline struct jump_entry *jump_label_get_entries(struct static_key *key)
 {
-	return (struct jump_entry *)((unsigned long)key->entries
-						& ~JUMP_LABEL_TRUE_BRANCH);
-}
-
-static inline bool jump_label_get_branch_default(struct static_key *key)
-{
-	if ((unsigned long)key->entries & JUMP_LABEL_TRUE_BRANCH)
-		return true;
-	return false;
+	return (struct jump_entry *)((unsigned long)key->entries);
 }
 
 static __always_inline bool static_key_false(struct static_key *key)
 {
-	return arch_static_branch(key);
+	return arch_static_branch(key, false);
 }
 
 static __always_inline bool static_key_true(struct static_key *key)
 {
-	return !static_key_false(key);
+	return arch_static_branch(key, true);
 }
 
 extern struct jump_entry __start___jump_table[];
@@ -116,10 +98,13 @@ extern void static_key_slow_inc(struct static_key *key);
 extern void static_key_slow_dec(struct static_key *key);
 extern void jump_label_apply_nops(struct module *mod);
 
-#define STATIC_KEY_INIT_TRUE ((struct static_key) \
-	{ .enabled = ATOMIC_INIT(1), .entries = (void *)1 })
-#define STATIC_KEY_INIT_FALSE ((struct static_key) \
-	{ .enabled = ATOMIC_INIT(0), .entries = (void *)0 })
+/* this function does not exactly belong here, but it is the path of least
+ * resistance; refactoring will move it into arch specific code */
+static inline enum jump_label_type
+jump_label_default_branch(struct jump_entry *entry) {
+	return entry->default_branch ? JUMP_LABEL_ENABLE
+	                             : JUMP_LABEL_DISABLE;
+}
 
 #else  /* !HAVE_JUMP_LABEL */
 
@@ -168,14 +153,12 @@ static inline int jump_label_apply_nops(struct module *mod)
 	return 0;
 }
 
-#define STATIC_KEY_INIT_TRUE ((struct static_key) \
-		{ .enabled = ATOMIC_INIT(1) })
-#define STATIC_KEY_INIT_FALSE ((struct static_key) \
-		{ .enabled = ATOMIC_INIT(0) })
-
 #endif	/* HAVE_JUMP_LABEL */
 
-#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
+#define STATIC_KEY_INIT(x) ((struct static_key) { .enabled = ATOMIC_INIT(x) })
+#define STATIC_KEY_INIT_TRUE  STATIC_KEY_INIT(1)
+#define STATIC_KEY_INIT_FALSE STATIC_KEY_INIT(0)
+
 #define jump_label_enabled static_key_enabled
 
 static inline bool static_key_enabled(struct static_key *key)
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 30aa3b0..3670c0e 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -63,10 +63,7 @@ void static_key_slow_inc(struct static_key *key)
 
 	jump_label_lock();
 	if (atomic_read(&key->enabled) == 0) {
-		if (!jump_label_get_branch_default(key))
-			jump_label_update(key, JUMP_LABEL_ENABLE);
-		else
-			jump_label_update(key, JUMP_LABEL_DISABLE);
+		jump_label_update(key, JUMP_LABEL_ENABLE);
 	}
 	atomic_inc(&key->enabled);
 	jump_label_unlock();
@@ -98,10 +95,7 @@ static void __static_key_slow_dec(struct static_key *key,
 			WARN(1, "jump label: negative deferred count!\n");
 		}
 	} else {
-		if (!jump_label_get_branch_default(key))
-			jump_label_update(key, JUMP_LABEL_DISABLE);
-		else
-			jump_label_update(key, JUMP_LABEL_ENABLE);
+		jump_label_update(key, JUMP_LABEL_DISABLE);
 	}
 	jump_label_unlock();
 }
@@ -189,13 +183,8 @@ static void __jump_label_update(struct static_key *key,
 
 static enum jump_label_type jump_label_type(struct static_key *key)
 {
-	bool true_branch = jump_label_get_branch_default(key);
-	bool state = static_key_enabled(key);
-
-	if ((!true_branch && state) || (true_branch && !state))
-		return JUMP_LABEL_ENABLE;
-
-	return JUMP_LABEL_DISABLE;
+	return static_key_enabled(key) ? JUMP_LABEL_ENABLE
+	                               : JUMP_LABEL_DISABLE;
 }
 
 static void static_key_rate_limit_flush(struct static_key *key)
@@ -225,10 +214,7 @@ void __init jump_label_init(void)
 			continue;
 
 		key = iterk;
-		/*
-		 * Set key->entries to iter, but preserve JUMP_LABEL_TRUE_BRANCH.
-		 */
-		*((unsigned long *)&key->entries) += (unsigned long)iter;
+		*((unsigned long *)&key->entries) = (unsigned long)iter;
 #ifdef CONFIG_MODULES
 		key->next = NULL;
 #endif
@@ -319,10 +305,7 @@ static int jump_label_add_module(struct module *mod)
 
 		key = iterk;
 		if (__module_address(iter->key) == mod) {
-			/*
-			 * Set key->entries to iter, but preserve JUMP_LABEL_TRUE_BRANCH.
-			 */
-			*((unsigned long *)&key->entries) += (unsigned long)iter;
+			*((unsigned long *)&key->entries) = (unsigned long)iter;
 			key->next = NULL;
 			continue;
 		}
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCHv1 0/8] ALSA: Add SAI driver and enable SGT15000 codec.
From: Lothar Waßmann @ 2013-10-17 10:22 UTC (permalink / raw)
  To: Xiubo Li
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, timur, perex,
	r65073, linux, b42378, linux-arm-kernel, grant.likely, devicetree,
	ian.campbell, pawel.moll, swarren, rob.herring, broonie, oskar,
	fabio.estevam, lgirdwood, linux-kernel, rob, r64188, shawn.guo,
	linuxppc-dev
In-Reply-To: <1382000477-17304-1-git-send-email-Li.Xiubo@freescale.com>

Hi,

Xiubo Li <Li.Xiubo@freescale.com> wrote:

The subject has a wrong name for the codec "SGT1..." instead of
"SGTL...", which will make it difficult to search for this thread in
mail archives or in commit messages once this patches should be applied!


Lothar Wa=C3=9Fmann
--=20
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra=C3=9Fe 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch=C3=A4ftsf=C3=BChrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

^ permalink raw reply

* Re: [PATCH] powerpc/vio: Fix modalias_show return values
From: Prarit Bhargava @ 2013-10-17 11:50 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: linuxppc-dev, stable
In-Reply-To: <1381982024.3267.14.camel@deadeye.wl.decadent.org.uk>



On 10/16/2013 11:53 PM, Ben Hutchings wrote:
> Commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 introduces a trivial
> local denial of service.
> 
>> --- a/arch/powerpc/kernel/vio.c
>> +++ b/arch/powerpc/kernel/vio.c
>> @@ -1351,11 +1351,15 @@ static ssize_t modalias_show(struct devi
>>  	const char *cp;
>>  
>>  	dn = dev->of_node;
>> -	if (!dn)
>> -		return -ENODEV;
>> +	if (!dn) {
>> +		strcat(buf, "\n");
> 
> Every read from the same sysfs file handle uses the same buffer, which
> gets zero-initialised just once.  So if I open the file, read it and
> seek back to 0 repeatedly, I can make modalias_show() write arbitrary
> numbers of newlines into *and beyond* that page-sized buffer.
> 
> Obviously strcat() should be strcpy().
> 

D'oh!  Of course -- I wasn't thinking clearly about that.  I'll send out a new
patch.

P.

> Ben.
> 
>> +		return strlen(buf);
>> +	}
>>  	cp = of_get_property(dn, "compatible", NULL);
>> -	if (!cp)
>> -		return -ENODEV;
>> +	if (!cp) {
>> +		strcat(buf, "\n");
>> +		return strlen(buf);
>> +	}
>>  
>>  	return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp);
>>  }
> 

^ permalink raw reply

* [PATCH] [PATCH] powerpc/vio: use strcpy in modalias_show
From: Prarit Bhargava @ 2013-10-17 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Prarit Bhargava, ben, stable

Commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 used strcat instead of
strcpy which can result in an overflow of newlines on the buffer.

Signed-off-by: Prarit Bhargava
Cc: benh@kernel.crashing.org
Cc: ben@decadent.org.uk
Cc: stable@vger.kernel.org
---
 arch/powerpc/kernel/vio.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index d38cc08..cb92d82 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1531,12 +1531,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
 	dn = dev->of_node;
 	if (!dn) {
-		strcat(buf, "\n");
+		strcpy(buf, "\n");
 		return strlen(buf);
 	}
 	cp = of_get_property(dn, "compatible", NULL);
 	if (!cp) {
-		strcat(buf, "\n");
+		strcpy(buf, "\n");
 		return strlen(buf);
 	}
 
-- 
1.7.9.3

^ permalink raw reply related

* Re: [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Timur Tabi @ 2013-10-17 12:15 UTC (permalink / raw)
  To: Xiubo Li, r65073, lgirdwood, broonie
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, perex, LW,
	linux, b42378, oskar, grant.likely, devicetree, ian.campbell,
	pawel.moll, swarren, rob.herring, linux-arm-kernel, fabio.estevam,
	linux-kernel, rob, r64188, shawn.guo, linuxppc-dev
In-Reply-To: <1382000477-17304-2-git-send-email-Li.Xiubo@freescale.com>

Xiubo Li wrote:
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	sai->base = devm_ioremap_resource(&pdev->dev, res);

Why not use of_iomap()?

^ permalink raw reply

* powerpc: Fix little endian issue in OF PCI scan
From: Anton Blanchard @ 2013-10-17 12:19 UTC (permalink / raw)
  To: benh, paulus, tony; +Cc: linuxppc-dev

    
This issue was causing the QEMU emulated USB device to fail dring
PCI probe.
    
Signed-off-by: Anton Blanchard <anton@samba.org>
---

diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 4368ec6..ac0b034 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -302,7 +302,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
 			    struct device_node *dn)
 {
 	struct pci_dev *dev = NULL;
-	const u32 *reg;
+	const __be32 *reg;
 	int reglen, devfn;
 
 	pr_debug("  * %s\n", dn->full_name);
@@ -312,7 +312,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
 	reg = of_get_property(dn, "reg", &reglen);
 	if (reg == NULL || reglen < 20)
 		return NULL;
-	devfn = (reg[0] >> 8) & 0xff;
+	devfn = (of_read_number(reg, 1) >> 8) & 0xff;
 
 	/* Check if the PCI device is already there */
 	dev = pci_get_slot(bus, devfn);

^ permalink raw reply related

* [PATCH] powerpc/pseries: Fix endian issues in pseries iommu code
From: Anton Blanchard @ 2013-10-17 12:21 UTC (permalink / raw)
  To: benh, paulus, tony, aik; +Cc: linuxppc-dev

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

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 0307901..f253361 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -52,7 +52,7 @@
 
 
 static void tce_invalidate_pSeries_sw(struct iommu_table *tbl,
-				      u64 *startp, u64 *endp)
+				      __be64 *startp, __be64 *endp)
 {
 	u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
 	unsigned long start, end, inc;
@@ -86,7 +86,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
 			      struct dma_attrs *attrs)
 {
 	u64 proto_tce;
-	u64 *tcep, *tces;
+	__be64 *tcep, *tces;
 	u64 rpn;
 
 	proto_tce = TCE_PCI_READ; // Read allowed
@@ -94,12 +94,12 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
 	if (direction != DMA_TO_DEVICE)
 		proto_tce |= TCE_PCI_WRITE;
 
-	tces = tcep = ((u64 *)tbl->it_base) + index;
+	tces = tcep = ((__be64 *)tbl->it_base) + index;
 
 	while (npages--) {
 		/* can't move this out since we might cross MEMBLOCK boundary */
 		rpn = __pa(uaddr) >> TCE_SHIFT;
-		*tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+		*tcep = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
 
 		uaddr += TCE_PAGE_SIZE;
 		tcep++;
@@ -113,9 +113,9 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
 
 static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 {
-	u64 *tcep, *tces;
+	__be64 *tcep, *tces;
 
-	tces = tcep = ((u64 *)tbl->it_base) + index;
+	tces = tcep = ((__be64 *)tbl->it_base) + index;
 
 	while (npages--)
 		*(tcep++) = 0;
@@ -126,11 +126,11 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 
 static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 {
-	u64 *tcep;
+	__be64 *tcep;
 
-	tcep = ((u64 *)tbl->it_base) + index;
+	tcep = ((__be64 *)tbl->it_base) + index;
 
-	return *tcep;
+	return be64_to_cpu(*tcep);
 }
 
 static void tce_free_pSeriesLP(struct iommu_table*, long, long);
@@ -177,7 +177,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	return ret;
 }
 
-static DEFINE_PER_CPU(u64 *, tce_page);
+static DEFINE_PER_CPU(__be64 *, tce_page);
 
 static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				     long npages, unsigned long uaddr,
@@ -186,7 +186,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 {
 	u64 rc = 0;
 	u64 proto_tce;
-	u64 *tcep;
+	__be64 *tcep;
 	u64 rpn;
 	long l, limit;
 	long tcenum_start = tcenum, npages_start = npages;
@@ -206,7 +206,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	 * from iommu_alloc{,_sg}()
 	 */
 	if (!tcep) {
-		tcep = (u64 *)__get_free_page(GFP_ATOMIC);
+		tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
 		/* If allocation fails, fall back to the loop implementation */
 		if (!tcep) {
 			local_irq_restore(flags);
@@ -230,7 +230,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 		limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
 
 		for (l = 0; l < limit; l++) {
-			tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+			tcep[l] = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
 			rpn++;
 		}
 
@@ -329,16 +329,16 @@ struct direct_window {
 
 /* Dynamic DMA Window support */
 struct ddw_query_response {
-	u32 windows_available;
-	u32 largest_available_block;
-	u32 page_size;
-	u32 migration_capable;
+	__be32 windows_available;
+	__be32 largest_available_block;
+	__be32 page_size;
+	__be32 migration_capable;
 };
 
 struct ddw_create_response {
-	u32 liobn;
-	u32 addr_hi;
-	u32 addr_lo;
+	__be32 liobn;
+	__be32 addr_hi;
+	__be32 addr_lo;
 };
 
 static LIST_HEAD(direct_window_list);
@@ -392,7 +392,8 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 					unsigned long num_pfn, const void *arg)
 {
 	const struct dynamic_dma_window_prop *maprange = arg;
-	u64 *tcep, tce_size, num_tce, dma_offset, next, proto_tce, liobn;
+	u64 tce_size, num_tce, dma_offset, next, proto_tce, liobn;
+	__be64 *tcep;
 	u32 tce_shift;
 	u64 rc = 0;
 	long l, limit;
@@ -401,7 +402,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 	tcep = __get_cpu_var(tce_page);
 
 	if (!tcep) {
-		tcep = (u64 *)__get_free_page(GFP_ATOMIC);
+		tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
 		if (!tcep) {
 			local_irq_enable();
 			return -ENOMEM;
@@ -435,7 +436,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 		dma_offset = next + be64_to_cpu(maprange->dma_base);
 
 		for (l = 0; l < limit; l++) {
-			tcep[l] = proto_tce | next;
+			tcep[l] = cpu_to_be64(proto_tce | next);
 			next += tce_size;
 		}
 
@@ -780,7 +781,7 @@ static u64 find_existing_ddw(struct device_node *pdn)
 	list_for_each_entry(window, &direct_window_list, list) {
 		if (window->device == pdn) {
 			direct64 = window->prop;
-			dma_addr = direct64->dma_base;
+			dma_addr = be64_to_cpu(direct64->dma_base);
 			break;
 		}
 	}
@@ -1045,11 +1046,11 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 		dev_dbg(&dev->dev, "no free dynamic windows");
 		goto out_restore_window;
 	}
-	if (query.page_size & 4) {
+	if (be32_to_cpu(query.page_size) & 4) {
 		page_shift = 24; /* 16MB */
-	} else if (query.page_size & 2) {
+	} else if (be32_to_cpu(query.page_size) & 2) {
 		page_shift = 16; /* 64kB */
-	} else if (query.page_size & 1) {
+	} else if (be32_to_cpu(query.page_size) & 1) {
 		page_shift = 12; /* 4kB */
 	} else {
 		dev_dbg(&dev->dev, "no supported direct page size in mask %x",
@@ -1059,7 +1060,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 	/* verify the window * number of ptes will map the partition */
 	/* check largest block * page size > max memory hotplug addr */
 	max_addr = memory_hotplug_max();
-	if (query.largest_available_block < (max_addr >> page_shift)) {
+	if (be32_to_cpu(query.largest_available_block) < (max_addr >> page_shift)) {
 		dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
 			  "%llu-sized pages\n", max_addr,  query.largest_available_block,
 			  1ULL << page_shift);
@@ -1085,7 +1086,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 	if (ret != 0)
 		goto out_free_prop;
 
-	ddwprop->liobn = cpu_to_be32(create.liobn);
+	ddwprop->liobn = create.liobn;
 	ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2));
 	ddwprop->tce_shift = cpu_to_be32(page_shift);
 	ddwprop->window_shift = cpu_to_be32(len);

^ permalink raw reply related

* RE: [PATCH] [PATCH] powerpc/vio: use strcpy in modalias_show
From: David Laight @ 2013-10-17 12:22 UTC (permalink / raw)
  To: Prarit Bhargava, linuxppc-dev; +Cc: ben, stable
In-Reply-To: <1382011211-15272-1-git-send-email-prarit@redhat.com>

> Commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 used strcat instead of
> strcpy which can result in an overflow of newlines on the buffer.
...
> --- a/arch/powerpc/kernel/vio.c
> +++ b/arch/powerpc/kernel/vio.c
> @@ -1531,12 +1531,12 @@ static ssize_t modalias_show(struct device =
*dev, struct device_attribute
> *attr,
>=20
>  	dn =3D dev->of_node;
>  	if (!dn) {
> -		strcat(buf, "\n");
> +		strcpy(buf, "\n");
>  		return strlen(buf);
>  	}
>  	cp =3D of_get_property(dn, "compatible", NULL);
>  	if (!cp) {
> -		strcat(buf, "\n");
> +		strcpy(buf, "\n");
>  		return strlen(buf);
>  	}

Why not just:
		buf[0] =3D '\n';
		buf[1] =3D 0;
		return 1;

The assignment to buf[1] might not even be needed.

	David

^ permalink raw reply

* Re: [PATCH] [PATCH] powerpc/vio: use strcpy in modalias_show
From: Prarit Bhargava @ 2013-10-17 12:29 UTC (permalink / raw)
  To: David Laight; +Cc: ben, linuxppc-dev, stable
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B7393@saturn3.aculab.com>



On 10/17/2013 08:22 AM, David Laight wrote:
>> Commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 used strcat instead of
>> strcpy which can result in an overflow of newlines on the buffer.
> ...
>> --- a/arch/powerpc/kernel/vio.c
>> +++ b/arch/powerpc/kernel/vio.c
>> @@ -1531,12 +1531,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute
>> *attr,
>>
>>  	dn = dev->of_node;
>>  	if (!dn) {
>> -		strcat(buf, "\n");
>> +		strcpy(buf, "\n");
>>  		return strlen(buf);
>>  	}
>>  	cp = of_get_property(dn, "compatible", NULL);
>>  	if (!cp) {
>> -		strcat(buf, "\n");
>> +		strcpy(buf, "\n");
>>  		return strlen(buf);
>>  	}
> 
> Why not just:
> 		buf[0] = '\n';
> 		buf[1] = 0;
> 		return 1;
> 
> The assignment to buf[1] might not even be needed.

Sure, I guess that'd work too.  But it really seems like 1/2 a dozen of one and
six of the other.  I'll defer to the preference of the maintainers to see what
they want.

P.

> 
> 	David
> 
> 
> 

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Lars-Peter Clausen @ 2013-10-17 12:21 UTC (permalink / raw)
  To: Timur Tabi
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, linux-kernel,
	r65073, LW, linux, b42378, Xiubo Li, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, lgirdwood, rob, r64188,
	shawn.guo, linuxppc-dev
In-Reply-To: <525FD4C7.3050806@tabi.org>

On 10/17/2013 02:15 PM, Timur Tabi wrote:
> Xiubo Li wrote:
>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +    sai->base = devm_ioremap_resource(&pdev->dev, res);
> 
> Why not use of_iomap()?

Because it won't check for conflicting resource regions.

- Lars

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Timur Tabi @ 2013-10-17 13:22 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, linux-kernel,
	r65073, LW, linux, b42378, Xiubo Li, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, lgirdwood, rob, r64188,
	shawn.guo, linuxppc-dev
In-Reply-To: <525FD65B.3040004@metafoo.de>

Lars-Peter Clausen wrote:
>>> >>+    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> >>+    sai->base = devm_ioremap_resource(&pdev->dev, res);
>> >
>> >Why not use of_iomap()?
> Because it won't check for conflicting resource regions.

Maybe I've been out of the loop for too long, but why is that a 
particular problem with this driver?

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Lars-Peter Clausen @ 2013-10-17 13:33 UTC (permalink / raw)
  To: Timur Tabi
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, linux-kernel,
	r65073, LW, linux, b42378, Xiubo Li, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, lgirdwood, rob, r64188,
	shawn.guo, linuxppc-dev
In-Reply-To: <525FE48B.7020709@tabi.org>

On 10/17/2013 03:22 PM, Timur Tabi wrote:
> Lars-Peter Clausen wrote:
>>>> >>+    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>> >>+    sai->base = devm_ioremap_resource(&pdev->dev, res);
>>> >
>>> >Why not use of_iomap()?
>> Because it won't check for conflicting resource regions.
> 
> Maybe I've been out of the loop for too long, but why is that a particular
> problem with this driver?

It is usually something you'd want to check in general to make sure that you
don't have multiple device that access the same iomem region at the same time.

- Lars

^ permalink raw reply

* RE: [4/4] powerpc/mpc8548: Add workaround for erratum NMG_SRIO135
From: Zhao Chenhui-B35336 @ 2013-10-17 13:36 UTC (permalink / raw)
  To: Wood Scott-B07421; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20131016232003.GA27543@home.buserror.net>

=0A=
OK. I will do.=0A=
=0A=
-Chenhui=0A=
=0A=
________________________________________=0A=
From: Wood Scott-B07421=0A=
Sent: Thursday, October 17, 2013 7:20=0A=
To: Zhao Chenhui-B35336=0A=
Cc: linuxppc-dev@lists.ozlabs.org=0A=
Subject: Re: [4/4] powerpc/mpc8548: Add workaround for erratum NMG_SRIO135=
=0A=
=0A=
On Tue, Mar 06, 2012 at 05:10:56PM +0800, chenhui zhao wrote:=0A=
> From: chenhui zhao <chenhui.zhao@freescale.com>=0A=
>=0A=
> Issue:=0A=
> Applications using lwarx/stwcx instructions in the core to=0A=
> compete for a software lock or semaphore with a device on=0A=
> RapidIO using read atomic set, clr, inc, or dec in a similar=0A=
> manner may falsely result in both masters seeing the lock=0A=
> as "available". This could result in data corruption as=0A=
> both masters try to modify the same piece of data protected=0A=
> by the lock.=0A=
>=0A=
> Workaround:=0A=
> Set bits 13 and 29 of CCSR offset 0x01010 (EEBPCR register=0A=
> of the ECM) during initialization and leave them set=0A=
> indefinitely. This may slightly degrade overall system=0A=
> performance.=0A=
>=0A=
> Refer to SRIO39 in MPC8548 errata document.=0A=
>=0A=
> Signed-off-by: Gong Chen <g.chen@freescale.com>=0A=
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>=0A=
> Signed-off-by: Li Yang <leoli@freescale.com>=0A=
>=0A=
> ---=0A=
> arch/powerpc/sysdev/fsl_rio.c |   44 ++++++++++++++++++++++++++++++++++++=
+++++=0A=
>  1 files changed, 44 insertions(+), 0 deletions(-)=0A=
[snip]=0A=
> @@ -358,6 +391,17 @@ int fsl_rio_setup(struct platform_device *dev)=0A=
>                               dev->dev.of_node->full_name);=0A=
>               return -EFAULT;=0A=
>       }=0A=
> +=0A=
> +     /* Fix erratum NMG_SRIO135 */=0A=
> +     if (fsl_svr_is(SVR_8548) || fsl_svr_is(SVR_8548_E)) {=0A=
> +             rc =3D fixup_erratum_srio135(&dev->dev);=0A=
> +             if (rc) {=0A=
> +                     dev_err(&dev->dev,=0A=
> +                             "Failed to fix the erratum NMG_SRIO135.");=
=0A=
> +                     return rc;=0A=
> +             }=0A=
> +     }=0A=
=0A=
This needs to be respun based on the current tree.=0A=
=0A=
-Scott=0A=

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Timur Tabi @ 2013-10-17 13:37 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, linux-kernel,
	r65073, LW, linux, b42378, Xiubo Li, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, lgirdwood, rob, r64188,
	shawn.guo, linuxppc-dev
In-Reply-To: <525FE728.90403@metafoo.de>

Lars-Peter Clausen wrote:
>> >Maybe I've been out of the loop for too long, but why is that a particular
>> >problem with this driver?

> It is usually something you'd want to check in general to make sure that you
> don't have multiple device that access the same iomem region at the same time.

I understand that, but I'm trying to figure out why of_iomap() is okay 
for hundreds of other drivers, but not this one.  I've used it dozens of 
times myself, without ever worrying about overlapping regions.

^ permalink raw reply

* RE: [PATCH 0/3 v2] iommu/fsl: PAMU driver fixes.
From: Sethi Varun-B16395 @ 2013-10-17 13:47 UTC (permalink / raw)
  To: Sethi Varun-B16395, joro@8bytes.org,
	iommu@lists.linux-foundation.org, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org, Yoder Stuart-B08248,
	Wood Scott-B07421, alex.williamson@redhat.com,
	Bhushan Bharat-R65777
In-Reply-To: <1381922582-28724-1-git-send-email-Varun.Sethi@freescale.com>

Hi Joerg,
Please consider these patches for 3.12.

Regards
Varun

> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Wednesday, October 16, 2013 4:53 PM
> To: joro@8bytes.org; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Yoder Stuart-B08248;
> Wood Scott-B07421; alex.williamson@redhat.com; Bhushan Bharat-R65777
> Cc: Sethi Varun-B16395
> Subject: [PATCH 0/3 v2] iommu/fsl: PAMU driver fixes.
>=20
> The first patch fixes a build failure, when we try to build for a
> Freescale platform without PCI support.
>=20
> The second patch enables a default DMA window for the device, once it's
> detached from a domain. In case of vfio, once device is detached from a
> guest it can be again used by the host.
>=20
> The last patch adds the maintainer entry for the Freescale PAMU driver.
>=20
> Varun Sethi (3):
>   iommu/fsl: Factor out PCI specific code.
>   iommu/fsl: Enable default DMA window for PCIe devices once detached
>   Add maintainers entry for the Freescale PAMU driver.
>=20
>  MAINTAINERS                     |    7 ++
>  drivers/iommu/fsl_pamu.c        |   43 ++++++++++---
>  drivers/iommu/fsl_pamu.h        |    1 +
>  drivers/iommu/fsl_pamu_domain.c |  134 +++++++++++++++++++++++++--------
> ------
>  4 files changed, 128 insertions(+), 57 deletions(-)
>=20
> --
> 1.7.9.5

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Lars-Peter Clausen @ 2013-10-17 13:51 UTC (permalink / raw)
  To: Timur Tabi
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, linux-kernel,
	r65073, LW, linux, b42378, Xiubo Li, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, lgirdwood, rob, r64188,
	shawn.guo, linuxppc-dev
In-Reply-To: <525FE815.1040300@tabi.org>

On 10/17/2013 03:37 PM, Timur Tabi wrote:
> Lars-Peter Clausen wrote:
>>> >Maybe I've been out of the loop for too long, but why is that a particular
>>> >problem with this driver?
> 
>> It is usually something you'd want to check in general to make sure that you
>> don't have multiple device that access the same iomem region at the same
>> time.
> 
> I understand that, but I'm trying to figure out why of_iomap() is okay for
> hundreds of other drivers, but not this one.  I've used it dozens of times
> myself, without ever worrying about overlapping regions.

The driver would work fine with just of_iomap(). But the resource range
check comes basically for free and it does help to catch errors, so I'd
recommend on using it rather than not using it.

- Lars

^ permalink raw reply

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Mark Brown @ 2013-10-17 14:10 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, Timur Tabi,
	lgirdwood, r65073, LW, linux, b42378, Xiubo Li, oskar,
	grant.likely, devicetree, ian.campbell, pawel.moll, swarren,
	rob.herring, linux-arm-kernel, fabio.estevam, linux-kernel, rob,
	r64188, shawn.guo, linuxppc-dev
In-Reply-To: <525FEB7A.5040406@metafoo.de>

[-- Attachment #1: Type: text/plain, Size: 710 bytes --]

On Thu, Oct 17, 2013 at 03:51:54PM +0200, Lars-Peter Clausen wrote:
> On 10/17/2013 03:37 PM, Timur Tabi wrote:

> > I understand that, but I'm trying to figure out why of_iomap() is okay for
> > hundreds of other drivers, but not this one.  I've used it dozens of times
> > myself, without ever worrying about overlapping regions.

> The driver would work fine with just of_iomap(). But the resource range
> check comes basically for free and it does help to catch errors, so I'd
> recommend on using it rather than not using it.

There's also the fact that it's a devm_ function which means less error
handling code that we can break which is nice.  There's probably a case
for an improved OF helper here...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: IBM OpenPower 720 ipr driver woes
From: Robert Knight @ 2013-10-17 14:57 UTC (permalink / raw)
  To: Gavin Shan; +Cc: Brian King, Wendy Xiong, linuxppc-dev
In-Reply-To: <20130607002459.GA5512@shangw.(null)>

On 06/06/2013 08:24 PM, Gavin Shan wrote:
> On Thu, Jun 06, 2013 at 08:39:45AM -0400, Robert Knight wrote:
>> On 06/06/2013 07:32 AM, Brian King wrote:
>>> On 06/05/2013 04:14 PM, Robert Knight wrote:
>>>> On 6/3/2013 11:52 PM, Gavin Shan wrote:
>>>>> On Tue, Jun 04, 2013 at 01:16:52PM +1000, Tony Breeds wrote:
>>>>>> On Mon, Jun 03, 2013 at 09:40:52PM -0400, Robert Knight wrote:
>>>>>>> On 6/3/2013 8:01 PM, Tony Breeds wrote:
>>>>>>>> On Mon, Jun 03, 2013 at 05:20:12PM -0400, Robert Knight wrote:
> .../...
>
>> Yes.  I've started rebuilding the kernel and I'm up to the module
>> building part, so I'd say it is solid.  Will this patch make it into
>> some version of the kernel?
>>
> The patch is being pushed to mainline or linux-next, and backported
> to stable-kernel (v3.4+)
>
>
>> What was killing me was that it would not complete boot.  It now
>> does.  I see:
>>
>> [   11.934481] scsi 0:0:15:0: Resetting device
>> [   11.934813] ipr 0001:d0:01.0: Adapter being reset as a result of
>> error recovery.
>>
>> on each boot.  It does not appear to affect operation.
>>
>> Thank you and the rest of the team for your rapid and helpful responses.
>>
> Thanks,
> Gavin
>
Well, it's four months later and I'm trying to get Fedora 20 Alpha to 
install on that same machine.  It appears to still have the same 
problem.  Did that patch ever make it into the mainline?

Strangely, the kernel from the installer (using DVD image) does NOT have 
the problem, only the installed system.

Regards,
Robert

^ permalink raw reply

* Re: [PATCH v5] powerpc/mpc85xx: Update the clock nodes in device tree
From: Scott Wood @ 2013-10-17 16:24 UTC (permalink / raw)
  To: Tang Yuantian-B29983
  Cc: Mark Rutland, Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org,
	Li Yang-Leo-R58472, devicetree@vger.kernel.org
In-Reply-To: <D07C73A334FF604B95B3CBD2A545D07B150C4600@039-SN2MPN1-013.039d.mgd.msft.net>

On Wed, 2013-10-16 at 21:08 -0500, Tang Yuantian-B29983 wrote:
> > > > That shows the dividers as being somewhere in between the PLL and the
> > MUX.
> > > > The MUX is where the divider is selected.  There's nothing in the
> > > > PLL's programming interface that relates to the dividers.  As such
> > > > it's simpler to model it as being part of the MUX.
> > > >
> > > > -Scott
> > > >
> > > I don't know whether it is simpler, but "modeling divider as being part
> > of the MUX"
> > > is your guess, right?
> > > If the "divider" is included in MUX, the MUX would not be called "MUX".
> > 
> > It's still selecting from multiple PLLs.
> > 
> > > I don't know whether "divider" module exists or not. If it exists, it
> > > should be part of PLL or between PLL and MUX. wherever it was, the
> > device tree binding is appropriate.
> > 
> > The device tree binding is unnecessarily complicated.
> > 
> > > The P3041RM shows exactly each PLL has 2 outputs which definitely have
> > no "divider" at all.
> > 
> > That diagram is a bit weird -- one of the outputs is used as is, and the
> > other is split into 1/2 and 1/4.  It doesn't really matter though; the
> > end result is the same.  We're describing the programming interface, not
> > artwork choices in the manual.
> > 
> > -Scott
> > 
> If the device tree needs to be modified, could you give me your suggestions?

My suggestion is to have only one output per PLL node.  The MUX node
would have one input per PLL.  Dividers would be handled internally to
the MUX driver.

-Scott

^ permalink raw reply

* Re: [PATCH -V2 00/14] Allow PR and HV KVM to coexist in one kernel
From: Alexander Graf @ 2013-10-17 16:49 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: Paul Mackerras, linuxppc-dev, kvm-ppc,
	kvm@vger.kernel.org mailing list
In-Reply-To: <1381164482-31001-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>


On 07.10.2013, at 18:47, Aneesh Kumar K.V =
<aneesh.kumar@linux.vnet.ibm.com> wrote:

> Hi All,
>=20
> This patch series support enabling HV and PR KVM together in the same =
kernel. We
> extend machine property with new property "kvm_type". A value of "HV" =
will force HV
> KVM and "PR" PR KVM. If we don't specify kvm_type we will select the =
fastest KVM mode.
> ie, HV if that is supported otherwise PR.

Thanks, applied all to kvm-ppc-queue.


Alex

^ permalink raw reply

* Re: [PATCH -V2 06/14] kvm: powerpc: booke: Convert BOOKE to use kvmppc_ops callbacks
From: Alexander Graf @ 2013-10-17 16:50 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: Paul Mackerras, linuxppc-dev, kvm-ppc,
	kvm@vger.kernel.org mailing list
In-Reply-To: <1381164482-31001-7-git-send-email-aneesh.kumar@linux.vnet.ibm.com>


On 07.10.2013, at 18:47, Aneesh Kumar K.V =
<aneesh.kumar@linux.vnet.ibm.com> wrote:

> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>=20
> Make required changes to get BOOKE configs to build with
> the introduction of kvmppc_ops callback
>=20
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

This can not be a separate commit, as you're breaking bisectability for =
booke this way.

I've squashed this in with the previous commit.


Alex

^ permalink raw reply

* Re: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and altivec idle
From: Scott Wood @ 2013-10-17 16:51 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org,
	Bhushan Bharat-R65777
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259010B189E@039-SN2MPN1-021.039d.mgd.msft.net>

On Thu, 2013-10-17 at 00:51 -0500, Wang Dongsheng-B40534 wrote:
> 
> > -----Original Message-----
> > From: Bhushan Bharat-R65777
> > Sent: Thursday, October 17, 2013 11:20 AM
> > To: Wang Dongsheng-B40534; Wood Scott-B07421
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Subject: RE: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and
> > altivec idle
> > 
> > 
> > 
> > > -----Original Message-----
> > > From: Wang Dongsheng-B40534
> > > Sent: Thursday, October 17, 2013 8:16 AM
> > > To: Bhushan Bharat-R65777; Wood Scott-B07421
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Subject: RE: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and
> > > altivec idle
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Bhushan Bharat-R65777
> > > > Sent: Thursday, October 17, 2013 1:01 AM
> > > > To: Wang Dongsheng-B40534; Wood Scott-B07421
> > > > Cc: linuxppc-dev@lists.ozlabs.org
> > > > Subject: RE: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state
> > > > and altivec idle
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wang Dongsheng-B40534
> > > > > Sent: Tuesday, October 15, 2013 2:51 PM
> > > > > To: Wood Scott-B07421
> > > > > Cc: Bhushan Bharat-R65777; linuxppc-dev@lists.ozlabs.org; Wang
> > > > Dongsheng-B40534
> > > > > Subject: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and
> > > > altivec idle
> > > > >
> > > > > +static ssize_t show_pw20_wait_time(struct device *dev,
> > > > > +				struct device_attribute *attr, char *buf) {
> > > > > +	u32 value;
> > > > > +	u64 tb_cycle;
> > > > > +	s64 time;
> > > > > +
> > > > > +	unsigned int cpu = dev->id;
> > > > > +
> > > > > +	if (!pw20_wt) {
> > > > > +		smp_call_function_single(cpu, do_show_pwrmgtcr0, &value,
> > 1);
> > > > > +		value = (value & PWRMGTCR0_PW20_ENT) >>
> > > > > +					PWRMGTCR0_PW20_ENT_SHIFT;
> > > > > +
> > > > > +		tb_cycle = (1 << (MAX_BIT - value)) * 2;
> > > >
> > > > Is value = 0 and value = 1 legal? These will make tb_cycle = 0,
> > > >
> > > > > +		time = div_u64(tb_cycle * 1000, tb_ticks_per_usec) - 1;
> > > >
> > > > And time = -1;
> > > >
> > > Please look at the end of the function, :)
> > >
> > > "return sprintf(buf, "%llu\n", time > 0 ? time : 0);"
> > 
> > I know you return 0 if value = 0/1, my question was that, is this correct
> > as per specification?
> > 
> > Ahh, also for "value" upto 7 you will return 0, no?
> > 
> If value = 0, MAX_BIT - value = 63
> tb_cycle = 0xffffffff_ffffffff, 

Actually, tb_cycle will be undefined because you shifted a 32-bit value
(1) by more than 31 bits.  s/1/1ULL/

> tb_cycle * 1000 will overflow, but this situation is not possible.
> Because if the "value = 0" means this feature will be "disable".
> Now The default wait bit is 50(MAX_BIT - value, value = 13), the
> PW20/Altivec Idle wait entry time is about 1ms, this time is very long
> for wait idle time, and it's cannot be increased(means (MAX_BIT -
> value) cannot greater than 50).

Why can it not be increased?

-Scott

^ permalink raw reply

* Re: [PATCH 02/10][v6] powerpc/Power7: detect load/store instructions
From: Sukadev Bhattiprolu @ 2013-10-17 17:20 UTC (permalink / raw)
  To: David Laight, Arnaldo Carvalho de Melo
  Cc: Michael Ellerman, linux-kernel, Stephane Eranian, linuxppc-dev,
	Paul Mackerras, Anshuman Khandual
In-Reply-To: <20131016152742.GB25073@us.ibm.com>

| 
| How about I add this to the function header ?
| 
|  * Please use the table in Appendix F (opcode maps) to determine
|  * events selected by this function.

Here is the updated patch with the comment.
---

>From 38d1f9ac67a7f50db593e5875a8de6a2ecbea8e0 Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Fri, 23 Aug 2013 18:35:02 -0700
Subject: [PATCH 6/10][v6] powerpc/Power7: detect load/store instructions

Implement instr_is_load_store_2_06() to detect whether a given instruction
is one of the fixed-point or floating-point load/store instructions in the
POWER Instruction Set Architecture v2.06.

This function will be used in a follow-on patch to save memory hierarchy
information of the load/store on a Power7 system. (Power8 systems set some
bits in the SIER to identify load/store operations and hence don't need a
similar functionality).

Based on optimized code from Michael Ellerman and comments from Tom Musta.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
Changelog[v6]
	- [David Laight, Anshuman Khandual] Add a comment in function
	  header to help better understand which instructions are selected
	  by the instr_is_load_store_2_06().
	- [Michael Ellerman, Tom Musta]: Optmize the implementation to
	  avoid for loop.

 arch/powerpc/include/asm/code-patching.h |    1 +
 arch/powerpc/lib/code-patching.c         |   48 ++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index a6f8c7a..9cc3ef1 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -34,6 +34,7 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
 unsigned long branch_target(const unsigned int *instr);
 unsigned int translate_branch(const unsigned int *dest,
 			      const unsigned int *src);
+int instr_is_load_store_2_06(const unsigned int *instr);
 
 static inline unsigned long ppc_function_entry(void *func)
 {
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 2bc9db3..84571aa 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -159,6 +159,54 @@ unsigned int translate_branch(const unsigned int *dest, const unsigned int *src)
 	return 0;
 }
 
+/*
+ * Determine if the op code in the instruction corresponds to a load or
+ * store instruction. Ignore the vector load instructions like evlddepx,
+ * evstddepx for now.
+ *
+ * This function is valid for POWER ISA 2.06.
+ *
+ * Reference:	PowerISA_V2.06B_Public.pdf, Sections 3.3.2 through 3.3.6
+ *		and 4.6.2 through 4.6.4, Appendix F (Opcode Maps).
+ *
+ *		Use the tables in Appendix F (Opcode Maps) to identify
+ *		instructions selected by this function.
+ */
+int instr_is_load_store_2_06(const unsigned int *instr)
+{
+	unsigned int op, upper, lower;
+
+	op = instr_opcode(*instr);
+
+	if ((op >= 32 && op <= 58) || (op == 61 || op == 62))
+		return true;
+
+	if (op != 31)
+		return false;
+
+	upper = op >> 5;
+	lower = op & 0x1f;
+
+	/* Short circuit as many misses as we can */
+	if (lower < 3 || lower > 23)
+		return false;
+
+	if (lower == 3) {
+		if (upper >= 16)
+			return true;
+
+		return false;
+	}
+
+	if (lower == 7 || lower == 12)
+		return true;
+
+	if (lower >= 20) /* && lower <= 23 (implicit) */
+		return true;
+
+	return false;
+}
+
 
 #ifdef CONFIG_CODE_PATCHING_SELFTEST
 
-- 
1.7.9.5

^ permalink raw reply related

* Re: [alsa-devel] [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
From: Lars-Peter Clausen @ 2013-10-17 17:43 UTC (permalink / raw)
  To: Xiubo Li
  Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, timur,
	lgirdwood, r65073, LW, linux, b42378, oskar, grant.likely,
	devicetree, ian.campbell, pawel.moll, swarren, rob.herring,
	broonie, linux-arm-kernel, fabio.estevam, linux-kernel, rob,
	r64188, shawn.guo, linuxppc-dev
In-Reply-To: <1382000477-17304-2-git-send-email-Li.Xiubo@freescale.com>

On 10/17/2013 11:01 AM, Xiubo Li wrote:
[...]
> +static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
> +		struct snd_pcm_hw_params *params,
> +		struct snd_soc_dai *cpu_dai)
> +{
> +	int ret;
> +
> +	ret = fsl_sai_hw_params_tr(substream, params, cpu_dai,
> +				FSL_FMT_TRANSMITTER);
> +	if (ret) {
> +		dev_err(cpu_dai->dev,
> +				"Cannot set sai transmitter hw params: %d\n",
> +				ret);
> +		return ret;
> +	}
> +
> +	ret = fsl_sai_hw_params_tr(substream, params, cpu_dai,
> +				FSL_FMT_RECEIVER);
> +	if (ret) {
> +		dev_err(cpu_dai->dev,
> +				"Cannot set sai's receiver hw params: %d\n",
> +				ret);
> +		return ret;
> +	}

Shouldn't, depending on the substream direction, either transmit or receiver
be configured, instead of always configuring both?

> +
> +	return 0;
> +}
> +
> +static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
> +		struct snd_soc_dai *dai)
> +{
> +	struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
> +	unsigned int tcsr, rcsr;
> +
> +	tcsr = readl(sai->base + SAI_TCSR);
> +	rcsr = readl(sai->base + SAI_RCSR);
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> +		rcsr |= SAI_CSR_TERE | SAI_CSR_FRDE;
> +		tcsr |= SAI_CSR_TERE | SAI_CSR_FRDE;
> +		writel(rcsr, sai->base + SAI_RCSR);
> +		udelay(10);
> +		writel(tcsr, sai->base + SAI_TCSR);
> +		break;
> +
> +	case SNDRV_PCM_TRIGGER_STOP:
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> +		tcsr &= ~(SAI_CSR_TERE | SAI_CSR_FRDE);
> +		rcsr &= ~(SAI_CSR_TERE | SAI_CSR_FRDE);
> +		writel(tcsr, sai->base + SAI_TCSR);
> +		udelay(10);
> +		writel(rcsr, sai->base + SAI_RCSR);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +

Same here, shouldn't tx and rx be started independently depending on the
substream direction?

> +	return 0;
> +}
> +
> +static struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {

const

> +	.set_sysclk	= fsl_sai_set_dai_sysclk,
> +	.set_clkdiv	= fsl_sai_set_dai_clkdiv,
> +	.set_fmt	= fsl_sai_set_dai_fmt,
> +	.set_tdm_slot	= fsl_sai_set_dai_tdm_slot,
> +	.hw_params	= fsl_sai_hw_params,
> +	.trigger	= fsl_sai_trigger,
> +};
[...]
> +static const struct snd_soc_component_driver fsl_component = {
> +	.name           = "fsl-sai",
> +};
> +
> +static int fsl_sai_probe(struct platform_device *pdev)
> +{
[...]
> +
> +	sai->dma_params_rx.addr = res->start + SAI_RDR;
> +	sai->dma_params_rx.maxburst = 6;
> +	index = of_property_match_string(np, "dma-names", "rx");
> +	ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", index,
> +				&dma_args);
> +	if (ret)
> +		return ret;
> +	sai->dma_params_rx.slave_id = dma_args.args[1];
> +
> +	sai->dma_params_tx.addr = res->start + SAI_TDR;
> +	sai->dma_params_tx.maxburst = 6;
> +	index = of_property_match_string(np, "dma-names", "tx");
> +	ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", index,
> +				&dma_args);
> +	if (ret)
> +		return ret;
> +	sai->dma_params_tx.slave_id = dma_args.args[1];

The driver should not have to manually parse the dma devicetree properties,
this is something that should be handled by the dma engine driver.

> +
> +	ret = snd_soc_register_component(&pdev->dev, &fsl_component,
> +			&fsl_sai_dai, 1);
> +	if (ret)
> +		return ret;
> +
> +	ret = fsl_pcm_dma_init(pdev);
> +	if (ret)
> +		goto out;
> +
> +	platform_set_drvdata(pdev, sai);
> +
> +	return 0;
> +
> +out:
> +	snd_soc_unregister_component(&pdev->dev);
> +	return ret;
> +}

^ permalink raw reply

* Re: [PATCH 5/7] jump_label: relax branch hinting restrictions
From: Steven Rostedt @ 2013-10-17 17:35 UTC (permalink / raw)
  To: rkrcmar
  Cc: linux-mips, x86, linux-doc, Heiko Carstens, sparclinux,
	Paul Mackerras, H. Peter Anvin, Masami Hiramatsu, linux-s390,
	Russell King, Raghavendra K T, Ingo Molnar, Andrew Jones,
	Konrad Rzeszutek Wilk, Thomas Gleixner, linux-arm-kernel,
	Richard Henderson, Jiri Kosina, linux-kernel, Ralf Baechle,
	Rob Landley, Martin Schwidefsky, linux390, linuxppc-dev,
	David S. Miller
In-Reply-To: <1382004631-25895-6-git-send-email-rkrcmar@redhat.com>

On Thu, 17 Oct 2013 12:10:28 +0200
Radim Kr=C4=8Dm=C3=A1=C5=99 <rkrcmar@redhat.com> wrote:

> We implemented the optimized branch selection in higher levels of api.
> That made static_keys very unintuitive, so this patch introduces another
> element to jump_table, carrying one bit that tells the underlying code
> which branch to optimize.
>=20
> It is now possible to select optimized branch for every jump_entry.
>=20
> Current side effect is 1/3 increase increase in space, we could:
> * use bitmasks and selectors on 2+ aligned code/struct.
>   - aligning jump target is easy, but because it is not done by default
>     and few bytes in .text are much worse that few kilos in .data,
>     I chose not to
>   - data is probably aligned by default on all current architectures,
>     but programmer can force misalignment of static_key
> * optimize each architecture independently
>   - I can't test everything and this patch shouldn't break anything, so
>     others can contribute in the future
> * choose something worse, like packing or splitting
> * ignore
>=20
> proof: example & x86_64 disassembly: (F =3D ffffffff)
>=20
>   struct static_key flexible_feature;
>   noinline void jump_label_experiment(void) {
>   	if ( static_key_false(&flexible_feature))
>   	     asm ("push 0xa1");
>   	else asm ("push 0xa0");
>   	if (!static_key_false(&flexible_feature))
>   	     asm ("push 0xb0");
>   	else asm ("push 0xb1");
>   	if ( static_key_true(&flexible_feature))
>   	     asm ("push 0xc1");
>   	else asm ("push 0xc0");
>   	if (!static_key_true(&flexible_feature))
>   	     asm ("push 0xd0");
>   	else asm ("push 0xd1");
>   }
>=20
>   Disassembly of section .text: (push marked by "->")
>=20
>   F81002000 <jump_label_experiment>:
>   F81002000:       e8 7b 29 75 00          callq  F81754980 <__fentry__>
>   F81002005:       55                      push   %rbp
>   F81002006:       48 89 e5                mov    %rsp,%rbp
>   F81002009:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   F8100200e: ->    ff 34 25 a0 00 00 00    pushq  0xa0
>   F81002015:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   F8100201a: ->    ff 34 25 b0 00 00 00    pushq  0xb0
>   F81002021:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   F81002026: ->    ff 34 25 c1 00 00 00    pushq  0xc1
>   F8100202d:       0f 1f 00                nopl   (%rax)
>   F81002030:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   F81002035: ->    ff 34 25 d1 00 00 00    pushq  0xd1
>   F8100203c:       5d                      pop    %rbp
>   F8100203d:       0f 1f 00                nopl   (%rax)
>   F81002040:       c3                      retq

This looks exactly like what we want. I take it this is with your
patch. What was the result before the patch?

-- Steve

>   F81002041:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
>   F81002048: ->    ff 34 25 d0 00 00 00    pushq  0xd0
>   F8100204f:       5d                      pop    %rbp
>   F81002050:       c3                      retq
>   F81002051:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
>   F81002058: ->    ff 34 25 c0 00 00 00    pushq  0xc0
>   F8100205f:       90                      nop
>   F81002060:       eb cb                   jmp    F8100202d <[...]+0x2d>
>   F81002062:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
>   F81002068: ->    ff 34 25 b1 00 00 00    pushq  0xb1
>   F8100206f:       90                      nop
>   F81002070:       eb af                   jmp    F81002021 <[...]+0x21>
>   F81002072:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
>   F81002078: ->    ff 34 25 a1 00 00 00    pushq  0xa1
>   F8100207f:       90                      nop
>   F81002080:       eb 93                   jmp    F81002015 <[...]+0x15>
>   F81002082:       66 66 66 66 66 2e 0f    [...]
>   F81002089:       1f 84 00 00 00 00 00
>=20
>   Contents of section .data: (relevant part of embedded __jump_table)

^ 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