Skip to content

Commit 6b79416

Browse files
committed
refactor(drivers): Make virtio-net optional and feature-gated
Signed-off-by: Jens Reidel <adrian@travitia.xyz>
1 parent be0a653 commit 6b79416

File tree

18 files changed

+664
-146
lines changed

18 files changed

+664
-146
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ tcp = ["smoltcp", "smoltcp/socket-tcp"]
6969
trace = ["smoltcp?/log", "smoltcp?/verbose"]
7070
udp = ["smoltcp", "smoltcp/socket-udp"]
7171
vga = []
72+
virtio-net = []
7273
vsock = ["pci"]
7374

7475
[lints.rust]

src/arch/x86_64/kernel/mmio.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use core::ptr::NonNull;
44
use core::{ptr, str};
55

66
use align_address::Align;
7-
use hermit_sync::{InterruptTicketMutex, without_interrupts};
7+
#[cfg(feature = "virtio-net")]
8+
use hermit_sync::InterruptTicketMutex;
9+
use hermit_sync::without_interrupts;
810
use memory_addresses::PhysAddr;
911
use virtio::mmio::{DeviceRegisters, DeviceRegistersVolatileFieldAccess};
1012
use volatile::VolatileRef;
@@ -13,8 +15,11 @@ use crate::arch::x86_64::mm::paging;
1315
use crate::arch::x86_64::mm::paging::{
1416
BasePageSize, PageSize, PageTableEntryFlags, PageTableEntryFlagsExt,
1517
};
18+
#[cfg(feature = "virtio-net")]
1619
use crate::drivers::net::virtio::VirtioNetDriver;
20+
#[cfg(feature = "virtio-net")]
1721
use crate::drivers::virtio::transport::mmio as mmio_virtio;
22+
#[cfg(feature = "virtio-net")]
1823
use crate::drivers::virtio::transport::mmio::VirtioDriver;
1924
use crate::env;
2025
use crate::init_cell::InitCell;
@@ -28,16 +33,19 @@ const IRQ_NUMBER: u8 = 44 - 32;
2833
static MMIO_DRIVERS: InitCell<Vec<MmioDriver>> = InitCell::new(Vec::new());
2934

3035
pub(crate) enum MmioDriver {
36+
#[cfg(feature = "virtio-net")]
3137
VirtioNet(InterruptTicketMutex<VirtioNetDriver>),
3238
}
3339

3440
impl MmioDriver {
35-
#[allow(unreachable_patterns)]
41+
#[cfg(feature = "virtio-net")]
3642
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver>> {
37-
match self {
38-
Self::VirtioNet(drv) => Some(drv),
39-
_ => None,
43+
#[allow(clippy::irrefutable_let_patterns)]
44+
if let MmioDriver::VirtioNet(drv) = self {
45+
return Some(drv);
4046
}
47+
48+
None
4149
}
4250
}
4351

@@ -186,6 +194,7 @@ pub(crate) fn register_driver(drv: MmioDriver) {
186194
MMIO_DRIVERS.with(|mmio_drivers| mmio_drivers.unwrap().push(drv));
187195
}
188196

197+
#[cfg(feature = "virtio-net")]
189198
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver>> {
190199
MMIO_DRIVERS
191200
.get()?
@@ -196,6 +205,7 @@ pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<Virti
196205
pub(crate) fn init_drivers() {
197206
// virtio: MMIO Device Discovery
198207
without_interrupts(|| {
208+
#[cfg(feature = "virtio-net")]
199209
if let Ok((mmio, irq)) = detect_network() {
200210
warn!("Found MMIO device, but we guess the interrupt number {irq}!");
201211
match mmio_virtio::init_device(mmio, irq) {

src/config.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ pub(crate) const USER_STACK_SIZE: usize = 0x0010_0000;
1212
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = if cfg!(feature = "pci") { 2048 } else { 1024 };
1313

1414
/// Default keep alive interval in milliseconds
15-
#[cfg(feature = "tcp")]
15+
#[cfg(all(
16+
feature = "tcp",
17+
any(
18+
feature = "virtio-net",
19+
all(target_arch = "riscv64", feature = "gem-net"),
20+
all(target_arch = "x86_64", feature = "rtl8139"),
21+
)
22+
))]
1623
pub(crate) const DEFAULT_KEEP_ALIVE_INTERVAL: u64 = 75000;
1724

1825
#[cfg(feature = "vsock")]

src/drivers/mmio.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
1-
#[cfg(any(feature = "tcp", feature = "udp"))]
1+
#[cfg(all(
2+
any(feature = "tcp", feature = "udp"),
3+
any(
4+
feature = "virtio-net",
5+
all(target_arch = "riscv64", feature = "gem-net"),
6+
all(target_arch = "x86_64", feature = "rtl8139"),
7+
)
8+
))]
29
use alloc::collections::VecDeque;
310

411
use ahash::RandomState;
512
use hashbrown::HashMap;
613

7-
#[cfg(any(feature = "tcp", feature = "udp"))]
14+
#[cfg(all(
15+
any(feature = "tcp", feature = "udp"),
16+
any(
17+
feature = "virtio-net",
18+
all(target_arch = "riscv64", feature = "gem-net"),
19+
all(target_arch = "x86_64", feature = "rtl8139"),
20+
)
21+
))]
822
pub(crate) use crate::arch::kernel::mmio::get_network_driver;
9-
#[cfg(any(feature = "tcp", feature = "udp"))]
23+
#[cfg(all(
24+
any(feature = "tcp", feature = "udp"),
25+
any(
26+
feature = "virtio-net",
27+
all(target_arch = "riscv64", feature = "gem-net"),
28+
all(target_arch = "x86_64", feature = "rtl8139"),
29+
)
30+
))]
1031
use crate::drivers::Driver;
11-
#[cfg(any(feature = "tcp", feature = "udp"))]
32+
#[cfg(all(
33+
any(feature = "tcp", feature = "udp"),
34+
any(
35+
feature = "virtio-net",
36+
all(target_arch = "riscv64", feature = "gem-net"),
37+
all(target_arch = "x86_64", feature = "rtl8139"),
38+
)
39+
))]
1240
use crate::drivers::net::NetworkDriver;
1341
use crate::drivers::{InterruptHandlerQueue, InterruptLine};
1442

@@ -18,7 +46,14 @@ pub(crate) fn get_interrupt_handlers() -> HashMap<InterruptLine, InterruptHandle
1846
let mut handlers: HashMap<InterruptLine, InterruptHandlerQueue, RandomState> =
1947
HashMap::with_hasher(RandomState::with_seeds(0, 0, 0, 0));
2048

21-
#[cfg(any(feature = "tcp", feature = "udp"))]
49+
#[cfg(all(
50+
any(feature = "tcp", feature = "udp"),
51+
any(
52+
feature = "virtio-net",
53+
all(target_arch = "riscv64", feature = "gem-net"),
54+
all(target_arch = "x86_64", feature = "rtl8139"),
55+
)
56+
))]
2257
if let Some(drv) = get_network_driver() {
2358
fn network_handler() {
2459
if let Some(driver) = get_network_driver() {

src/drivers/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44
pub mod fs;
55
#[cfg(not(feature = "pci"))]
66
pub mod mmio;
7-
#[cfg(any(feature = "tcp", feature = "udp"))]
7+
#[cfg(all(
8+
any(feature = "tcp", feature = "udp"),
9+
any(
10+
feature = "virtio-net",
11+
all(target_arch = "riscv64", feature = "gem-net"),
12+
all(target_arch = "x86_64", feature = "rtl8139"),
13+
)
14+
))]
815
pub mod net;
916
#[cfg(feature = "pci")]
1017
pub mod pci;

src/drivers/net/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pub mod gem;
33
#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
44
pub mod rtl8139;
5-
#[cfg(not(all(target_arch = "x86_64", feature = "rtl8139")))]
5+
#[cfg(feature = "virtio-net")]
66
pub mod virtio;
77

88
use core::str::FromStr;

src/drivers/pci.rs

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ use pci_types::{
1919
use crate::arch::pci::PciConfigRegion;
2020
#[cfg(feature = "fuse")]
2121
use crate::drivers::fs::virtio_fs::VirtioFsDriver;
22-
#[cfg(any(feature = "tcp", feature = "udp"))]
22+
#[cfg(all(
23+
any(feature = "tcp", feature = "udp"),
24+
any(
25+
feature = "virtio-net",
26+
all(target_arch = "riscv64", feature = "gem-net"),
27+
all(target_arch = "x86_64", feature = "rtl8139"),
28+
)
29+
))]
2330
use crate::drivers::net::NetworkDriver;
2431
#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
2532
use crate::drivers::net::rtl8139::{self, RTL8139Driver};
26-
#[cfg(all(
27-
not(all(target_arch = "x86_64", feature = "rtl8139")),
28-
any(feature = "tcp", feature = "udp")
29-
))]
33+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
3034
use crate::drivers::net::virtio::VirtioNetDriver;
3135
#[cfg(any(
3236
all(
@@ -333,10 +337,7 @@ pub(crate) enum PciDriver {
333337
VirtioFs(InterruptTicketMutex<VirtioFsDriver>),
334338
#[cfg(feature = "vsock")]
335339
VirtioVsock(InterruptTicketMutex<VirtioVsockDriver>),
336-
#[cfg(all(
337-
not(all(target_arch = "x86_64", feature = "rtl8139")),
338-
any(feature = "tcp", feature = "udp")
339-
))]
340+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
340341
VirtioNet(InterruptTicketMutex<VirtioNetDriver>),
341342
#[cfg(all(
342343
target_arch = "x86_64",
@@ -347,16 +348,14 @@ pub(crate) enum PciDriver {
347348
}
348349

349350
impl PciDriver {
350-
#[cfg(all(
351-
not(all(target_arch = "x86_64", feature = "rtl8139")),
352-
any(feature = "tcp", feature = "udp")
353-
))]
351+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
354352
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver>> {
355-
#[allow(unreachable_patterns)]
356-
match self {
357-
Self::VirtioNet(drv) => Some(drv),
358-
_ => None,
353+
#[allow(irrefutable_let_patterns)]
354+
if let Self::VirtioNet(drv) = self {
355+
return Some(drv);
359356
}
357+
358+
None
360359
}
361360

362361
#[cfg(all(
@@ -365,29 +364,32 @@ impl PciDriver {
365364
any(feature = "tcp", feature = "udp")
366365
))]
367366
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<RTL8139Driver>> {
368-
#[allow(unreachable_patterns)]
369-
match self {
370-
Self::RTL8139Net(drv) => Some(drv),
371-
_ => None,
367+
#[allow(irrefutable_let_patterns)]
368+
if let Self::RTL8139Net(drv) = self {
369+
return Some(drv);
372370
}
371+
372+
None
373373
}
374374

375375
#[cfg(feature = "vsock")]
376376
fn get_vsock_driver(&self) -> Option<&InterruptTicketMutex<VirtioVsockDriver>> {
377-
#[allow(unreachable_patterns)]
378-
match self {
379-
Self::VirtioVsock(drv) => Some(drv),
380-
_ => None,
377+
#[allow(irrefutable_let_patterns)]
378+
if let Self::VirtioVsock(drv) = self {
379+
return Some(drv);
381380
}
381+
382+
None
382383
}
383384

384385
#[cfg(feature = "fuse")]
385386
fn get_filesystem_driver(&self) -> Option<&InterruptTicketMutex<VirtioFsDriver>> {
386-
match self {
387-
Self::VirtioFs(drv) => Some(drv),
388-
#[allow(unreachable_patterns)]
389-
_ => None,
387+
#[allow(irrefutable_let_patterns)]
388+
if let Self::VirtioFs(drv) = self {
389+
return Some(drv);
390390
}
391+
392+
None
391393
}
392394

393395
fn get_interrupt_handler(&self) -> (InterruptLine, fn()) {
@@ -421,10 +423,7 @@ impl PciDriver {
421423

422424
(irq_number, rtl8139_handler)
423425
}
424-
#[cfg(all(
425-
not(all(target_arch = "x86_64", feature = "rtl8139")),
426-
any(feature = "tcp", feature = "udp")
427-
))]
426+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
428427
Self::VirtioNet(drv) => {
429428
fn network_handler() {
430429
if let Some(driver) = get_network_driver() {
@@ -473,10 +472,7 @@ pub(crate) fn get_interrupt_handlers() -> HashMap<InterruptLine, InterruptHandle
473472
handlers
474473
}
475474

476-
#[cfg(all(
477-
not(all(target_arch = "x86_64", feature = "rtl8139")),
478-
any(feature = "tcp", feature = "udp")
479-
))]
475+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
480476
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver>> {
481477
PCI_DRIVERS
482478
.get()?
@@ -525,18 +521,12 @@ pub(crate) fn init() {
525521
);
526522

527523
#[cfg(any(
528-
all(
529-
any(feature = "tcp", feature = "udp"),
530-
not(all(target_arch = "x86_64", feature = "rtl8139"))
531-
),
524+
all(any(feature = "tcp", feature = "udp"), feature = "virtio-net"),
532525
feature = "fuse",
533526
feature = "vsock"
534527
))]
535528
match pci_virtio::init_device(adapter) {
536-
#[cfg(all(
537-
not(all(target_arch = "x86_64", feature = "rtl8139")),
538-
any(feature = "tcp", feature = "udp")
539-
))]
529+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
540530
Ok(VirtioDriver::Network(drv)) => {
541531
register_driver(PciDriver::VirtioNet(InterruptTicketMutex::new(drv)));
542532
}

src/drivers/virtio/mod.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ pub mod error {
99

1010
#[cfg(feature = "fuse")]
1111
pub use crate::drivers::fs::virtio_fs::error::VirtioFsError;
12-
#[cfg(all(
13-
not(all(target_arch = "x86_64", feature = "rtl8139")),
14-
any(feature = "tcp", feature = "udp")
15-
))]
12+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
1613
pub use crate::drivers::net::virtio::error::VirtioNetError;
1714
#[cfg(feature = "pci")]
1815
use crate::drivers::pci::error::PciError;
@@ -31,10 +28,7 @@ pub mod error {
3128
#[cfg(feature = "pci")]
3229
NoNotifCfg(u16),
3330
DevNotSupported(u16),
34-
#[cfg(all(
35-
not(all(target_arch = "x86_64", feature = "rtl8139")),
36-
any(feature = "tcp", feature = "udp")
37-
))]
31+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
3832
NetDriver(VirtioNetError),
3933
#[cfg(feature = "fuse")]
4034
FsDriver(VirtioFsError),
@@ -86,10 +80,7 @@ pub mod error {
8680
VirtioError::DevNotSupported(id) => {
8781
write!(f, "Device with id {id:#x} not supported.")
8882
}
89-
#[cfg(all(
90-
not(all(target_arch = "x86_64", feature = "rtl8139")),
91-
any(feature = "tcp", feature = "udp")
92-
))]
83+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
9384
VirtioError::NetDriver(net_error) => match net_error {
9485
#[cfg(feature = "pci")]
9586
VirtioNetError::NoDevCfg(id) => write!(

src/drivers/virtio/transport/mmio.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use volatile::{VolatilePtr, VolatileRef};
1616

1717
use crate::drivers::InterruptLine;
1818
use crate::drivers::error::DriverError;
19-
#[cfg(any(feature = "tcp", feature = "udp"))]
19+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
2020
use crate::drivers::net::virtio::VirtioNetDriver;
2121
use crate::drivers::virtio::error::VirtioError;
2222

@@ -360,7 +360,7 @@ impl IsrStatus {
360360
}
361361

362362
pub(crate) enum VirtioDriver {
363-
#[cfg(any(feature = "tcp", feature = "udp"))]
363+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
364364
Network(VirtioNetDriver),
365365
}
366366

@@ -380,7 +380,7 @@ pub(crate) fn init_device(
380380

381381
// Verify the device-ID to find the network card
382382
match registers.as_ptr().device_id().read() {
383-
#[cfg(any(feature = "tcp", feature = "udp"))]
383+
#[cfg(all(feature = "virtio-net", any(feature = "tcp", feature = "udp")))]
384384
virtio::Id::Net => match VirtioNetDriver::init(dev_id, registers, irq_no) {
385385
Ok(virt_net_drv) => {
386386
info!("Virtio network driver initialized.");

0 commit comments

Comments
 (0)