Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

platform: move I/O port driver into platform abstraction #463

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions kernel/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
//
// Author: Joerg Roedel <[email protected]>

use crate::error::SvsmError;
use crate::io::IOPort;
use crate::locking::SpinLock;
use crate::serial::{Terminal, DEFAULT_SERIAL_PORT};
use crate::serial::{SerialPort, Terminal, DEFAULT_SERIAL_PORT};
use crate::utils::immut_after_init::{ImmutAfterInitCell, ImmutAfterInitResult};
use core::fmt;

Expand All @@ -27,14 +29,23 @@ static WRITER: SpinLock<Console> = SpinLock::new(Console {
writer: &DEFAULT_SERIAL_PORT,
});
static CONSOLE_INITIALIZED: ImmutAfterInitCell<bool> = ImmutAfterInitCell::new(false);
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();

pub fn init_console(writer: &'static dyn Terminal) -> ImmutAfterInitResult<()> {
fn init_console(writer: &'static dyn Terminal) -> ImmutAfterInitResult<()> {
WRITER.lock().writer = writer;
CONSOLE_INITIALIZED.reinit(&true)?;
log::info!("COCONUT Secure Virtual Machine Service Module");
Ok(())
}

pub fn init_svsm_console(writer: &'static dyn IOPort, port: u16) -> Result<(), SvsmError> {
CONSOLE_SERIAL
.init(&SerialPort::new(writer, port))
.map_err(|_| SvsmError::Console)?;
(*CONSOLE_SERIAL).init();
init_console(&*CONSOLE_SERIAL).map_err(|_| SvsmError::Console)
}

#[doc(hidden)]
pub fn _print(args: fmt::Arguments<'_>) {
use core::fmt::Write;
Expand Down
1 change: 0 additions & 1 deletion kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub mod requests;
pub mod serial;
pub mod sev;
pub mod string;
pub mod svsm_console;
pub mod svsm_paging;
pub mod syscall;
pub mod task;
Expand Down
18 changes: 4 additions & 14 deletions kernel/src/platform/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@
// Author: Jon Lange <[email protected]>

use crate::address::{PhysAddr, VirtAddr};
use crate::console::init_console;
use crate::console::init_svsm_console;
use crate::cpu::cpuid::CpuidResult;
use crate::cpu::msr::write_msr;
use crate::cpu::percpu::PerCpu;
use crate::error::SvsmError;
use crate::io::IOPort;
use crate::io::{IOPort, DEFAULT_IO_DRIVER};
use crate::platform::{PageEncryptionMasks, PageStateChangeOp, SvsmPlatform};
use crate::serial::SerialPort;
use crate::svsm_console::NativeIOPort;
use crate::types::PageSize;
use crate::utils::immut_after_init::ImmutAfterInitCell;
use crate::utils::MemoryRegion;

static CONSOLE_IO: NativeIOPort = NativeIOPort::new();
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();

const APIC_MSR_ICR: u32 = 0x830;

#[derive(Clone, Copy, Debug)]
Expand All @@ -42,11 +36,7 @@ impl SvsmPlatform for NativePlatform {
fn env_setup(&mut self, debug_serial_port: u16, _vtom: usize) -> Result<(), SvsmError> {
// In the native platform, console output does not require the use of
// any platform services, so it can be initialized immediately.
CONSOLE_SERIAL
.init(&SerialPort::new(&CONSOLE_IO, debug_serial_port))
.map_err(|_| SvsmError::Console)?;
(*CONSOLE_SERIAL).init();
init_console(&*CONSOLE_SERIAL).map_err(|_| SvsmError::Console)
init_svsm_console(&DEFAULT_IO_DRIVER, debug_serial_port)
}

fn env_setup_late(&mut self, _debug_serial_port: u16) -> Result<(), SvsmError> {
Expand Down Expand Up @@ -83,7 +73,7 @@ impl SvsmPlatform for NativePlatform {
fn setup_guest_host_comm(&mut self, _cpu: &PerCpu, _is_bsp: bool) {}

fn get_io_port(&self) -> &'static dyn IOPort {
&CONSOLE_IO
&DEFAULT_IO_DRIVER
}

fn page_state_change(
Expand Down
76 changes: 64 additions & 12 deletions kernel/src/platform/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@
// Author: Jon Lange <[email protected]>

use crate::address::{PhysAddr, VirtAddr};
use crate::console::init_console;
use crate::console::init_svsm_console;
use crate::cpu::cpuid::{cpuid_table, CpuidResult};
use crate::cpu::percpu::{current_ghcb, this_cpu, PerCpu};
use crate::error::ApicError::Registration;
use crate::error::SvsmError;
use crate::greq::driver::guest_request_driver_init;
use crate::io::IOPort;
use crate::platform::{PageEncryptionMasks, PageStateChangeOp, SvsmPlatform};
use crate::serial::SerialPort;
use crate::sev::ghcb::GHCBIOSize;
use crate::sev::hv_doorbell::current_hv_doorbell;
use crate::sev::msr_protocol::{hypervisor_ghcb_features, verify_ghcb_version, GHCBHvFeatures};
use crate::sev::msr_protocol::{
hypervisor_ghcb_features, request_termination_msr, verify_ghcb_version, GHCBHvFeatures,
};
use crate::sev::status::vtom_enabled;
use crate::sev::{
init_hypervisor_ghcb_features, pvalidate_range, sev_status_init, sev_status_verify, PvalidateOp,
};
use crate::svsm_console::SVSMIOPort;
use crate::types::PageSize;
use crate::utils::immut_after_init::ImmutAfterInitCell;
use crate::utils::MemoryRegion;

use core::sync::atomic::{AtomicU32, Ordering};

static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();
static GHCB_IO_DRIVER: GHCBIOPort = GHCBIOPort::new();

static VTOM: ImmutAfterInitCell<usize> = ImmutAfterInitCell::uninit();

Expand Down Expand Up @@ -57,11 +57,7 @@ impl SvsmPlatform for SnpPlatform {
}

fn env_setup_late(&mut self, debug_serial_port: u16) -> Result<(), SvsmError> {
CONSOLE_SERIAL
.init(&SerialPort::new(&CONSOLE_IO, debug_serial_port))
.map_err(|_| SvsmError::Console)?;
(*CONSOLE_SERIAL).init();
init_console(&*CONSOLE_SERIAL).map_err(|_| SvsmError::Console)?;
init_svsm_console(&GHCB_IO_DRIVER, debug_serial_port)?;
sev_status_verify();
init_hypervisor_ghcb_features()?;
Ok(())
Expand Down Expand Up @@ -129,7 +125,7 @@ impl SvsmPlatform for SnpPlatform {
}

fn get_io_port(&self) -> &'static dyn IOPort {
&CONSOLE_IO
&GHCB_IO_DRIVER
}

fn page_state_change(
Expand Down Expand Up @@ -230,3 +226,59 @@ impl SvsmPlatform for SnpPlatform {
current_ghcb().ap_create(vmsa_pa, cpu.get_apic_id().into(), 0, sev_features)
}
}

#[derive(Clone, Copy, Debug, Default)]
pub struct GHCBIOPort {}

impl GHCBIOPort {
pub const fn new() -> Self {
GHCBIOPort {}
}
}

impl IOPort for GHCBIOPort {
fn outb(&self, port: u16, value: u8) {
let ret = current_ghcb().ioio_out(port, GHCBIOSize::Size8, value as u64);
if ret.is_err() {
request_termination_msr();
}
}

fn inb(&self, port: u16) -> u8 {
let ret = current_ghcb().ioio_in(port, GHCBIOSize::Size8);
match ret {
Ok(v) => (v & 0xff) as u8,
Err(_e) => request_termination_msr(),
}
}

fn outw(&self, port: u16, value: u16) {
let ret = current_ghcb().ioio_out(port, GHCBIOSize::Size16, value as u64);
if ret.is_err() {
request_termination_msr();
}
}

fn inw(&self, port: u16) -> u16 {
let ret = current_ghcb().ioio_in(port, GHCBIOSize::Size16);
match ret {
Ok(v) => (v & 0xffff) as u16,
Err(_e) => request_termination_msr(),
}
}

fn outl(&self, port: u16, value: u32) {
let ret = current_ghcb().ioio_out(port, GHCBIOSize::Size32, value as u64);
if ret.is_err() {
request_termination_msr();
}
}

fn inl(&self, port: u16) -> u32 {
let ret = current_ghcb().ioio_in(port, GHCBIOSize::Size32);
match ret {
Ok(v) => (v & 0xffffffff) as u32,
Err(_e) => request_termination_msr(),
}
}
}
21 changes: 6 additions & 15 deletions kernel/src/platform/tdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,16 @@
// Author: Peter Fang <[email protected]>

use crate::address::{PhysAddr, VirtAddr};
use crate::console::init_console;
use crate::console::init_svsm_console;
use crate::cpu::cpuid::CpuidResult;
use crate::cpu::percpu::PerCpu;
use crate::error::SvsmError;
use crate::io::IOPort;
use crate::io::{IOPort, DEFAULT_IO_DRIVER};
use crate::platform::{PageEncryptionMasks, PageStateChangeOp, SvsmPlatform};
use crate::serial::SerialPort;
use crate::svsm_console::SVSMIOPort;
use crate::types::PageSize;
use crate::utils::immut_after_init::ImmutAfterInitCell;
use crate::utils::MemoryRegion;

// FIXME - SVSMIOPort doesn't work on TDP, but the platform does not yet have
// an alternative available.
static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();

static VTOM: ImmutAfterInitCell<usize> = ImmutAfterInitCell::uninit();

#[derive(Clone, Copy, Debug)]
Expand All @@ -45,11 +38,7 @@ impl SvsmPlatform for TdpPlatform {
}

fn env_setup_late(&mut self, debug_serial_port: u16) -> Result<(), SvsmError> {
CONSOLE_SERIAL
.init(&SerialPort::new(&CONSOLE_IO, debug_serial_port))
.map_err(|_| SvsmError::Console)?;
(*CONSOLE_SERIAL).init();
init_console(&*CONSOLE_SERIAL).map_err(|_| SvsmError::Console)
init_svsm_console(&DEFAULT_IO_DRIVER, debug_serial_port)
}

fn env_setup_svsm(&self) -> Result<(), SvsmError> {
Expand Down Expand Up @@ -83,7 +72,9 @@ impl SvsmPlatform for TdpPlatform {
fn setup_guest_host_comm(&mut self, _cpu: &PerCpu, _is_bsp: bool) {}

fn get_io_port(&self) -> &'static dyn IOPort {
&CONSOLE_IO
// FIXME - the default I/O port implementation doesn't work on TDP,
// but the platform does not yet have an alternative available.
&DEFAULT_IO_DRIVER
}

fn page_state_change(
Expand Down
119 changes: 0 additions & 119 deletions kernel/src/svsm_console.rs

This file was deleted.

Loading