diff mbox

QEMU dies on any attempt to load a Linux kernel module when using a 9P rootfs

Message ID 5294C05C.20802@gentoo.org
State New
Headers show

Commit Message

Richard Yao Nov. 26, 2013, 3:38 p.m. UTC
Christopher,

It sounds like you disabled zero-copy entirely, which is not necessary.
As far as I recall, loading kernel modules is the only case in which
valloc() allocated buffers are used. In the worst case, we only need to
disable zero-copy on such buffers. I have been using a small patch to do
precisely that since yesterday. I have attached it to this email since
it sounds like the first version might be helpful to others while I take
the time to explore a few loose ends.

That being said, I would like to investigate a couple of things before I
send either this patch or some variant of it to the appropriate
subsystem maintainer. First, I need to review the valloc() routines to
ensure that range checking against [VMALLOC_START, VMALLOC_END) is the
correct way to identify valloc() generated buffers. Second, I want to
explore the feasibility of a suggestion by Alexander Graf to instead
rework the zero-copy to properly handle valloc() allocated buffers.

Yours truly,
Richard Yao

On 11/26/2013 10:16 AM, Christopher Covington wrote:
> Hi Richard,
> 
> On 11/25/2013 04:50 PM, Richard Yao wrote:
>> I figured out the problem. There is zerocopy IO is being done via DMA to
>> a buffer allocated with valloc(). Right now, I am running a hack-fix
>> locally so I can get some other stuff done first. I will propose a
>> proper fix to the list in a few days.
> 
> I've also encountered this issue on a non-QEMU simulator and have been
> carrying a disable-zero-copy hack for a few months. Let me know if there's
> anything I can help with.
> 
> Christopher
>

Comments

Richard Yao Nov. 26, 2013, 3:47 p.m. UTC | #1
I have this bad habit of not reviewing emails until after I send them.
Anyway, Chris, thanks for your offer of help, but I can handle this on
my own. The previous email was mostly to give you an early version of
the patch and let you know what I plan to do to improve upon it before I
propose some version of this patch to the appropriate subsystem
maintainer(s).

On 11/26/2013 10:38 AM, Richard Yao wrote:
> Christopher,
> 
> It sounds like you disabled zero-copy entirely, which is not necessary.
> As far as I recall, loading kernel modules is the only case in which
> valloc() allocated buffers are used. In the worst case, we only need to
> disable zero-copy on such buffers. I have been using a small patch to do
> precisely that since yesterday. I have attached it to this email since
> it sounds like the first version might be helpful to others while I take
> the time to explore a few loose ends.
> 
> That being said, I would like to investigate a couple of things before I
> send either this patch or some variant of it to the appropriate
> subsystem maintainer. First, I need to review the valloc() routines to
> ensure that range checking against [VMALLOC_START, VMALLOC_END) is the
> correct way to identify valloc() generated buffers. Second, I want to
> explore the feasibility of a suggestion by Alexander Graf to instead
> rework the zero-copy to properly handle valloc() allocated buffers.
> Yours truly,
> Richard Yao
> 
> On 11/26/2013 10:16 AM, Christopher Covington wrote:
>> Hi Richard,
>>
>> On 11/25/2013 04:50 PM, Richard Yao wrote:
>>> I figured out the problem. There is zerocopy IO is being done via DMA to
>>> a buffer allocated with valloc(). Right now, I am running a hack-fix
>>> locally so I can get some other stuff done first. I will propose a
>>> proper fix to the list in a few days.
>>
>> I've also encountered this issue on a non-QEMU simulator and have been
>> carrying a disable-zero-copy hack for a few months. Let me know if there's
>> anything I can help with.
>>
>> Christopher
>>
diff mbox

Patch

diff --git a/net/9p/client.c b/net/9p/client.c
index ee8fd6b..0adfcf5 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1557,7 +1557,9 @@  p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
 		rsize = count;
 
 	/* Don't bother zerocopy for small IO (< 1024) */
-	if (clnt->trans_mod->zc_request && rsize > 1024) {
+	if (clnt->trans_mod->zc_request && rsize > 1024 &&
+		!(udata >= (char __user *)VMALLOC_START &&
+			udata < (char __user *)VMALLOC_END)) {
 		char *indata;
 		if (data) {
 			kernel_buf = 1;