Skip to content

Commit 94e01d2

Browse files
io: make {set,get}_{fs,gs}_base indirect functions
Signed-off-by: Anhad Singh <[email protected]>
1 parent 120f2d3 commit 94e01d2

File tree

5 files changed

+75
-26
lines changed

5 files changed

+75
-26
lines changed

bootstrap.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ packages:
902902
- '--prefix=/usr'
903903
- '-Dheaders_only=true'
904904
- '-Ddisable_iconv_option=true'
905-
- '-Dbuildtype=debug'
905+
- '--buildtype=release'
906906
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
907907
- '@THIS_SOURCE_DIR@'
908908
build:
@@ -929,7 +929,7 @@ packages:
929929
- '--libdir=lib'
930930
- '-Dmlibc_no_headers=true'
931931
- '-Ddisable_iconv_option=true'
932-
- '-Dbuildtype=debug'
932+
- '--buildtype=release'
933933
- '-Dlinux_kernel_headers=@BUILD_ROOT@/packages/linux-headers/usr/include'
934934
- '@THIS_SOURCE_DIR@'
935935
build:

src/aero_kernel/src/arch/x86_64/io.rs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ pub fn rdgsbase() -> VirtAddr {
261261

262262
/// # Safety
263263
/// The caller must ensure that the swap operation does not cause any undefined behavior.
264-
#[inline]
264+
#[inline(always)]
265265
pub unsafe fn swapgs() {
266266
asm!("swapgs", options(nostack, preserves_flags));
267267
}
@@ -271,48 +271,80 @@ pub unsafe fn swapgs() {
271271
// the `KERNEL_GS_BASE` MSR.
272272

273273
/// Sets the inactive `GS` segment's base address.
274-
#[inline]
275-
pub unsafe fn set_inactive_gsbase(base: VirtAddr) {
276-
if super::has_fsgsbase() {
274+
#[indirect]
275+
pub fn set_inactive_gsbase() -> fn(base: VirtAddr) {
276+
unsafe fn with_wrgsbase(base: VirtAddr) {
277277
swapgs();
278278
wrgsbase(base);
279279
swapgs();
280-
} else {
280+
}
281+
282+
unsafe fn with_wrmsr(base: VirtAddr) {
281283
wrmsr(IA32_KERNEL_GSBASE, base.as_u64());
282284
}
285+
286+
if super::has_fsgsbase() {
287+
with_wrgsbase
288+
} else {
289+
with_wrmsr
290+
}
283291
}
284292

285293
/// Returns the inactive `GS` segment's base address.
286-
#[inline]
287-
pub fn get_inactive_gsbase() -> VirtAddr {
288-
if super::has_fsgsbase() {
294+
#[indirect]
295+
pub fn get_inactive_gsbase() -> fn() -> VirtAddr {
296+
fn with_rdgsbase() -> VirtAddr {
289297
// SAFETY: The GS base is swapped back to the original value after the read.
290298
unsafe { swapgs() };
291299
let base = rdgsbase();
292300
unsafe { swapgs() };
293301

294302
base
295-
} else {
303+
}
304+
305+
fn with_rdmsr() -> VirtAddr {
296306
VirtAddr::new(unsafe { rdmsr(IA32_KERNEL_GSBASE) })
297307
}
298-
}
299308

300-
/// Returns the `FS` segment's base address.
301-
#[inline]
302-
pub fn get_fsbase() -> VirtAddr {
303309
if super::has_fsgsbase() {
304-
rdfsbase()
310+
with_rdgsbase
305311
} else {
306-
VirtAddr::new(unsafe { rdmsr(IA32_FS_BASE) })
312+
with_rdmsr
307313
}
308314
}
309315

310316
/// Sets the `FS` segment's base address.
311-
#[inline]
312-
pub unsafe fn set_fsbase(base: VirtAddr) {
313-
if super::has_fsgsbase() {
317+
#[indirect]
318+
pub fn set_fsbase() -> fn(base: VirtAddr) {
319+
unsafe fn with_wrfsbase(base: VirtAddr) {
314320
wrfsbase(base);
315-
} else {
321+
}
322+
323+
unsafe fn with_wrmsr(base: VirtAddr) {
316324
wrmsr(IA32_FS_BASE, base.as_u64());
317325
}
326+
327+
if super::has_fsgsbase() {
328+
with_wrfsbase
329+
} else {
330+
with_wrmsr
331+
}
332+
}
333+
334+
/// Returns the `FS` segment's base address.
335+
#[indirect]
336+
pub fn get_fsbase() -> fn() -> VirtAddr {
337+
fn with_rdfsbase() -> VirtAddr {
338+
rdfsbase()
339+
}
340+
341+
fn with_rdmsr() -> VirtAddr {
342+
VirtAddr::new(unsafe { rdmsr(IA32_FS_BASE) })
343+
}
344+
345+
if super::has_fsgsbase() {
346+
with_rdfsbase
347+
} else {
348+
with_rdmsr
349+
}
318350
}

src/aero_kernel/src/arch/x86_64/mem.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ unsafe extern "C" fn memcpy_movsb(dest: *mut u8, src: *const u8, len: usize) ->
6767
}
6868

6969
#[indirect]
70-
extern "C" fn memcpy() -> fn(*mut u8, *const u8, usize) {
70+
extern "C" fn memcpy() -> fn(dest: *mut u8, src: *const u8, len: usize) {
7171
if should_store_by_byte() {
7272
memcpy_movsb
7373
} else {
@@ -125,7 +125,7 @@ unsafe extern "C" fn memset_stosb(dest: *mut u8, byte: i32, len: usize) -> *mut
125125
}
126126

127127
#[indirect]
128-
extern "C" fn memset() -> fn(*mut u8, i32, usize) {
128+
extern "C" fn memset() -> fn(dest: *mut u8, byte: i32, len: usize) {
129129
if should_store_by_byte() {
130130
memset_stosb
131131
} else {

src/aero_proc/src/indirect.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
use proc_macro::TokenStream;
22
use proc_macro2::{Ident, Span};
3+
use syn::spanned::Spanned;
34

45
pub fn parse(_: TokenStream, item: TokenStream) -> TokenStream {
56
let item = syn::parse_macro_input!(item as syn::ItemFn);
67
let args = item.sig.inputs;
78

9+
if !args.is_empty() {
10+
abort!(args.span(), "resolver is expected to take no arguments");
11+
}
12+
813
let name = item.sig.ident.to_string();
14+
let vis = item.vis;
15+
16+
let output_fn = match item.sig.output {
17+
syn::ReturnType::Type(_, ty) => match ty.as_ref() {
18+
syn::Type::BareFn(bare_fn) => bare_fn.clone(),
19+
ty => abort!(ty.span(), "expected output function type"),
20+
},
21+
ty => abort!(ty.span(), "expected output function type"),
22+
};
23+
24+
let output_args = &output_fn.inputs;
25+
let output_ret = &output_fn.output;
926

1027
// Underscores at the beginning of the identifier make it reserved, and the more underscores
1128
// there are, the more reserveder it is.
@@ -35,7 +52,7 @@ pub fn parse(_: TokenStream, item: TokenStream) -> TokenStream {
3552
::core::arch::global_asm!(#inline, sym #resolve_name);
3653

3754
extern "C" {
38-
fn #name(#args);
55+
#vis fn #name(#output_args) #output_ret;
3956
}
4057
}
4158
.into()

userland/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)