Skip to content

Commit 0bbb4f8

Browse files
committed
Add assertions in per_cpu for offset definitions in cpu_local
1 parent c60bb2e commit 0bbb4f8

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

Cargo.lock

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

kernel/cpu_local/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ use spin::Mutex;
2828
use x86_64::{registers::model_specific::GsBase, VirtAddr};
2929

3030
/// Info use to obtain a reference to a CPU-local variable; see [`CpuLocal::new()`].
31+
///
32+
/// This struct is marked `#[non_exhaustive]`, so it cannot be instantiated elsewhere.
33+
#[non_exhaustive]
3134
pub struct FixedCpuLocal {
32-
offset: usize,
33-
size: usize,
34-
align: usize,
35+
pub offset: usize,
36+
pub size: usize,
37+
pub align: usize,
3538
}
3639
// NOTE: These fields must be kept in sync with `cpu_local::FixedCpuLocal`.
3740
impl FixedCpuLocal {
@@ -119,7 +122,7 @@ impl<const OFFSET: usize, T> CpuLocal<OFFSET, T> {
119122
unsafe {
120123
#[cfg(target_arch = "x86_64")]
121124
asm!(
122-
"mov {}, gs:[0]", // the SELF_PTR_OFFSET is 0
125+
"mov {}, gs:[0]", // the self ptr offset is 0
123126
lateout(reg) self_ptr,
124127
options(nostack, preserves_flags, readonly, pure)
125128
);

kernel/per_cpu/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ version = "0.1.0"
66
edition = "2021"
77

88
[dependencies]
9+
memoffset = "0.8.0"
10+
911
cpu = { path = "../cpu" }
1012
cpu_local = { path = "../cpu_local" }
1113
preemption = { path = "../preemption" }

kernel/per_cpu/src/lib.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,14 @@
3131
//!
3232
3333
#![no_std]
34+
#![feature(const_refs_to_cell)]
3435

3536
extern crate alloc; // TODO temp remove this
3637

3738
use cpu::CpuId;
3839
use preemption::{PreemptionCount, PreemptionGuard};
3940
use task::TaskRef;
4041

41-
42-
struct TestU32(u32);
43-
impl Drop for TestU32 {
44-
fn drop(&mut self) {
45-
panic!("Dropping TestU32({})", self.0);
46-
}
47-
}
48-
4942
/// The data stored on a per-CPU basis in Theseus.
5043
///
5144
/// Currently, we do not support additional arbitrary per-CPU states, e.g.,
@@ -56,6 +49,11 @@ impl Drop for TestU32 {
5649
/// by other crates using the functions in the [`cpu_local`] crate.
5750
#[allow(dead_code)] // These fields are accessed via `cpu_local` functions.
5851
#[repr(C)]
52+
//
53+
// IMPORTANT NOTE:
54+
// * These fields must be kept in sync with `cpu_local::FixedCpuLocal`.
55+
// * The same applies for the `const_assertions` module at the end of this file.
56+
//
5957
pub struct PerCpuData {
6058
/// A pointer to the start of this struct in memory, similar to a TLS self pointer.
6159
/// This has a different initial value for each CPU's data image, of course.
@@ -65,7 +63,6 @@ pub struct PerCpuData {
6563
/// loaded in full before accessing a single sub-field. See this for more:
6664
/// <https://github.com/rust-osdev/x86_64/pull/257#issuecomment-849514649>.
6765
self_ptr: usize,
68-
// NOTE: These fields must be kept in sync with `cpu_local::FixedCpuLocal`.
6966
/// The unique ID of this CPU.
7067
cpu_id: CpuId,
7168
/// The current preemption count of this CPU, which is used to determine
@@ -109,3 +106,30 @@ pub fn init(cpu_id: CpuId) -> Result<(), &'static str> {
109106
|self_ptr| PerCpuData::new(self_ptr, cpu_id),
110107
)
111108
}
109+
110+
mod const_assertions {
111+
use core::mem::{align_of, size_of};
112+
use cpu_local::FixedCpuLocal;
113+
use memoffset::offset_of;
114+
use super::*;
115+
116+
const _: () = assert!(0 == offset_of!(PerCpuData, self_ptr));
117+
const _: () = assert!(8 == size_of::<usize>());
118+
const _: () = assert!(8 == align_of::<usize>());
119+
120+
const _: () = assert!(FixedCpuLocal::CPU_ID.offset == offset_of!(PerCpuData, cpu_id));
121+
const _: () = assert!(FixedCpuLocal::CPU_ID.size == size_of::<CpuId>());
122+
const _: () = assert!(FixedCpuLocal::CPU_ID.align == align_of::<CpuId>());
123+
124+
const _: () = assert!(FixedCpuLocal::PREEMPTION_COUNT.offset == offset_of!(PerCpuData, preemption_count));
125+
const _: () = assert!(FixedCpuLocal::PREEMPTION_COUNT.size == size_of::<PreemptionCount>());
126+
const _: () = assert!(FixedCpuLocal::PREEMPTION_COUNT.align == align_of::<PreemptionCount>());
127+
128+
const _: () = assert!(FixedCpuLocal::TASK_SWITCH_PREEMPTION_GUARD.offset == offset_of!(PerCpuData, task_switch_preemption_guard));
129+
const _: () = assert!(FixedCpuLocal::TASK_SWITCH_PREEMPTION_GUARD.size == size_of::<Option<PreemptionGuard>>());
130+
const _: () = assert!(FixedCpuLocal::TASK_SWITCH_PREEMPTION_GUARD.align == align_of::<Option<PreemptionGuard>>());
131+
132+
const _: () = assert!(FixedCpuLocal::DROP_AFTER_TASK_SWITCH.offset == offset_of!(PerCpuData, drop_after_task_switch));
133+
const _: () = assert!(FixedCpuLocal::DROP_AFTER_TASK_SWITCH.size == size_of::<Option<TaskRef>>());
134+
const _: () = assert!(FixedCpuLocal::DROP_AFTER_TASK_SWITCH.align == align_of::<Option<TaskRef >>());
135+
}

0 commit comments

Comments
 (0)