Use offset_of! in context::arch::switch_to.
This is definitely better than hardcoding the offsets!
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -1,5 +1,13 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.1"
|
||||
@@ -66,6 +74,7 @@ dependencies = [
|
||||
"goblin",
|
||||
"linked_list_allocator 0.9.0",
|
||||
"log",
|
||||
"memoffset",
|
||||
"paste",
|
||||
"raw-cpuid 8.1.2",
|
||||
"redox_syscall",
|
||||
@@ -113,6 +122,15 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.5"
|
||||
|
||||
@@ -17,7 +17,8 @@ rustc-cfg = "0.3.0"
|
||||
bitflags = "1.2.1"
|
||||
bitfield = "0.13.2"
|
||||
linked_list_allocator = "0.9.0"
|
||||
log = { version = "0.4" }
|
||||
log = "0.4"
|
||||
memoffset = { version = "0.6", features = ["unstable_const"] }
|
||||
redox_syscall = { path = "syscall" }
|
||||
slab_allocator = { path = "slab_allocator", optional = true }
|
||||
spin = "0.9"
|
||||
|
||||
@@ -3,6 +3,8 @@ use core::sync::atomic::AtomicBool;
|
||||
|
||||
use crate::syscall::FloatRegisters;
|
||||
|
||||
use memoffset::offset_of;
|
||||
|
||||
/// This must be used by the kernel to ensure that context switches are done atomically
|
||||
/// Compare and exchange this to true when beginning a context switch on any CPU
|
||||
/// The `Context::switch_to` function will set it back to false, allowing other CPU's to switch
|
||||
@@ -138,10 +140,11 @@ impl Context {
|
||||
|
||||
/// Switch to the next context by restoring its stack and registers
|
||||
/// Check disassembly!
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn switch_to(_prev: &mut Context, _next: &mut Context) {
|
||||
use Context as Cx;
|
||||
|
||||
asm!(
|
||||
// As a quick reminder for those who are unfamiliar with the System V ABI (extern "C"):
|
||||
//
|
||||
@@ -151,29 +154,29 @@ pub unsafe extern "C" fn switch_to(_prev: &mut Context, _next: &mut Context) {
|
||||
// store them here in the first place.
|
||||
"
|
||||
// load `prev.fx`
|
||||
mov rax, [rdi + 0x00]
|
||||
mov rax, [rdi + {off_fx}]
|
||||
|
||||
// save processor SSE/FPU/AVX state in `prev.fx` pointee
|
||||
fxsave64 [rax]
|
||||
|
||||
// set `prev.loadable` to true
|
||||
mov BYTE PTR [rdi + 0x50], {true}
|
||||
mov BYTE PTR [rdi + {off_loadable}], {true}
|
||||
// compare `next.loadable` with true
|
||||
cmp BYTE PTR [rsi + 0x50], {true}
|
||||
cmp BYTE PTR [rsi + {off_loadable}], {true}
|
||||
je switch_to.next_is_loadable
|
||||
|
||||
fninit
|
||||
jmp switch_to.after_fx
|
||||
|
||||
switch_to.next_is_loadable:
|
||||
mov rax, [rsi + 0x00]
|
||||
mov rax, [rsi + {off_fx}]
|
||||
fxrstor64 [rax]
|
||||
|
||||
switch_to.after_fx:
|
||||
// Save the current CR3, and load the next CR3 if not identical
|
||||
mov rcx, cr3
|
||||
mov [rdi + 0x08], rcx
|
||||
mov rax, [rsi + 0x08]
|
||||
mov [rdi + {off_cr3}], rcx
|
||||
mov rax, [rsi + {off_cr3}]
|
||||
cmp rax, rcx
|
||||
|
||||
je switch_to.same_cr3
|
||||
@@ -181,34 +184,34 @@ pub unsafe extern "C" fn switch_to(_prev: &mut Context, _next: &mut Context) {
|
||||
|
||||
switch_to.same_cr3:
|
||||
// Save old registers, and load new ones
|
||||
mov [rdi + 0x18], rbx
|
||||
mov rbx, [rsi + 0x18]
|
||||
mov [rdi + {off_rbx}], rbx
|
||||
mov rbx, [rsi + {off_rbx}]
|
||||
|
||||
mov [rdi + 0x20], r12
|
||||
mov r12, [rsi + 0x20]
|
||||
mov [rdi + {off_r12}], r12
|
||||
mov r12, [rsi + {off_r12}]
|
||||
|
||||
mov [rdi + 0x28], r13
|
||||
mov r13, [rsi + 0x28]
|
||||
mov [rdi + {off_r13}], r13
|
||||
mov r13, [rsi + {off_r13}]
|
||||
|
||||
mov [rdi + 0x30], r14
|
||||
mov r14, [rsi + 0x30]
|
||||
mov [rdi + {off_r14}], r14
|
||||
mov r14, [rsi + {off_r14}]
|
||||
|
||||
mov [rdi + 0x38], r15
|
||||
mov r15, [rsi + 0x38]
|
||||
mov [rdi + {off_r15}], r15
|
||||
mov r15, [rsi + {off_r15}]
|
||||
|
||||
mov [rdi + 0x40], rbp
|
||||
mov rbp, [rsi + 0x40]
|
||||
mov [rdi + {off_rbp}], rbp
|
||||
mov rbp, [rsi + {off_rbp}]
|
||||
|
||||
mov [rdi + 0x48], rsp
|
||||
mov rsp, [rsi + 0x48]
|
||||
mov [rdi + {off_rsp}], rsp
|
||||
mov rsp, [rsi + {off_rsp}]
|
||||
|
||||
// push RFLAGS (can only be modified via stack)
|
||||
pushfq
|
||||
// pop RFLAGS into `self.rflags`
|
||||
pop QWORD PTR [rdi + 0x10]
|
||||
pop QWORD PTR [rdi + {off_rflags}]
|
||||
|
||||
// push `next.rflags`
|
||||
push QWORD PTR [rsi + 0x10]
|
||||
push QWORD PTR [rsi + {off_rflags}]
|
||||
// pop into RFLAGS
|
||||
popfq
|
||||
|
||||
@@ -221,6 +224,19 @@ pub unsafe extern "C" fn switch_to(_prev: &mut Context, _next: &mut Context) {
|
||||
|
||||
",
|
||||
|
||||
off_fx = const(offset_of!(Cx, fx)),
|
||||
off_cr3 = const(offset_of!(Cx, cr3)),
|
||||
off_rflags = const(offset_of!(Cx, rflags)),
|
||||
off_loadable = const(offset_of!(Cx, loadable)),
|
||||
|
||||
off_rbx = const(offset_of!(Cx, rbx)),
|
||||
off_r12 = const(offset_of!(Cx, r12)),
|
||||
off_r13 = const(offset_of!(Cx, r13)),
|
||||
off_r14 = const(offset_of!(Cx, r14)),
|
||||
off_r15 = const(offset_of!(Cx, r15)),
|
||||
off_rbp = const(offset_of!(Cx, rbp)),
|
||||
off_rsp = const(offset_of!(Cx, rsp)),
|
||||
|
||||
true = const(AbiCompatBool::True as u8),
|
||||
switch_hook = sym crate::context::switch_finish_hook,
|
||||
options(noreturn),
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
#![cfg_attr(target_arch = "aarch64", feature(llvm_asm))] // TODO: Rewrite using asm!
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_btree_new)]
|
||||
#![feature(const_maybe_uninit_as_ptr)]
|
||||
#![feature(const_ptr_offset_from)]
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(global_asm)]
|
||||
#![feature(integer_atomics)]
|
||||
|
||||
Reference in New Issue
Block a user