Skip to content

Commit b86b9f4

Browse files
committed
pci: make PCIe support optional
Add a command line argument to enable PCIe support. By default, PCIe is disabled. The reason for making PCIe off by default is that users need to explicitly enable PCI support in their kernels. Requiring users to explicitly enable it, does not break existing deployments, i.e. users can upgrade Firecracker within their existing environments without breaking any deployment. Signed-off-by: Babis Chalios <[email protected]>
1 parent 1cd7e7d commit b86b9f4

File tree

6 files changed

+32
-12
lines changed

6 files changed

+32
-12
lines changed

src/firecracker/src/api_server_adapter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub(crate) fn run_with_api(
143143
instance_info: InstanceInfo,
144144
process_time_reporter: ProcessTimeReporter,
145145
boot_timer_enabled: bool,
146+
pci_enabled: bool,
146147
api_payload_limit: usize,
147148
mmds_size_limit: usize,
148149
metadata_json: Option<&str>,
@@ -212,6 +213,7 @@ pub(crate) fn run_with_api(
212213
json,
213214
instance_info,
214215
boot_timer_enabled,
216+
pci_enabled,
215217
mmds_size_limit,
216218
metadata_json,
217219
)
@@ -224,6 +226,7 @@ pub(crate) fn run_with_api(
224226
&to_api,
225227
&api_event_fd,
226228
boot_timer_enabled,
229+
pci_enabled,
227230
mmds_size_limit,
228231
metadata_json,
229232
)

src/firecracker/src/main.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ fn main_exec() -> Result<(), MainError> {
260260
Argument::new("mmds-size-limit")
261261
.takes_value(true)
262262
.help("Mmds data store limit, in bytes."),
263+
)
264+
.arg(
265+
Argument::new("enable-pci")
266+
.takes_value(false)
267+
.help("Enables PCIe support."),
263268
);
264269

265270
arg_parser.parse_from_cmdline()?;
@@ -369,6 +374,7 @@ fn main_exec() -> Result<(), MainError> {
369374
.map(|x| x.expect("Unable to open or read from the mmds content file"));
370375

371376
let boot_timer_enabled = arguments.flag_present("boot-timer");
377+
let pci_enabled = arguments.flag_present("enable-pci");
372378
let api_enabled = !arguments.flag_present("no-api");
373379
let api_payload_limit = arg_parser
374380
.arguments()
@@ -422,6 +428,7 @@ fn main_exec() -> Result<(), MainError> {
422428
instance_info,
423429
process_time_reporter,
424430
boot_timer_enabled,
431+
pci_enabled,
425432
api_payload_limit,
426433
mmds_size_limit,
427434
metadata_json.as_deref(),
@@ -437,6 +444,7 @@ fn main_exec() -> Result<(), MainError> {
437444
vmm_config_json,
438445
instance_info,
439446
boot_timer_enabled,
447+
pci_enabled,
440448
mmds_size_limit,
441449
metadata_json.as_deref(),
442450
)
@@ -554,19 +562,22 @@ pub enum BuildFromJsonError {
554562
}
555563

556564
// Configure and start a microVM as described by the command-line JSON.
565+
#[allow(clippy::too_many_arguments)]
557566
fn build_microvm_from_json(
558567
seccomp_filters: &BpfThreadMap,
559568
event_manager: &mut EventManager,
560569
config_json: String,
561570
instance_info: InstanceInfo,
562571
boot_timer_enabled: bool,
572+
pci_enabled: bool,
563573
mmds_size_limit: usize,
564574
metadata_json: Option<&str>,
565575
) -> Result<(VmResources, Arc<Mutex<vmm::Vmm>>), BuildFromJsonError> {
566576
let mut vm_resources =
567577
VmResources::from_json(&config_json, &instance_info, mmds_size_limit, metadata_json)
568578
.map_err(BuildFromJsonError::ParseFromJson)?;
569579
vm_resources.boot_timer = boot_timer_enabled;
580+
vm_resources.pci_enabled = pci_enabled;
570581
let vmm = vmm::builder::build_and_boot_microvm(
571582
&instance_info,
572583
&vm_resources,
@@ -593,6 +604,7 @@ fn run_without_api(
593604
config_json: Option<String>,
594605
instance_info: InstanceInfo,
595606
bool_timer_enabled: bool,
607+
pci_enabled: bool,
596608
mmds_size_limit: usize,
597609
metadata_json: Option<&str>,
598610
) -> Result<(), RunWithoutApiError> {
@@ -610,6 +622,7 @@ fn run_without_api(
610622
config_json.unwrap(),
611623
instance_info,
612624
bool_timer_enabled,
625+
pci_enabled,
613626
mmds_size_limit,
614627
metadata_json,
615628
)

src/vmm/src/builder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ pub fn build_microvm_for_boot(
217217
.map(|vcpu| vcpu.copy_kvm_vcpu_fd(vmm.vm()))
218218
.collect::<Result<Vec<_>, _>>()?;
219219

220-
vmm.device_manager.enable_pci()?;
220+
if vm_resources.pci_enabled {
221+
vmm.device_manager.enable_pci()?;
222+
} else {
223+
boot_cmdline.insert("pci", "off")?;
224+
}
221225

222226
// The boot timer device needs to be the first device attached in order
223227
// to maintain the same MMIO address referenced in the documentation

src/vmm/src/resources.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ pub struct VmResources {
114114
pub mmds_size_limit: usize,
115115
/// Whether or not to load boot timer device.
116116
pub boot_timer: bool,
117+
/// Whether or not to use PCIe transport for VirtIO devices.
118+
pub pci_enabled: bool,
117119
}
118120

119121
impl VmResources {
@@ -613,6 +615,7 @@ mod tests {
613615
boot_timer: false,
614616
mmds_size_limit: HTTP_MAX_PAYLOAD_SIZE,
615617
entropy: Default::default(),
618+
pci_enabled: false,
616619
}
617620
}
618621

src/vmm/src/rpc_interface.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -327,18 +327,16 @@ impl<'a> PrebootApiController<'a> {
327327
to_api: &std::sync::mpsc::Sender<ApiResponse>,
328328
api_event_fd: &vmm_sys_util::eventfd::EventFd,
329329
boot_timer_enabled: bool,
330+
pci_enabled: bool,
330331
mmds_size_limit: usize,
331332
metadata_json: Option<&str>,
332333
) -> Result<(VmResources, Arc<Mutex<Vmm>>), BuildMicrovmFromRequestsError> {
333-
let mut vm_resources = VmResources::default();
334-
// Silence false clippy warning. Clippy suggests using
335-
// VmResources { boot_timer: boot_timer_enabled, ..Default::default() }; but this will
336-
// generate build errors because VmResources contains private fields.
337-
#[allow(clippy::field_reassign_with_default)]
338-
{
339-
vm_resources.mmds_size_limit = mmds_size_limit;
340-
vm_resources.boot_timer = boot_timer_enabled;
341-
}
334+
let mut vm_resources = VmResources {
335+
boot_timer: boot_timer_enabled,
336+
mmds_size_limit,
337+
pci_enabled,
338+
..Default::default()
339+
};
342340

343341
// Init the data store from file, if present.
344342
if let Some(data) = metadata_json {

src/vmm/src/vmm_config/boot_source.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ use serde::{Deserialize, Serialize};
99
/// Default guest kernel command line:
1010
/// - `reboot=k` shut down the guest on reboot, instead of well... rebooting;
1111
/// - `panic=1` on panic, reboot after 1 second;
12-
/// - `pci=off` do not scan for PCI devices (save boot time);
1312
/// - `nomodule` disable loadable kernel module support;
1413
/// - `8250.nr_uarts=0` disable 8250 serial interface;
1514
/// - `i8042.noaux` do not probe the i8042 controller for an attached mouse (save boot time);
1615
/// - `i8042.nomux` do not probe i8042 for a multiplexing controller (save boot time);
1716
/// - `i8042.dumbkbd` do not attempt to control kbd state via the i8042 (save boot time).
1817
pub const DEFAULT_KERNEL_CMDLINE: &str =
19-
"reboot=k panic=1 pci=off nomodule 8250.nr_uarts=0 i8042.noaux i8042.nomux i8042.dumbkbd";
18+
"reboot=k panic=1 nomodule 8250.nr_uarts=0 i8042.noaux i8042.nomux i8042.dumbkbd";
2019

2120
/// Strongly typed data structure used to configure the boot source of the
2221
/// microvm.

0 commit comments

Comments
 (0)