-
Notifications
You must be signed in to change notification settings - Fork 40
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
SSE and FPU support #410
base: main
Are you sure you want to change the base?
SSE and FPU support #410
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This goes into the right direction, thanks for the work! I marked some desired changes inline.
Addressed the review comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating the PR! I left a couple of review comments.
kernel/src/cpu/sse.rs
Outdated
|
||
// Check if at least SSE1 is supported | ||
fn legacy_sse_supported() -> bool { | ||
let Some(res) = cpuid_table_raw(1, 0, 0, 0) else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code needs to use the cpuid
instruction directly to be compatible with the native and TD platform targets. I just realized there is no wrapper yet for cpuid
, so please add one and use it for any FPU-related CPUID queries. This also affects other places in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about CpuidResult::get() which is also being used in places like kernel/src/platform/native.rs?
kernel/src/cpu/sse.rs
Outdated
if extended_sse_supported() && xsave_supported() { | ||
cr4_xsave_enable(); | ||
xcr0_set(); | ||
} else { | ||
panic!("XSAVE is not supported by this hardware"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if extended_sse_supported() && xsave_supported() { | |
cr4_xsave_enable(); | |
xcr0_set(); | |
} else { | |
panic!("XSAVE is not supported by this hardware"); | |
} | |
if !extended_sse_supported() { | |
panic!("Extended SSE is not supported by this hardware"); | |
} | |
if !xsave_supported() { | |
panic!("XSAVE is not supported by this hardware"); | |
} | |
cr4_xsave_enable(); | |
xcr0_set(); |
Make the panic messages a bit more concise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, truncated them a bit.
kernel/src/task/schedule.rs
Outdated
if !prev.is_null() { | ||
sse_save_context(u64::from((*prev).xsa.vaddr())); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can happen in schedule()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to schedule()
kernel/src/task/schedule.rs
Outdated
let cur = current_task(); | ||
unsafe { | ||
sse_restore_context(u64::from(cur.xsa.vaddr())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be moved into the if let Some((current, next)) = work {
branch. Otherwise the code will load an old FPU context when no context switch is happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right! good point.
kernel/src/task/tasks.rs
Outdated
unsafe { | ||
sse_restore_context(xsa_addr); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be in setup_new_task()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
let xsa = Self::allocate_xsave_area(); | ||
let xsa_addr = u64::from(xsa.vaddr()) as usize; | ||
let (stack, raw_bounds, rsp_offset) = Self::allocate_ktask_stack(cpu, entry, xsa_addr)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same needs to happen for user tasks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added to user tasks as well.
Addressed review comments. |
Some cpuid functions require a non-zero value of xcr0 to be passed. Signed-off-by: Vasant Karasulli <[email protected]>
Check for the available SSE/FPU related features and initialize them. Signed-off-by: Vasant Karasulli <[email protected]>
Reserve xsave area for tasks to manage xstate. Signed-off-by: Vasant Karasulli <[email protected]>
use xsaveopt/xrstor instructions to save and restore task context. Signed-off-by: Vasant Karasulli <[email protected]>
These in-svsm tests check if tasks can use some sse/fpu instructions and xstate is saved/restored properly during task switches. Signed-off-by: Vasant Karasulli <[email protected]>
This is a temporary solution until we have smart pointer. This also gives a chance to move xsave/xrestor functionality outside the assembly block. Signed-off-by: Vasant Karasulli <[email protected]>
Rebase done. |
This PR entails following changes:
I will submit the related exception handling in another PR.