diff --git linux-libre-4.9.316-gnu1/Makefile linux-libre-4.9.317-gnu1/Makefile
index 0fe78ad076e0..02d474eb1e62 100644
--- linux-libre-4.9.316-gnu1/Makefile
+++ linux-libre-4.9.317-gnu1/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 316
+SUBLEVEL = 317
 EXTRAVERSION = -gnu1
 NAME = Roaring Lionus
 
diff --git linux-libre-4.9.316-gnu1/block/bio.c linux-libre-4.9.317-gnu1/block/bio.c
index 4c18a68913de..db3723675f5a 100644
--- linux-libre-4.9.316-gnu1/block/bio.c
+++ linux-libre-4.9.317-gnu1/block/bio.c
@@ -1538,7 +1538,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
 		if (bytes > len)
 			bytes = len;
 
-		page = alloc_page(q->bounce_gfp | gfp_mask);
+		page = alloc_page(q->bounce_gfp | __GFP_ZERO | gfp_mask);
 		if (!page)
 			goto cleanup;
 
diff --git linux-libre-4.9.316-gnu1/drivers/char/tpm/tpm_ibmvtpm.c linux-libre-4.9.317-gnu1/drivers/char/tpm/tpm_ibmvtpm.c
index 0fad6cf37bab..b0f546f4b15c 100644
--- linux-libre-4.9.316-gnu1/drivers/char/tpm/tpm_ibmvtpm.c
+++ linux-libre-4.9.317-gnu1/drivers/char/tpm/tpm_ibmvtpm.c
@@ -653,6 +653,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
 	if (!wait_event_timeout(ibmvtpm->crq_queue.wq,
 				ibmvtpm->rtce_buf != NULL,
 				HZ)) {
+		rc = -ENODEV;
 		dev_err(dev, "CRQ response timed out\n");
 		goto init_irq_cleanup;
 	}
diff --git linux-libre-4.9.316-gnu1/drivers/gpu/drm/i915/intel_pm.c linux-libre-4.9.317-gnu1/drivers/gpu/drm/i915/intel_pm.c
index 202c00b17df2..dcae0ec973a9 100644
--- linux-libre-4.9.316-gnu1/drivers/gpu/drm/i915/intel_pm.c
+++ linux-libre-4.9.317-gnu1/drivers/gpu/drm/i915/intel_pm.c
@@ -2083,7 +2083,7 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *cstate)
 	       PIPE_WM_LINETIME_TIME(linetime);
 }
 
-static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
+static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[])
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
diff --git linux-libre-4.9.316-gnu1/drivers/i2c/busses/i2c-thunderx-pcidrv.c linux-libre-4.9.317-gnu1/drivers/i2c/busses/i2c-thunderx-pcidrv.c
index bba5b429f69c..3298483bb9b4 100644
--- linux-libre-4.9.316-gnu1/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+++ linux-libre-4.9.317-gnu1/drivers/i2c/busses/i2c-thunderx-pcidrv.c
@@ -208,6 +208,7 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
 	i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
 	i2c->adap.dev.parent = dev;
 	i2c->adap.dev.of_node = pdev->dev.of_node;
+	i2c->adap.dev.fwnode = dev->fwnode;
 	snprintf(i2c->adap.name, sizeof(i2c->adap.name),
 		 "Cavium ThunderX i2c adapter at %s", dev_name(dev));
 	i2c_set_adapdata(&i2c->adap, i2c);
diff --git linux-libre-4.9.316-gnu1/drivers/md/dm-crypt.c linux-libre-4.9.317-gnu1/drivers/md/dm-crypt.c
index 0aedd0ebccec..13a5fcca2833 100644
--- linux-libre-4.9.316-gnu1/drivers/md/dm-crypt.c
+++ linux-libre-4.9.317-gnu1/drivers/md/dm-crypt.c
@@ -1943,6 +1943,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
 	return DM_MAPIO_SUBMITTED;
 }
 
+static char hex2asc(unsigned char c)
+{
+	return c + '0' + ((unsigned)(9 - c) >> 4 & 0x27);
+}
+
 static void crypt_status(struct dm_target *ti, status_type_t type,
 			 unsigned status_flags, char *result, unsigned maxlen)
 {
@@ -1958,10 +1963,12 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
 	case STATUSTYPE_TABLE:
 		DMEMIT("%s ", cc->cipher_string);
 
-		if (cc->key_size > 0)
-			for (i = 0; i < cc->key_size; i++)
-				DMEMIT("%02x", cc->key[i]);
-		else
+		if (cc->key_size > 0) {
+			for (i = 0; i < cc->key_size; i++) {
+				DMEMIT("%c%c", hex2asc(cc->key[i] >> 4),
+				       hex2asc(cc->key[i] & 0xf));
+			}
+		} else
 			DMEMIT("-");
 
 		DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
diff --git linux-libre-4.9.316-gnu1/drivers/md/dm-stats.c linux-libre-4.9.317-gnu1/drivers/md/dm-stats.c
index 0250e7e521ab..fdd4a840b30f 100644
--- linux-libre-4.9.316-gnu1/drivers/md/dm-stats.c
+++ linux-libre-4.9.317-gnu1/drivers/md/dm-stats.c
@@ -228,6 +228,7 @@ void dm_stats_cleanup(struct dm_stats *stats)
 				       atomic_read(&shared->in_flight[READ]),
 				       atomic_read(&shared->in_flight[WRITE]));
 			}
+			cond_resched();
 		}
 		dm_stat_free(&s->rcu_head);
 	}
@@ -316,6 +317,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
 	for (ni = 0; ni < n_entries; ni++) {
 		atomic_set(&s->stat_shared[ni].in_flight[READ], 0);
 		atomic_set(&s->stat_shared[ni].in_flight[WRITE], 0);
+		cond_resched();
 	}
 
 	if (s->n_histogram_entries) {
@@ -328,6 +330,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
 		for (ni = 0; ni < n_entries; ni++) {
 			s->stat_shared[ni].tmp.histogram = hi;
 			hi += s->n_histogram_entries + 1;
+			cond_resched();
 		}
 	}
 
@@ -348,6 +351,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
 			for (ni = 0; ni < n_entries; ni++) {
 				p[ni].histogram = hi;
 				hi += s->n_histogram_entries + 1;
+				cond_resched();
 			}
 		}
 	}
@@ -477,6 +481,7 @@ static int dm_stats_list(struct dm_stats *stats, const char *program,
 			}
 			DMEMIT("\n");
 		}
+		cond_resched();
 	}
 	mutex_unlock(&stats->mutex);
 
@@ -753,6 +758,7 @@ static void __dm_stat_clear(struct dm_stat *s, size_t idx_start, size_t idx_end,
 				local_irq_enable();
 			}
 		}
+		cond_resched();
 	}
 }
 
@@ -868,6 +874,8 @@ static int dm_stats_print(struct dm_stats *stats, int id,
 
 		if (unlikely(sz + 1 >= maxlen))
 			goto buffer_overflow;
+
+		cond_resched();
 	}
 
 	if (clear)
diff --git linux-libre-4.9.316-gnu1/drivers/md/dm-verity-target.c linux-libre-4.9.317-gnu1/drivers/md/dm-verity-target.c
index 727f9e571955..bd9d9f183e4b 100644
--- linux-libre-4.9.316-gnu1/drivers/md/dm-verity-target.c
+++ linux-libre-4.9.317-gnu1/drivers/md/dm-verity-target.c
@@ -1056,6 +1056,7 @@ bad:
 
 static struct target_type verity_target = {
 	.name		= "verity",
+	.features	= DM_TARGET_IMMUTABLE,
 	.version	= {1, 3, 0},
 	.module		= THIS_MODULE,
 	.ctr		= verity_ctr,
diff --git linux-libre-4.9.316-gnu1/fs/exec.c linux-libre-4.9.317-gnu1/fs/exec.c
index 482a8b4f41a5..19f8b075d3b6 100644
--- linux-libre-4.9.316-gnu1/fs/exec.c
+++ linux-libre-4.9.317-gnu1/fs/exec.c
@@ -1758,6 +1758,9 @@ static int do_execveat_common(int fd, struct filename *filename,
 		goto out_unmark;
 
 	bprm->argc = count(argv, MAX_ARG_STRINGS);
+	if (bprm->argc == 0)
+		pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n",
+			     current->comm, bprm->filename);
 	if ((retval = bprm->argc) < 0)
 		goto out;
 
@@ -1782,6 +1785,20 @@ static int do_execveat_common(int fd, struct filename *filename,
 	if (retval < 0)
 		goto out;
 
+	/*
+	 * When argv is empty, add an empty string ("") as argv[0] to
+	 * ensure confused userspace programs that start processing
+	 * from argv[1] won't end up walking envp. See also
+	 * bprm_stack_limits().
+	 */
+	if (bprm->argc == 0) {
+		const char *argv[] = { "", NULL };
+		retval = copy_strings_kernel(1, argv, bprm);
+		if (retval < 0)
+			goto out;
+		bprm->argc = 1;
+	}
+
 	retval = exec_binprm(bprm);
 	if (retval < 0)
 		goto out;
diff --git linux-libre-4.9.316-gnu1/fs/nfsd/nfs4state.c linux-libre-4.9.317-gnu1/fs/nfsd/nfs4state.c
index d9381ca0ac47..b13649c63653 100644
--- linux-libre-4.9.316-gnu1/fs/nfsd/nfs4state.c
+++ linux-libre-4.9.317-gnu1/fs/nfsd/nfs4state.c
@@ -6342,16 +6342,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
 		if (sop->so_is_open_owner || !same_owner_str(sop, owner))
 			continue;
 
-		/* see if there are still any locks associated with it */
-		lo = lockowner(sop);
-		list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
-			if (check_for_locks(stp->st_stid.sc_file, lo)) {
-				status = nfserr_locks_held;
-				spin_unlock(&clp->cl_lock);
-				return status;
-			}
+		if (atomic_read(&sop->so_count) != 1) {
+			spin_unlock(&clp->cl_lock);
+			return nfserr_locks_held;
 		}
 
+		lo = lockowner(sop);
 		nfs4_get_stateowner(sop);
 		break;
 	}
diff --git linux-libre-4.9.316-gnu1/lib/assoc_array.c linux-libre-4.9.317-gnu1/lib/assoc_array.c
index 3b46c5433b7a..70ef5fdd11c7 100644
--- linux-libre-4.9.316-gnu1/lib/assoc_array.c
+++ linux-libre-4.9.317-gnu1/lib/assoc_array.c
@@ -1478,6 +1478,7 @@ int assoc_array_gc(struct assoc_array *array,
 	struct assoc_array_ptr *cursor, *ptr;
 	struct assoc_array_ptr *new_root, *new_parent, **new_ptr_pp;
 	unsigned long nr_leaves_on_tree;
+	bool retained;
 	int keylen, slot, nr_free, next_slot, i;
 
 	pr_devel("-->%s()\n", __func__);
@@ -1554,6 +1555,7 @@ continue_node:
 		goto descend;
 	}
 
+retry_compress:
 	pr_devel("-- compress node %p --\n", new_n);
 
 	/* Count up the number of empty slots in this node and work out the
@@ -1571,6 +1573,7 @@ continue_node:
 	pr_devel("free=%d, leaves=%lu\n", nr_free, new_n->nr_leaves_on_branch);
 
 	/* See what we can fold in */
+	retained = false;
 	next_slot = 0;
 	for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) {
 		struct assoc_array_shortcut *s;
@@ -1620,9 +1623,14 @@ continue_node:
 			pr_devel("[%d] retain node %lu/%d [nx %d]\n",
 				 slot, child->nr_leaves_on_branch, nr_free + 1,
 				 next_slot);
+			retained = true;
 		}
 	}
 
+	if (retained && new_n->nr_leaves_on_branch <= ASSOC_ARRAY_FAN_OUT) {
+		pr_devel("internal nodes remain despite enough space, retrying\n");
+		goto retry_compress;
+	}
 	pr_devel("after: %lu\n", new_n->nr_leaves_on_branch);
 
 	nr_leaves_on_tree = new_n->nr_leaves_on_branch;
diff --git linux-libre-4.9.316-gnu1/net/core/filter.c linux-libre-4.9.317-gnu1/net/core/filter.c
index 94bf897485db..799ac1fb46f2 100644
--- linux-libre-4.9.316-gnu1/net/core/filter.c
+++ linux-libre-4.9.317-gnu1/net/core/filter.c
@@ -1388,7 +1388,7 @@ BPF_CALL_5(bpf_skb_store_bytes, struct sk_buff *, skb, u32, offset,
 
 	if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH)))
 		return -EINVAL;
-	if (unlikely(offset > 0xffff))
+	if (unlikely(offset > INT_MAX))
 		return -EFAULT;
 	if (unlikely(bpf_try_make_writable(skb, offset + len)))
 		return -EFAULT;
@@ -1423,7 +1423,7 @@ BPF_CALL_4(bpf_skb_load_bytes, const struct sk_buff *, skb, u32, offset,
 {
 	void *ptr;
 
-	if (unlikely(offset > 0xffff))
+	if (unlikely(offset > INT_MAX))
 		goto err_clear;
 
 	ptr = skb_header_pointer(skb, offset, len, to);
diff --git linux-libre-4.9.316-gnu1/net/key/af_key.c linux-libre-4.9.317-gnu1/net/key/af_key.c
index 776f94ecbfe6..d5dc614af2f9 100644
--- linux-libre-4.9.316-gnu1/net/key/af_key.c
+++ linux-libre-4.9.317-gnu1/net/key/af_key.c
@@ -2935,7 +2935,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
 			break;
 		if (!aalg->pfkey_supported)
 			continue;
-		if (aalg_tmpl_set(t, aalg))
+		if (aalg_tmpl_set(t, aalg) && aalg->available)
 			sz += sizeof(struct sadb_comb);
 	}
 	return sz + sizeof(struct sadb_prop);
@@ -2953,7 +2953,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
 		if (!ealg->pfkey_supported)
 			continue;
 
-		if (!(ealg_tmpl_set(t, ealg)))
+		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
 			continue;
 
 		for (k = 1; ; k++) {
@@ -2964,7 +2964,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
 			if (!aalg->pfkey_supported)
 				continue;
 
-			if (aalg_tmpl_set(t, aalg))
+			if (aalg_tmpl_set(t, aalg) && aalg->available)
 				sz += sizeof(struct sadb_comb);
 		}
 	}
