Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed overflow bug in PageRangeInclusive #351

Merged
merged 3 commits into from
Mar 18, 2022

Conversation

drzewiec
Copy link
Contributor

This PR is to implement the solution suggested by @phil-opp and @Freax13 in #346. Please let me know your thoughts.

One thing that maybe could use doing still: I wanted to add a test case to check this, but it looks like the testing code is largely copied from blog_os and maybe isn't used? I admit I am really not familiar with unit testing so I could use some help on writing a test if that is something you guys would like to see.

@drzewiec
Copy link
Contributor Author

Another thing I was uncertain about: constructing the max address on every iteration is needlessly expensive. However, I would imagine that we would need to add a field to the struct in order to be able to construct it only once. I don't know if that is something you would like to see or not.

@Freax13
Copy link
Member

Freax13 commented Mar 18, 2022

Thank you for your contribution!

One thing that maybe could use doing still: I wanted to add a test case to check this, but it looks like the testing code is largely copied from blog_os and maybe isn't used? I admit I am really not familiar with unit testing so I could use some help on writing a test if that is something you guys would like to see.

Yes, we should absolutely test that. Perhaps this example will help you write a test.

@drzewiec
Copy link
Contributor Author

Ah, I see... I was looking at the testing/ directory to find tests, or a tests module, rather than in the individual source files. Looks fairly straightforward. Thank you!

@Freax13
Copy link
Member

Freax13 commented Mar 18, 2022

Another thing I was uncertain about: constructing the max address on every iteration is needlessly expensive. However, I would imagine that we would need to add a field to the struct in order to be able to construct it only once. I don't know if that is something you would like to see or not.

Creating the max address is actually really fast. In optimized builds creating and comparing the address boils down to a single instruction:

 push    rax
 mov     rax, qword, ptr, [rsi]
 mov     rcx, qword, ptr, [rsi, +, 8]
 cmp     rax, rcx
 jbe     .LBB30_2
 xor     eax, eax
 mov     qword, ptr, [rdi], rax
 mov     rax, rdi
 pop     rcx
 ret
.LBB30_2:
 cmp     rax, -4096  # <-----  The address is directly compared against 0xffff_ffff_ffff_f000.
 jae     .LBB30_3
 lea     rcx, [rax, +, 4096]
 mov     rdx, rcx
 shr     rdx, 47
 jne     .LBB30_6
 jmp     .LBB30_9
.LBB30_3:
 sub     rcx, 4096
 jb      .LBB30_13
 add     rsi, 8
 mov     rdx, rcx
 shr     rdx, 47
 je      .LBB30_9
.LBB30_6:
 cmp     edx, 131071
 je      .LBB30_9
 cmp     edx, 1
 jne     .LBB30_12
 shl     rcx, 16
 sar     rcx, 16
.LBB30_9:
 and     rcx, -4096
 mov     qword, ptr, [rsi], rcx
 mov     qword, ptr, [rdi, +, 8], rax
 mov     eax, 1
 mov     qword, ptr, [rdi], rax
 mov     rax, rdi
 pop     rcx
 ret
.LBB30_13:
 lea     rdi, [rip, +, .L__unnamed_40]
 lea     rdx, [rip, +, .L__unnamed_41]
 mov     esi, 43
 call    qword, ptr, [rip, +, _ZN4core9panicking5panic17h81c3143387dc6c76E@GOTPCREL]
 ud2
.LBB30_12:
 mov     qword, ptr, [rsp], rcx
 lea     rdi, [rip, +, .L__unnamed_42]
 lea     rcx, [rip, +, .L__unnamed_43]
 lea     r8, [rip, +, .L__unnamed_44]
 mov     rdx, rsp
 mov     esi, 74
 call    qword, ptr, [rip, +, _ZN4core6result13unwrap_failed17hedb62ff4b6c4ec9fE@GOTPCREL]
 ud2

Admittedly the generated code is far from perfect, I believe at least one of the panicking branches is actually unreachable, but creating the maximum page isn't the problem here.

Copy link
Member

@Freax13 Freax13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see one small change, but after that I think it's ready to get merged.

src/structures/paging/page.rs Outdated Show resolved Hide resolved
src/structures/paging/page.rs Show resolved Hide resolved
@Freax13 Freax13 enabled auto-merge March 18, 2022 23:21
@Freax13 Freax13 merged commit 8ac2487 into rust-osdev:master Mar 18, 2022
@drzewiec drzewiec deleted the pagerangeinclusive_fix branch March 18, 2022 23:28
@Freax13
Copy link
Member

Freax13 commented Mar 18, 2022

Thank you for your contribution!

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.

2 participants