mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	sparc: bpf_jit: fix loads from negative offsets
- fix BPF_LD|ABS|IND from negative offsets: make sure to sign extend lower 32 bits in 64-bit register before calling C helpers from JITed code, otherwise 'int k' argument of bpf_internal_load_pointer_neg_helper() function will be added as large unsigned integer, causing packet size check to trigger and abort the program. It's worth noting that JITed code for 'A = A op K' will affect upper 32 bits differently depending whether K is simm13 or not. Since small constants are sign extended, whereas large constants are stored in temp register and zero extended. That is ok and we don't have to pay a penalty of sign extension for every sethi, since all classic BPF instructions have 32-bit semantics and we only need to set correct upper bits when transitioning from JITed code into C. - though instructions 'A &= 0' and 'A *= 0' are odd, JIT compiler should not optimize them out Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									543a2dff5e
								
							
						
					
					
						commit
						35607b02db
					
				
					 2 changed files with 4 additions and 1 deletions
				
			
		| 
						 | 
					@ -6,10 +6,12 @@
 | 
				
			||||||
#define SAVE_SZ		176
 | 
					#define SAVE_SZ		176
 | 
				
			||||||
#define SCRATCH_OFF	STACK_BIAS + 128
 | 
					#define SCRATCH_OFF	STACK_BIAS + 128
 | 
				
			||||||
#define BE_PTR(label)	be,pn %xcc, label
 | 
					#define BE_PTR(label)	be,pn %xcc, label
 | 
				
			||||||
 | 
					#define SIGN_EXTEND(reg)	sra reg, 0, reg
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SAVE_SZ		96
 | 
					#define SAVE_SZ		96
 | 
				
			||||||
#define SCRATCH_OFF	72
 | 
					#define SCRATCH_OFF	72
 | 
				
			||||||
#define BE_PTR(label)	be label
 | 
					#define BE_PTR(label)	be label
 | 
				
			||||||
 | 
					#define SIGN_EXTEND(reg)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SKF_MAX_NEG_OFF	(-0x200000) /* SKF_LL_OFF from filter.h */
 | 
					#define SKF_MAX_NEG_OFF	(-0x200000) /* SKF_LL_OFF from filter.h */
 | 
				
			||||||
| 
						 | 
					@ -135,6 +137,7 @@ bpf_slow_path_byte_msh:
 | 
				
			||||||
	save	%sp, -SAVE_SZ, %sp;			\
 | 
						save	%sp, -SAVE_SZ, %sp;			\
 | 
				
			||||||
	mov	%i0, %o0;				\
 | 
						mov	%i0, %o0;				\
 | 
				
			||||||
	mov	r_OFF, %o1;				\
 | 
						mov	r_OFF, %o1;				\
 | 
				
			||||||
 | 
						SIGN_EXTEND(%o1);				\
 | 
				
			||||||
	call	bpf_internal_load_pointer_neg_helper;	\
 | 
						call	bpf_internal_load_pointer_neg_helper;	\
 | 
				
			||||||
	 mov	(LEN), %o2;				\
 | 
						 mov	(LEN), %o2;				\
 | 
				
			||||||
	mov	%o0, r_TMP;				\
 | 
						mov	%o0, r_TMP;				\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,7 +184,7 @@ do {								\
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
#define emit_alu_K(OPCODE, K)					\
 | 
					#define emit_alu_K(OPCODE, K)					\
 | 
				
			||||||
do {								\
 | 
					do {								\
 | 
				
			||||||
	if (K) {						\
 | 
						if (K || OPCODE == AND || OPCODE == MUL) {		\
 | 
				
			||||||
		unsigned int _insn = OPCODE;			\
 | 
							unsigned int _insn = OPCODE;			\
 | 
				
			||||||
		_insn |= RS1(r_A) | RD(r_A);			\
 | 
							_insn |= RS1(r_A) | RD(r_A);			\
 | 
				
			||||||
		if (is_simm13(K)) {				\
 | 
							if (is_simm13(K)) {				\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue