mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
bpf: Move bpf_is_reg64() to fixups.c
The following patches are going to remove bpf_is_reg64() users from everywhere except fixups.c, and also make it dependent on functions local to fixups.c. Move the function before hand to simplify the review. Non functional change. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-3-b6c270013c77@gmail.com
This commit is contained in:
parent
d977dca7d0
commit
05b71078f3
|
|
@ -64,6 +64,96 @@ static int insn_def_regno(const struct bpf_insn *insn)
|
|||
}
|
||||
}
|
||||
|
||||
/* This function is supposed to be used by the zero extension optimization
|
||||
* code only. It returns TRUE if the source or destination register operates
|
||||
* on 64-bit, otherwise return FALSE.
|
||||
*/
|
||||
bool bpf_is_reg64(struct bpf_insn *insn,
|
||||
u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t)
|
||||
{
|
||||
u8 code, class, op;
|
||||
|
||||
code = insn->code;
|
||||
class = BPF_CLASS(code);
|
||||
op = BPF_OP(code);
|
||||
if (class == BPF_JMP) {
|
||||
/* BPF_EXIT for "main" will reach here. Return TRUE
|
||||
* conservatively.
|
||||
*/
|
||||
if (op == BPF_EXIT)
|
||||
return true;
|
||||
if (op == BPF_CALL) {
|
||||
/* BPF to BPF call will reach here because of marking
|
||||
* caller saved clobber with DST_OP_NO_MARK for which we
|
||||
* don't care the register def because they are anyway
|
||||
* marked as NOT_INIT already.
|
||||
*/
|
||||
if (insn->src_reg == BPF_PSEUDO_CALL)
|
||||
return false;
|
||||
/* Helper call will reach here because of arg type
|
||||
* check, conservatively return TRUE.
|
||||
*/
|
||||
if (t == SRC_OP)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class == BPF_ALU64 && op == BPF_END && (insn->imm == 16 || insn->imm == 32))
|
||||
return false;
|
||||
|
||||
if (class == BPF_ALU64 || class == BPF_JMP ||
|
||||
(class == BPF_ALU && op == BPF_END && insn->imm == 64))
|
||||
return true;
|
||||
|
||||
if (class == BPF_ALU || class == BPF_JMP32)
|
||||
return false;
|
||||
|
||||
if (class == BPF_LDX) {
|
||||
if (t != SRC_OP)
|
||||
return BPF_SIZE(code) == BPF_DW || BPF_MODE(code) == BPF_MEMSX;
|
||||
/* LDX source must be ptr. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (class == BPF_STX) {
|
||||
/* BPF_STX (including atomic variants) has one or more source
|
||||
* operands, one of which is a ptr. Check whether the caller is
|
||||
* asking about it.
|
||||
*/
|
||||
if (t == SRC_OP && reg->type != SCALAR_VALUE)
|
||||
return true;
|
||||
return BPF_SIZE(code) == BPF_DW;
|
||||
}
|
||||
|
||||
if (class == BPF_LD) {
|
||||
u8 mode = BPF_MODE(code);
|
||||
|
||||
/* LD_IMM64 */
|
||||
if (mode == BPF_IMM)
|
||||
return true;
|
||||
|
||||
/* Both LD_IND and LD_ABS return 32-bit data. */
|
||||
if (t != SRC_OP)
|
||||
return false;
|
||||
|
||||
/* Implicit ctx ptr. */
|
||||
if (regno == BPF_REG_6)
|
||||
return true;
|
||||
|
||||
/* Explicit source could be any width. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (class == BPF_ST)
|
||||
/* The only source register for BPF_ST is a ptr. */
|
||||
return true;
|
||||
|
||||
/* Conservatively return true at default. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return TRUE if INSN has defined any 32-bit value explicitly. */
|
||||
static bool insn_has_def32(struct bpf_insn *insn)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3058,96 +3058,6 @@ static void mark_stack_slots_scratched(struct bpf_verifier_env *env,
|
|||
mark_stack_slot_scratched(env, spi - i);
|
||||
}
|
||||
|
||||
/* This function is supposed to be used by the following 32-bit optimization
|
||||
* code only. It returns TRUE if the source or destination register operates
|
||||
* on 64-bit, otherwise return FALSE.
|
||||
*/
|
||||
bool bpf_is_reg64(struct bpf_insn *insn,
|
||||
u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t)
|
||||
{
|
||||
u8 code, class, op;
|
||||
|
||||
code = insn->code;
|
||||
class = BPF_CLASS(code);
|
||||
op = BPF_OP(code);
|
||||
if (class == BPF_JMP) {
|
||||
/* BPF_EXIT for "main" will reach here. Return TRUE
|
||||
* conservatively.
|
||||
*/
|
||||
if (op == BPF_EXIT)
|
||||
return true;
|
||||
if (op == BPF_CALL) {
|
||||
/* BPF to BPF call will reach here because of marking
|
||||
* caller saved clobber with DST_OP_NO_MARK for which we
|
||||
* don't care the register def because they are anyway
|
||||
* marked as NOT_INIT already.
|
||||
*/
|
||||
if (insn->src_reg == BPF_PSEUDO_CALL)
|
||||
return false;
|
||||
/* Helper call will reach here because of arg type
|
||||
* check, conservatively return TRUE.
|
||||
*/
|
||||
if (t == SRC_OP)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class == BPF_ALU64 && op == BPF_END && (insn->imm == 16 || insn->imm == 32))
|
||||
return false;
|
||||
|
||||
if (class == BPF_ALU64 || class == BPF_JMP ||
|
||||
(class == BPF_ALU && op == BPF_END && insn->imm == 64))
|
||||
return true;
|
||||
|
||||
if (class == BPF_ALU || class == BPF_JMP32)
|
||||
return false;
|
||||
|
||||
if (class == BPF_LDX) {
|
||||
if (t != SRC_OP)
|
||||
return BPF_SIZE(code) == BPF_DW || BPF_MODE(code) == BPF_MEMSX;
|
||||
/* LDX source must be ptr. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (class == BPF_STX) {
|
||||
/* BPF_STX (including atomic variants) has one or more source
|
||||
* operands, one of which is a ptr. Check whether the caller is
|
||||
* asking about it.
|
||||
*/
|
||||
if (t == SRC_OP && reg->type != SCALAR_VALUE)
|
||||
return true;
|
||||
return BPF_SIZE(code) == BPF_DW;
|
||||
}
|
||||
|
||||
if (class == BPF_LD) {
|
||||
u8 mode = BPF_MODE(code);
|
||||
|
||||
/* LD_IMM64 */
|
||||
if (mode == BPF_IMM)
|
||||
return true;
|
||||
|
||||
/* Both LD_IND and LD_ABS return 32-bit data. */
|
||||
if (t != SRC_OP)
|
||||
return false;
|
||||
|
||||
/* Implicit ctx ptr. */
|
||||
if (regno == BPF_REG_6)
|
||||
return true;
|
||||
|
||||
/* Explicit source could be any width. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (class == BPF_ST)
|
||||
/* The only source register for BPF_ST is a ptr. */
|
||||
return true;
|
||||
|
||||
/* Conservatively return true at default. */
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mark_insn_zext(struct bpf_verifier_env *env,
|
||||
struct bpf_reg_state *reg)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user