#15902: PANIC: IORequest::_CopyData(): invalid range: (684032, 3584)
---------------------------+-----------------------------
Reporter: waddlesplash | Owner: nobody
Type: bug | Status: new
Priority: normal | Milestone: Unscheduled
Component: System/Kernel | Version: R1/Development
Keywords: | Blocked By:
Blocking: 14881 | Platform: All
---------------------------+-----------------------------
I've run into this while working on refactoring nvme_disk driver to use
DMAResource:
{{{
Offset: 684032; Length 2048
PANIC: IORequest::_CopyData(): invalid range: (684032, 3584)
Welcome to Kernel Debugging Land...
Thread 356 "sync" running on CPU 0
stack trace for thread 356 "sync"
kernel stack: 0xffffffff814c1000 to 0xffffffff814c6000
user stack: 0x00007f47bc2d7000 to 0x00007f47bd2d7000
frame caller <image>:function + offset
0 ffffffff814c5618 (+ 24) ffffffff8014e44c <kernel_x86_64>
arch_debug_call_with_fault_handler + 0x16
1 ffffffff814c5630 (+ 80) ffffffff800ad6d8 <kernel_x86_64>
debug_call_with_fault_handler + 0x88
2 ffffffff814c5680 (+ 96) ffffffff800af061 <kernel_x86_64>
kernel_debugger_loop(char const*, char const*, __va_list_tag*, int) + 0xf1
3 ffffffff814c56e0 (+ 80) ffffffff800af35e <kernel_x86_64>
kernel_debugger_internal(char const*, char const*, __va_list_tag*, int) +
0x6e
4 ffffffff814c5730 (+ 240) ffffffff800af6c7 <kernel_x86_64> panic +
0xb7
5 ffffffff814c5820 (+ 96) ffffffff800db624 <kernel_x86_64>
IORequest::_CopyData(void*, long, unsigned long, bool) + 0x154
6 ffffffff814c5880 (+ 96) ffffffff800dbb3c <kernel_x86_64>
IOOperation::Prepare(IORequest*) + 0x13c
7 ffffffff814c58e0 (+ 192) ffffffff800d6ff2 <kernel_x86_64>
DMAResource::TranslateNext(IORequest*, IOOperation*, unsigned long) +
0x802
8 ffffffff814c59a0 (+ 256) ffffffff8151956e <nvme_disk>
nvme_disk_io(void*, IORequest*) + 0xde
9 ffffffff814c5aa0 (+ 352) ffffffff8151a331 <nvme_disk>
nvme_disk_write(void*, long, void const*, unsigned long*) + 0x81
10 ffffffff814c5c00 (+ 112) ffffffff800f1c18 <kernel_x86_64>
_kern_writev + 0x118
11 ffffffff814c5c70 (+ 32) ffffffff8016b7e3 <kernel_x86_64> writev_pos
+ 0x13
12 ffffffff814c5c90 (+ 384) ffffffff818b8e54 <bfs>
_ZN7Journal22_WriteTransactionToLogEv.localalias.9 + 0x8f4
13 ffffffff814c5e10 (+ 48) ffffffff818b9138 <bfs>
_ZN7Journal9_FlushLogEbb.localalias.8 + 0x78
14 ffffffff814c5e40 (+ 224) ffffffff8010b59a <kernel_x86_64> _kern_sync
+ 0x11a
}}}
That is, the IORequest itself is the offset/length on top, but then by the
time it gets to IOOperation::Prepare(), it is trying to copy more data
than is actually in the request.
It appears this is due to DMAResource::TranslateNext aligning the length
to "alignment", which in the case of nvme_disk, is actually B_PAGE_SIZE;
and then it does not trim this down to only the length of the IORequest
length.
It looks like #14881 has the same or similar cause.
I spent some time reading IORequest::Prepare, and I think the issue is in
the loop that CopyData() occurs in. The offset and length are checked only
against the endOffset, which is the total end offset, not the IORequest
end offset for this operation (i.e. fOriginalOffset+fOriginalLength.) I
tried adding a naive bounds check like in Finish() for read (out)
transfers:
{{{
@@ -469,12 +470,17 @@ IOOperation::Prepare(IORequest* request)
vecOffset = 0;
if (base >= bounceBufferStart && base <
bounceBufferEnd) {
if (offset + (off_t)length >
endOffset)
length = endOffset -
offset;
+
+ generic_size_t copyLength =
length;
+ if (offset + (off_t)copyLength >
originalEndOffset)
+ copyLength =
originalEndOffset - offset;
+
status_t error =
fParent->CopyData(offset,
- bounceBuffer + (base -
bounceBufferStart), length);
+ bounceBuffer + (base -
bounceBufferStart), copyLength);
}}}
but this resulted in a second panic:
{{{
PANIC: vm_page_fault: unhandled page fault in kernel space at
0xffffffff00000600, ip 0xffffffff8016e373
Welcome to Kernel Debugging Land...
Thread 373 "sync" running on CPU 0
stack trace for thread 373 "sync"
kernel stack: 0xffffffff815e9000 to 0xffffffff815ee000
user stack: 0x00007fdb308cd000 to 0x00007fdb318cd000
frame caller <image>:function + offset
0 ffffffff815ed278 (+ 24) ffffffff8014e46c <kernel_x86_64>
arch_debug_call_with_fault_handler + 0x16
1 ffffffff815ed290 (+ 80) ffffffff800ad6d8 <kernel_x86_64>
debug_call_with_fault_handler + 0x88
2 ffffffff815ed2e0 (+ 96) ffffffff800af061 <kernel_x86_64>
kernel_debugger_loop(char const*, char const*, __va_list_tag*, int) + 0xf1
3 ffffffff815ed340 (+ 80) ffffffff800af35e <kernel_x86_64>
kernel_debugger_internal(char const*, char const*, __va_list_tag*, int) +
0x6e
4 ffffffff815ed390 (+ 240) ffffffff800af6c7 <kernel_x86_64> panic +
0xb7
5 ffffffff815ed480 (+ 240) ffffffff80138c80 <kernel_x86_64>
vm_page_fault + 0x260
6 ffffffff815ed570 (+ 64) ffffffff80158e70 <kernel_x86_64>
x86_page_fault_exception + 0x160
7 ffffffff815ed5b0 (+ 536) ffffffff8014fd12 <kernel_x86_64> int_bottom
+ 0x56
kernel iframe at 0xffffffff815ed7c8 (end = 0xffffffff815ed890)
rax 0xffffffff8040be00 rbx 0xffffffff00000600 rcx
0xcccccccccc00c6cc
rdx 0xcccccccccc00c6cc rsi 0xffffffff00000600 rdi
0xffffffff8040be00
rbp 0xffffffff815ed8b0 r8 0x1 r9 0x0
r10 0xffffffff823dc340 r11 0x1 r12
0xffffffff815edab0
r13 0xffffffff8040be00 r14 0xfffffffffffffa00 r15
0xffffffff860db190
rip 0xffffffff8016e373 rsp 0xffffffff815ed890 rflags 0x13292
vector: 0xe, error code: 0x0
8 ffffffff815ed7c8 (+ 232) ffffffff8016e373 <kernel_x86_64> memcpy +
0x23
9 ffffffff815ed8b0 (+ 16) ffffffff800d941d <kernel_x86_64>
IORequest::_CopySimple(void*, unsigned long, unsigned long, int, bool) +
0x5d
10 ffffffff815ed8c0 (+ 96) ffffffff800db59b <kernel_x86_64>
IORequest::_CopyData(void*, long, unsigned long, bool) + 0xcb
11 ffffffff815ed920 (+ 128) ffffffff800db995 <kernel_x86_64>
IOOperation::Finish() + 0x235
12 ffffffff815ed9a0 (+ 256) ffffffff81519613 <nvme_disk>
nvme_disk_io(void*, IORequest*) + 0x1f3
13 ffffffff815edaa0 (+ 352) ffffffff8151a261 <nvme_disk>
nvme_disk_write(void*, long, void const*, unsigned long*) + 0x81
14 ffffffff815edc00 (+ 112) ffffffff800f1c38 <kernel_x86_64>
_kern_writev + 0x118
15 ffffffff815edc70 (+ 32) ffffffff8016b803 <kernel_x86_64> writev_pos
+ 0x13
16 ffffffff815edc90 (+ 384) ffffffff818b8e54 <bfs>
_ZN7Journal22_WriteTransactionToLogEv.localalias.9 + 0x8f4
17 ffffffff815ede10 (+ 48) ffffffff818b9138 <bfs>
_ZN7Journal9_FlushLogEbb.localalias.8 + 0x78
18 ffffffff815ede40 (+ 224) ffffffff8010b5ba <kernel_x86_64> _kern_sync
+ 0x11a
}}}
--
Ticket URL: <https://dev.haiku-os.org/ticket/15902>
Haiku <https://dev.haiku-os.org>
The Haiku operating system.