diff options
Diffstat (limited to 'arch/s390/net/bpf_jit_comp.c')
| -rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 14 | 
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 5af0402e94b8..4be8f5cadd02 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -1427,8 +1427,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,  	EMIT6_DISP_LH(0xeb000000, is32 ? (op32) : (op64),		\  		      (insn->imm & BPF_FETCH) ? src_reg : REG_W0,	\  		      src_reg, dst_reg, off);				\ -	if (is32 && (insn->imm & BPF_FETCH))				\ -		EMIT_ZERO(src_reg);					\ +	if (insn->imm & BPF_FETCH) {					\ +		/* bcr 14,0 - see atomic_fetch_{add,and,or,xor}() */	\ +		_EMIT2(0x07e0);						\ +		if (is32)                                               \ +			EMIT_ZERO(src_reg);				\ +	}								\  } while (0)  		case BPF_ADD:  		case BPF_ADD | BPF_FETCH: @@ -2108,7 +2112,11 @@ skip_init_ctx:  		print_fn_code(jit.prg_buf, jit.size_prg);  	}  	if (!fp->is_func || extra_pass) { -		bpf_jit_binary_lock_ro(header); +		if (bpf_jit_binary_lock_ro(header)) { +			bpf_jit_binary_free(header); +			fp = orig_fp; +			goto free_addrs; +		}  	} else {  		jit_data->header = header;  		jit_data->ctx = jit;  |