bpf: move tmp variable into ax register in interpreter
This change moves the on-stack 64 bit tmp variable in ___bpf_prog_run() into the hidden ax register. The latter is currently only used in JITs for constant blinding as a temporary scratch register, meaning the BPF interpreter will never see the use of ax. Therefore it is safe to use it for the cases where tmp has been used earlier. This is needed to later on allow restricted hidden use of ax in both interpreter and JITs. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
c08435ec7f
commit
144cd91c4c
|
@ -60,7 +60,8 @@ struct sock_reuseport;
|
||||||
* constants. See JIT pre-step in bpf_jit_blind_constants().
|
* constants. See JIT pre-step in bpf_jit_blind_constants().
|
||||||
*/
|
*/
|
||||||
#define BPF_REG_AX MAX_BPF_REG
|
#define BPF_REG_AX MAX_BPF_REG
|
||||||
#define MAX_BPF_JIT_REG (MAX_BPF_REG + 1)
|
#define MAX_BPF_EXT_REG (MAX_BPF_REG + 1)
|
||||||
|
#define MAX_BPF_JIT_REG MAX_BPF_EXT_REG
|
||||||
|
|
||||||
/* unused opcode to mark special call to bpf_tail_call() helper */
|
/* unused opcode to mark special call to bpf_tail_call() helper */
|
||||||
#define BPF_TAIL_CALL 0xf0
|
#define BPF_TAIL_CALL 0xf0
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#define DST regs[insn->dst_reg]
|
#define DST regs[insn->dst_reg]
|
||||||
#define SRC regs[insn->src_reg]
|
#define SRC regs[insn->src_reg]
|
||||||
#define FP regs[BPF_REG_FP]
|
#define FP regs[BPF_REG_FP]
|
||||||
|
#define AX regs[BPF_REG_AX]
|
||||||
#define ARG1 regs[BPF_REG_ARG1]
|
#define ARG1 regs[BPF_REG_ARG1]
|
||||||
#define CTX regs[BPF_REG_CTX]
|
#define CTX regs[BPF_REG_CTX]
|
||||||
#define IMM insn->imm
|
#define IMM insn->imm
|
||||||
|
@ -1188,7 +1189,6 @@ bool bpf_opcode_in_insntable(u8 code)
|
||||||
*/
|
*/
|
||||||
static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack)
|
static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack)
|
||||||
{
|
{
|
||||||
u64 tmp;
|
|
||||||
#define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y
|
#define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y
|
||||||
#define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z
|
#define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z
|
||||||
static const void *jumptable[256] = {
|
static const void *jumptable[256] = {
|
||||||
|
@ -1268,36 +1268,36 @@ select_insn:
|
||||||
(*(s64 *) &DST) >>= IMM;
|
(*(s64 *) &DST) >>= IMM;
|
||||||
CONT;
|
CONT;
|
||||||
ALU64_MOD_X:
|
ALU64_MOD_X:
|
||||||
div64_u64_rem(DST, SRC, &tmp);
|
div64_u64_rem(DST, SRC, &AX);
|
||||||
DST = tmp;
|
DST = AX;
|
||||||
CONT;
|
CONT;
|
||||||
ALU_MOD_X:
|
ALU_MOD_X:
|
||||||
tmp = (u32) DST;
|
AX = (u32) DST;
|
||||||
DST = do_div(tmp, (u32) SRC);
|
DST = do_div(AX, (u32) SRC);
|
||||||
CONT;
|
CONT;
|
||||||
ALU64_MOD_K:
|
ALU64_MOD_K:
|
||||||
div64_u64_rem(DST, IMM, &tmp);
|
div64_u64_rem(DST, IMM, &AX);
|
||||||
DST = tmp;
|
DST = AX;
|
||||||
CONT;
|
CONT;
|
||||||
ALU_MOD_K:
|
ALU_MOD_K:
|
||||||
tmp = (u32) DST;
|
AX = (u32) DST;
|
||||||
DST = do_div(tmp, (u32) IMM);
|
DST = do_div(AX, (u32) IMM);
|
||||||
CONT;
|
CONT;
|
||||||
ALU64_DIV_X:
|
ALU64_DIV_X:
|
||||||
DST = div64_u64(DST, SRC);
|
DST = div64_u64(DST, SRC);
|
||||||
CONT;
|
CONT;
|
||||||
ALU_DIV_X:
|
ALU_DIV_X:
|
||||||
tmp = (u32) DST;
|
AX = (u32) DST;
|
||||||
do_div(tmp, (u32) SRC);
|
do_div(AX, (u32) SRC);
|
||||||
DST = (u32) tmp;
|
DST = (u32) AX;
|
||||||
CONT;
|
CONT;
|
||||||
ALU64_DIV_K:
|
ALU64_DIV_K:
|
||||||
DST = div64_u64(DST, IMM);
|
DST = div64_u64(DST, IMM);
|
||||||
CONT;
|
CONT;
|
||||||
ALU_DIV_K:
|
ALU_DIV_K:
|
||||||
tmp = (u32) DST;
|
AX = (u32) DST;
|
||||||
do_div(tmp, (u32) IMM);
|
do_div(AX, (u32) IMM);
|
||||||
DST = (u32) tmp;
|
DST = (u32) AX;
|
||||||
CONT;
|
CONT;
|
||||||
ALU_END_TO_BE:
|
ALU_END_TO_BE:
|
||||||
switch (IMM) {
|
switch (IMM) {
|
||||||
|
@ -1553,7 +1553,7 @@ STACK_FRAME_NON_STANDARD(___bpf_prog_run); /* jump table */
|
||||||
static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \
|
static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \
|
||||||
{ \
|
{ \
|
||||||
u64 stack[stack_size / sizeof(u64)]; \
|
u64 stack[stack_size / sizeof(u64)]; \
|
||||||
u64 regs[MAX_BPF_REG]; \
|
u64 regs[MAX_BPF_EXT_REG]; \
|
||||||
\
|
\
|
||||||
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
|
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
|
||||||
ARG1 = (u64) (unsigned long) ctx; \
|
ARG1 = (u64) (unsigned long) ctx; \
|
||||||
|
@ -1566,7 +1566,7 @@ static u64 PROG_NAME_ARGS(stack_size)(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5, \
|
||||||
const struct bpf_insn *insn) \
|
const struct bpf_insn *insn) \
|
||||||
{ \
|
{ \
|
||||||
u64 stack[stack_size / sizeof(u64)]; \
|
u64 stack[stack_size / sizeof(u64)]; \
|
||||||
u64 regs[MAX_BPF_REG]; \
|
u64 regs[MAX_BPF_EXT_REG]; \
|
||||||
\
|
\
|
||||||
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
|
FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
|
||||||
BPF_R1 = r1; \
|
BPF_R1 = r1; \
|
||||||
|
|
Loading…
Reference in New Issue