Skip to content

Commit 2d55a4b

Browse files
authored
Merge pull request #368 from msft-jlange/alt_injection
svsm: implement SVSM Alternate Injection protocol for APIC emulation
2 parents d559334 + 1ff90ca commit 2d55a4b

34 files changed

+1640
-48
lines changed

Cargo.lock

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bootlib/src/igvm_params.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ pub struct IgvmParamBlock {
115115
/// The port number of the serial port to use for debugging.
116116
pub debug_serial_port: u16,
117117

118+
/// Indicates whether the guest can support alternate injection.
119+
pub use_alternate_injection: u8,
120+
118121
#[doc(hidden)]
119-
pub _reserved: [u16; 3],
122+
pub _reserved: [u8; 5],
120123

121124
/// Metadata containing information about the firmware image embedded in the
122125
/// IGVM file.

bootlib/src/kernel_launch.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub struct KernelLaunchInfo {
3131
pub igvm_params_virt_addr: u64,
3232
pub vtom: u64,
3333
pub debug_serial_port: u16,
34+
pub use_alternate_injection: bool,
3435
pub platform_type: SvsmPlatformType,
3536
}
3637

cpuarch/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7+
bitfield-struct.workspace = true
78

89
[lints]
9-
workspace = true
10+
workspace = true

cpuarch/src/vmsa.rs

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

7+
use bitfield_struct::bitfield;
8+
79
// AE Exitcodes
810
// Table 15-35, AMD64 Architecture Programmer’s Manual, Vol. 2
911
#[repr(u64)]
@@ -43,6 +45,64 @@ pub enum GuestVMExit {
4345
BUSY = 0xfffffffffffffffe,
4446
}
4547

48+
#[bitfield(u64)]
49+
pub struct VIntrCtrl {
50+
pub v_tpr: u8,
51+
pub v_irq: bool,
52+
pub vgif: bool,
53+
pub int_shadow: bool,
54+
pub v_nmi: bool,
55+
pub v_nmi_mask: bool,
56+
#[bits(3)]
57+
_rsvd_15_13: u8,
58+
#[bits(4)]
59+
pub v_intr_prio: u8,
60+
pub v_ign_tpr: bool,
61+
#[bits(5)]
62+
_rsvd_25_21: u8,
63+
v_nmi_enable: bool,
64+
#[bits(5)]
65+
_rsvd_31_27: u8,
66+
pub v_intr_vector: u8,
67+
#[bits(23)]
68+
_rsvd_62_40: u32,
69+
busy: bool,
70+
}
71+
72+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
73+
pub enum VmsaEventType {
74+
Interrupt = 0,
75+
NMI = 2,
76+
Exception = 3,
77+
SoftwareInterrupt = 4,
78+
}
79+
80+
impl VmsaEventType {
81+
const fn into_bits(self) -> u64 {
82+
self as _
83+
}
84+
const fn from_bits(value: u64) -> Self {
85+
match value {
86+
2 => Self::NMI,
87+
3 => Self::Exception,
88+
4 => Self::SoftwareInterrupt,
89+
_ => Self::Interrupt,
90+
}
91+
}
92+
}
93+
94+
#[bitfield(u64)]
95+
pub struct VmsaEventInject {
96+
pub vector: u8,
97+
#[bits(3)]
98+
pub event_type: VmsaEventType,
99+
pub error_code_valid: bool,
100+
#[bits(19)]
101+
_rsvd_30_12: u32,
102+
pub valid: bool,
103+
pub error_code: u32,
104+
}
105+
46106
#[repr(C, packed)]
47107
#[derive(Debug, Default, Clone, Copy)]
48108
pub struct VMSASegment {
@@ -139,15 +199,15 @@ pub struct VMSA {
139199
pub reserved_380: [u8; 16],
140200
pub guest_exitinfo1: u64,
141201
pub guest_exitinfo2: u64,
142-
pub guest_exitintinfo: u64,
202+
pub guest_exitintinfo: VmsaEventInject,
143203
pub guest_nrip: u64,
144204
pub sev_features: u64,
145-
pub vintr_ctrl: u64,
205+
pub vintr_ctrl: VIntrCtrl,
146206
pub guest_exit_code: GuestVMExit,
147207
pub vtom: u64,
148208
pub tlb_id: u64,
149209
pub pcpu_id: u64,
150-
pub event_inj: u64,
210+
pub event_inj: VmsaEventInject,
151211
pub xcr0: u64,
152212
pub reserved_3f0: [u8; 16],
153213
pub x87_dp: u64,
@@ -279,13 +339,3 @@ impl Default for VMSA {
279339
}
280340
}
281341
}
282-
283-
impl VMSA {
284-
pub fn enable(&mut self) {
285-
self.efer |= 1u64 << 12;
286-
}
287-
288-
pub fn disable(&mut self) {
289-
self.efer &= !(1u64 << 12);
290-
}
291-
}

igvmbuilder/src/cmd_options.rs

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ pub struct CmdOptions {
5959
/// Extra SEV features to be enabled in the VMSA (multiple values can be provided separated by ',')
6060
#[arg(long, value_delimiter = ',')]
6161
pub sev_features: Vec<SevExtraFeatures>,
62+
63+
/// Use Alternate Injection if available
64+
#[arg(long, default_value_t = false)]
65+
pub alt_injection: bool,
6266
}
6367

6468
impl CmdOptions {

igvmbuilder/src/igvm_builder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ impl IgvmBuilder {
221221
kernel_size: self.gpa_map.kernel.get_size() as u32,
222222
kernel_base: self.gpa_map.kernel.get_start(),
223223
vtom,
224+
use_alternate_injection: match self.options.alt_injection {
225+
true => 1,
226+
false => 0,
227+
},
224228
..Default::default()
225229
};
226230

kernel/src/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,11 @@ impl SvsmConfig<'_> {
184184
SvsmConfig::IgvmConfig(igvm_params) => igvm_params.initialize_guest_vmsa(vmsa),
185185
}
186186
}
187+
188+
pub fn use_alternate_injection(&self) -> bool {
189+
match self {
190+
SvsmConfig::FirmwareConfig(_) => false,
191+
SvsmConfig::IgvmConfig(igvm_params) => igvm_params.use_alternate_injection(),
192+
}
193+
}
187194
}

0 commit comments

Comments
 (0)