diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-06-18 13:38:32 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-18 13:45:21 +0200 |
commit | 22b0cbe1fe7c5f9dcdf56e4d327a7f3e277d7f81 (patch) | |
tree | c79e36366350e9b8ecd2cf719c2da28568df52ad /Kernel | |
parent | 02de3cbce3379eae34c642995cdcad34e2785ed7 (diff) | |
download | serenity-22b0cbe1fe7c5f9dcdf56e4d327a7f3e277d7f81.zip |
Kernel: Fix crash when changing screen resolution
Steps to reproduce:
1. Change resolution to 640x480.
2. Change resolution to 1280x1024.
3. Observe the following kernel panic:
Kernel::__panic(char const*, unsigned int, char const*) +0x55
Kernel::handle_crash(Kernel::RegisterState&, char const*, ...) +0x112
page_fault_handler +0x1130
page_fault_asm_entry +0x26
Kernel::VirtualConsole::refresh_after_resolution_change() +0x35e4
Kernel::ConsoleManagement::resolution_was_changed() +0x38b
Kernel::Graphics::FramebufferConsole::set_resolution(...) +0x3e1
Kernel::BochsGraphicsAdapter::try_to_set_resolution(...) +0x319
.L4213 +0x40a
Kernel::Process::sys$ioctl(int, unsigned int, unsigned int) +0x2fa
Kernel::Syscall::handle(Kernel::RegisterState&, ...) +0xfdc
syscall_handler +0x19c0
Kernel::syscall_asm_entry_dummy() +0x31
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/TTY/VirtualConsole.cpp | 19 |
1 files changed, 6 insertions, 13 deletions
diff --git a/Kernel/TTY/VirtualConsole.cpp b/Kernel/TTY/VirtualConsole.cpp index e82a8e854d..318b2f414f 100644 --- a/Kernel/TTY/VirtualConsole.cpp +++ b/Kernel/TTY/VirtualConsole.cpp @@ -151,19 +151,12 @@ void VirtualConsole::refresh_after_resolution_change() } // Note: A potential loss of displayed data occur when resolution width shrinks. - if (columns() < old_columns_count) { - for (size_t row = 0; row < rows(); row++) { - auto& line = m_lines[row]; - memcpy(new_cells->vaddr().offset((row)*columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset((row) * (old_columns_count) * sizeof(Cell)).as_ptr(), columns() * sizeof(Cell)); - line.dirty = true; - } - } else { - // Handle Growth of resolution - for (size_t row = 0; row < rows(); row++) { - auto& line = m_lines[row]; - memcpy(new_cells->vaddr().offset((row)*columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset((row) * (old_columns_count) * sizeof(Cell)).as_ptr(), old_columns_count * sizeof(Cell)); - line.dirty = true; - } + auto common_rows_count = min(old_rows_count, rows()); + auto common_columns_count = min(old_columns_count, columns()); + for (size_t row = 0; row < common_rows_count; row++) { + auto& line = m_lines[row]; + memcpy(new_cells->vaddr().offset(row * columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset(row * old_columns_count * sizeof(Cell)).as_ptr(), common_columns_count * sizeof(Cell)); + line.dirty = true; } // Update the new cells Region |