Skip to content

Commit ffc32fa

Browse files
committed
2 parents e8c9fc9 + 6714d11 commit ffc32fa

File tree

12 files changed

+104
-44
lines changed

12 files changed

+104
-44
lines changed

kernel/src/cpu/control_regs.rs

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

77
use super::features::cpu_has_pge;
88
use crate::address::{Address, PhysAddr};
9+
use crate::platform::SvsmPlatform;
910
use bitflags::bitflags;
1011
use core::arch::asm;
1112

@@ -19,15 +20,15 @@ pub fn cr0_init() {
1920
write_cr0(cr0);
2021
}
2122

22-
pub fn cr4_init() {
23+
pub fn cr4_init(platform: &dyn SvsmPlatform) {
2324
let mut cr4 = read_cr4();
2425

2526
cr4.insert(CR4Flags::PSE); // Enable Page Size Extensions
2627

2728
// All processors that are capable of virtualization will support global
2829
// page table entries, so there is no reason to support any processor that
2930
// does not enumerate PGE capability.
30-
assert!(cpu_has_pge(), "CPU does not support PGE");
31+
assert!(cpu_has_pge(platform), "CPU does not support PGE");
3132

3233
cr4.insert(CR4Flags::PGE); // Enable Global Pages
3334
write_cr4(cr4);

kernel/src/cpu/efer.rs

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

77
use super::features::cpu_has_nx;
88
use super::msr::{read_msr, write_msr, EFER};
9+
use crate::platform::SvsmPlatform;
910
use bitflags::bitflags;
1011

1112
bitflags! {
@@ -33,13 +34,13 @@ pub fn write_efer(efer: EFERFlags) {
3334
write_msr(EFER, val);
3435
}
3536

36-
pub fn efer_init() {
37+
pub fn efer_init(platform: &dyn SvsmPlatform) {
3738
let mut efer = read_efer();
3839

3940
// All processors that are capable of virtualization will support
4041
// no-execute table entries, so there is no reason to support any processor
4142
// that does not enumerate NX capability.
42-
assert!(cpu_has_nx(), "CPU does not support NX");
43+
assert!(cpu_has_nx(platform), "CPU does not support NX");
4344

4445
efer.insert(EFERFlags::NXE);
4546
write_efer(efer);

kernel/src/cpu/features.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
//
55
// Author: Joerg Roedel <[email protected]>
66

7-
use super::cpuid::cpuid_table;
7+
use crate::platform::SvsmPlatform;
88

99
const X86_FEATURE_NX: u32 = 20;
1010
const X86_FEATURE_PGE: u32 = 13;
1111

12-
pub fn cpu_has_nx() -> bool {
13-
let ret = cpuid_table(0x80000001);
12+
pub fn cpu_has_nx(platform: &dyn SvsmPlatform) -> bool {
13+
let ret = platform.cpuid(0x80000001);
1414

1515
match ret {
1616
None => false,
1717
Some(c) => (c.edx >> X86_FEATURE_NX) & 1 == 1,
1818
}
1919
}
2020

21-
pub fn cpu_has_pge() -> bool {
22-
let ret = cpuid_table(0x00000001);
21+
pub fn cpu_has_pge(platform: &dyn SvsmPlatform) -> bool {
22+
let ret = platform.cpuid(0x00000001);
2323

2424
match ret {
2525
None => false,

kernel/src/cpu/smp.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,30 @@
55
// Author: Joerg Roedel <[email protected]>
66

77
use crate::acpi::tables::ACPICPUInfo;
8-
use crate::cpu::percpu::{current_ghcb, this_cpu, this_cpu_shared, PerCpu};
8+
use crate::cpu::percpu::{this_cpu, this_cpu_shared, PerCpu};
99
use crate::error::SvsmError;
1010
use crate::platform::SvsmPlatform;
1111
use crate::platform::SVSM_PLATFORM;
1212
use crate::requests::{request_loop, request_processing_main};
1313
use crate::task::{create_kernel_task, schedule_init};
1414
use crate::utils::immut_after_init::immut_after_init_set_multithreaded;
1515

16-
fn start_cpu(platform: &dyn SvsmPlatform, apic_id: u32, vtom: u64) -> Result<(), SvsmError> {
16+
fn start_cpu(platform: &dyn SvsmPlatform, apic_id: u32) -> Result<(), SvsmError> {
1717
let start_rip: u64 = (start_ap as *const u8) as u64;
1818
let percpu = PerCpu::alloc(apic_id)?;
19+
platform.start_cpu(percpu, start_rip)?;
1920

20-
percpu.setup(platform)?;
21-
let (vmsa_pa, sev_features) = percpu.alloc_svsm_vmsa(vtom, start_rip)?;
2221
let percpu_shared = percpu.shared();
23-
24-
current_ghcb().ap_create(vmsa_pa, apic_id.into(), 0, sev_features)?;
2522
while !percpu_shared.is_online() {}
2623
Ok(())
2724
}
2825

29-
pub fn start_secondary_cpus(platform: &dyn SvsmPlatform, cpus: &[ACPICPUInfo], vtom: u64) {
26+
pub fn start_secondary_cpus(platform: &dyn SvsmPlatform, cpus: &[ACPICPUInfo]) {
3027
immut_after_init_set_multithreaded();
3128
let mut count: usize = 0;
3229
for c in cpus.iter().filter(|c| c.apic_id != 0 && c.enabled) {
3330
log::info!("Launching AP with APIC-ID {}", c.apic_id);
34-
start_cpu(platform, c.apic_id, vtom).expect("Failed to bring CPU online");
31+
start_cpu(platform, c.apic_id).expect("Failed to bring CPU online");
3532
count += 1;
3633
}
3734
log::info!("Brought {} AP(s) online", count);

kernel/src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ pub enum ApicError {
4545
/// A generic error during SVSM operation.
4646
#[derive(Clone, Copy, Debug)]
4747
pub enum SvsmError {
48+
/// Errors related to platform initialization.
49+
PlatformInit,
4850
/// Errors during ELF parsing and loading.
4951
Elf(ElfError),
5052
/// Errors related to GHCB

kernel/src/mm/pagetable.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ static FEATURE_MASK: ImmutAfterInitCell<PTEntryFlags> =
4343
ImmutAfterInitCell::new(PTEntryFlags::empty());
4444

4545
/// Re-initializes early paging settings.
46-
pub fn paging_init_early(platform: &dyn SvsmPlatform, vtom: u64) -> ImmutAfterInitResult<()> {
47-
init_encrypt_mask(platform, vtom.try_into().unwrap())?;
46+
pub fn paging_init_early(platform: &dyn SvsmPlatform) -> ImmutAfterInitResult<()> {
47+
init_encrypt_mask(platform)?;
4848

4949
let mut feature_mask = PTEntryFlags::all();
5050
feature_mask.remove(PTEntryFlags::NX);
@@ -53,16 +53,16 @@ pub fn paging_init_early(platform: &dyn SvsmPlatform, vtom: u64) -> ImmutAfterIn
5353
}
5454

5555
/// Initializes paging settings.
56-
pub fn paging_init(platform: &dyn SvsmPlatform, vtom: u64) -> ImmutAfterInitResult<()> {
57-
init_encrypt_mask(platform, vtom.try_into().unwrap())?;
56+
pub fn paging_init(platform: &dyn SvsmPlatform) -> ImmutAfterInitResult<()> {
57+
init_encrypt_mask(platform)?;
5858

5959
let feature_mask = PTEntryFlags::all();
6060
FEATURE_MASK.reinit(&feature_mask)
6161
}
6262

6363
/// Initializes the encrypt mask.
64-
fn init_encrypt_mask(platform: &dyn SvsmPlatform, vtom: usize) -> ImmutAfterInitResult<()> {
65-
let masks = platform.get_page_encryption_masks(vtom);
64+
fn init_encrypt_mask(platform: &dyn SvsmPlatform) -> ImmutAfterInitResult<()> {
65+
let masks = platform.get_page_encryption_masks();
6666

6767
PRIVATE_PTE_MASK.reinit(&masks.private_pte_mask)?;
6868
SHARED_PTE_MASK.reinit(&masks.shared_pte_mask)?;

kernel/src/platform/mod.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Author: Jon Lange <[email protected]>
66

77
use crate::address::{PhysAddr, VirtAddr};
8+
use crate::cpu::cpuid::CpuidResult;
89
use crate::cpu::percpu::PerCpu;
910
use crate::error::SvsmError;
1011
use crate::io::IOPort;
@@ -44,20 +45,27 @@ pub enum PageStateChangeOp {
4445
/// underlying architectures.
4546
pub trait SvsmPlatform {
4647
/// Performs basic early initialization of the runtime environment.
47-
fn env_setup(&mut self, debug_serial_port: u16) -> Result<(), SvsmError>;
48+
fn env_setup(&mut self, debug_serial_port: u16, vtom: usize) -> Result<(), SvsmError>;
4849

4950
/// Performs initialization of the platform runtime environment after
5051
/// the core system environment has been initialized.
5152
fn env_setup_late(&mut self, debug_serial_port: u16) -> Result<(), SvsmError>;
5253

54+
/// Performs initialiation of the environment specfic to the SVSM kernel
55+
/// (for services not used by stage2).
56+
fn env_setup_svsm(&self) -> Result<(), SvsmError>;
57+
5358
/// Completes initialization of a per-CPU object during construction.
5459
fn setup_percpu(&self, cpu: &PerCpu) -> Result<(), SvsmError>;
5560

5661
/// Completes initialization of a per-CPU object on the target CPU.
5762
fn setup_percpu_current(&self, cpu: &PerCpu) -> Result<(), SvsmError>;
5863

5964
/// Determines the paging encryption masks for the current architecture.
60-
fn get_page_encryption_masks(&self, vtom: usize) -> PageEncryptionMasks;
65+
fn get_page_encryption_masks(&self) -> PageEncryptionMasks;
66+
67+
/// Obtain CPUID using platform-specific tables.
68+
fn cpuid(&self, eax: u32) -> Option<CpuidResult>;
6169

6270
/// Establishes state required for guest/host communication.
6371
fn setup_guest_host_comm(&mut self, cpu: &PerCpu, is_bsp: bool);
@@ -95,6 +103,9 @@ pub trait SvsmPlatform {
95103

96104
/// Perform an EOI of the current interrupt.
97105
fn eoi(&self);
106+
107+
/// Start an additional processor.
108+
fn start_cpu(&self, cpu: &PerCpu, start_rip: u64) -> Result<(), SvsmError>;
98109
}
99110

100111
//FIXME - remove Copy trait

kernel/src/platform/native.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl Default for NativePlatform {
3939
}
4040

4141
impl SvsmPlatform for NativePlatform {
42-
fn env_setup(&mut self, debug_serial_port: u16) -> Result<(), SvsmError> {
42+
fn env_setup(&mut self, debug_serial_port: u16, _vtom: usize) -> Result<(), SvsmError> {
4343
// In the native platform, console output does not require the use of
4444
// any platform services, so it can be initialized immediately.
4545
CONSOLE_SERIAL
@@ -53,6 +53,10 @@ impl SvsmPlatform for NativePlatform {
5353
Ok(())
5454
}
5555

56+
fn env_setup_svsm(&self) -> Result<(), SvsmError> {
57+
Ok(())
58+
}
59+
5660
fn setup_percpu(&self, _cpu: &PerCpu) -> Result<(), SvsmError> {
5761
Ok(())
5862
}
@@ -61,7 +65,7 @@ impl SvsmPlatform for NativePlatform {
6165
Ok(())
6266
}
6367

64-
fn get_page_encryption_masks(&self, _vtom: usize) -> PageEncryptionMasks {
68+
fn get_page_encryption_masks(&self) -> PageEncryptionMasks {
6569
// Find physical address size.
6670
let res = CpuidResult::get(0x80000008, 0);
6771
PageEncryptionMasks {
@@ -72,6 +76,10 @@ impl SvsmPlatform for NativePlatform {
7276
}
7377
}
7478

79+
fn cpuid(&self, eax: u32) -> Option<CpuidResult> {
80+
Some(CpuidResult::get(eax, 0))
81+
}
82+
7583
fn setup_guest_host_comm(&mut self, _cpu: &PerCpu, _is_bsp: bool) {}
7684

7785
fn get_io_port(&self) -> &'static dyn IOPort {
@@ -117,4 +125,8 @@ impl SvsmPlatform for NativePlatform {
117125
fn eoi(&self) {
118126
todo!();
119127
}
128+
129+
fn start_cpu(&self, _cpu: &PerCpu, _start_rip: u64) -> Result<(), SvsmError> {
130+
todo!();
131+
}
120132
}

kernel/src/platform/snp.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
use crate::address::{PhysAddr, VirtAddr};
88
use crate::console::init_console;
9-
use crate::cpu::cpuid::cpuid_table;
10-
use crate::cpu::percpu::{current_ghcb, PerCpu};
9+
use crate::cpu::cpuid::{cpuid_table, CpuidResult};
10+
use crate::cpu::percpu::{current_ghcb, this_cpu, PerCpu};
1111
use crate::error::ApicError::Registration;
1212
use crate::error::SvsmError;
1313
use crate::io::IOPort;
@@ -29,6 +29,8 @@ use core::sync::atomic::{AtomicU32, Ordering};
2929
static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
3030
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();
3131

32+
static VTOM: ImmutAfterInitCell<usize> = ImmutAfterInitCell::uninit();
33+
3234
static APIC_EMULATION_REG_COUNT: AtomicU32 = AtomicU32::new(0);
3335

3436
#[derive(Clone, Copy, Debug)]
@@ -47,8 +49,9 @@ impl Default for SnpPlatform {
4749
}
4850

4951
impl SvsmPlatform for SnpPlatform {
50-
fn env_setup(&mut self, _debug_serial_port: u16) -> Result<(), SvsmError> {
52+
fn env_setup(&mut self, _debug_serial_port: u16, vtom: usize) -> Result<(), SvsmError> {
5153
sev_status_init();
54+
VTOM.init(&vtom).map_err(|_| SvsmError::PlatformInit)?;
5255
Ok(())
5356
}
5457

@@ -63,6 +66,10 @@ impl SvsmPlatform for SnpPlatform {
6366
Ok(())
6467
}
6568

69+
fn env_setup_svsm(&self) -> Result<(), SvsmError> {
70+
this_cpu().configure_hv_doorbell()
71+
}
72+
6673
fn setup_percpu(&self, cpu: &PerCpu) -> Result<(), SvsmError> {
6774
// Setup GHCB
6875
cpu.setup_ghcb()
@@ -73,11 +80,12 @@ impl SvsmPlatform for SnpPlatform {
7380
Ok(())
7481
}
7582

76-
fn get_page_encryption_masks(&self, vtom: usize) -> PageEncryptionMasks {
83+
fn get_page_encryption_masks(&self) -> PageEncryptionMasks {
7784
// Find physical address size.
7885
let processor_capacity =
7986
cpuid_table(0x80000008).expect("Can not get physical address size from CPUID table");
8087
if vtom_enabled() {
88+
let vtom = *VTOM;
8189
PageEncryptionMasks {
8290
private_pte_mask: 0,
8391
shared_pte_mask: vtom,
@@ -98,6 +106,10 @@ impl SvsmPlatform for SnpPlatform {
98106
}
99107
}
100108

109+
fn cpuid(&self, eax: u32) -> Option<CpuidResult> {
110+
cpuid_table(eax)
111+
}
112+
101113
fn setup_guest_host_comm(&mut self, cpu: &PerCpu, is_bsp: bool) {
102114
if is_bsp {
103115
verify_ghcb_version();
@@ -206,4 +218,11 @@ impl SvsmPlatform for SnpPlatform {
206218
let _ = current_ghcb().wrmsr(0x80B, 0);
207219
}
208220
}
221+
222+
fn start_cpu(&self, cpu: &PerCpu, start_rip: u64) -> Result<(), SvsmError> {
223+
cpu.setup(self)?;
224+
let (vmsa_pa, sev_features) = cpu.alloc_svsm_vmsa(*VTOM as u64, start_rip)?;
225+
226+
current_ghcb().ap_create(vmsa_pa, cpu.get_apic_id().into(), 0, sev_features)
227+
}
209228
}

kernel/src/platform/tdp.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use crate::utils::MemoryRegion;
2222
static CONSOLE_IO: SVSMIOPort = SVSMIOPort::new();
2323
static CONSOLE_SERIAL: ImmutAfterInitCell<SerialPort<'_>> = ImmutAfterInitCell::uninit();
2424

25+
static VTOM: ImmutAfterInitCell<usize> = ImmutAfterInitCell::uninit();
26+
2527
#[derive(Clone, Copy, Debug)]
2628
pub struct TdpPlatform {}
2729

@@ -38,8 +40,8 @@ impl Default for TdpPlatform {
3840
}
3941

4042
impl SvsmPlatform for TdpPlatform {
41-
fn env_setup(&mut self, _debug_serial_port: u16) -> Result<(), SvsmError> {
42-
Ok(())
43+
fn env_setup(&mut self, _debug_serial_port: u16, vtom: usize) -> Result<(), SvsmError> {
44+
VTOM.init(&vtom).map_err(|_| SvsmError::PlatformInit)
4345
}
4446

4547
fn env_setup_late(&mut self, debug_serial_port: u16) -> Result<(), SvsmError> {
@@ -50,6 +52,10 @@ impl SvsmPlatform for TdpPlatform {
5052
init_console(&*CONSOLE_SERIAL).map_err(|_| SvsmError::Console)
5153
}
5254

55+
fn env_setup_svsm(&self) -> Result<(), SvsmError> {
56+
Ok(())
57+
}
58+
5359
fn setup_percpu(&self, _cpu: &PerCpu) -> Result<(), SvsmError> {
5460
Err(SvsmError::Tdx)
5561
}
@@ -58,9 +64,10 @@ impl SvsmPlatform for TdpPlatform {
5864
Err(SvsmError::Tdx)
5965
}
6066

61-
fn get_page_encryption_masks(&self, vtom: usize) -> PageEncryptionMasks {
67+
fn get_page_encryption_masks(&self) -> PageEncryptionMasks {
6268
// Find physical address size.
6369
let res = CpuidResult::get(0x80000008, 0);
70+
let vtom = *VTOM;
6471
PageEncryptionMasks {
6572
private_pte_mask: 0,
6673
shared_pte_mask: vtom,
@@ -69,6 +76,10 @@ impl SvsmPlatform for TdpPlatform {
6976
}
7077
}
7178

79+
fn cpuid(&self, eax: u32) -> Option<CpuidResult> {
80+
Some(CpuidResult::get(eax, 0))
81+
}
82+
7283
fn setup_guest_host_comm(&mut self, _cpu: &PerCpu, _is_bsp: bool) {}
7384

7485
fn get_io_port(&self) -> &'static dyn IOPort {
@@ -109,4 +120,8 @@ impl SvsmPlatform for TdpPlatform {
109120
}
110121

111122
fn eoi(&self) {}
123+
124+
fn start_cpu(&self, _cpu: &PerCpu, _start_rip: u64) -> Result<(), SvsmError> {
125+
todo!();
126+
}
112127
}

0 commit comments

Comments
 (0)