android_kernel_sony_msm8994/net/9p
Richard Yao b9776f5963 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
[ Upstream commit b6f52ae2f0d32387bde2b89883e3b64d88b9bfe8 ]

The 9p-virtio transport does zero copy on things larger than 1024 bytes
in size. It accomplishes this by returning the physical addresses of
pages to the virtio-pci device. At present, the translation is usually a
bit shift.

That approach produces an invalid page address when we read/write to
vmalloc buffers, such as those used for Linux kernel modules. Any
attempt to load a Linux kernel module from 9p-virtio produces the
following stack.

[<ffffffff814878ce>] p9_virtio_zc_request+0x45e/0x510
[<ffffffff814814ed>] p9_client_zc_rpc.constprop.16+0xfd/0x4f0
[<ffffffff814839dd>] p9_client_read+0x15d/0x240
[<ffffffff811c8440>] v9fs_fid_readn+0x50/0xa0
[<ffffffff811c84a0>] v9fs_file_readn+0x10/0x20
[<ffffffff811c84e7>] v9fs_file_read+0x37/0x70
[<ffffffff8114e3fb>] vfs_read+0x9b/0x160
[<ffffffff81153571>] kernel_read+0x41/0x60
[<ffffffff810c83ab>] copy_module_from_fd.isra.34+0xfb/0x180

Subsequently, QEMU will die printing:

qemu-system-x86_64: virtio: trying to map MMIO memory

This patch enables 9p-virtio to correctly handle this case. This not
only enables us to load Linux kernel modules off virtfs, but also
enables ZFS file-based vdevs on virtfs to be used without killing QEMU.

Special thanks to both Avi Kivity and Alexander Graf for their
interpretation of QEMU backtraces. Without their guidence, tracking down
this bug would have taken much longer. Also, special thanks to Linus
Torvalds for his insightful explanation of why this should use
is_vmalloc_addr() instead of is_vmalloc_or_module_addr():

https://lkml.org/lkml/2014/2/8/272

Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-03-06 21:30:03 -08:00
..
client.c net/9p: Handle error in zero copy request correctly for 9p2000.u 2013-05-28 11:47:57 -05:00
error.c hlist: drop the node parameter from iterators 2013-02-27 19:10:24 -08:00
Kconfig net/9p: remove depends on CONFIG_EXPERIMENTAL 2013-01-11 11:39:33 -08:00
Makefile [net/9p] Preparation and helper functions for zero copy 2011-03-15 09:57:34 -05:00
mod.c 9p: Reduce object size with CONFIG_NET_9P_DEBUG 2012-01-05 10:51:44 -06:00
protocol.c 9p: Modify the stat structures to use kuid_t and kgid_t 2013-02-12 03:19:31 -08:00
protocol.h net/9p: Convert net/9p protocol dumps to tracepoints 2011-10-24 11:13:12 -05:00
trans_common.c 9p: fix off by one causing access violations and memory corruption 2013-07-28 16:29:58 -07:00
trans_common.h fs/9p: Update zero-copy implementation in 9p 2011-10-24 11:13:11 -05:00
trans_fd.c The following changes since commit 4cbe5a555f: 2012-10-12 09:59:23 +09:00
trans_rdma.c 9p: Reduce object size with CONFIG_NET_9P_DEBUG 2012-01-05 10:51:44 -06:00
trans_virtio.c 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers 2014-03-06 21:30:03 -08:00
util.c net/9p: convert to idr_alloc() 2013-02-27 19:10:20 -08:00