Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b19a42e3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more s390 updates from Martin Schwidefsky:
 "The big thing in this second merge for s390 is the new eBPF JIT from
  Michael which replaces the old 32-bit backend.

  The remaining commits are bug fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/pci: add locking for fmb access
  s390/pci: extract software counters from fmb
  s390/dasd: Fix unresumed device after suspend/resume having no paths
  s390/dasd: fix unresumed device after suspend/resume
  s390/dasd: fix inability to set a DASD device offline
  s390/mm: Fix memory hotplug for unaligned standby memory
  s390/bpf: Add s390x eBPF JIT compiler backend
  s390: Use bool function return values of true/false not 1/0
parents 5ca08a82 80ed156a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ config S390
	select HAVE_ARCH_SECCOMP_FILTER
	select HAVE_ARCH_TRACEHOOK
	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
	select HAVE_BPF_JIT if PACK_STACK
	select HAVE_BPF_JIT if PACK_STACK && HAVE_MARCH_Z9_109_FEATURES
	select HAVE_CMPXCHG_DOUBLE
	select HAVE_CMPXCHG_LOCAL
	select HAVE_DEBUG_KMEMLEAK
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ static inline int dma_supported(struct device *dev, u64 mask)
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
	if (!dev->dma_mask)
		return 0;
		return false;
	return addr + size - 1 <= *dev->dma_mask;
}

+6 −4
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define PCI_BAR_COUNT	6

#include <linux/pci.h>
#include <linux/mutex.h>
#include <asm-generic/pci.h>
#include <asm-generic/pci-dma-compat.h>
#include <asm/pci_clp.h>
@@ -44,10 +45,6 @@ struct zpci_fmb {
	u64 rpcit_ops;
	u64 dma_rbytes;
	u64 dma_wbytes;
	/* software counters */
	atomic64_t allocated_pages;
	atomic64_t mapped_pages;
	atomic64_t unmapped_pages;
} __packed __aligned(16);

enum zpci_state {
@@ -80,6 +77,7 @@ struct zpci_dev {
	u8		pft;		/* pci function type */
	u16		domain;

	struct mutex lock;
	u8 pfip[CLP_PFIP_NR_SEGMENTS];	/* pci function internal path */
	u32 uid;			/* user defined id */
	u8 util_str[CLP_UTIL_STR_LEN];	/* utility string */
@@ -111,6 +109,10 @@ struct zpci_dev {
	/* Function measurement block */
	struct zpci_fmb *fmb;
	u16		fmb_update;	/* update interval */
	/* software counters */
	atomic64_t allocated_pages;
	atomic64_t mapped_pages;
	atomic64_t unmapped_pages;

	enum pci_bus_speed max_bus_speed;

+89 −108
Original line number Diff line number Diff line
/*
 * BPF Jit compiler for s390, help functions.
 *
 * Copyright IBM Corp. 2012
 * Copyright IBM Corp. 2012,2015
 *
 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 *	      Michael Holzheu <holzheu@linux.vnet.ibm.com>
 */

#include <linux/linkage.h>
#include "bpf_jit.h"

/*
 * Calling convention:
 * registers %r2, %r6-%r8, %r10-%r11, %r13, %r15 are call saved
 *   %r2: skb pointer
 *   %r3: offset parameter
 *   %r5: BPF A accumulator
 *   %r8: return address
 *   %r9: save register for skb pointer
 *   %r10: skb->data
 *   %r11: skb->len - skb->data_len (headlen)
 *   %r12: BPF X accumulator
 * registers %r7-%r10, %r11,%r13, and %r15 are call saved
 *
 * Input (64 bit):
 *   %r3 (%b2) = offset into skb data
 *   %r6 (%b5) = return address
 *   %r7 (%b6) = skb pointer
 *   %r12      = skb data pointer
 *
 * Output:
 *   %r14= %b0 = return value (read skb value)
 *
 * Work registers: %r2,%r4,%r5,%r14
 *
 * skb_copy_bits takes 4 parameters:
 *   %r2 = skb pointer
 *   %r3 = offset into skb data
 *   %r4 = pointer to temp buffer
 *   %r5 = length to copy
 *   Return value in %r2: 0 = ok
 *
 * bpf_internal_load_pointer_neg_helper takes 3 parameters:
 *   %r2 = skb pointer
 *   %r3 = offset into data
 *   %r4 = length to copy
 *   Return value in %r2: Pointer to data
 */
#define SKBDATA	%r8

	/* A = *(u32 *) (skb->data+K+X) */
ENTRY(sk_load_word_ind)
	ar	%r3,%r12		# offset += X
	bmr	%r8			# < 0 -> return with cc

	/* A = *(u32 *) (skb->data+K) */
ENTRY(sk_load_word)
	llgfr	%r1,%r3			# extend offset
	ahi	%r3,4			# offset + 4
	clr	%r11,%r3		# hlen <= offset + 4 ?
	jl	sk_load_word_slow
	l	%r5,0(%r1,%r10)		# get word from skb
	xr	%r1,%r1			# set cc to zero
	br	%r8

sk_load_word_slow:
	lgr	%r9,%r2			# save %r2
	lgr	%r3,%r1			# offset
	la	%r4,160(%r15)		# pointer to temp buffer
	lghi	%r5,4			# 4 bytes
	brasl	%r14,skb_copy_bits	# get data from skb
	l	%r5,160(%r15)		# load result from temp buffer
	ltgr	%r2,%r2			# set cc to (%r2 != 0)
	lgr	%r2,%r9			# restore %r2
	br	%r8
#define SKF_MAX_NEG_OFF	-0x200000	/* SKF_LL_OFF from filter.h */

	/* A = *(u16 *) (skb->data+K+X) */
ENTRY(sk_load_half_ind)
	ar	%r3,%r12		# offset += X
	bmr	%r8			# < 0 -> return with cc

	/* A = *(u16 *) (skb->data+K) */
ENTRY(sk_load_half)
	llgfr	%r1,%r3			# extend offset
	ahi	%r3,2			# offset + 2
	clr	%r11,%r3		# hlen <= offset + 2 ?
	jl	sk_load_half_slow
	llgh	%r5,0(%r1,%r10)		# get half from skb
	xr	%r1,%r1			# set cc to zero
	br	%r8

sk_load_half_slow:
	lgr	%r9,%r2			# save %r2
	lgr	%r3,%r1			# offset
	la	%r4,162(%r15)		# pointer to temp buffer
	lghi	%r5,2			# 2 bytes
	brasl	%r14,skb_copy_bits	# get data from skb
	xc	160(2,%r15),160(%r15)
	l	%r5,160(%r15)		# load result from temp buffer
	ltgr	%r2,%r2			# set cc to (%r2 != 0)
	lgr	%r2,%r9			# restore %r2
	br	%r8
/*
 * Load SIZE bytes from SKB
 */
#define sk_load_common(NAME, SIZE, LOAD)				\
ENTRY(sk_load_##NAME);							\
	ltgr	%r3,%r3;		/* Is offset negative? */	\
	jl	sk_load_##NAME##_slow_neg;				\
ENTRY(sk_load_##NAME##_pos);						\
	aghi	%r3,SIZE;		/* Offset + SIZE */		\
	clg	%r3,STK_OFF_HLEN(%r15);	/* Offset + SIZE > hlen? */	\
	jh	sk_load_##NAME##_slow;					\
	LOAD	%r14,-SIZE(%r3,%r12);	/* Get data from skb */		\
	b	OFF_OK(%r6);		/* Return */			\
									\
sk_load_##NAME##_slow:;							\
	lgr	%r2,%r7;		/* Arg1 = skb pointer */	\
	aghi	%r3,-SIZE;		/* Arg2 = offset */		\
	la	%r4,STK_OFF_TMP(%r15);	/* Arg3 = temp bufffer */	\
	lghi	%r5,SIZE;		/* Arg4 = size */		\
	brasl	%r14,skb_copy_bits;	/* Get data from skb */		\
	LOAD	%r14,STK_OFF_TMP(%r15);	/* Load from temp bufffer */	\
	ltgr	%r2,%r2;		/* Set cc to (%r2 != 0) */	\
	br	%r6;			/* Return */

	/* A = *(u8 *) (skb->data+K+X) */
ENTRY(sk_load_byte_ind)
	ar	%r3,%r12		# offset += X
	bmr	%r8			# < 0 -> return with cc
sk_load_common(word, 4, llgf)	/* r14 = *(u32 *) (skb->data+offset) */
sk_load_common(half, 2, llgh)	/* r14 = *(u16 *) (skb->data+offset) */

	/* A = *(u8 *) (skb->data+K) */
/*
 * Load 1 byte from SKB (optimized version)
 */
	/* r14 = *(u8 *) (skb->data+offset) */
ENTRY(sk_load_byte)
	llgfr	%r1,%r3			# extend offset
	clr	%r11,%r3		# hlen < offset ?
	jle	sk_load_byte_slow
	lhi	%r5,0
	ic	%r5,0(%r1,%r10)		# get byte from skb
	xr	%r1,%r1			# set cc to zero
	br	%r8
	ltgr	%r3,%r3			# Is offset negative?
	jl	sk_load_byte_slow_neg
ENTRY(sk_load_byte_pos)
	clg	%r3,STK_OFF_HLEN(%r15)	# Offset >= hlen?
	jnl	sk_load_byte_slow
	llgc	%r14,0(%r3,%r12)	# Get byte from skb
	b	OFF_OK(%r6)		# Return OK

sk_load_byte_slow:
	lgr	%r9,%r2			# save %r2
	lgr	%r3,%r1			# offset
	la	%r4,163(%r15)		# pointer to temp buffer
	lghi	%r5,1			# 1 byte
	brasl	%r14,skb_copy_bits	# get data from skb
	xc	160(3,%r15),160(%r15)
	l	%r5,160(%r15)		# load result from temp buffer
	ltgr	%r2,%r2			# set cc to (%r2 != 0)
	lgr	%r2,%r9			# restore %r2
	br	%r8
	lgr	%r2,%r7			# Arg1 = skb pointer
					# Arg2 = offset
	la	%r4,STK_OFF_TMP(%r15)	# Arg3 = pointer to temp buffer
	lghi	%r5,1			# Arg4 = size (1 byte)
	brasl	%r14,skb_copy_bits	# Get data from skb
	llgc	%r14,STK_OFF_TMP(%r15)	# Load result from temp buffer
	ltgr	%r2,%r2			# Set cc to (%r2 != 0)
	br	%r6			# Return cc

#define sk_negative_common(NAME, SIZE, LOAD)				\
sk_load_##NAME##_slow_neg:;						\
	cgfi	%r3,SKF_MAX_NEG_OFF;					\
	jl	bpf_error;						\
	lgr	%r2,%r7;		/* Arg1 = skb pointer */	\
					/* Arg2 = offset */		\
	lghi	%r4,SIZE;		/* Arg3 = size */		\
	brasl	%r14,bpf_internal_load_pointer_neg_helper;		\
	ltgr	%r2,%r2;						\
	jz	bpf_error;						\
	LOAD	%r14,0(%r2);		/* Get data from pointer */	\
	xr	%r3,%r3;		/* Set cc to zero */		\
	br	%r6;			/* Return cc */

	/* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
ENTRY(sk_load_byte_msh)
	llgfr	%r1,%r3			# extend offset
	clr	%r11,%r3		# hlen < offset ?
	jle	sk_load_byte_msh_slow
	lhi	%r12,0
	ic	%r12,0(%r1,%r10)	# get byte from skb
	nill	%r12,0x0f
	sll	%r12,2
	xr	%r1,%r1			# set cc to zero
	br	%r8
sk_negative_common(word, 4, llgf)
sk_negative_common(half, 2, llgh)
sk_negative_common(byte, 1, llgc)

sk_load_byte_msh_slow:
	lgr	%r9,%r2			# save %r2
	lgr	%r3,%r1			# offset
	la	%r4,163(%r15)		# pointer to temp buffer
	lghi	%r5,1			# 1 byte
	brasl	%r14,skb_copy_bits	# get data from skb
	xc	160(3,%r15),160(%r15)
	l	%r12,160(%r15)		# load result from temp buffer
	nill	%r12,0x0f
	sll	%r12,2
	ltgr	%r2,%r2			# set cc to (%r2 != 0)
	lgr	%r2,%r9			# restore %r2
	br	%r8
bpf_error:
# force a return 0 from jit handler
	ltgr	%r15,%r15	# Set condition code
	br	%r6
+58 −0
Original line number Diff line number Diff line
/*
 * BPF Jit compiler defines
 *
 * Copyright IBM Corp. 2012,2015
 *
 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 *	      Michael Holzheu <holzheu@linux.vnet.ibm.com>
 */

#ifndef __ARCH_S390_NET_BPF_JIT_H
#define __ARCH_S390_NET_BPF_JIT_H

#ifndef __ASSEMBLY__

#include <linux/filter.h>
#include <linux/types.h>

extern u8 sk_load_word_pos[], sk_load_half_pos[], sk_load_byte_pos[];
extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];

#endif /* __ASSEMBLY__ */

/*
 * Stackframe layout (packed stack):
 *
 *				    ^ high
 *	      +---------------+     |
 *	      | old backchain |     |
 *	      +---------------+     |
 *	      |   r15 - r6    |     |
 * BFP	   -> +===============+     |
 *	      |		      |     |
 *	      |   BPF stack   |     |
 *	      |		      |     |
 *	      +---------------+     |
 *	      | 8 byte hlen   |     |
 * R15+168 -> +---------------+     |
 *	      | 4 byte align  |     |
 *	      +---------------+     |
 *	      | 4 byte temp   |     |
 *	      | for bpf_jit.S |     |
 * R15+160 -> +---------------+     |
 *	      | new backchain |     |
 * R15+152 -> +---------------+     |
 *	      | + 152 byte SA |     |
 * R15	   -> +---------------+     + low
 *
 * We get 160 bytes stack space from calling function, but only use
 * 11 * 8 byte (old backchain + r15 - r6) for storing registers.
 */
#define STK_OFF (MAX_BPF_STACK + 8 + 4 + 4 + (160 - 11 * 8))
#define STK_OFF_TMP	160	/* Offset of tmp buffer on stack */
#define STK_OFF_HLEN	168	/* Offset of SKB header length on stack */

/* Offset to skip condition code check */
#define OFF_OK		4

#endif /* __ARCH_S390_NET_BPF_JIT_H */
Loading