Skip to content

Commit c199984

Browse files
authored
Merge pull request #130 from Freax13/fix/misc-safety-2
miscellaneous fixes
2 parents 17a14c7 + 0abd335 commit c199984

14 files changed

+61
-102
lines changed

src/console.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,44 @@ use crate::utils::immut_after_init::ImmutAfterInitCell;
1010
use core::fmt;
1111
use log;
1212

13-
#[derive(Debug)]
1413
pub struct Console {
15-
writer: *const dyn Terminal,
14+
writer: Option<&'static dyn Terminal>,
1615
}
1716

1817
impl Console {
19-
pub fn set(&mut self, w: *mut dyn Terminal) {
20-
self.writer = w;
18+
pub fn set(&mut self, w: &'static dyn Terminal) {
19+
self.writer = Some(w);
2120
}
2221
}
2322

2423
impl fmt::Write for Console {
2524
fn write_str(&mut self, s: &str) -> fmt::Result {
26-
if self.writer.is_null() {
27-
return Ok(());
28-
}
29-
30-
for ch in s.bytes() {
31-
unsafe {
32-
(*self.writer).put_byte(ch);
25+
if let Some(writer) = self.writer {
26+
for ch in s.bytes() {
27+
writer.put_byte(ch);
3328
}
3429
}
3530

3631
Ok(())
3732
}
3833
}
3934

40-
pub static WRITER: SpinLock<Console> = SpinLock::new(unsafe {
41-
Console {
42-
writer: &DEFAULT_SERIAL_PORT,
35+
impl fmt::Debug for Console {
36+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37+
f.debug_struct("Console")
38+
.field(
39+
"writer",
40+
&format_args!(
41+
"{:?}",
42+
self.writer.as_ref().map(|writer| writer as *const _)
43+
),
44+
)
45+
.finish()
4346
}
47+
}
48+
49+
pub static WRITER: SpinLock<Console> = SpinLock::new(Console {
50+
writer: Some(&DEFAULT_SERIAL_PORT),
4451
});
4552
static CONSOLE_INITIALIZED: ImmutAfterInitCell<bool> = ImmutAfterInitCell::new(false);
4653

src/cpu/gdt.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::types::{SVSM_CS, SVSM_DS, SVSM_TSS};
1010
use core::arch::asm;
1111
use core::mem;
1212

13-
#[repr(packed)]
13+
#[repr(C, packed(2))]
1414
pub struct GdtDesc {
1515
size: u16,
1616
addr: VirtAddr,
@@ -59,11 +59,6 @@ pub fn load_tss(tss: &X86Tss) {
5959
}
6060
}
6161

62-
static mut GDT_DESC: GdtDesc = GdtDesc {
63-
size: 0,
64-
addr: VirtAddr::null(),
65-
};
66-
6762
pub fn gdt_base_limit() -> (u64, u32) {
6863
unsafe {
6964
let gdt_entries = GDT_SIZE as usize;
@@ -75,10 +70,10 @@ pub fn gdt_base_limit() -> (u64, u32) {
7570

7671
pub fn load_gdt() {
7772
unsafe {
78-
let vaddr = VirtAddr::from(GDT.as_ptr());
79-
80-
GDT_DESC.addr = vaddr;
81-
GDT_DESC.size = (GDT_SIZE * 8) - 1;
73+
let gdt_desc: GdtDesc = GdtDesc {
74+
size: (GDT_SIZE * 8) - 1,
75+
addr: VirtAddr::from(GDT.as_ptr()),
76+
};
8277

8378
asm!(r#" /* Load GDT */
8479
lgdt (%rax)
@@ -97,7 +92,7 @@ pub fn load_gdt() {
9792
lretq
9893
1:
9994
"#,
100-
in("rax") &GDT_DESC,
95+
in("rax") &gdt_desc,
10196
in("rdx") SVSM_CS,
10297
in("rcx") SVSM_DS,
10398
options(att_syntax));

src/fs/api.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ impl FsError {
5959
impl_fs_err!(file_not_found, FileNotFound);
6060
}
6161

62-
pub trait File: Debug {
62+
pub trait File: Debug + Send + Sync {
6363
fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SvsmError>;
6464
fn write(&self, buf: &[u8], offset: usize) -> Result<usize, SvsmError>;
6565
fn truncate(&self, size: usize) -> Result<usize, SvsmError>;
6666
fn size(&self) -> usize;
6767
}
6868

69-
pub trait Directory: Debug {
69+
pub trait Directory: Debug + Send + Sync {
7070
fn list(&self) -> Vec<FileName>;
7171
fn lookup_entry(&self, name: FileName) -> Result<DirEntry, SvsmError>;
7272
fn create_file(&self, name: FileName) -> Result<Arc<dyn File>, SvsmError>;

src/fs/filesystem.rs

-4
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ pub struct FileHandle {
6767
handle: SpinLock<RawFileHandle>,
6868
}
6969

70-
unsafe impl Sync for FileHandle {}
71-
7270
impl FileHandle {
7371
pub fn new(file: &Arc<dyn File>) -> Self {
7472
FileHandle {
@@ -102,8 +100,6 @@ struct SvsmFs {
102100
root: Option<Arc<RamDirectory>>,
103101
}
104102

105-
unsafe impl Sync for SvsmFs {}
106-
107103
impl SvsmFs {
108104
const fn new() -> Self {
109105
SvsmFs { root: None }

src/fs/ramfs.rs

-5
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,6 @@ pub struct RamFile {
171171
rawfile: RWLock<RawRamFile>,
172172
}
173173

174-
unsafe impl Sync for RamFile {}
175-
176174
impl RamFile {
177175
#[allow(dead_code)]
178176
pub fn new() -> Self {
@@ -205,9 +203,6 @@ pub struct RamDirectory {
205203
entries: RWLock<Vec<DirectoryEntry>>,
206204
}
207205

208-
unsafe impl Sync for RamDirectory {}
209-
unsafe impl Send for RamDirectory {}
210-
211206
impl RamDirectory {
212207
pub fn new() -> Self {
213208
RamDirectory {

src/io.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use core::arch::asm;
88

9-
pub trait IOPort {
9+
pub trait IOPort: Sync {
1010
fn outb(&self, port: u16, value: u8) {
1111
unsafe { asm!("outb %al, %dx", in("al") value, in("dx") port, options(att_syntax)) }
1212
}

src/locking/spinlock.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ pub struct SpinLock<T: Debug> {
4242
data: UnsafeCell<T>,
4343
}
4444

45-
unsafe impl<T: Debug> Sync for SpinLock<T> {}
45+
unsafe impl<T: Debug + Send> Send for SpinLock<T> {}
46+
unsafe impl<T: Debug + Send> Sync for SpinLock<T> {}
4647

4748
impl<T: Debug> SpinLock<T> {
4849
pub const fn new(data: T) -> Self {

src/mm/alloc.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,19 @@ impl SvsmAllocator {
11831183
}
11841184
}
11851185

1186+
/// Resets the internal state. This is equivalent to reassigning `self`
1187+
/// with `Self::new()`.
1188+
#[cfg(test)]
1189+
fn reset(&self) {
1190+
*self.slab_size_32.lock() = Slab::new(32);
1191+
*self.slab_size_64.lock() = Slab::new(64);
1192+
*self.slab_size_128.lock() = Slab::new(128);
1193+
*self.slab_size_256.lock() = Slab::new(256);
1194+
*self.slab_size_512.lock() = Slab::new(512);
1195+
*self.slab_size_1024.lock() = Slab::new(1024);
1196+
*self.slab_size_2048.lock() = Slab::new(2048);
1197+
}
1198+
11861199
fn get_slab(&self, size: usize) -> Option<&SpinLock<Slab>> {
11871200
if size <= 32 {
11881201
Some(&self.slab_size_32)
@@ -1248,7 +1261,7 @@ unsafe impl GlobalAlloc for SvsmAllocator {
12481261

12491262
#[cfg_attr(any(target_os = "none"), global_allocator)]
12501263
#[cfg_attr(not(target_os = "none"), allow(dead_code))]
1251-
static mut ALLOCATOR: SvsmAllocator = SvsmAllocator::new();
1264+
static ALLOCATOR: SvsmAllocator = SvsmAllocator::new();
12521265

12531266
pub fn root_mem_init(pstart: PhysAddr, vstart: VirtAddr, page_count: usize) {
12541267
{
@@ -1319,7 +1332,7 @@ impl Drop for TestRootMem<'_> {
13191332

13201333
// Reset the Slabs
13211334
*SLAB_PAGE_SLAB.lock() = SlabPageSlab::new();
1322-
unsafe { ALLOCATOR = SvsmAllocator::new() };
1335+
ALLOCATOR.reset();
13231336
}
13241337
}
13251338

src/mm/pagetable.rs

+5
Original file line numberDiff line numberDiff line change
@@ -736,3 +736,8 @@ impl DerefMut for PageTableRef {
736736
unsafe { &mut *self.pgtable_ptr }
737737
}
738738
}
739+
740+
/// SAFETY: `PageTableRef` is more or less equivalent to a mutable reference to
741+
/// a PageTable and so if `&mut PageTable` implements `Send` so does
742+
/// `PageTableRef`.
743+
unsafe impl Send for PageTableRef where &'static mut PageTable: Send {}

src/mm/validate.rs

+2
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,5 @@ impl ValidBitmap {
287287
}
288288
}
289289
}
290+
291+
unsafe impl Send for ValidBitmap {}

src/serial.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub const DLH: u16 = 1; // Divisor Latch High
2525
pub const RCVRDY: u8 = 0x01;
2626
pub const XMTRDY: u8 = 0x20;
2727

28-
pub trait Terminal {
28+
pub trait Terminal: Sync {
2929
fn put_byte(&self, _ch: u8) {}
3030
fn get_byte(&self) -> u8 {
3131
0
@@ -88,7 +88,7 @@ impl<'a> Terminal for SerialPort<'a> {
8888
}
8989
}
9090

91-
pub static mut DEFAULT_SERIAL_PORT: SerialPort = SerialPort {
91+
pub static DEFAULT_SERIAL_PORT: SerialPort = SerialPort {
9292
driver: &DEFAULT_IO_DRIVER,
9393
port: SERIAL_PORT,
9494
};

src/sev/ghcb.rs

+1-52
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::address::{Address, PhysAddr, VirtAddr};
88
use crate::cpu::flush_tlb_global_sync;
99
use crate::cpu::msr::{write_msr, SEV_GHCB};
1010
use crate::error::SvsmError;
11-
use crate::io::IOPort;
1211
use crate::mm::pagetable::get_init_pgtable_locked;
1312
use crate::mm::validate::{
1413
valid_bitmap_clear_valid_4k, valid_bitmap_set_valid_4k, valid_bitmap_valid_addr,
@@ -17,12 +16,9 @@ use crate::mm::virt_to_phys;
1716
use crate::sev::sev_snp_enabled;
1817
use crate::sev::utils::raw_vmgexit;
1918
use crate::types::{PageSize, PAGE_SIZE_2M};
20-
use core::cell::RefCell;
2119
use core::{mem, ptr};
2220

23-
use super::msr_protocol::{
24-
invalidate_page_msr, register_ghcb_gpa_msr, request_termination_msr, validate_page_msr,
25-
};
21+
use super::msr_protocol::{invalidate_page_msr, register_ghcb_gpa_msr, validate_page_msr};
2622
use super::{pvalidate, PvalidateOp};
2723

2824
// TODO: Fix this when Rust gets decent compile time struct offset support
@@ -486,50 +482,3 @@ impl GHCB {
486482
Ok(())
487483
}
488484
}
489-
490-
pub struct GHCBIOPort<'a> {
491-
pub ghcb: RefCell<&'a mut GHCB>,
492-
}
493-
494-
impl<'a> GHCBIOPort<'a> {
495-
pub fn new(ghcb: RefCell<&'a mut GHCB>) -> Self {
496-
GHCBIOPort { ghcb }
497-
}
498-
}
499-
unsafe impl<'a> Sync for GHCBIOPort<'a> {}
500-
501-
impl<'a> IOPort for GHCBIOPort<'a> {
502-
fn outb(&self, port: u16, value: u8) {
503-
let mut g = self.ghcb.borrow_mut();
504-
let ret = g.ioio_out(port, GHCBIOSize::Size8, value as u64);
505-
if ret.is_err() {
506-
request_termination_msr();
507-
}
508-
}
509-
510-
fn inb(&self, port: u16) -> u8 {
511-
let mut g = self.ghcb.borrow_mut();
512-
let ret = g.ioio_in(port, GHCBIOSize::Size8);
513-
match ret {
514-
Ok(v) => (v & 0xff) as u8,
515-
Err(_e) => request_termination_msr(),
516-
}
517-
}
518-
519-
fn outw(&self, port: u16, value: u16) {
520-
let mut g = self.ghcb.borrow_mut();
521-
let ret = g.ioio_out(port, GHCBIOSize::Size16, value as u64);
522-
if ret.is_err() {
523-
request_termination_msr();
524-
}
525-
}
526-
527-
fn inw(&self, port: u16) -> u16 {
528-
let mut g = self.ghcb.borrow_mut();
529-
let ret = g.ioio_in(port, GHCBIOSize::Size16);
530-
match ret {
531-
Ok(v) => (v & 0xffff) as u16,
532-
Err(_e) => request_termination_msr(),
533-
}
534-
}
535-
}

src/stage2.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn shutdown_percpu() {
7373
}
7474

7575
static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
76-
static mut CONSOLE_SERIAL: SerialPort = SerialPort {
76+
static CONSOLE_SERIAL: SerialPort = SerialPort {
7777
driver: &CONSOLE_IO,
7878
port: SERIAL_PORT,
7979
};
@@ -95,9 +95,7 @@ fn setup_env() {
9595
setup_stage2_allocator();
9696
init_percpu();
9797

98-
unsafe {
99-
WRITER.lock().set(&mut CONSOLE_SERIAL);
100-
}
98+
WRITER.lock().set(&CONSOLE_SERIAL);
10199
init_console();
102100

103101
// Console is fully working now and any unsupported configuration can be

src/svsm.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn memory_init(launch_info: &KernelLaunchInfo) {
290290
}
291291

292292
static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
293-
static mut CONSOLE_SERIAL: SerialPort = SerialPort {
293+
static CONSOLE_SERIAL: SerialPort = SerialPort {
294294
driver: &CONSOLE_IO,
295295
port: SERIAL_PORT,
296296
};
@@ -381,9 +381,7 @@ pub extern "C" fn svsm_start(li: &KernelLaunchInfo, vb_addr: usize) {
381381
}
382382
idt_init();
383383

384-
unsafe {
385-
WRITER.lock().set(&mut CONSOLE_SERIAL);
386-
}
384+
WRITER.lock().set(&CONSOLE_SERIAL);
387385
init_console();
388386
install_console_logger("SVSM");
389387

0 commit comments

Comments
 (0)