Skip to content

lkl: block: copy kernel buffers not in the linear map#639

Open
clingfei wants to merge 1 commit into
lkl:masterfrom
clingfei:master
Open

lkl: block: copy kernel buffers not in the linear map#639
clingfei wants to merge 1 commit into
lkl:masterfrom
clingfei:master

Conversation

@clingfei
Copy link
Copy Markdown

blk_rq_map_kern() relies on object_is_on_stack() to route stack-allocated buffers to the bio_copy_kern() bounce path, since a buffer on the stack cannot be mapped directly into a bio.

object_is_on_stack() tests whether the buffer lies within [task_stack_page(current), task_stack_page(current) + THREAD_SIZE). On native architectures that range is the task's real execution stack, so the test works. Under LKL it does not: threads actually execute on host pthread stacks, and object_is_on_stack only checks whether it lies in init_thread_union.thread_info.stack. A buffer placed on the stack therefore lives on the host stack, outside the thread_info range, and object_is_on_stack() returns false. The bounce path is skipped and bio_map_kern() ends up calling virt_to_page() on a host-stack address that is not part of the kernel linear map, corrupting the I/O.

Add blk_kern_needs_copy() to detect this case by checking that both the start and the last byte of the buffer are virt_addr_valid(), and force the bio_copy_kern() bounce path when they are not. The check is guarded by CONFIG_LKL and compiles to false on other builds, so non-LKL kernels are unchanged.

blk_rq_map_kern() relies on object_is_on_stack() to route stack-allocated
buffers to the bio_copy_kern() bounce path, since a buffer on the stack
cannot be mapped directly into a bio.

object_is_on_stack() tests whether the buffer lies within
[task_stack_page(current), task_stack_page(current) + THREAD_SIZE). On
native architectures that range is the task's real execution stack, so the
test works. Under LKL it does not: threads actually execute on host pthread
stacks, and object_is_on_stack only checks whether it lies in
init_thread_union.thread_info.stack. A buffer placed on the stack
therefore lives on the host stack, outside the thread_info range, and
object_is_on_stack() returns false. The bounce path is skipped and
bio_map_kern() ends up calling virt_to_page() on a host-stack address that
is not part of the kernel linear map, corrupting the I/O.

Add blk_kern_needs_copy() to detect this case by checking that both the
start and the last byte of the buffer are virt_addr_valid(), and force
the bio_copy_kern() bounce path when they are not. The check is guarded
by CONFIG_LKL and compiles to false on other builds, so non-LKL kernels
are unchanged.

Signed-off-by: Cheng Lingfei <chenglingfei@foxmail.com>
@github-actions
Copy link
Copy Markdown

Test Results

106 files  ±0  106 suites  ±0   7m 31s ⏱️ -13s
205 tests ±0  194 ✅ ±0  11 💤 ±0  0 ❌ ±0 
822 runs  ±0  766 ✅ ±0  56 💤 ±0  0 ❌ ±0 

Results for commit 97bb7f1. ± Comparison against base commit d25752c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant