Skip to content

Commit 30a7ed1

Browse files
syscall: move the syscall handler to x85_64/
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 5358da9 commit 30a7ed1

File tree

7 files changed

+58
-59
lines changed

7 files changed

+58
-59
lines changed

src/aero_kernel/src/arch/x86_64/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod controlregs;
2121
pub mod gdt;
2222
pub mod interrupts;
2323
pub mod signals;
24+
pub mod syscall;
2425
pub mod task;
2526
pub mod tls;
2627

@@ -198,6 +199,8 @@ extern "C" fn x86_64_aero_main(boot_info: &'static StivaleStruct) -> ! {
198199
gdt::init(stack_top_addr);
199200
log::info!("loaded GDT");
200201

202+
syscall::init();
203+
201204
// Architecture init is done. Now we can initialize and start the init
202205
// process in the non-architecture specific part of the kernel.
203206
crate::aero_main();
@@ -216,6 +219,8 @@ extern "C" fn x86_64_aero_ap_main(ap_id: usize, stack_top_addr: VirtAddr) {
216219
gdt::init(stack_top_addr);
217220
log::info!("AP{}: loaded GDT", ap_id);
218221

222+
syscall::init();
223+
219224
apic::mark_ap_ready(true);
220225

221226
// Wait for the BSP to be ready (after the BSP has initialized
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use raw_cpuid::CpuId;
2+
3+
use crate::arch::gdt::GdtEntryType;
4+
use crate::utils::io;
5+
6+
extern "C" {
7+
fn x86_64_syscall_handler();
8+
}
9+
10+
/// Initializes support for the `syscall` and `sysret` instructions for the
11+
/// current CPU.
12+
pub(super) fn init() {
13+
// Check if syscall is supported as it is a required CPU feature for aero to run.
14+
let has_syscall = CpuId::new()
15+
.get_extended_processor_and_feature_identifiers()
16+
.map_or(false, |i| i.has_syscall_sysret());
17+
18+
assert!(has_syscall);
19+
20+
unsafe {
21+
/*
22+
* Enable support for `syscall` and `sysret` instructions if the current
23+
* CPU supports them and the target pointer width is 64.
24+
*/
25+
let syscall_base = GdtEntryType::KERNEL_CODE << 3;
26+
let sysret_base = (GdtEntryType::USER_CODE32_UNUSED << 3) | 3;
27+
28+
let star_hi = syscall_base as u32 | ((sysret_base as u32) << 16);
29+
30+
io::wrmsr(io::IA32_STAR, (star_hi as u64) << 32);
31+
io::wrmsr(io::IA32_LSTAR, x86_64_syscall_handler as u64);
32+
33+
// Clear the trap flag and enable interrupts.
34+
io::wrmsr(io::IA32_FMASK, 0x300);
35+
36+
// Set the EFER.SCE bit to enable the syscall feature
37+
let efer = io::rdmsr(io::IA32_EFER);
38+
io::wrmsr(io::IA32_EFER, efer | 1);
39+
}
40+
}

src/aero_kernel/src/syscall/handler.asm renamed to src/aero_kernel/src/arch/x86_64/syscall_handler.asm

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@
1515
; You should have received a copy of the GNU General Public License
1616
; along with Aero. If not, see <https://www.gnu.org/licenses/>.
1717

18-
extern restore_kernel_fs_base_locked
19-
extern restore_user_tls
2018
extern __inner_syscall
21-
22-
global syscall_handler
19+
global x86_64_syscall_handler
2320

2421
%define TSS_TEMP_USTACK_OFF 0x1c
2522
%define TSS_RSP0_OFF 0x04
@@ -49,7 +46,7 @@ global syscall_handler
4946
;
5047
; The instruction also does not save anything on the stack and does
5148
; *not* change the RSP.
52-
syscall_handler:
49+
x86_64_syscall_handler:
5350
; swap the GS base to ensure that it points to the
5451
; kernel PCR.
5552
swapgs
@@ -112,8 +109,7 @@ syscall_handler:
112109
add rsp, 8
113110
pop r11
114111

115-
pop qword [gs:TSS_TEMP_USTACK_OFF]
116-
mov rsp, [gs:TSS_TEMP_USTACK_OFF]
112+
pop rsp
117113

118114
swapgs
119115
o64 sysret

src/aero_kernel/src/arch/x86_64/task.asm

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,15 @@ jump_userland_exec:
3535
o64 sysret
3636

3737
fork_init:
38+
cli
3839
swapgs
39-
jmp iretq_init
40+
jmp generic_iretq_init
4041

4142
iretq_init:
43+
cli
44+
jmp generic_iretq_init
45+
46+
generic_iretq_init:
4247
; pop the preserved registers
4348
pop r15
4449
pop r14

src/aero_kernel/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ fn aero_main() -> ! {
117117
time::init();
118118
log::info!("loaded timer");
119119

120-
userland::init();
121-
log::info!("loaded userland");
120+
userland::scheduler::init();
121+
log::info!("loaded scheduler");
122122

123123
apic::mark_bsp_ready(true);
124124

@@ -171,7 +171,6 @@ fn kernel_main_thread() {
171171
}
172172

173173
extern "C" fn aero_ap_main(ap_id: usize) -> ! {
174-
userland::init_ap();
175174
log::info!("AP{}: Loaded userland", ap_id);
176175

177176
loop {

src/aero_kernel/src/syscall/mod.rs

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,12 @@ use alloc::vec::Vec;
7373
pub use fs::*;
7474
pub use ipc::*;
7575
pub use process::*;
76-
use raw_cpuid::CpuId;
7776
pub use time::*;
7877

7978
use crate::arch::interrupts::InterruptStack;
8079
use crate::arch::signals;
81-
use crate::arch::{gdt::GdtEntryType, interrupts};
82-
use crate::utils::{io, StackHelper};
80+
use crate::arch::{interrupts};
81+
use crate::utils::{StackHelper};
8382

8483
pub struct ExecArgs {
8584
inner: Vec<Box<[u8]>>,
@@ -246,37 +245,3 @@ extern "C" fn __inner_syscall(stack: &mut InterruptStack) {
246245
crate::arch::signals::syscall_check_signals(result_usize as isize, stack);
247246
stack.scratch.rax = result_usize;
248247
}
249-
250-
extern "C" {
251-
fn syscall_handler();
252-
}
253-
254-
pub fn init() {
255-
// Check if syscall is supported as it is a required CPU feature for aero to run.
256-
let has_syscall = CpuId::new()
257-
.get_extended_processor_and_feature_identifiers()
258-
.map_or(false, |i| i.has_syscall_sysret());
259-
260-
assert!(has_syscall);
261-
262-
unsafe {
263-
/*
264-
* Enable support for `syscall` and `sysret` instructions if the current
265-
* CPU supports them and the target pointer width is 64.
266-
*/
267-
let syscall_base = GdtEntryType::KERNEL_CODE << 3;
268-
let sysret_base = (GdtEntryType::USER_CODE32_UNUSED << 3) | 3;
269-
270-
let star_hi = syscall_base as u32 | ((sysret_base as u32) << 16);
271-
272-
io::wrmsr(io::IA32_STAR, (star_hi as u64) << 32);
273-
io::wrmsr(io::IA32_LSTAR, syscall_handler as u64);
274-
275-
// Clear the trap flag and enable interrupts.
276-
io::wrmsr(io::IA32_FMASK, 0x300);
277-
278-
// Set the EFER.SCE bit to enable the syscall feature
279-
let efer = io::rdmsr(io::IA32_EFER);
280-
io::wrmsr(io::IA32_EFER, efer | 1);
281-
}
282-
}

src/aero_kernel/src/userland/mod.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
use crate::fs;
2121
use crate::fs::Path;
2222

23-
use crate::syscall;
24-
2523
pub mod scheduler;
2624
pub mod signals;
2725
pub mod task;
@@ -43,12 +41,3 @@ pub fn run_tests() -> fs::Result<()> {
4341
scheduler::get_scheduler().exec(utest_inode, None, None);
4442
Ok(())
4543
}
46-
47-
pub fn init_ap() {
48-
syscall::init();
49-
}
50-
51-
pub fn init() {
52-
scheduler::init();
53-
syscall::init();
54-
}

0 commit comments

Comments
 (0)