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

Commit ba45a7f1 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres
Browse files

Merge remote-tracking branch 'remotes/origin/tmp-c3a2eda1' into msm-4.14



* remotes/origin/tmp-c3a2eda1:
  Linux 4.14.16
  nfsd: auth: Fix gid sorting when rootsquash enabled
  cpufreq: governor: Ensure sufficiently large sampling intervals
  bpf, arm64: fix stack_depth tracking in combination with tail calls
  bpf: reject stores into ctx via st and xadd
  bpf: fix 32-bit divide by zero
  bpf: fix divides by zero
  bpf: avoid false sharing of map refcount with max_entries
  bpf: introduce BPF_JIT_ALWAYS_ON config
  hrtimer: Reset hrtimer cpu base proper on CPU hotplug
  x86/mm/64: Fix vmapped stack syncing on very-large-memory 4-level systems
  x86/microcode: Fix again accessing initrd after having been freed
  x86/microcode/intel: Extend BDW late-loading further with LLC size check
  perf/x86/amd/power: Do not load AMD power module on !AMD platforms
  vmxnet3: repair memory leak
  net: ipv4: Make "ip route get" match iif lo rules again.
  tls: reset crypto_info when do_tls_setsockopt_tx fails
  tls: return -EBUSY if crypto_info is already set
  tls: fix sw_ctx leak
  net/tls: Only attach to sockets in ESTABLISHED state
  netlink: reset extack earlier in netlink_rcv_skb
  nfp: use the correct index for link speed table
  net/mlx5e: Fix fixpoint divide exception in mlx5e_am_stats_compare
  netlink: extack needs to be reset each time through loop
  sctp: reinit stream if stream outcnt has been change by sinit in sendmsg
  flow_dissector: properly cap thoff field
  tun: fix a memory leak for tfile->tx_array
  mlxsw: spectrum_router: Don't log an error on missing neighbor
  gso: validate gso_type in GSO handlers
  ip6_gre: init dev->mtu and dev->hard_header_len correctly
  be2net: restore properly promisc mode after queues reconfiguration
  ppp: unlock all_ppp_mutex before registering device
  net/mlx5: Fix get vector affinity helper function
  {net,ib}/mlx5: Don't disable local loopback multicast traffic when needed
  tipc: fix a memory leak in tipc_nl_node_get_link()
  sctp: return error if the asoc has been peeled off in sctp_wait_for_sndbuf
  sctp: do not allow the v4 socket to bind a v4mapped v6 address
  r8169: fix memory corruption on retrieval of hardware statistics.
  pppoe: take ->needed_headroom of lower device into account on xmit
  net: vrf: Add support for sends to local broadcast address
  net/tls: Fix inverted error codes to avoid endless loop
  net: tcp: close sock if net namespace is exiting
  net: qdisc_pkt_len_init() should be more robust
  net: igmp: fix source address check for IGMPv3 reports
  lan78xx: Fix failure in USB Full Speed
  ipv6: ip6_make_skb() needs to clear cork.base.dst
  ipv6: fix udpv6 sendmsg crash caused by too small MTU
  ipv6: Fix getsockopt() for sockets with default IPV6_AUTOFLOWLABEL
  dccp: don't restart ccid2_hc_tx_rto_expire() if sk in closed state
  ipv4: Make neigh lookup keys for loopback/point-to-point devices be INADDR_ANY
  net: Allow neigh contructor functions ability to modify the primary_key
  drm/vc4: Fix NULL pointer dereference in vc4_save_hang_state()
  ARM: net: bpf: clarify tail_call index
  ARM: net: bpf: fix LDX instructions
  ARM: net: bpf: fix register saving
  ARM: net: bpf: correct stack layout documentation
  ARM: net: bpf: move stack documentation
  ARM: net: bpf: fix stack alignment
  ARM: net: bpf: fix tail call jumps
  ARM: net: bpf: avoid 'bx' instruction on non-Thumb capable CPUs
  orangefs: fix deadlock; do not write i_size in read_iter
  KVM: s390: add proper locking for CMMA migration bitmap
  Btrfs: fix stale entries in readdir
  Input: trackpoint - only expose supported controls for Elan, ALPS and NXP
  Input: trackpoint - force 3 buttons if 0 button is reported
  Input: xpad - add support for PDP Xbox One controllers
  Revert "module: Add retpoline tag to VERMAGIC"
  xfrm: Fix a race in the xdst pcpu cache.
  netfilter: xt_osf: Add missing permission checks
  netfilter: nfnetlink_cthelper: Add missing permission checks
  mm, page_alloc: fix potential false positive in __zone_watermark_ok
  orangefs: initialize op on loop restart in orangefs_devreq_read
  orangefs: use list_for_each_entry_safe in purge_waiting_ops
  ANDROID: Revert "fs: unexport vfs_read and vfs_write"
  ANDROID: sdcardfs: port to 4.14
  ANDROID: fs: Export vfs_rmdir2
  ANDROID: mm: Export do_munmap
  ANDROID: fs: Export d_absolute_path
  ANDROID: fs: Export free_fs_struct and set_fs_pwd
  ANDROID: export security_path_chown
  ANDROID: sdcardfs: Add default_normal option
  ANDROID: sdcardfs: notify lower file of opens
  ANDROID: Sdcardfs: Move gid derivation under flag
  ANDROID: sdcardfs: override credential for ioctl to lower fs
  ANDROID: sdcardfs: Remove unnecessary lock
  ANDROID: sdcardfs: use mount_nodev and fix a issue in sdcardfs_kill_sb
  ANDROID: sdcardfs: remove dead function open_flags_to_access_mode()
  ANDROID: sdcardfs: d_splice_alias can return error values
  ANDROID: sdcardfs: Check for NULL in revalidate
  ANDROID: sdcardfs: Move top to its own struct
  ANDROID: sdcardfs: fix sdcardfs_destroy_inode for the inode RCU approach
  ANDROID: sdcardfs: Don't iput if we didn't igrab
  ANDROID: sdcardfs: Call lower fs's revalidate
  ANDROID: sdcardfs: Avoid setting GIDs outside of valid ranges
  ANDROID: sdcardfs: Copy meta-data from lower inode
  ANDROID: sdcardfs: Use filesystem specific hash
  ANDROID: sdcardfs: Don't complain in fixup_lower_ownership
  ANDROID: sdcardfs: Don't do d_add for lower fs
  ANDROID: sdcardfs: ->iget fixes
  ANDROID: sdcardfs: Change cache GID value
  ANDROID: sdcardfs: Directly pass lower file for mmap
  ANDROID: sdcardfs: update module info
  ANDROID: sdcardfs: use d_splice_alias
  ANDROID: sdcardfs: add read_iter/write_iter opeations
  ANDROID: sdcardfs: fix ->llseek to update upper and lower offset
  ANDROID: sdcardfs: copy lower inode attributes in ->ioctl
  ANDROID: sdcardfs: remove unnecessary call to do_munmap
  ANDROID: sdcardfs: Fix style issues in macros
  ANDROID: sdcardfs: Use seq_puts over seq_printf
  ANDROID: sdcardfs: Use to kstrout
  ANDROID: sdcardfs: Use pr_[...] instead of printk
  ANDROID: sdcardfs: remove unneeded null check
  ANDROID: sdcardfs: Fix style issues with comments
  ANDROID: sdcardfs: Fix formatting
  ANDROID: sdcardfs: correct order of descriptors
  ANDROID: sdcardfs: Fix gid issue
  ANDROID: sdcardfs: Remove uninformative prints
  ANDROID: sdcardfs: move path_put outside of spinlock
  ANDROID: sdcardfs: Use case insensitive hash function
  ANDROID: sdcardfs: declare MODULE_ALIAS_FS
  ANDROID: sdcardfs: Get the blocksize from the lower fs
  ANDROID: sdcardfs: Use d_invalidate instead of drop_recurisve
  ANDROID: sdcardfs: Switch to internal case insensitive compare
  ANDROID: sdcardfs: Use spin_lock_nested
  ANDROID: sdcardfs: Replace get/put with d_lock
  ANDROID: sdcardfs: rate limit warning print
  ANDROID: sdcardfs: Fix case insensitive lookup
  ANDROID: sdcardfs: support direct-IO (DIO) operations
  ANDROID: sdcardfs: implement vm_ops->page_mkwrite
  ANDROID: sdcardfs: Don't bother deleting freelist
  ANDROID: sdcardfs: Add missing path_put
  ANDROID: sdcardfs: Fix incorrect hash
  ANDROID: sdcardfs: Switch strcasecmp for internal call
  ANDROID: sdcardfs: switch to full_name_hash and qstr
  ANDROID: sdcardfs: Add GID Derivation to sdcardfs
  ANDROID: sdcardfs: Remove redundant operation
  ANDROID: sdcardfs: add support for user permission isolation
  ANDROID: sdcardfs: Refactor configfs interface
  ANDROID: sdcardfs: Allow non-owners to touch
  ANDROID: sdcardfs: eliminate the offset argument to ->direct_IO
  ANDROID: sdcardfs: make it use new .rename i_op
  ANDROID: sdcardfs: Propagate dentry down to inode_change_ok()
  ANDROID: sdcardfs: get rid of 'parent' argument of ->d_compare()
  ANDROID: sdcardfs: add parent pointer into dentry name hash
  ANDROID: sdcardfs: use wrappers to access i_mutex
  ANDROID: sdcardfs: Fix locking issue with permision fix up
  ANDROID: sdcardfs: Switch ->d_inode to d_inode()
  ANDROID: sdcardfs: Change magic value
  ANDROID: sdcardfs: Use per mount permissions
  ANDROID: sdcardfs: Add gid and mask to private mount data
  ANDROID: sdcardfs: User new permission2 functions
  ANDROID: sdcardfs: Move directory unlock before touch
  ANDROID: sdcardfs: fix external storage exporting incorrect uid
  ANDROID: sdcardfs: Added top to sdcardfs_inode_info
  ANDROID: sdcardfs: Switch package list to RCU
  ANDROID: sdcardfs: Fix locking for permission fix up
  ANDROID: sdcardfs: Check for other cases on path lookup
  ANDROID: sdcardfs: override umask on mkdir and create
  ANDROID: sdcardfs: fix itnull.cocci warnings
  ANDROID: sdcardfs: Truncate packages_gid.list on overflow
  ANDROID: sdcardfs: remove unneeded __init and __exit
  ANDROID: sdcardfs: Remove unused code
  ANDROID: sdcardfs: remove effectless config option
  ANDROID: sdcardfs: Add support for d_canonical_path
  ANDROID: sdcardfs: Bring up to date with Android M permissions:
  ANDROID: Changed type-casting in packagelist management
  ANDROID: Port of sdcardfs to 4.4
  ANDROID: xattr: Pass EOPNOTSUPP to permission2
  ANDROID: vfs: Add permission2 for filesystems with per mount permissions
  ANDROID: vfs: Add setattr2 for filesystems with per mount permissions
  ANDROID: vfs: Allow filesystems to access their private mount data
  ANDROID: fuse: Add support for d_canonical_path
  ANDROID: mnt: Add filesystem private data to mount points
  ANDROID: vfs: add d_canonical_path for stacked filesystem support
  ANDROID: Included sdcardfs source code for kernel 3.0
  BACKPORT: thermal/drivers/hisi: Add support for hi3660 SoC
  BACKPORT: thermal/drivers/hisi: Prepare to add support for other hisi platforms
  BACKPORT: thermal/drivers/hisi: Add platform prefix to function name
  BACKPORT: thermal/drivers/hisi: Put platform code together
  BACKPORT: thermal/drivers/hisi: Use round up step value
  BACKPORT: thermal/drivers/hisi: Move the clk setup in the corresponding functions
  BACKPORT: thermal/drivers/hisi: Remove mutex_lock in the code
  BACKPORT: thermal/drivers/hisi: Remove thermal data back pointer
  BACKPORT: thermal/drivers/hisi: Convert long to int
  BACKPORT: thermal/drivers/hisi: Rename and remove unused field
  BACKPORT: thermal/drivers/hisi: Remove costly sensor inspection
  BACKPORT: thermal/drivers/hisi: Fix configuration register setting
  BACKPORT: thermal/drivers/hisi: Encapsulate register writes into helpers
  BACKPORT: thermal/drivers/hisi: Remove pointless lock
  BACKPORT: thermal/drivers/hisi: Remove the multiple sensors support
  ANDROID: Fix script to fetch android kernel config fragments for 4.14

Conflicts:
	fs/namei.c
	fs/namespace.c
	fs/open.c
	fs/pnode.c
	fs/sdcardfs/inode.c
	fs/sdcardfs/lookup.c
	include/linux/fs.h

Change-Id: I10679bc0171d61332f99d43b73820c91ae883336
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parents abc8cf11 c3a2eda1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 15
SUBLEVEL = 16
EXTRAVERSION =
NAME = Petit Gorille

+111 −114
Original line number Diff line number Diff line
@@ -27,14 +27,58 @@

int bpf_jit_enable __read_mostly;

/*
 * eBPF prog stack layout:
 *
 *                         high
 * original ARM_SP =>     +-----+
 *                        |     | callee saved registers
 *                        +-----+ <= (BPF_FP + SCRATCH_SIZE)
 *                        | ... | eBPF JIT scratch space
 * eBPF fp register =>    +-----+
 *   (BPF_FP)             | ... | eBPF prog stack
 *                        +-----+
 *                        |RSVD | JIT scratchpad
 * current ARM_SP =>      +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE)
 *                        |     |
 *                        | ... | Function call stack
 *                        |     |
 *                        +-----+
 *                          low
 *
 * The callee saved registers depends on whether frame pointers are enabled.
 * With frame pointers (to be compliant with the ABI):
 *
 *                                high
 * original ARM_SP =>     +------------------+ \
 *                        |        pc        | |
 * current ARM_FP =>      +------------------+ } callee saved registers
 *                        |r4-r8,r10,fp,ip,lr| |
 *                        +------------------+ /
 *                                low
 *
 * Without frame pointers:
 *
 *                                high
 * original ARM_SP =>     +------------------+
 *                        | r4-r8,r10,fp,lr  | callee saved registers
 * current ARM_FP =>      +------------------+
 *                                low
 *
 * When popping registers off the stack at the end of a BPF function, we
 * reference them via the current ARM_FP register.
 */
#define CALLEE_MASK	(1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \
			 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R10 | \
			 1 << ARM_FP)
#define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR)
#define CALLEE_POP_MASK  (CALLEE_MASK | 1 << ARM_PC)

#define STACK_OFFSET(k)	(k)
#define TMP_REG_1	(MAX_BPF_JIT_REG + 0)	/* TEMP Register 1 */
#define TMP_REG_2	(MAX_BPF_JIT_REG + 1)	/* TEMP Register 2 */
#define TCALL_CNT	(MAX_BPF_JIT_REG + 2)	/* Tail Call Count */

/* Flags used for JIT optimization */
#define SEEN_CALL	(1 << 0)

#define FLAG_IMM_OVERFLOW	(1 << 0)

/*
@@ -95,7 +139,6 @@ static const u8 bpf2a32[][2] = {
 * idx			:	index of current last JITed instruction.
 * prologue_bytes	:	bytes used in prologue.
 * epilogue_offset	:	offset of epilogue starting.
 * seen			:	bit mask used for JIT optimization.
 * offsets		:	array of eBPF instruction offsets in
 *				JITed code.
 * target		:	final JITed code.
@@ -110,7 +153,6 @@ struct jit_ctx {
	unsigned int idx;
	unsigned int prologue_bytes;
	unsigned int epilogue_offset;
	u32 seen;
	u32 flags;
	u32 *offsets;
	u32 *target;
@@ -179,8 +221,13 @@ static void jit_fill_hole(void *area, unsigned int size)
		*ptr++ = __opcode_to_mem_arm(ARM_INST_UDF);
}

/* Stack must be multiples of 16 Bytes */
#define STACK_ALIGN(sz) (((sz) + 3) & ~3)
#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
/* EABI requires the stack to be aligned to 64-bit boundaries */
#define STACK_ALIGNMENT	8
#else
/* Stack must be aligned to 32-bit boundaries */
#define STACK_ALIGNMENT	4
#endif

/* Stack space for BPF_REG_2, BPF_REG_3, BPF_REG_4,
 * BPF_REG_5, BPF_REG_7, BPF_REG_8, BPF_REG_9,
@@ -194,7 +241,7 @@ static void jit_fill_hole(void *area, unsigned int size)
	 + SCRATCH_SIZE + \
	 + 4 /* extra for skb_copy_bits buffer */)

#define STACK_SIZE STACK_ALIGN(_STACK_SIZE)
#define STACK_SIZE ALIGN(_STACK_SIZE, STACK_ALIGNMENT)

/* Get the offset of eBPF REGISTERs stored on scratch space. */
#define STACK_VAR(off) (STACK_SIZE-off-4)
@@ -285,16 +332,19 @@ static inline void emit_mov_i(const u8 rd, u32 val, struct jit_ctx *ctx)
		emit_mov_i_no8m(rd, val, ctx);
}

static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
static void emit_bx_r(u8 tgt_reg, struct jit_ctx *ctx)
{
	ctx->seen |= SEEN_CALL;
#if __LINUX_ARM_ARCH__ < 5
	emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);

	if (elf_hwcap & HWCAP_THUMB)
		emit(ARM_BX(tgt_reg), ctx);
	else
		emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx);
}

static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
{
#if __LINUX_ARM_ARCH__ < 5
	emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);
	emit_bx_r(tgt_reg, ctx);
#else
	emit(ARM_BLX_R(tgt_reg), ctx);
#endif
@@ -354,7 +404,6 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
	}

	/* Call appropriate function */
	ctx->seen |= SEEN_CALL;
	emit_mov_i(ARM_IP, op == BPF_DIV ?
		   (u32)jit_udiv32 : (u32)jit_mod32, ctx);
	emit_blx_r(ARM_IP, ctx);
@@ -620,8 +669,6 @@ static inline void emit_a32_lsh_r64(const u8 dst[], const u8 src[], bool dstk,
	/* Do LSH operation */
	emit(ARM_SUB_I(ARM_IP, rt, 32), ctx);
	emit(ARM_RSB_I(tmp2[0], rt, 32), ctx);
	/* As we are using ARM_LR */
	ctx->seen |= SEEN_CALL;
	emit(ARM_MOV_SR(ARM_LR, rm, SRTYPE_ASL, rt), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd, SRTYPE_ASL, ARM_IP), ctx);
	emit(ARM_ORR_SR(ARM_IP, ARM_LR, rd, SRTYPE_LSR, tmp2[0]), ctx);
@@ -656,8 +703,6 @@ static inline void emit_a32_arsh_r64(const u8 dst[], const u8 src[], bool dstk,
	/* Do the ARSH operation */
	emit(ARM_RSB_I(ARM_IP, rt, 32), ctx);
	emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx);
	/* As we are using ARM_LR */
	ctx->seen |= SEEN_CALL;
	emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx);
	_emit(ARM_COND_MI, ARM_B(0), ctx);
@@ -692,8 +737,6 @@ static inline void emit_a32_lsr_r64(const u8 dst[], const u8 src[], bool dstk,
	/* Do LSH operation */
	emit(ARM_RSB_I(ARM_IP, rt, 32), ctx);
	emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx);
	/* As we are using ARM_LR */
	ctx->seen |= SEEN_CALL;
	emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_LSR, tmp2[0]), ctx);
@@ -828,8 +871,6 @@ static inline void emit_a32_mul_r64(const u8 dst[], const u8 src[], bool dstk,
	/* Do Multiplication */
	emit(ARM_MUL(ARM_IP, rd, rn), ctx);
	emit(ARM_MUL(ARM_LR, rm, rt), ctx);
	/* As we are using ARM_LR */
	ctx->seen |= SEEN_CALL;
	emit(ARM_ADD_R(ARM_LR, ARM_IP, ARM_LR), ctx);

	emit(ARM_UMULL(ARM_IP, rm, rd, rt), ctx);
@@ -872,33 +913,53 @@ static inline void emit_str_r(const u8 dst, const u8 src, bool dstk,
}

/* dst = *(size*)(src + off) */
static inline void emit_ldx_r(const u8 dst, const u8 src, bool dstk,
			      const s32 off, struct jit_ctx *ctx, const u8 sz){
static inline void emit_ldx_r(const u8 dst[], const u8 src, bool dstk,
			      s32 off, struct jit_ctx *ctx, const u8 sz){
	const u8 *tmp = bpf2a32[TMP_REG_1];
	u8 rd = dstk ? tmp[1] : dst;
	const u8 *rd = dstk ? tmp : dst;
	u8 rm = src;
	s32 off_max;

	if (off) {
	if (sz == BPF_H)
		off_max = 0xff;
	else
		off_max = 0xfff;

	if (off < 0 || off > off_max) {
		emit_a32_mov_i(tmp[0], off, false, ctx);
		emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
		rm = tmp[0];
		off = 0;
	} else if (rd[1] == rm) {
		emit(ARM_MOV_R(tmp[0], rm), ctx);
		rm = tmp[0];
	}
	switch (sz) {
	case BPF_W:
		/* Load a Word */
		emit(ARM_LDR_I(rd, rm, 0), ctx);
	case BPF_B:
		/* Load a Byte */
		emit(ARM_LDRB_I(rd[1], rm, off), ctx);
		emit_a32_mov_i(dst[0], 0, dstk, ctx);
		break;
	case BPF_H:
		/* Load a HalfWord */
		emit(ARM_LDRH_I(rd, rm, 0), ctx);
		emit(ARM_LDRH_I(rd[1], rm, off), ctx);
		emit_a32_mov_i(dst[0], 0, dstk, ctx);
		break;
	case BPF_B:
		/* Load a Byte */
		emit(ARM_LDRB_I(rd, rm, 0), ctx);
	case BPF_W:
		/* Load a Word */
		emit(ARM_LDR_I(rd[1], rm, off), ctx);
		emit_a32_mov_i(dst[0], 0, dstk, ctx);
		break;
	case BPF_DW:
		/* Load a Double Word */
		emit(ARM_LDR_I(rd[1], rm, off), ctx);
		emit(ARM_LDR_I(rd[0], rm, off + 4), ctx);
		break;
	}
	if (dstk)
		emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst)), ctx);
		emit(ARM_STR_I(rd[1], ARM_SP, STACK_VAR(dst[1])), ctx);
	if (dstk && sz == BPF_DW)
		emit(ARM_STR_I(rd[0], ARM_SP, STACK_VAR(dst[0])), ctx);
}

/* Arithmatic Operation */
@@ -906,7 +967,6 @@ static inline void emit_ar_r(const u8 rd, const u8 rt, const u8 rm,
			     const u8 rn, struct jit_ctx *ctx, u8 op) {
	switch (op) {
	case BPF_JSET:
		ctx->seen |= SEEN_CALL;
		emit(ARM_AND_R(ARM_IP, rt, rn), ctx);
		emit(ARM_AND_R(ARM_LR, rd, rm), ctx);
		emit(ARM_ORRS_R(ARM_IP, ARM_LR, ARM_IP), ctx);
@@ -945,7 +1005,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
	const u8 *tcc = bpf2a32[TCALL_CNT];
	const int idx0 = ctx->idx;
#define cur_offset (ctx->idx - idx0)
#define jmp_offset (out_offset - (cur_offset))
#define jmp_offset (out_offset - (cur_offset) - 2)
	u32 off, lo, hi;

	/* if (index >= array->map.max_entries)
@@ -956,7 +1016,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
	emit_a32_mov_i(tmp[1], off, false, ctx);
	emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r2[1])), ctx);
	emit(ARM_LDR_R(tmp[1], tmp2[1], tmp[1]), ctx);
	/* index (64 bit) */
	/* index is 32-bit for arrays */
	emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r3[1])), ctx);
	/* index >= array->map.max_entries */
	emit(ARM_CMP_R(tmp2[1], tmp[1]), ctx);
@@ -997,7 +1057,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
	emit_a32_mov_i(tmp2[1], off, false, ctx);
	emit(ARM_LDR_R(tmp[1], tmp[1], tmp2[1]), ctx);
	emit(ARM_ADD_I(tmp[1], tmp[1], ctx->prologue_bytes), ctx);
	emit(ARM_BX(tmp[1]), ctx);
	emit_bx_r(tmp[1], ctx);

	/* out: */
	if (out_offset == -1)
@@ -1070,54 +1130,22 @@ static void build_prologue(struct jit_ctx *ctx)
	const u8 r2 = bpf2a32[BPF_REG_1][1];
	const u8 r3 = bpf2a32[BPF_REG_1][0];
	const u8 r4 = bpf2a32[BPF_REG_6][1];
	const u8 r5 = bpf2a32[BPF_REG_6][0];
	const u8 r6 = bpf2a32[TMP_REG_1][1];
	const u8 r7 = bpf2a32[TMP_REG_1][0];
	const u8 r8 = bpf2a32[TMP_REG_2][1];
	const u8 r10 = bpf2a32[TMP_REG_2][0];
	const u8 fplo = bpf2a32[BPF_REG_FP][1];
	const u8 fphi = bpf2a32[BPF_REG_FP][0];
	const u8 sp = ARM_SP;
	const u8 *tcc = bpf2a32[TCALL_CNT];

	u16 reg_set = 0;

	/*
	 * eBPF prog stack layout
	 *
	 *                         high
	 * original ARM_SP =>     +-----+ eBPF prologue
	 *                        |FP/LR|
	 * current ARM_FP =>      +-----+
	 *                        | ... | callee saved registers
	 * eBPF fp register =>    +-----+ <= (BPF_FP)
	 *                        | ... | eBPF JIT scratch space
	 *                        |     | eBPF prog stack
	 *                        +-----+
	 *			  |RSVD | JIT scratchpad
	 * current A64_SP =>      +-----+ <= (BPF_FP - STACK_SIZE)
	 *                        |     |
	 *                        | ... | Function call stack
	 *                        |     |
	 *                        +-----+
	 *                          low
	 */

	/* Save callee saved registers. */
	reg_set |= (1<<r4) | (1<<r5) | (1<<r6) | (1<<r7) | (1<<r8) | (1<<r10);
#ifdef CONFIG_FRAME_POINTER
	reg_set |= (1<<ARM_FP) | (1<<ARM_IP) | (1<<ARM_LR) | (1<<ARM_PC);
	emit(ARM_MOV_R(ARM_IP, sp), ctx);
	u16 reg_set = CALLEE_PUSH_MASK | 1 << ARM_IP | 1 << ARM_PC;
	emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
	emit(ARM_PUSH(reg_set), ctx);
	emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
#else
	/* Check if call instruction exists in BPF body */
	if (ctx->seen & SEEN_CALL)
		reg_set |= (1<<ARM_LR);
	emit(ARM_PUSH(reg_set), ctx);
	emit(ARM_PUSH(CALLEE_PUSH_MASK), ctx);
	emit(ARM_MOV_R(ARM_FP, ARM_SP), ctx);
#endif
	/* Save frame pointer for later */
	emit(ARM_SUB_I(ARM_IP, sp, SCRATCH_SIZE), ctx);
	emit(ARM_SUB_I(ARM_IP, ARM_SP, SCRATCH_SIZE), ctx);

	ctx->stack_size = imm8m(STACK_SIZE);

@@ -1140,33 +1168,19 @@ static void build_prologue(struct jit_ctx *ctx)
	/* end of prologue */
}

/* restore callee saved registers. */
static void build_epilogue(struct jit_ctx *ctx)
{
	const u8 r4 = bpf2a32[BPF_REG_6][1];
	const u8 r5 = bpf2a32[BPF_REG_6][0];
	const u8 r6 = bpf2a32[TMP_REG_1][1];
	const u8 r7 = bpf2a32[TMP_REG_1][0];
	const u8 r8 = bpf2a32[TMP_REG_2][1];
	const u8 r10 = bpf2a32[TMP_REG_2][0];
	u16 reg_set = 0;

	/* unwind function call stack */
	emit(ARM_ADD_I(ARM_SP, ARM_SP, ctx->stack_size), ctx);

	/* restore callee saved registers. */
	reg_set |= (1<<r4) | (1<<r5) | (1<<r6) | (1<<r7) | (1<<r8) | (1<<r10);
#ifdef CONFIG_FRAME_POINTER
	/* the first instruction of the prologue was: mov ip, sp */
	reg_set |= (1<<ARM_FP) | (1<<ARM_SP) | (1<<ARM_PC);
	/* When using frame pointers, some additional registers need to
	 * be loaded. */
	u16 reg_set = CALLEE_POP_MASK | 1 << ARM_SP;
	emit(ARM_SUB_I(ARM_SP, ARM_FP, hweight16(reg_set) * 4), ctx);
	emit(ARM_LDM(ARM_SP, reg_set), ctx);
#else
	if (ctx->seen & SEEN_CALL)
		reg_set |= (1<<ARM_PC);
	/* Restore callee saved registers. */
	emit(ARM_POP(reg_set), ctx);
	/* Return back to the callee function */
	if (!(ctx->seen & SEEN_CALL))
		emit(ARM_BX(ARM_LR), ctx);
	emit(ARM_MOV_R(ARM_SP, ARM_FP), ctx);
	emit(ARM_POP(CALLEE_POP_MASK), ctx);
#endif
}

@@ -1394,8 +1408,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
			emit_rev32(rt, rt, ctx);
			goto emit_bswap_uxt;
		case 64:
			/* Because of the usage of ARM_LR */
			ctx->seen |= SEEN_CALL;
			emit_rev32(ARM_LR, rt, ctx);
			emit_rev32(rt, rd, ctx);
			emit(ARM_MOV_R(rd, ARM_LR), ctx);
@@ -1448,22 +1460,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		rn = sstk ? tmp2[1] : src_lo;
		if (sstk)
			emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx);
		switch (BPF_SIZE(code)) {
		case BPF_W:
			/* Load a Word */
		case BPF_H:
			/* Load a Half-Word */
		case BPF_B:
			/* Load a Byte */
			emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_SIZE(code));
			emit_a32_mov_i(dst_hi, 0, dstk, ctx);
			break;
		case BPF_DW:
			/* Load a double word */
			emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_W);
			emit_ldx_r(dst_hi, rn, dstk, off+4, ctx, BPF_W);
			break;
		}
		emit_ldx_r(dst, rn, dstk, off, ctx, BPF_SIZE(code));
		break;
	/* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */
	case BPF_LD | BPF_ABS | BPF_W:
+11 −9
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
/* Stack must be multiples of 16B */
#define STACK_ALIGN(sz) (((sz) + 15) & ~15)

#define PROLOGUE_OFFSET 8
/* Tail call offset to jump into */
#define PROLOGUE_OFFSET 7

static int build_prologue(struct jit_ctx *ctx)
{
@@ -200,19 +201,19 @@ static int build_prologue(struct jit_ctx *ctx)
	/* Initialize tail_call_cnt */
	emit(A64_MOVZ(1, tcc, 0, 0), ctx);

	/* 4 byte extra for skb_copy_bits buffer */
	ctx->stack_size = prog->aux->stack_depth + 4;
	ctx->stack_size = STACK_ALIGN(ctx->stack_size);

	/* Set up function call stack */
	emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);

	cur_offset = ctx->idx - idx0;
	if (cur_offset != PROLOGUE_OFFSET) {
		pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
			    cur_offset, PROLOGUE_OFFSET);
		return -1;
	}

	/* 4 byte extra for skb_copy_bits buffer */
	ctx->stack_size = prog->aux->stack_depth + 4;
	ctx->stack_size = STACK_ALIGN(ctx->stack_size);

	/* Set up function call stack */
	emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
	return 0;
}

@@ -260,11 +261,12 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
	emit(A64_LDR64(prg, tmp, prg), ctx);
	emit(A64_CBZ(1, prg, jmp_offset), ctx);

	/* goto *(prog->bpf_func + prologue_size); */
	/* goto *(prog->bpf_func + prologue_offset); */
	off = offsetof(struct bpf_prog, bpf_func);
	emit_a64_mov_i64(tmp, off, ctx);
	emit(A64_LDR64(tmp, prg, tmp), ctx);
	emit(A64_ADD_I(1, tmp, tmp, sizeof(u32) * PROLOGUE_OFFSET), ctx);
	emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
	emit(A64_BR(tmp), ctx);

	/* out: */
+11 −7
Original line number Diff line number Diff line
@@ -768,7 +768,7 @@ static void kvm_s390_sync_request_broadcast(struct kvm *kvm, int req)

/*
 * Must be called with kvm->srcu held to avoid races on memslots, and with
 * kvm->lock to avoid races with ourselves and kvm_s390_vm_stop_migration.
 * kvm->slots_lock to avoid races with ourselves and kvm_s390_vm_stop_migration.
 */
static int kvm_s390_vm_start_migration(struct kvm *kvm)
{
@@ -824,7 +824,7 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
}

/*
 * Must be called with kvm->lock to avoid races with ourselves and
 * Must be called with kvm->slots_lock to avoid races with ourselves and
 * kvm_s390_vm_start_migration.
 */
static int kvm_s390_vm_stop_migration(struct kvm *kvm)
@@ -839,6 +839,8 @@ static int kvm_s390_vm_stop_migration(struct kvm *kvm)

	if (kvm->arch.use_cmma) {
		kvm_s390_sync_request_broadcast(kvm, KVM_REQ_STOP_MIGRATION);
		/* We have to wait for the essa emulation to finish */
		synchronize_srcu(&kvm->srcu);
		vfree(mgs->pgste_bitmap);
	}
	kfree(mgs);
@@ -848,14 +850,12 @@ static int kvm_s390_vm_stop_migration(struct kvm *kvm)
static int kvm_s390_vm_set_migration(struct kvm *kvm,
				     struct kvm_device_attr *attr)
{
	int idx, res = -ENXIO;
	int res = -ENXIO;

	mutex_lock(&kvm->lock);
	mutex_lock(&kvm->slots_lock);
	switch (attr->attr) {
	case KVM_S390_VM_MIGRATION_START:
		idx = srcu_read_lock(&kvm->srcu);
		res = kvm_s390_vm_start_migration(kvm);
		srcu_read_unlock(&kvm->srcu, idx);
		break;
	case KVM_S390_VM_MIGRATION_STOP:
		res = kvm_s390_vm_stop_migration(kvm);
@@ -863,7 +863,7 @@ static int kvm_s390_vm_set_migration(struct kvm *kvm,
	default:
		break;
	}
	mutex_unlock(&kvm->lock);
	mutex_unlock(&kvm->slots_lock);

	return res;
}
@@ -1753,7 +1753,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
		r = -EFAULT;
		if (copy_from_user(&args, argp, sizeof(args)))
			break;
		mutex_lock(&kvm->slots_lock);
		r = kvm_s390_get_cmma_bits(kvm, &args);
		mutex_unlock(&kvm->slots_lock);
		if (!r) {
			r = copy_to_user(argp, &args, sizeof(args));
			if (r)
@@ -1767,7 +1769,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
		r = -EFAULT;
		if (copy_from_user(&args, argp, sizeof(args)))
			break;
		mutex_lock(&kvm->slots_lock);
		r = kvm_s390_set_cmma_bits(kvm, &args);
		mutex_unlock(&kvm->slots_lock);
		break;
	}
	default:
+1 −1
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ static int __init amd_power_pmu_init(void)
	int ret;

	if (!x86_match_cpu(cpu_match))
		return 0;
		return -ENODEV;

	if (!boot_cpu_has(X86_FEATURE_ACC_POWER))
		return -ENODEV;
Loading