lkl: block: copy kernel buffers not in the linear map#639
Open
clingfei wants to merge 1 commit into
Open
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.