Skip to content

Commit 77a0ff7

Browse files
committed
extend socket interface to support Vsocks
- fix typos and use virtio::vsock::F instead of virtio::net::F - use sa_family to check type of the socket address - revise driver to share interrupt handles between virtio devices - remove compiler warnings
1 parent d1b4a5f commit 77a0ff7

File tree

18 files changed

+666
-236
lines changed

18 files changed

+666
-236
lines changed

src/arch/x86_64/kernel/interrupts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use hermit_sync::{InterruptSpinMutex, InterruptTicketMutex};
99
use x86_64::instructions::interrupts::enable_and_hlt;
1010
pub use x86_64::instructions::interrupts::{disable, enable};
1111
use x86_64::set_general_handler;
12-
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp"))]
12+
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp", feature = "vsock"))]
1313
use x86_64::structures::idt;
1414
use x86_64::structures::idt::InterruptDescriptorTable;
1515
pub use x86_64::structures::idt::InterruptStackFrame as ExceptionStackFrame;
@@ -155,7 +155,7 @@ pub(crate) fn install() {
155155
IRQ_NAMES.lock().insert(7, "FPU");
156156
}
157157

158-
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp"))]
158+
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp", feature = "vsock"))]
159159
pub fn irq_install_handler(irq_number: u8, handler: idt::HandlerFunc) {
160160
debug!("Install handler for interrupt {}", irq_number);
161161

src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 2048;
1212
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 1024;
1313

1414
/// Default keep alive interval in milliseconds
15-
#[cfg(any(feature = "tcp", feature = "udp"))]
15+
#[cfg(feature = "tcp")]
1616
pub(crate) const DEFAULT_KEEP_ALIVE_INTERVAL: u64 = 75000;

src/drivers/net/gem.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ pub enum GEMError {
197197
Unknown,
198198
}
199199

200+
fn gem_irqhandler() {
201+
use crate::scheduler::PerCoreSchedulerExt;
202+
203+
debug!("Receive network interrupt");
204+
205+
// PLIC end of interrupt
206+
crate::arch::kernel::interrupts::external_eoi();
207+
let _ = network_irqhandler();
208+
209+
core_scheduler().reschedule();
210+
}
211+
200212
/// GEM network driver struct.
201213
///
202214
/// Struct allows to control device queus as also
@@ -674,9 +686,9 @@ pub fn init_device(
674686
// Configure Interrupts
675687
debug!(
676688
"Install interrupt handler for GEM at {:x}",
677-
network_irqhandler as usize
689+
gem_irqhandler as usize
678690
);
679-
irq_install_handler(irq, network_irqhandler);
691+
irq_install_handler(irq, gem_irqhandler);
680692
(*gem).int_enable.write(Interrupts::FRAMERX::SET); // + Interrupts::TXCOMPL::SET
681693

682694
// Enable the Controller (again?)

src/drivers/net/mod.rs

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,10 @@ pub mod virtio;
77

88
use smoltcp::phy::ChecksumCapabilities;
99

10-
#[cfg(target_arch = "x86_64")]
11-
use crate::arch::kernel::apic;
1210
#[allow(unused_imports)]
1311
use crate::arch::kernel::core_local::*;
14-
#[cfg(target_arch = "x86_64")]
15-
use crate::arch::kernel::interrupts::ExceptionStackFrame;
1612
#[cfg(not(feature = "pci"))]
1713
use crate::arch::kernel::mmio as hardware;
18-
#[cfg(target_arch = "aarch64")]
19-
use crate::arch::scheduler::State;
2014
#[cfg(feature = "pci")]
2115
use crate::drivers::pci as hardware;
2216
use crate::executor::device::{RxToken, TxToken};
@@ -47,7 +41,7 @@ pub(crate) trait NetworkDriver {
4741
}
4842

4943
#[inline]
50-
fn _irqhandler() -> bool {
44+
pub(crate) fn network_irqhandler() -> bool {
5145
let result = if let Some(driver) = hardware::get_network_driver() {
5246
driver.lock().handle_interrupt()
5347
} else {
@@ -60,35 +54,3 @@ fn _irqhandler() -> bool {
6054

6155
result
6256
}
63-
64-
#[cfg(target_arch = "aarch64")]
65-
pub(crate) fn network_irqhandler(_state: &State) -> bool {
66-
debug!("Receive network interrupt");
67-
_irqhandler()
68-
}
69-
70-
#[cfg(target_arch = "x86_64")]
71-
pub(crate) extern "x86-interrupt" fn network_irqhandler(stack_frame: ExceptionStackFrame) {
72-
crate::arch::x86_64::swapgs(&stack_frame);
73-
use crate::scheduler::PerCoreSchedulerExt;
74-
75-
debug!("Receive network interrupt");
76-
apic::eoi();
77-
let _ = _irqhandler();
78-
79-
core_scheduler().reschedule();
80-
crate::arch::x86_64::swapgs(&stack_frame);
81-
}
82-
83-
#[cfg(target_arch = "riscv64")]
84-
pub fn network_irqhandler() {
85-
use crate::scheduler::PerCoreSchedulerExt;
86-
87-
debug!("Receive network interrupt");
88-
89-
// PLIC end of interrupt
90-
crate::arch::kernel::interrupts::external_eoi();
91-
let _ = _irqhandler();
92-
93-
core_scheduler().reschedule();
94-
}

src/drivers/net/rtl8139.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use pci_types::{Bar, CommandRegister, InterruptLine, MAX_BARS};
99
use x86::io::*;
1010

1111
use crate::arch::kernel::core_local::increment_irq_counter;
12+
#[cfg(target_arch = "x86_64")]
13+
use crate::arch::kernel::interrupts::ExceptionStackFrame;
1214
use crate::arch::kernel::interrupts::*;
1315
use crate::arch::mm::paging::virt_to_phys;
1416
use crate::arch::mm::VirtAddr;
@@ -419,6 +421,19 @@ impl Drop for RTL8139Driver {
419421
}
420422
}
421423

424+
extern "x86-interrupt" fn rtl8139_irqhandler(stack_frame: ExceptionStackFrame) {
425+
crate::arch::x86_64::swapgs(&stack_frame);
426+
use crate::arch::kernel::core_local::core_scheduler;
427+
use crate::scheduler::PerCoreSchedulerExt;
428+
429+
debug!("Receive network interrupt");
430+
crate::arch::x86_64::kernel::apic::eoi();
431+
let _ = network_irqhandler();
432+
433+
core_scheduler().reschedule();
434+
crate::arch::x86_64::swapgs(&stack_frame);
435+
}
436+
422437
pub(crate) fn init_device(
423438
device: &PciDevice<PciConfigRegion>,
424439
) -> Result<RTL8139Driver, DriverError> {
@@ -573,7 +588,7 @@ pub(crate) fn init_device(
573588

574589
// Install interrupt handler for RTL8139
575590
debug!("Install interrupt handler for RTL8139 at {}", irq);
576-
irq_install_handler(irq, network_irqhandler);
591+
irq_install_handler(irq, rtl8139_irqhandler);
577592
add_irq_name(irq, "rtl8139_net");
578593

579594
Ok(RTL8139Driver {

src/drivers/virtio/transport/mmio.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ use crate::arch::kernel::interrupts::*;
1818
use crate::arch::mm::PhysAddr;
1919
use crate::drivers::error::DriverError;
2020
#[cfg(any(feature = "tcp", feature = "udp"))]
21-
use crate::drivers::net::network_irqhandler;
22-
#[cfg(any(feature = "tcp", feature = "udp"))]
2321
use crate::drivers::net::virtio::VirtioNetDriver;
2422
use crate::drivers::virtio::error::VirtioError;
23+
use crate::drivers::virtio::transport::virtio_irqhandler;
2524

2625
pub struct VqCfgHandler<'a> {
2726
vq_index: u16,
@@ -386,9 +385,9 @@ pub(crate) fn init_device(
386385
Ok(virt_net_drv) => {
387386
info!("Virtio network driver initialized.");
388387
// Install interrupt handler
389-
irq_install_handler(irq_no, network_irqhandler);
388+
irq_install_handler(irq_no, virtio_irqhandler);
390389
#[cfg(not(target_arch = "riscv64"))]
391-
add_irq_name(irq_no, "virtio_net");
390+
add_irq_name(irq_no, "virtio");
392391

393392
Ok(VirtioDriver::Network(virt_net_drv))
394393
}
@@ -398,6 +397,24 @@ pub(crate) fn init_device(
398397
}
399398
}
400399
}
400+
#[cfg(feature = "vsock")]
401+
virtio::Id::Vsock => {
402+
match VirtioVsockDriver::init(dev_id, registers, irq_no) {
403+
Ok(virt_net_drv) => {
404+
info!("Virtio sock driver initialized.");
405+
// Install interrupt handler
406+
irq_install_handler(irq_no, virtio_irqhandler);
407+
#[cfg(not(target_arch = "riscv64"))]
408+
add_irq_name(irq_no, "virtio");
409+
410+
Ok(VirtioDriver::Vsock(virt_vsock_drv))
411+
}
412+
Err(virtio_error) => {
413+
error!("Virtio sock driver could not be initialized with device");
414+
Err(DriverError::InitVirtioDevFail(virtio_error))
415+
}
416+
}
417+
}
401418
device_id => {
402419
error!("Device with id {device_id:?} is currently not supported!");
403420
// Return Driver error inidacting device is not supported

src/drivers/virtio/transport/mod.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,52 @@
88
pub mod mmio;
99
#[cfg(feature = "pci")]
1010
pub mod pci;
11+
12+
#[cfg(target_arch = "x86_64")]
13+
use crate::arch::kernel::interrupts::ExceptionStackFrame;
14+
#[cfg(target_arch = "aarch64")]
15+
use crate::arch::scheduler::State;
16+
#[cfg(any(feature = "tcp", feature = "udp"))]
17+
use crate::drivers::net::network_irqhandler;
18+
19+
#[cfg(target_arch = "aarch64")]
20+
pub(crate) fn virtio_irqhandler(_state: &State) -> bool {
21+
debug!("Receive virtio interrupt");
22+
cfg_if::cfg_if! {
23+
if #[cfg(any(feature = "tcp", feature = "udp"))] {
24+
network_irqhandler()
25+
} else {
26+
false
27+
}
28+
}
29+
}
30+
31+
#[cfg(target_arch = "x86_64")]
32+
pub(crate) extern "x86-interrupt" fn virtio_irqhandler(stack_frame: ExceptionStackFrame) {
33+
crate::arch::x86_64::swapgs(&stack_frame);
34+
use crate::arch::kernel::core_local::core_scheduler;
35+
use crate::scheduler::PerCoreSchedulerExt;
36+
37+
info!("Receive virtio interrupt");
38+
crate::kernel::apic::eoi();
39+
#[cfg(any(feature = "tcp", feature = "udp"))]
40+
let _ = network_irqhandler();
41+
42+
core_scheduler().reschedule();
43+
crate::arch::x86_64::swapgs(&stack_frame);
44+
}
45+
46+
#[cfg(target_arch = "riscv64")]
47+
pub(crate) fn virtio_irqhandler() {
48+
use crate::arch::kernel::core_local::core_scheduler;
49+
use crate::scheduler::PerCoreSchedulerExt;
50+
51+
debug!("Receive virtio interrupt");
52+
53+
// PLIC end of interrupt
54+
crate::arch::kernel::interrupts::external_eoi();
55+
#[cfg(any(feature = "tcp", feature = "udp"))]
56+
let _ = network_irqhandler();
57+
58+
core_scheduler().reschedule();
59+
}

src/drivers/virtio/transport/pci.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use virtio::{le16, le32, DeviceStatus};
1616
use volatile::access::ReadOnly;
1717
use volatile::{VolatilePtr, VolatileRef};
1818

19-
#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
19+
#[cfg(all(
20+
not(feature = "rtl8139"),
21+
any(feature = "tcp", feature = "udp", feature = "vsock")
22+
))]
2023
use crate::arch::kernel::interrupts::*;
2124
use crate::arch::memory_barrier;
2225
use crate::arch::mm::PhysAddr;
@@ -25,12 +28,11 @@ use crate::drivers::error::DriverError;
2528
#[cfg(feature = "fuse")]
2629
use crate::drivers::fs::virtio_fs::VirtioFsDriver;
2730
#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
28-
use crate::drivers::net::network_irqhandler;
29-
#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
3031
use crate::drivers::net::virtio::VirtioNetDriver;
3132
use crate::drivers::pci::error::PciError;
3233
use crate::drivers::pci::PciDevice;
3334
use crate::drivers::virtio::error::VirtioError;
35+
use crate::drivers::virtio::transport::virtio_irqhandler;
3436
#[cfg(feature = "vsock")]
3537
use crate::drivers::vsock::VirtioVsockDriver;
3638

@@ -967,13 +969,21 @@ pub(crate) fn init_device(
967969
let irq = device.get_irq().unwrap();
968970
info!("Install virtio interrupt handler at line {}", irq);
969971
// Install interrupt handler
970-
irq_install_handler(irq, network_irqhandler);
971-
add_irq_name(irq, "virtio_net");
972+
irq_install_handler(irq, virtio_irqhandler);
973+
add_irq_name(irq, "virtio");
972974

973975
Ok(drv)
974976
}
975977
#[cfg(feature = "vsock")]
976-
VirtioDriver::Vsock(_) => Ok(drv),
978+
VirtioDriver::Vsock(_) => {
979+
let irq = device.get_irq().unwrap();
980+
info!("Install virtio interrupt handler at line {}", irq);
981+
// Install interrupt handler
982+
irq_install_handler(irq, virtio_irqhandler);
983+
add_irq_name(irq, "virtio");
984+
985+
Ok(drv)
986+
}
977987
#[cfg(feature = "fuse")]
978988
VirtioDriver::FileSystem(_) => Ok(drv),
979989
}

src/drivers/vsock/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod pci;
66
use alloc::rc::Rc;
77
use alloc::vec::Vec;
88

9+
use pci_types::InterruptLine;
910
use virtio::FeatureBits;
1011

1112
use crate::config::VIRTIO_MAX_QUEUE_SIZE;
@@ -23,14 +24,15 @@ use crate::drivers::vsock::pci::VsockDevCfgRaw;
2324
pub(crate) struct VsockDevCfg {
2425
pub raw: &'static VsockDevCfgRaw,
2526
pub dev_id: u16,
26-
pub features: virtio::net::F,
27+
pub features: virtio::vsock::F,
2728
}
2829

2930
pub(crate) struct VirtioVsockDriver {
3031
pub(super) dev_cfg: VsockDevCfg,
3132
pub(super) com_cfg: ComCfg,
3233
pub(super) isr_stat: IsrStatus,
3334
pub(super) notif_cfg: NotifCfg,
35+
pub(super) irq: InterruptLine,
3436
pub(super) vqueues: Vec<Rc<dyn Virtq>>,
3537
}
3638

src/drivers/vsock/pci.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ impl VirtioVsockDriver {
8383
com_cfg,
8484
isr_stat,
8585
notif_cfg,
86+
irq: device.get_irq().unwrap(),
8687
vqueues: Vec::new(),
8788
})
8889
}

0 commit comments

Comments
 (0)