Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Oct 2018 11:06:54 +0200
From:      Hans Petter Selasky <hps@selasky.org>
To:        Peter Holm <peter@holm.cc>, current@freebsd.org
Subject:   Re: Page fault in midi/sequencer.c
Message-ID:  <612cae90-cd82-6ade-ad9a-349d32965d88@selasky.org>
In-Reply-To: <20181020165604.GA4946@x2.osted.lan>
References:  <20181020165604.GA4946@x2.osted.lan>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------7DA408B79955E35972546159
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

On 10/20/18 6:56 PM, Peter Holm wrote:
> I can trigger this on 13.0-CURRENT r339445 with a non-root test program:
> 
> Calling uiomove() with the following non-sleepable locks held:
> exclusive sleep mutex seqflq (seqflq) r = 0 (0xfffff80003860c08) locked @ dev/sound/midi/sequencer.c:952
> stack backtrace:
> #0 0xffffffff80bfe263 at witness_debugger+0x73
> #1 0xffffffff80bff1b8 at witness_warn+0x448
> #2 0xffffffff80bf6a91 at uiomove_faultflag+0x71
> #3 0xffffffff809439e6 at mseq_write+0x4c6
> #4 0xffffffff80a4f725 at devfs_write_f+0x185
> #5 0xffffffff80c02a87 at dofilewrite+0x97
> #6 0xffffffff80c0287f at kern_pwritev+0x5f
> #7 0xffffffff80c0277d at sys_pwrite+0x8d
> #8 0xffffffff81070af7 at amd64_syscall+0x2a7
> #9 0xffffffff8104a4ad at fast_syscall_common+0x101
> Kernel page fault with the following non-sleepable locks held:
> exclusive sleep mutex seqflq (seqflq) r = 0 (0xfffff80003860c08) locked @ dev/sound/midi/sequencer.c:952
> stack backtrace:
> #0 0xffffffff80bfe263 at witness_debugger+0x73
> #1 0xffffffff80bff1b8 at witness_warn+0x448
> #2 0xffffffff810700d3 at trap_pfault+0x53
> #3 0xffffffff8106f70a at trap+0x2ba
> #4 0xffffffff81049bc5 at calltrap+0x8
> #5 0xffffffff80bf6b42 at uiomove_faultflag+0x122
> #6 0xffffffff809439e6 at mseq_write+0x4c6
> #7 0xffffffff80a4f725 at devfs_write_f+0x185
> #8 0xffffffff80c02a87 at dofilewrite+0x97
> #9 0xffffffff80c0287f at kern_pwritev+0x5f
> #10 0xffffffff80c0277d at sys_pwrite+0x8d
> #11 0xffffffff81070af7 at amd64_syscall+0x2a7
> #12 0xffffffff8104a4ad at fast_syscall_common+0x101
> 
> 
> Fatal trap 12: page fault while in kernel mode
> cpuid = 4; apic id = 04
> fault virtual address = 0x20ea6b
> fault code  = supervisor read data, page not present
> instruction pointer = 0x20:0xffffffff8106d32d
> stack pointer         = 0x28:0xfffffe00a844a660
> frame pointer         = 0x28:0xfffffe00a844a660
> code segment  = base 0x0, limit 0xfffff, type 0x1b
>     = DPL 0, pres 1, long 1, def32 0, gran 1
> processor eflags = interrupt enabled, resume, IOPL = 0
> current process  = 2356 (xxx)
> [ thread pid 2356 tid 100278 ]
> Stopped at      copyin_nosmap_erms+0xdd:        movl    (%rsi),%edx
> db>
> 

Hi,

Can you test the attached patch?

--HPS

--------------7DA408B79955E35972546159
Content-Type: text/x-patch;
 name="seq.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="seq.diff"

Index: sys/dev/sound/midi/sequencer.c
===================================================================
--- sys/dev/sound/midi/sequencer.c	(revision 339376)
+++ sys/dev/sound/midi/sequencer.c	(working copy)
@@ -921,7 +921,9 @@
 
 		SEQ_DEBUG(8, printf("midiread: uiomove cc=%d\n", used));
 		MIDIQ_DEQ(scp->in_q, buf, used);
+		mtx_unlock(&scp->seq_lock);
 		retval = uiomove(buf, used, uio);
+		mtx_lock(&scp->seq_lock);
 		if (retval)
 			goto err1;
 	}
@@ -996,7 +998,9 @@
 			retval = ENXIO;
 			goto err0;
 		}
+		mtx_unlock(&scp->seq_lock);
 		retval = uiomove(event, used, uio);
+		mtx_lock(&scp->seq_lock);
 		if (retval)
 			goto err0;
 
@@ -1034,7 +1038,9 @@
 			SEQ_DEBUG(2,
 			   printf("seq_write: SEQ_FULLSIZE flusing buffer.\n"));
 			while (uio->uio_resid > 0) {
+				mtx_unlock(&scp->seq_lock);
 				retval = uiomove(event, EV_SZ, uio);
+				mtx_lock(&scp->seq_lock);
 				if (retval)
 					goto err0;
 
@@ -1045,6 +1051,7 @@
 		}
 		retval = EINVAL;
 		if (ev_code >= 128) {
+			int error;
 
 			/*
 			 * Some sort of an extended event. The size is eight
@@ -1054,7 +1061,10 @@
 				SEQ_DEBUG(2, printf("seq_write: invalid level two event %x.\n", ev_code));
 				goto err0;
 			}
-			if (uiomove((caddr_t)&event[4], 4, uio)) {
+			mtx_unlock(&scp->seq_lock);
+			error = uiomove((caddr_t)&event[4], 4, uio);
+			mtx_lock(&scp->seq_lock);
+			if (error) {
 				SEQ_DEBUG(2,
 				   printf("seq_write: user memory mangled?\n"));
 				goto err0;

--------------7DA408B79955E35972546159--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?612cae90-cd82-6ade-ad9a-349d32965d88>