From: Greg Kroah-Hartman Date: Mon, 29 Apr 2019 09:51:49 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.9.172~37 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=062f8f358039b2a52182b6ff264ea5a9092ee01a;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: arm-8857-1-efi-enable-cp15-dmb-instructions-before-cleaning-the-cache.patch ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch ceph-fix-ci-i_head_snapc-leak.patch dmaengine-sh-rcar-dmac-with-cyclic-dma-residue-0-is-valid.patch drm-vc4-fix-compilation-error-reported-by-kbuild-test-bot.patch drm-vc4-fix-memory-leak-during-gpu-reset.patch input-synaptics-rmi4-write-config-register-values-to-the-right-offset.patch nfsd-don-t-release-the-callback-slot-unless-it-was-actually-held.patch nfsd-wake-blocked-file-lock-waiters-before-sending-callback.patch sunrpc-don-t-mark-uninitialised-items-as-valid.patch usb-add-new-usb-lpm-helpers.patch usb-consolidate-lpm-checks-to-avoid-enabling-lpm-twice.patch vsock-virtio-fix-kernel-panic-from-virtio_transport_reset_no_sock.patch --- diff --git a/queue-4.9/arm-8857-1-efi-enable-cp15-dmb-instructions-before-cleaning-the-cache.patch b/queue-4.9/arm-8857-1-efi-enable-cp15-dmb-instructions-before-cleaning-the-cache.patch new file mode 100644 index 00000000000..7a2bfd38038 --- /dev/null +++ b/queue-4.9/arm-8857-1-efi-enable-cp15-dmb-instructions-before-cleaning-the-cache.patch @@ -0,0 +1,60 @@ +From e17b1af96b2afc38e684aa2f1033387e2ed10029 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Fri, 12 Apr 2019 22:34:18 +0100 +Subject: ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache + +From: Ard Biesheuvel + +commit e17b1af96b2afc38e684aa2f1033387e2ed10029 upstream. + +The EFI stub is entered with the caches and MMU enabled by the +firmware, and once the stub is ready to hand over to the decompressor, +we clean and disable the caches. + +The cache clean routines use CP15 barrier instructions, which can be +disabled via SCTLR. Normally, when using the provided cache handling +routines to enable the caches and MMU, this bit is enabled as well. +However, but since we entered the stub with the caches already enabled, +this routine is not executed before we call the cache clean routines, +resulting in undefined instruction exceptions if the firmware never +enabled this bit. + +So set the bit explicitly in the EFI entry code, but do so in a way that +guarantees that the resulting code can still run on v6 cores as well +(which are guaranteed to have CP15 barriers enabled) + +Cc: # v4.9+ +Acked-by: Marc Zyngier +Signed-off-by: Ard Biesheuvel +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/compressed/head.S | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -1383,7 +1383,21 @@ ENTRY(efi_stub_entry) + + @ Preserve return value of efi_entry() in r4 + mov r4, r0 +- bl cache_clean_flush ++ ++ @ our cache maintenance code relies on CP15 barrier instructions ++ @ but since we arrived here with the MMU and caches configured ++ @ by UEFI, we must check that the CP15BEN bit is set in SCTLR. ++ @ Note that this bit is RAO/WI on v6 and earlier, so the ISB in ++ @ the enable path will be executed on v7+ only. ++ mrc p15, 0, r1, c1, c0, 0 @ read SCTLR ++ tst r1, #(1 << 5) @ CP15BEN bit set? ++ bne 0f ++ orr r1, r1, #(1 << 5) @ CP15 barrier instructions ++ mcr p15, 0, r1, c1, c0, 0 @ write SCTLR ++ ARM( .inst 0xf57ff06f @ v7+ isb ) ++ THUMB( isb ) ++ ++0: bl cache_clean_flush + bl cache_off + + @ Set parameters for booting zImage according to boot protocol diff --git a/queue-4.9/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch b/queue-4.9/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch new file mode 100644 index 00000000000..b44bf5404c9 --- /dev/null +++ b/queue-4.9/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch @@ -0,0 +1,44 @@ +From 76a495d666e5043ffc315695f8241f5e94a98849 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 17 Apr 2019 12:58:28 -0400 +Subject: ceph: ensure d_name stability in ceph_dentry_hash() + +From: Jeff Layton + +commit 76a495d666e5043ffc315695f8241f5e94a98849 upstream. + +Take the d_lock here to ensure that d_name doesn't change. + +Cc: stable@vger.kernel.org +Signed-off-by: Jeff Layton +Reviewed-by: "Yan, Zheng" +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/dir.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/ceph/dir.c ++++ b/fs/ceph/dir.c +@@ -1471,6 +1471,7 @@ void ceph_dentry_lru_del(struct dentry * + unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn) + { + struct ceph_inode_info *dci = ceph_inode(dir); ++ unsigned hash; + + switch (dci->i_dir_layout.dl_dir_hash) { + case 0: /* for backward compat */ +@@ -1478,8 +1479,11 @@ unsigned ceph_dentry_hash(struct inode * + return dn->d_name.hash; + + default: +- return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, ++ spin_lock(&dn->d_lock); ++ hash = ceph_str_hash(dci->i_dir_layout.dl_dir_hash, + dn->d_name.name, dn->d_name.len); ++ spin_unlock(&dn->d_lock); ++ return hash; + } + } + diff --git a/queue-4.9/ceph-fix-ci-i_head_snapc-leak.patch b/queue-4.9/ceph-fix-ci-i_head_snapc-leak.patch new file mode 100644 index 00000000000..abee6e40905 --- /dev/null +++ b/queue-4.9/ceph-fix-ci-i_head_snapc-leak.patch @@ -0,0 +1,59 @@ +From 37659182bff1eeaaeadcfc8f853c6d2b6dbc3f47 Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Thu, 18 Apr 2019 11:24:57 +0800 +Subject: ceph: fix ci->i_head_snapc leak + +From: Yan, Zheng + +commit 37659182bff1eeaaeadcfc8f853c6d2b6dbc3f47 upstream. + +We missed two places that i_wrbuffer_ref_head, i_wr_ref, i_dirty_caps +and i_flushing_caps may change. When they are all zeros, we should free +i_head_snapc. + +Cc: stable@vger.kernel.org +Link: https://tracker.ceph.com/issues/38224 +Reported-and-tested-by: Luis Henriques +Signed-off-by: "Yan, Zheng" +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/mds_client.c | 9 +++++++++ + fs/ceph/snap.c | 7 ++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -1187,6 +1187,15 @@ static int remove_session_caps_cb(struct + list_add(&ci->i_prealloc_cap_flush->i_list, &to_remove); + ci->i_prealloc_cap_flush = NULL; + } ++ ++ if (drop && ++ ci->i_wrbuffer_ref_head == 0 && ++ ci->i_wr_ref == 0 && ++ ci->i_dirty_caps == 0 && ++ ci->i_flushing_caps == 0) { ++ ceph_put_snap_context(ci->i_head_snapc); ++ ci->i_head_snapc = NULL; ++ } + } + spin_unlock(&ci->i_ceph_lock); + while (!list_empty(&to_remove)) { +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -563,7 +563,12 @@ void ceph_queue_cap_snap(struct ceph_ino + old_snapc = NULL; + + update_snapc: +- if (ci->i_head_snapc) { ++ if (ci->i_wrbuffer_ref_head == 0 && ++ ci->i_wr_ref == 0 && ++ ci->i_dirty_caps == 0 && ++ ci->i_flushing_caps == 0) { ++ ci->i_head_snapc = NULL; ++ } else { + ci->i_head_snapc = ceph_get_snap_context(new_snapc); + dout(" new snapc is %p\n", new_snapc); + } diff --git a/queue-4.9/dmaengine-sh-rcar-dmac-with-cyclic-dma-residue-0-is-valid.patch b/queue-4.9/dmaengine-sh-rcar-dmac-with-cyclic-dma-residue-0-is-valid.patch new file mode 100644 index 00000000000..3784793f9f3 --- /dev/null +++ b/queue-4.9/dmaengine-sh-rcar-dmac-with-cyclic-dma-residue-0-is-valid.patch @@ -0,0 +1,51 @@ +From 907bd68a2edc491849e2fdcfe52c4596627bca94 Mon Sep 17 00:00:00 2001 +From: Dirk Behme +Date: Fri, 12 Apr 2019 07:29:13 +0200 +Subject: dmaengine: sh: rcar-dmac: With cyclic DMA residue 0 is valid + +From: Dirk Behme + +commit 907bd68a2edc491849e2fdcfe52c4596627bca94 upstream. + +Having a cyclic DMA, a residue 0 is not an indication of a completed +DMA. In case of cyclic DMA make sure that dma_set_residue() is called +and with this a residue of 0 is forwarded correctly to the caller. + +Fixes: 3544d2878817 ("dmaengine: rcar-dmac: use result of updated get_residue in tx_status") +Signed-off-by: Dirk Behme +Signed-off-by: Achim Dahlhoff +Signed-off-by: Hiroyuki Yokoyama +Signed-off-by: Yao Lihua +Reviewed-by: Yoshihiro Shimoda +Reviewed-by: Laurent Pinchart +Cc: # v4.8+ +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/sh/rcar-dmac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/dma/sh/rcar-dmac.c ++++ b/drivers/dma/sh/rcar-dmac.c +@@ -1311,6 +1311,7 @@ static enum dma_status rcar_dmac_tx_stat + enum dma_status status; + unsigned long flags; + unsigned int residue; ++ bool cyclic; + + status = dma_cookie_status(chan, cookie, txstate); + if (status == DMA_COMPLETE || !txstate) +@@ -1318,10 +1319,11 @@ static enum dma_status rcar_dmac_tx_stat + + spin_lock_irqsave(&rchan->lock, flags); + residue = rcar_dmac_chan_get_residue(rchan, cookie); ++ cyclic = rchan->desc.running ? rchan->desc.running->cyclic : false; + spin_unlock_irqrestore(&rchan->lock, flags); + + /* if there's no residue, the cookie is complete */ +- if (!residue) ++ if (!residue && !cyclic) + return DMA_COMPLETE; + + dma_set_residue(txstate, residue); diff --git a/queue-4.9/drm-vc4-fix-compilation-error-reported-by-kbuild-test-bot.patch b/queue-4.9/drm-vc4-fix-compilation-error-reported-by-kbuild-test-bot.patch new file mode 100644 index 00000000000..1727cf36bde --- /dev/null +++ b/queue-4.9/drm-vc4-fix-compilation-error-reported-by-kbuild-test-bot.patch @@ -0,0 +1,39 @@ +From 462ce5d963f18b71c63f6b7730a35a2ee5273540 Mon Sep 17 00:00:00 2001 +From: Maarten Lankhorst +Date: Wed, 24 Apr 2019 17:06:29 +0200 +Subject: drm/vc4: Fix compilation error reported by kbuild test bot + +From: Maarten Lankhorst + +commit 462ce5d963f18b71c63f6b7730a35a2ee5273540 upstream. + +A pointer to crtc was missing, resulting in the following build error: +drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: sparse: incorrect type in argument 1 (different base types) +drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: expected struct drm_crtc *crtc +drivers/gpu/drm/vc4/vc4_crtc.c:1045:44: sparse: got struct drm_crtc_state *state +drivers/gpu/drm/vc4/vc4_crtc.c:1045:39: sparse: sparse: not enough arguments for function vc4_crtc_destroy_state + +Signed-off-by: Maarten Lankhorst +Reported-by: kbuild test robot +Cc: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/2b6ed5e6-81b0-4276-8860-870b54ca3262@linux.intel.com +Fixes: d08106796a78 ("drm/vc4: Fix memory leak during gpu reset.") +Cc: # v4.6+ +Acked-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -846,7 +846,7 @@ static void + vc4_crtc_reset(struct drm_crtc *crtc) + { + if (crtc->state) +- vc4_crtc_destroy_state(crtc->state); ++ vc4_crtc_destroy_state(crtc, crtc->state); + + crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); + if (crtc->state) diff --git a/queue-4.9/drm-vc4-fix-memory-leak-during-gpu-reset.patch b/queue-4.9/drm-vc4-fix-memory-leak-during-gpu-reset.patch new file mode 100644 index 00000000000..955d71a2da3 --- /dev/null +++ b/queue-4.9/drm-vc4-fix-memory-leak-during-gpu-reset.patch @@ -0,0 +1,35 @@ +From d08106796a78a4273e39e1bbdf538dc4334b2635 Mon Sep 17 00:00:00 2001 +From: Maarten Lankhorst +Date: Fri, 1 Mar 2019 13:56:11 +0100 +Subject: drm/vc4: Fix memory leak during gpu reset. + +From: Maarten Lankhorst + +commit d08106796a78a4273e39e1bbdf538dc4334b2635 upstream. + +__drm_atomic_helper_crtc_destroy_state does not free memory, it only +cleans it up. Fix this by calling the functions own destroy function. + +Fixes: 6d6e50039187 ("drm/vc4: Allocate the right amount of space for boot-time CRTC state.") +Cc: Eric Anholt +Cc: # v4.6+ +Reviewed-by: Eric Anholt +Signed-off-by: Maarten Lankhorst +Link: https://patchwork.freedesktop.org/patch/msgid/20190301125627.7285-2-maarten.lankhorst@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -846,7 +846,7 @@ static void + vc4_crtc_reset(struct drm_crtc *crtc) + { + if (crtc->state) +- __drm_atomic_helper_crtc_destroy_state(crtc->state); ++ vc4_crtc_destroy_state(crtc->state); + + crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); + if (crtc->state) diff --git a/queue-4.9/input-synaptics-rmi4-write-config-register-values-to-the-right-offset.patch b/queue-4.9/input-synaptics-rmi4-write-config-register-values-to-the-right-offset.patch new file mode 100644 index 00000000000..c2608cbd60d --- /dev/null +++ b/queue-4.9/input-synaptics-rmi4-write-config-register-values-to-the-right-offset.patch @@ -0,0 +1,35 @@ +From 3a349763cf11e63534b8f2d302f2d0c790566497 Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Fri, 26 Apr 2019 17:22:01 -0700 +Subject: Input: synaptics-rmi4 - write config register values to the right offset + +From: Lucas Stach + +commit 3a349763cf11e63534b8f2d302f2d0c790566497 upstream. + +Currently any changed config register values don't take effect, as the +function to write them back is called with the wrong register offset. + +Fixes: ff8f83708b3e (Input: synaptics-rmi4 - add support for 2D + sensors and F11) +Signed-off-by: Lucas Stach +Reviewed-by: Philipp Zabel +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/rmi4/rmi_f11.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/rmi4/rmi_f11.c ++++ b/drivers/input/rmi4/rmi_f11.c +@@ -1198,7 +1198,7 @@ static int rmi_f11_initialize(struct rmi + ctrl->ctrl0_11[11] = ctrl->ctrl0_11[11] & ~BIT(0); + + rc = f11_write_control_regs(fn, &f11->sens_query, +- &f11->dev_controls, fn->fd.query_base_addr); ++ &f11->dev_controls, fn->fd.control_base_addr); + if (rc) + dev_warn(&fn->dev, "Failed to write control registers\n"); + diff --git a/queue-4.9/nfsd-don-t-release-the-callback-slot-unless-it-was-actually-held.patch b/queue-4.9/nfsd-don-t-release-the-callback-slot-unless-it-was-actually-held.patch new file mode 100644 index 00000000000..b3b1b01c8ed --- /dev/null +++ b/queue-4.9/nfsd-don-t-release-the-callback-slot-unless-it-was-actually-held.patch @@ -0,0 +1,82 @@ +From e6abc8caa6deb14be2a206253f7e1c5e37e9515b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 5 Apr 2019 08:54:37 -0700 +Subject: nfsd: Don't release the callback slot unless it was actually held + +From: Trond Myklebust + +commit e6abc8caa6deb14be2a206253f7e1c5e37e9515b upstream. + +If there are multiple callbacks queued, waiting for the callback +slot when the callback gets shut down, then they all currently +end up acting as if they hold the slot, and call +nfsd4_cb_sequence_done() resulting in interesting side-effects. + +In addition, the 'retry_nowait' path in nfsd4_cb_sequence_done() +causes a loop back to nfsd4_cb_prepare() without first freeing the +slot, which causes a deadlock when nfsd41_cb_get_slot() gets called +a second time. + +This patch therefore adds a boolean to track whether or not the +callback did pick up the slot, so that it can do the right thing +in these 2 cases. + +Cc: stable@vger.kernel.org +Signed-off-by: Trond Myklebust +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4callback.c | 8 +++++++- + fs/nfsd/state.h | 1 + + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -934,8 +934,9 @@ static void nfsd4_cb_prepare(struct rpc_ + cb->cb_seq_status = 1; + cb->cb_status = 0; + if (minorversion) { +- if (!nfsd41_cb_get_slot(clp, task)) ++ if (!cb->cb_holds_slot && !nfsd41_cb_get_slot(clp, task)) + return; ++ cb->cb_holds_slot = true; + } + rpc_call_start(task); + } +@@ -962,6 +963,9 @@ static bool nfsd4_cb_sequence_done(struc + return true; + } + ++ if (!cb->cb_holds_slot) ++ goto need_restart; ++ + switch (cb->cb_seq_status) { + case 0: + /* +@@ -999,6 +1003,7 @@ static bool nfsd4_cb_sequence_done(struc + cb->cb_seq_status); + } + ++ cb->cb_holds_slot = false; + clear_bit(0, &clp->cl_cb_slot_busy); + rpc_wake_up_next(&clp->cl_cb_waitq); + dprintk("%s: freed slot, new seqid=%d\n", __func__, +@@ -1206,6 +1211,7 @@ void nfsd4_init_cb(struct nfsd4_callback + cb->cb_seq_status = 1; + cb->cb_status = 0; + cb->cb_need_restart = false; ++ cb->cb_holds_slot = false; + } + + void nfsd4_run_cb(struct nfsd4_callback *cb) +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -69,6 +69,7 @@ struct nfsd4_callback { + int cb_seq_status; + int cb_status; + bool cb_need_restart; ++ bool cb_holds_slot; + }; + + struct nfsd4_callback_ops { diff --git a/queue-4.9/nfsd-wake-blocked-file-lock-waiters-before-sending-callback.patch b/queue-4.9/nfsd-wake-blocked-file-lock-waiters-before-sending-callback.patch new file mode 100644 index 00000000000..5b1a6749937 --- /dev/null +++ b/queue-4.9/nfsd-wake-blocked-file-lock-waiters-before-sending-callback.patch @@ -0,0 +1,56 @@ +From f456458e4d25a8962d0946891617c76cc3ff5fb9 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Mon, 22 Apr 2019 12:34:24 -0400 +Subject: nfsd: wake blocked file lock waiters before sending callback + +From: Jeff Layton + +commit f456458e4d25a8962d0946891617c76cc3ff5fb9 upstream. + +When a blocked NFS lock is "awoken" we send a callback to the server and +then wake any hosts waiting on it. If a client attempts to get a lock +and then drops off the net, we could end up waiting for a long time +until we end up waking locks blocked on that request. + +So, wake any other waiting lock requests before sending the callback. +Do this by calling locks_delete_block in a new "prepare" phase for +CB_NOTIFY_LOCK callbacks. + +URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363 +Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.") +Reported-by: Slawomir Pryczek +Cc: Neil Brown +Cc: stable@vger.kernel.org +Signed-off-by: Jeff Layton +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -292,6 +292,14 @@ remove_blocked_locks(struct nfs4_lockown + } + } + ++static void ++nfsd4_cb_notify_lock_prepare(struct nfsd4_callback *cb) ++{ ++ struct nfsd4_blocked_lock *nbl = container_of(cb, ++ struct nfsd4_blocked_lock, nbl_cb); ++ locks_delete_block(&nbl->nbl_lock); ++} ++ + static int + nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task) + { +@@ -319,6 +327,7 @@ nfsd4_cb_notify_lock_release(struct nfsd + } + + static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops = { ++ .prepare = nfsd4_cb_notify_lock_prepare, + .done = nfsd4_cb_notify_lock_done, + .release = nfsd4_cb_notify_lock_release, + }; diff --git a/queue-4.9/series b/queue-4.9/series index 95f2086ea1a..9d45e891a53 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -5,3 +5,16 @@ mips-scall64-o32-fix-indirect-syscall-number-load.patch trace-fix-preempt_enable_no_resched-abuse.patch ib-rdmavt-fix-frwr-memory-registration.patch sched-numa-fix-a-possible-divide-by-zero.patch +ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch +ceph-fix-ci-i_head_snapc-leak.patch +nfsd-don-t-release-the-callback-slot-unless-it-was-actually-held.patch +nfsd-wake-blocked-file-lock-waiters-before-sending-callback.patch +sunrpc-don-t-mark-uninitialised-items-as-valid.patch +input-synaptics-rmi4-write-config-register-values-to-the-right-offset.patch +dmaengine-sh-rcar-dmac-with-cyclic-dma-residue-0-is-valid.patch +arm-8857-1-efi-enable-cp15-dmb-instructions-before-cleaning-the-cache.patch +drm-vc4-fix-memory-leak-during-gpu-reset.patch +drm-vc4-fix-compilation-error-reported-by-kbuild-test-bot.patch +usb-add-new-usb-lpm-helpers.patch +usb-consolidate-lpm-checks-to-avoid-enabling-lpm-twice.patch +vsock-virtio-fix-kernel-panic-from-virtio_transport_reset_no_sock.patch diff --git a/queue-4.9/sunrpc-don-t-mark-uninitialised-items-as-valid.patch b/queue-4.9/sunrpc-don-t-mark-uninitialised-items-as-valid.patch new file mode 100644 index 00000000000..226040a54a6 --- /dev/null +++ b/queue-4.9/sunrpc-don-t-mark-uninitialised-items-as-valid.patch @@ -0,0 +1,57 @@ +From d58431eacb226222430940134d97bfd72f292fcd Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 5 Apr 2019 11:34:40 +1100 +Subject: sunrpc: don't mark uninitialised items as VALID. + +From: NeilBrown + +commit d58431eacb226222430940134d97bfd72f292fcd upstream. + +A recent commit added a call to cache_fresh_locked() +when an expired item was found. +The call sets the CACHE_VALID flag, so it is important +that the item actually is valid. +There are two ways it could be valid: +1/ If ->update has been called to fill in relevant content +2/ if CACHE_NEGATIVE is set, to say that content doesn't exist. + +An expired item that is waiting for an update will be neither. +Setting CACHE_VALID will mean that a subsequent call to cache_put() +will be likely to dereference uninitialised pointers. + +So we must make sure the item is valid, and we already have code to do +that in try_to_negate_entry(). This takes the hash lock and so cannot +be used directly, so take out the two lines that we need and use them. + +Now cache_fresh_locked() is certain to be called only on +a valid item. + +Cc: stable@kernel.org # 2.6.35 +Fixes: 4ecd55ea0742 ("sunrpc: fix cache_head leak due to queued request") +Signed-off-by: NeilBrown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/cache.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -54,6 +54,7 @@ static void cache_init(struct cache_head + h->last_refresh = now; + } + ++static inline int cache_is_valid(struct cache_head *h); + static void cache_fresh_locked(struct cache_head *head, time_t expiry, + struct cache_detail *detail); + static void cache_fresh_unlocked(struct cache_head *head, +@@ -100,6 +101,8 @@ struct cache_head *sunrpc_cache_lookup(s + if (cache_is_expired(detail, tmp)) { + hlist_del_init(&tmp->cache_list); + detail->entries --; ++ if (cache_is_valid(tmp) == -EAGAIN) ++ set_bit(CACHE_NEGATIVE, &tmp->flags); + cache_fresh_locked(tmp, 0, detail); + freeme = tmp; + break; diff --git a/queue-4.9/usb-add-new-usb-lpm-helpers.patch b/queue-4.9/usb-add-new-usb-lpm-helpers.patch new file mode 100644 index 00000000000..8c84cd3aaa7 --- /dev/null +++ b/queue-4.9/usb-add-new-usb-lpm-helpers.patch @@ -0,0 +1,160 @@ +From 7529b2574a7aaf902f1f8159fbc2a7caa74be559 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Sat, 12 Jan 2019 03:54:24 +0800 +Subject: USB: Add new USB LPM helpers + +From: Kai-Heng Feng + +commit 7529b2574a7aaf902f1f8159fbc2a7caa74be559 upstream. + +Use new helpers to make LPM enabling/disabling more clear. + +This is a preparation to subsequent patch. + +Signed-off-by: Kai-Heng Feng +Cc: stable # after much soaking +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 12 +++++++++++- + drivers/usb/core/hub.c | 12 ++++++------ + drivers/usb/core/message.c | 2 +- + drivers/usb/core/sysfs.c | 5 ++++- + drivers/usb/core/usb.h | 10 ++++++++-- + 5 files changed, 30 insertions(+), 11 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1888,7 +1888,7 @@ int usb_runtime_idle(struct device *dev) + return -EBUSY; + } + +-int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) ++static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) + { + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + int ret = -EPERM; +@@ -1905,6 +1905,16 @@ int usb_set_usb2_hardware_lpm(struct usb + return ret; + } + ++int usb_enable_usb2_hardware_lpm(struct usb_device *udev) ++{ ++ return usb_set_usb2_hardware_lpm(udev, 1); ++} ++ ++int usb_disable_usb2_hardware_lpm(struct usb_device *udev) ++{ ++ return usb_set_usb2_hardware_lpm(udev, 0); ++} ++ + #endif /* CONFIG_PM */ + + struct bus_type usb_bus_type = { +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3169,7 +3169,7 @@ int usb_port_suspend(struct usb_device * + + /* disable USB2 hardware LPM */ + if (udev->usb2_hw_lpm_enabled == 1) +- usb_set_usb2_hardware_lpm(udev, 0); ++ usb_disable_usb2_hardware_lpm(udev); + + if (usb_disable_ltm(udev)) { + dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); +@@ -3216,7 +3216,7 @@ int usb_port_suspend(struct usb_device * + err_ltm: + /* Try to enable USB2 hardware LPM again */ + if (udev->usb2_hw_lpm_capable == 1) +- usb_set_usb2_hardware_lpm(udev, 1); ++ usb_enable_usb2_hardware_lpm(udev); + + if (udev->do_remote_wakeup) + (void) usb_disable_remote_wakeup(udev); +@@ -3500,7 +3500,7 @@ int usb_port_resume(struct usb_device *u + } else { + /* Try to enable USB2 hardware LPM */ + if (udev->usb2_hw_lpm_capable == 1) +- usb_set_usb2_hardware_lpm(udev, 1); ++ usb_enable_usb2_hardware_lpm(udev); + + /* Try to enable USB3 LTM and LPM */ + usb_enable_ltm(udev); +@@ -4337,7 +4337,7 @@ static void hub_set_initial_usb2_lpm_pol + if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || + connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { + udev->usb2_hw_lpm_allowed = 1; +- usb_set_usb2_hardware_lpm(udev, 1); ++ usb_enable_usb2_hardware_lpm(udev); + } + } + +@@ -5482,7 +5482,7 @@ static int usb_reset_and_verify_device(s + * It will be re-enabled by the enumeration process. + */ + if (udev->usb2_hw_lpm_enabled == 1) +- usb_set_usb2_hardware_lpm(udev, 0); ++ usb_disable_usb2_hardware_lpm(udev); + + /* Disable LPM and LTM while we reset the device and reinstall the alt + * settings. Device-initiated LPM settings, and system exit latency +@@ -5592,7 +5592,7 @@ static int usb_reset_and_verify_device(s + + done: + /* Now that the alt settings are re-installed, enable LTM and LPM. */ +- usb_set_usb2_hardware_lpm(udev, 1); ++ usb_enable_usb2_hardware_lpm(udev); + usb_unlocked_enable_lpm(udev); + usb_enable_ltm(udev); + usb_release_bos_descriptor(udev); +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1182,7 +1182,7 @@ void usb_disable_device(struct usb_devic + } + + if (dev->usb2_hw_lpm_enabled == 1) +- usb_set_usb2_hardware_lpm(dev, 0); ++ usb_disable_usb2_hardware_lpm(dev); + usb_unlocked_disable_lpm(dev); + usb_disable_ltm(dev); + +--- a/drivers/usb/core/sysfs.c ++++ b/drivers/usb/core/sysfs.c +@@ -494,7 +494,10 @@ static ssize_t usb2_hardware_lpm_store(s + + if (!ret) { + udev->usb2_hw_lpm_allowed = value; +- ret = usb_set_usb2_hardware_lpm(udev, value); ++ if (value) ++ ret = usb_enable_usb2_hardware_lpm(udev); ++ else ++ ret = usb_disable_usb2_hardware_lpm(udev); + } + + usb_unlock_device(udev); +--- a/drivers/usb/core/usb.h ++++ b/drivers/usb/core/usb.h +@@ -84,7 +84,8 @@ extern int usb_remote_wakeup(struct usb_ + extern int usb_runtime_suspend(struct device *dev); + extern int usb_runtime_resume(struct device *dev); + extern int usb_runtime_idle(struct device *dev); +-extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable); ++extern int usb_enable_usb2_hardware_lpm(struct usb_device *udev); ++extern int usb_disable_usb2_hardware_lpm(struct usb_device *udev); + + #else + +@@ -104,7 +105,12 @@ static inline int usb_autoresume_device( + return 0; + } + +-static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) ++static inline int usb_enable_usb2_hardware_lpm(struct usb_device *udev) ++{ ++ return 0; ++} ++ ++static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) + { + return 0; + } diff --git a/queue-4.9/usb-consolidate-lpm-checks-to-avoid-enabling-lpm-twice.patch b/queue-4.9/usb-consolidate-lpm-checks-to-avoid-enabling-lpm-twice.patch new file mode 100644 index 00000000000..bbb9d56d9b6 --- /dev/null +++ b/queue-4.9/usb-consolidate-lpm-checks-to-avoid-enabling-lpm-twice.patch @@ -0,0 +1,125 @@ +From d7a6c0ce8d26412903c7981503bad9e1cc7c45d2 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Sat, 12 Jan 2019 03:54:25 +0800 +Subject: USB: Consolidate LPM checks to avoid enabling LPM twice +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai-Heng Feng + +commit d7a6c0ce8d26412903c7981503bad9e1cc7c45d2 upstream. + +USB Bluetooth controller QCA ROME (0cf3:e007) sometimes stops working +after S3: +[ 165.110742] Bluetooth: hci0: using NVM file: qca/nvm_usb_00000302.bin +[ 168.432065] Bluetooth: hci0: Failed to send body at 4 of 1953 (-110) + +After some experiments, I found that disabling LPM can workaround the +issue. + +On some platforms, the USB power is cut during S3, so the driver uses +reset-resume to resume the device. During port resume, LPM gets enabled +twice, by usb_reset_and_verify_device() and usb_port_resume(). + +Consolidate all checks into new LPM helpers to make sure LPM only gets +enabled once. + +Fixes: de68bab4fa96 ("usb: Don't enable USB 2.0 Link PM by default.”) +Signed-off-by: Kai-Heng Feng +Cc: stable # after much soaking +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 11 ++++++++--- + drivers/usb/core/hub.c | 12 ++++-------- + drivers/usb/core/message.c | 3 +-- + 3 files changed, 13 insertions(+), 13 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1893,9 +1893,6 @@ static int usb_set_usb2_hardware_lpm(str + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + int ret = -EPERM; + +- if (enable && !udev->usb2_hw_lpm_allowed) +- return 0; +- + if (hcd->driver->set_usb2_hw_lpm) { + ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); + if (!ret) +@@ -1907,11 +1904,19 @@ static int usb_set_usb2_hardware_lpm(str + + int usb_enable_usb2_hardware_lpm(struct usb_device *udev) + { ++ if (!udev->usb2_hw_lpm_capable || ++ !udev->usb2_hw_lpm_allowed || ++ udev->usb2_hw_lpm_enabled) ++ return 0; ++ + return usb_set_usb2_hardware_lpm(udev, 1); + } + + int usb_disable_usb2_hardware_lpm(struct usb_device *udev) + { ++ if (!udev->usb2_hw_lpm_enabled) ++ return 0; ++ + return usb_set_usb2_hardware_lpm(udev, 0); + } + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3168,8 +3168,7 @@ int usb_port_suspend(struct usb_device * + } + + /* disable USB2 hardware LPM */ +- if (udev->usb2_hw_lpm_enabled == 1) +- usb_disable_usb2_hardware_lpm(udev); ++ usb_disable_usb2_hardware_lpm(udev); + + if (usb_disable_ltm(udev)) { + dev_err(&udev->dev, "Failed to disable LTM before suspend\n."); +@@ -3215,8 +3214,7 @@ int usb_port_suspend(struct usb_device * + usb_enable_ltm(udev); + err_ltm: + /* Try to enable USB2 hardware LPM again */ +- if (udev->usb2_hw_lpm_capable == 1) +- usb_enable_usb2_hardware_lpm(udev); ++ usb_enable_usb2_hardware_lpm(udev); + + if (udev->do_remote_wakeup) + (void) usb_disable_remote_wakeup(udev); +@@ -3499,8 +3497,7 @@ int usb_port_resume(struct usb_device *u + hub_port_logical_disconnect(hub, port1); + } else { + /* Try to enable USB2 hardware LPM */ +- if (udev->usb2_hw_lpm_capable == 1) +- usb_enable_usb2_hardware_lpm(udev); ++ usb_enable_usb2_hardware_lpm(udev); + + /* Try to enable USB3 LTM and LPM */ + usb_enable_ltm(udev); +@@ -5481,8 +5478,7 @@ static int usb_reset_and_verify_device(s + /* Disable USB2 hardware LPM. + * It will be re-enabled by the enumeration process. + */ +- if (udev->usb2_hw_lpm_enabled == 1) +- usb_disable_usb2_hardware_lpm(udev); ++ usb_disable_usb2_hardware_lpm(udev); + + /* Disable LPM and LTM while we reset the device and reinstall the alt + * settings. Device-initiated LPM settings, and system exit latency +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1181,8 +1181,7 @@ void usb_disable_device(struct usb_devic + dev->actconfig->interface[i] = NULL; + } + +- if (dev->usb2_hw_lpm_enabled == 1) +- usb_disable_usb2_hardware_lpm(dev); ++ usb_disable_usb2_hardware_lpm(dev); + usb_unlocked_disable_lpm(dev); + usb_disable_ltm(dev); + diff --git a/queue-4.9/vsock-virtio-fix-kernel-panic-from-virtio_transport_reset_no_sock.patch b/queue-4.9/vsock-virtio-fix-kernel-panic-from-virtio_transport_reset_no_sock.patch new file mode 100644 index 00000000000..766940ddf44 --- /dev/null +++ b/queue-4.9/vsock-virtio-fix-kernel-panic-from-virtio_transport_reset_no_sock.patch @@ -0,0 +1,105 @@ +From 4c404ce23358d5d8fbdeb7a6021a9b33d3c3c167 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= +Date: Wed, 6 Mar 2019 12:13:53 +0200 +Subject: vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Adalbert Lazăr + +commit 4c404ce23358d5d8fbdeb7a6021a9b33d3c3c167 upstream. + +Previous to commit 22b5c0b63f32 ("vsock/virtio: fix kernel panic +after device hot-unplug"), vsock_core_init() was called from +virtio_vsock_probe(). Now, virtio_transport_reset_no_sock() can be called +before vsock_core_init() has the chance to run. + +[Wed Feb 27 14:17:09 2019] BUG: unable to handle kernel NULL pointer dereference at 0000000000000110 +[Wed Feb 27 14:17:09 2019] #PF error: [normal kernel read fault] +[Wed Feb 27 14:17:09 2019] PGD 0 P4D 0 +[Wed Feb 27 14:17:09 2019] Oops: 0000 [#1] SMP PTI +[Wed Feb 27 14:17:09 2019] CPU: 3 PID: 59 Comm: kworker/3:1 Not tainted 5.0.0-rc7-390-generic-hvi #390 +[Wed Feb 27 14:17:09 2019] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 +[Wed Feb 27 14:17:09 2019] Workqueue: virtio_vsock virtio_transport_rx_work [vmw_vsock_virtio_transport] +[Wed Feb 27 14:17:09 2019] RIP: 0010:virtio_transport_reset_no_sock+0x8c/0xc0 [vmw_vsock_virtio_transport_common] +[Wed Feb 27 14:17:09 2019] Code: 35 8b 4f 14 48 8b 57 08 31 f6 44 8b 4f 10 44 8b 07 48 8d 7d c8 e8 84 f8 ff ff 48 85 c0 48 89 c3 74 2a e8 f7 31 03 00 48 89 df <48> 8b 80 10 01 00 00 e8 68 fb 69 ed 48 8b 75 f0 65 48 33 34 25 28 +[Wed Feb 27 14:17:09 2019] RSP: 0018:ffffb42701ab7d40 EFLAGS: 00010282 +[Wed Feb 27 14:17:09 2019] RAX: 0000000000000000 RBX: ffff9d79637ee080 RCX: 0000000000000003 +[Wed Feb 27 14:17:09 2019] RDX: 0000000000000001 RSI: 0000000000000002 RDI: ffff9d79637ee080 +[Wed Feb 27 14:17:09 2019] RBP: ffffb42701ab7d78 R08: ffff9d796fae70e0 R09: ffff9d796f403500 +[Wed Feb 27 14:17:09 2019] R10: ffffb42701ab7d90 R11: 0000000000000000 R12: ffff9d7969d09240 +[Wed Feb 27 14:17:09 2019] R13: ffff9d79624e6840 R14: ffff9d7969d09318 R15: ffff9d796d48ff80 +[Wed Feb 27 14:17:09 2019] FS: 0000000000000000(0000) GS:ffff9d796fac0000(0000) knlGS:0000000000000000 +[Wed Feb 27 14:17:09 2019] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[Wed Feb 27 14:17:09 2019] CR2: 0000000000000110 CR3: 0000000427f22000 CR4: 00000000000006e0 +[Wed Feb 27 14:17:09 2019] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[Wed Feb 27 14:17:09 2019] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[Wed Feb 27 14:17:09 2019] Call Trace: +[Wed Feb 27 14:17:09 2019] virtio_transport_recv_pkt+0x63/0x820 [vmw_vsock_virtio_transport_common] +[Wed Feb 27 14:17:09 2019] ? kfree+0x17e/0x190 +[Wed Feb 27 14:17:09 2019] ? detach_buf_split+0x145/0x160 +[Wed Feb 27 14:17:09 2019] ? __switch_to_asm+0x40/0x70 +[Wed Feb 27 14:17:09 2019] virtio_transport_rx_work+0xa0/0x106 [vmw_vsock_virtio_transport] +[Wed Feb 27 14:17:09 2019] NET: Registered protocol family 40 +[Wed Feb 27 14:17:09 2019] process_one_work+0x167/0x410 +[Wed Feb 27 14:17:09 2019] worker_thread+0x4d/0x460 +[Wed Feb 27 14:17:09 2019] kthread+0x105/0x140 +[Wed Feb 27 14:17:09 2019] ? rescuer_thread+0x360/0x360 +[Wed Feb 27 14:17:09 2019] ? kthread_destroy_worker+0x50/0x50 +[Wed Feb 27 14:17:09 2019] ret_from_fork+0x35/0x40 +[Wed Feb 27 14:17:09 2019] Modules linked in: vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common input_leds vsock serio_raw i2c_piix4 mac_hid qemu_fw_cfg autofs4 cirrus ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops virtio_net psmouse drm net_failover pata_acpi virtio_blk failover floppy + +Fixes: 22b5c0b63f32 ("vsock/virtio: fix kernel panic after device hot-unplug") +Reported-by: Alexandru Herghelegiu +Signed-off-by: Adalbert Lazăr +Co-developed-by: Stefan Hajnoczi +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Stefano Garzarella +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/vmw_vsock/virtio_transport_common.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -601,6 +601,8 @@ static int virtio_transport_reset(struct + */ + static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) + { ++ const struct virtio_transport *t; ++ struct virtio_vsock_pkt *reply; + struct virtio_vsock_pkt_info info = { + .op = VIRTIO_VSOCK_OP_RST, + .type = le16_to_cpu(pkt->hdr.type), +@@ -611,15 +613,21 @@ static int virtio_transport_reset_no_soc + if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) + return 0; + +- pkt = virtio_transport_alloc_pkt(&info, 0, +- le64_to_cpu(pkt->hdr.dst_cid), +- le32_to_cpu(pkt->hdr.dst_port), +- le64_to_cpu(pkt->hdr.src_cid), +- le32_to_cpu(pkt->hdr.src_port)); +- if (!pkt) ++ reply = virtio_transport_alloc_pkt(&info, 0, ++ le64_to_cpu(pkt->hdr.dst_cid), ++ le32_to_cpu(pkt->hdr.dst_port), ++ le64_to_cpu(pkt->hdr.src_cid), ++ le32_to_cpu(pkt->hdr.src_port)); ++ if (!reply) + return -ENOMEM; + +- return virtio_transport_get_ops()->send_pkt(pkt); ++ t = virtio_transport_get_ops(); ++ if (!t) { ++ virtio_transport_free_pkt(reply); ++ return -ENOTCONN; ++ } ++ ++ return t->send_pkt(reply); + } + + static void virtio_transport_wait_close(struct sock *sk, long timeout)