Re: [1/3] bpf powerpc: introduce accessors for using the tmp local stack space

2016-10-04 Thread Michael Ellerman
On Fri, 2016-23-09 at 20:35:00 UTC, "Naveen N. Rao" wrote:
> While at it, ensure that the location of the local save area is
> consistent whether or not we setup our own stackframe. This property is
> utilised in the next patch that adds support for tail calls.
> 
> Signed-off-by: Naveen N. Rao 

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/7b847f523fe07b4ad73a01cec49a4d

cheers


[PATCH 1/3] bpf powerpc: introduce accessors for using the tmp local stack space

2016-09-23 Thread Naveen N. Rao
While at it, ensure that the location of the local save area is
consistent whether or not we setup our own stackframe. This property is
utilised in the next patch that adds support for tail calls.

Signed-off-by: Naveen N. Rao 
---
 arch/powerpc/net/bpf_jit64.h  | 16 +---
 arch/powerpc/net/bpf_jit_comp64.c | 79 ++-
 2 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit64.h b/arch/powerpc/net/bpf_jit64.h
index 5046d6f..a1645d7 100644
--- a/arch/powerpc/net/bpf_jit64.h
+++ b/arch/powerpc/net/bpf_jit64.h
@@ -16,22 +16,25 @@
 
 /*
  * Stack layout:
+ * Ensure the top half (upto local_tmp_var) stays consistent
+ * with our redzone usage.
  *
  * [   prev sp ] <-
  * [   nv gpr save area] 8*8   |
+ * [tail_call_cnt  ] 8 |
+ * [local_tmp_var  ] 8 |
  * fp (r31) -->[   ebpf stack space] 512   |
- * [  local/tmp var space  ] 16|
  * [ frame header  ] 32/112|
  * sp (r1) --->[stack pointer  ] --
  */
 
-/* for bpf JIT code internal usage */
-#define BPF_PPC_STACK_LOCALS   16
 /* for gpr non volatile registers BPG_REG_6 to 10, plus skb cache registers */
 #define BPF_PPC_STACK_SAVE (8*8)
+/* for bpf JIT code internal usage */
+#define BPF_PPC_STACK_LOCALS   16
 /* Ensure this is quadword aligned */
-#define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + BPF_PPC_STACK_LOCALS + \
-MAX_BPF_STACK + BPF_PPC_STACK_SAVE)
+#define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + MAX_BPF_STACK + \
+BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE)
 
 #ifndef __ASSEMBLY__
 
@@ -65,6 +68,9 @@ static const int b2p[] = {
[TMP_REG_2] = 10
 };
 
+/* PPC NVR range -- update this if we ever use NVRs below r24 */
+#define BPF_PPC_NVR_MIN24
+
 /* Assembly helpers */
 #define DECLARE_LOAD_FUNC(func)u64 func(u64 r3, u64 r4);   
\
u64 func##_negative_offset(u64 r3, u64 r4); 
\
diff --git a/arch/powerpc/net/bpf_jit_comp64.c 
b/arch/powerpc/net/bpf_jit_comp64.c
index 6073b78..5f8c91f 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -58,6 +58,35 @@ static inline bool bpf_has_stack_frame(struct 
codegen_context *ctx)
return ctx->seen & SEEN_FUNC || bpf_is_seen_register(ctx, BPF_REG_FP);
 }
 
+/*
+ * When not setting up our own stackframe, the redzone usage is:
+ *
+ * [   prev sp ] <-
+ * [ ...   ]   |
+ * sp (r1) --->[stack pointer  ] --
+ * [   nv gpr save area] 8*8
+ * [tail_call_cnt  ] 8
+ * [local_tmp_var  ] 8
+ * [   unused red zone ] 208 bytes protected
+ */
+static int bpf_jit_stack_local(struct codegen_context *ctx)
+{
+   if (bpf_has_stack_frame(ctx))
+   return STACK_FRAME_MIN_SIZE + MAX_BPF_STACK;
+   else
+   return -(BPF_PPC_STACK_SAVE + 16);
+}
+
+static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg)
+{
+   if (reg >= BPF_PPC_NVR_MIN && reg < 32)
+   return (bpf_has_stack_frame(ctx) ? BPF_PPC_STACKFRAME : 0)
+   - (8 * (32 - reg));
+
+   pr_err("BPF JIT is asking about unknown registers");
+   BUG();
+}
+
 static void bpf_jit_emit_skb_loads(u32 *image, struct codegen_context *ctx)
 {
/*
@@ -100,9 +129,8 @@ static void bpf_jit_emit_func_call(u32 *image, struct 
codegen_context *ctx, u64
 static void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
 {
int i;
-   bool new_stack_frame = bpf_has_stack_frame(ctx);
 
-   if (new_stack_frame) {
+   if (bpf_has_stack_frame(ctx)) {
/*
 * We need a stack frame, but we don't necessarily need to
 * save/restore LR unless we call other functions
@@ -122,9 +150,7 @@ static void bpf_jit_build_prologue(u32 *image, struct 
codegen_context *ctx)
 */
for (i = BPF_REG_6; i <= BPF_REG_10; i++)
if (bpf_is_seen_register(ctx, i))
-   PPC_BPF_STL(b2p[i], 1,
-   (new_stack_frame ? BPF_PPC_STACKFRAME : 0) -
-   (8 * (32 - b2p[i])));
+   PPC_BPF_STL(b2p[i], 1, bpf_jit_stack_offsetof(ctx, 
b2p[i]));
 
/*
 * Save additional non-volatile regs if we cache skb
@@ -132,22 +158,21 @@ static void bpf_jit_build_prologue(u32 *image, struct 
codegen_context *ctx)
 */
if (ctx->seen & SEEN_SKB) {
PPC_BPF_STL(b2p[SKB_HLEN_REG], 1,