Skip to content

Commit

Permalink
extend socket interface to support Vsocks
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
stlankes committed Jul 25, 2024
1 parent d1b4a5f commit 77a0ff7
Show file tree
Hide file tree
Showing 18 changed files with 666 additions and 236 deletions.
4 changes: 2 additions & 2 deletions src/arch/x86_64/kernel/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use hermit_sync::{InterruptSpinMutex, InterruptTicketMutex};
use x86_64::instructions::interrupts::enable_and_hlt;
pub use x86_64::instructions::interrupts::{disable, enable};
use x86_64::set_general_handler;
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp"))]
#[cfg(any(feature = "fuse", feature = "tcp", feature = "udp", feature = "vsock"))]
use x86_64::structures::idt;
use x86_64::structures::idt::InterruptDescriptorTable;
pub use x86_64::structures::idt::InterruptStackFrame as ExceptionStackFrame;
Expand Down Expand Up @@ -155,7 +155,7 @@ pub(crate) fn install() {
IRQ_NAMES.lock().insert(7, "FPU");
}

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

Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 2048;
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 1024;

/// Default keep alive interval in milliseconds
#[cfg(any(feature = "tcp", feature = "udp"))]
#[cfg(feature = "tcp")]
pub(crate) const DEFAULT_KEEP_ALIVE_INTERVAL: u64 = 75000;
16 changes: 14 additions & 2 deletions src/drivers/net/gem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ pub enum GEMError {
Unknown,
}

fn gem_irqhandler() {
use crate::scheduler::PerCoreSchedulerExt;

debug!("Receive network interrupt");

// PLIC end of interrupt
crate::arch::kernel::interrupts::external_eoi();
let _ = network_irqhandler();

core_scheduler().reschedule();
}

/// GEM network driver struct.
///
/// Struct allows to control device queus as also
Expand Down Expand Up @@ -674,9 +686,9 @@ pub fn init_device(
// Configure Interrupts
debug!(
"Install interrupt handler for GEM at {:x}",
network_irqhandler as usize
gem_irqhandler as usize
);
irq_install_handler(irq, network_irqhandler);
irq_install_handler(irq, gem_irqhandler);
(*gem).int_enable.write(Interrupts::FRAMERX::SET); // + Interrupts::TXCOMPL::SET

// Enable the Controller (again?)
Expand Down
40 changes: 1 addition & 39 deletions src/drivers/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@ pub mod virtio;

use smoltcp::phy::ChecksumCapabilities;

#[cfg(target_arch = "x86_64")]
use crate::arch::kernel::apic;
#[allow(unused_imports)]
use crate::arch::kernel::core_local::*;
#[cfg(target_arch = "x86_64")]
use crate::arch::kernel::interrupts::ExceptionStackFrame;
#[cfg(not(feature = "pci"))]
use crate::arch::kernel::mmio as hardware;
#[cfg(target_arch = "aarch64")]
use crate::arch::scheduler::State;
#[cfg(feature = "pci")]
use crate::drivers::pci as hardware;
use crate::executor::device::{RxToken, TxToken};
Expand Down Expand Up @@ -47,7 +41,7 @@ pub(crate) trait NetworkDriver {
}

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

result
}

#[cfg(target_arch = "aarch64")]
pub(crate) fn network_irqhandler(_state: &State) -> bool {
debug!("Receive network interrupt");
_irqhandler()
}

#[cfg(target_arch = "x86_64")]
pub(crate) extern "x86-interrupt" fn network_irqhandler(stack_frame: ExceptionStackFrame) {
crate::arch::x86_64::swapgs(&stack_frame);
use crate::scheduler::PerCoreSchedulerExt;

debug!("Receive network interrupt");
apic::eoi();
let _ = _irqhandler();

core_scheduler().reschedule();
crate::arch::x86_64::swapgs(&stack_frame);
}

#[cfg(target_arch = "riscv64")]
pub fn network_irqhandler() {
use crate::scheduler::PerCoreSchedulerExt;

debug!("Receive network interrupt");

// PLIC end of interrupt
crate::arch::kernel::interrupts::external_eoi();
let _ = _irqhandler();

core_scheduler().reschedule();
}
17 changes: 16 additions & 1 deletion src/drivers/net/rtl8139.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use pci_types::{Bar, CommandRegister, InterruptLine, MAX_BARS};
use x86::io::*;

use crate::arch::kernel::core_local::increment_irq_counter;
#[cfg(target_arch = "x86_64")]
use crate::arch::kernel::interrupts::ExceptionStackFrame;
use crate::arch::kernel::interrupts::*;
use crate::arch::mm::paging::virt_to_phys;
use crate::arch::mm::VirtAddr;
Expand Down Expand Up @@ -419,6 +421,19 @@ impl Drop for RTL8139Driver {
}
}

extern "x86-interrupt" fn rtl8139_irqhandler(stack_frame: ExceptionStackFrame) {
crate::arch::x86_64::swapgs(&stack_frame);
use crate::arch::kernel::core_local::core_scheduler;
use crate::scheduler::PerCoreSchedulerExt;

debug!("Receive network interrupt");
crate::arch::x86_64::kernel::apic::eoi();
let _ = network_irqhandler();

core_scheduler().reschedule();
crate::arch::x86_64::swapgs(&stack_frame);
}

pub(crate) fn init_device(
device: &PciDevice<PciConfigRegion>,
) -> Result<RTL8139Driver, DriverError> {
Expand Down Expand Up @@ -573,7 +588,7 @@ pub(crate) fn init_device(

// Install interrupt handler for RTL8139
debug!("Install interrupt handler for RTL8139 at {}", irq);
irq_install_handler(irq, network_irqhandler);
irq_install_handler(irq, rtl8139_irqhandler);
add_irq_name(irq, "rtl8139_net");

Ok(RTL8139Driver {
Expand Down
25 changes: 21 additions & 4 deletions src/drivers/virtio/transport/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ use crate::arch::kernel::interrupts::*;
use crate::arch::mm::PhysAddr;
use crate::drivers::error::DriverError;
#[cfg(any(feature = "tcp", feature = "udp"))]
use crate::drivers::net::network_irqhandler;
#[cfg(any(feature = "tcp", feature = "udp"))]
use crate::drivers::net::virtio::VirtioNetDriver;
use crate::drivers::virtio::error::VirtioError;
use crate::drivers::virtio::transport::virtio_irqhandler;

pub struct VqCfgHandler<'a> {
vq_index: u16,
Expand Down Expand Up @@ -386,9 +385,9 @@ pub(crate) fn init_device(
Ok(virt_net_drv) => {
info!("Virtio network driver initialized.");
// Install interrupt handler
irq_install_handler(irq_no, network_irqhandler);
irq_install_handler(irq_no, virtio_irqhandler);
#[cfg(not(target_arch = "riscv64"))]
add_irq_name(irq_no, "virtio_net");
add_irq_name(irq_no, "virtio");

Ok(VirtioDriver::Network(virt_net_drv))
}
Expand All @@ -398,6 +397,24 @@ pub(crate) fn init_device(
}
}
}
#[cfg(feature = "vsock")]
virtio::Id::Vsock => {
match VirtioVsockDriver::init(dev_id, registers, irq_no) {
Ok(virt_net_drv) => {
info!("Virtio sock driver initialized.");
// Install interrupt handler
irq_install_handler(irq_no, virtio_irqhandler);
#[cfg(not(target_arch = "riscv64"))]
add_irq_name(irq_no, "virtio");

Ok(VirtioDriver::Vsock(virt_vsock_drv))
}
Err(virtio_error) => {
error!("Virtio sock driver could not be initialized with device");
Err(DriverError::InitVirtioDevFail(virtio_error))
}
}
}
device_id => {
error!("Device with id {device_id:?} is currently not supported!");
// Return Driver error inidacting device is not supported
Expand Down
49 changes: 49 additions & 0 deletions src/drivers/virtio/transport/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,52 @@
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;

#[cfg(target_arch = "x86_64")]
use crate::arch::kernel::interrupts::ExceptionStackFrame;
#[cfg(target_arch = "aarch64")]
use crate::arch::scheduler::State;
#[cfg(any(feature = "tcp", feature = "udp"))]
use crate::drivers::net::network_irqhandler;

#[cfg(target_arch = "aarch64")]
pub(crate) fn virtio_irqhandler(_state: &State) -> bool {
debug!("Receive virtio interrupt");
cfg_if::cfg_if! {
if #[cfg(any(feature = "tcp", feature = "udp"))] {
network_irqhandler()
} else {
false
}
}
}

#[cfg(target_arch = "x86_64")]
pub(crate) extern "x86-interrupt" fn virtio_irqhandler(stack_frame: ExceptionStackFrame) {
crate::arch::x86_64::swapgs(&stack_frame);
use crate::arch::kernel::core_local::core_scheduler;
use crate::scheduler::PerCoreSchedulerExt;

info!("Receive virtio interrupt");
crate::kernel::apic::eoi();
#[cfg(any(feature = "tcp", feature = "udp"))]
let _ = network_irqhandler();

core_scheduler().reschedule();
crate::arch::x86_64::swapgs(&stack_frame);
}

#[cfg(target_arch = "riscv64")]
pub(crate) fn virtio_irqhandler() {
use crate::arch::kernel::core_local::core_scheduler;
use crate::scheduler::PerCoreSchedulerExt;

debug!("Receive virtio interrupt");

// PLIC end of interrupt
crate::arch::kernel::interrupts::external_eoi();
#[cfg(any(feature = "tcp", feature = "udp"))]
let _ = network_irqhandler();

core_scheduler().reschedule();
}
22 changes: 16 additions & 6 deletions src/drivers/virtio/transport/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use virtio::{le16, le32, DeviceStatus};
use volatile::access::ReadOnly;
use volatile::{VolatilePtr, VolatileRef};

#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
#[cfg(all(
not(feature = "rtl8139"),
any(feature = "tcp", feature = "udp", feature = "vsock")
))]
use crate::arch::kernel::interrupts::*;
use crate::arch::memory_barrier;
use crate::arch::mm::PhysAddr;
Expand All @@ -25,12 +28,11 @@ use crate::drivers::error::DriverError;
#[cfg(feature = "fuse")]
use crate::drivers::fs::virtio_fs::VirtioFsDriver;
#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
use crate::drivers::net::network_irqhandler;
#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
use crate::drivers::net::virtio::VirtioNetDriver;
use crate::drivers::pci::error::PciError;
use crate::drivers::pci::PciDevice;
use crate::drivers::virtio::error::VirtioError;
use crate::drivers::virtio::transport::virtio_irqhandler;
#[cfg(feature = "vsock")]
use crate::drivers::vsock::VirtioVsockDriver;

Expand Down Expand Up @@ -967,13 +969,21 @@ pub(crate) fn init_device(
let irq = device.get_irq().unwrap();
info!("Install virtio interrupt handler at line {}", irq);
// Install interrupt handler
irq_install_handler(irq, network_irqhandler);
add_irq_name(irq, "virtio_net");
irq_install_handler(irq, virtio_irqhandler);
add_irq_name(irq, "virtio");

Ok(drv)
}
#[cfg(feature = "vsock")]
VirtioDriver::Vsock(_) => Ok(drv),
VirtioDriver::Vsock(_) => {
let irq = device.get_irq().unwrap();
info!("Install virtio interrupt handler at line {}", irq);
// Install interrupt handler
irq_install_handler(irq, virtio_irqhandler);
add_irq_name(irq, "virtio");

Ok(drv)
}
#[cfg(feature = "fuse")]
VirtioDriver::FileSystem(_) => Ok(drv),
}
Expand Down
4 changes: 3 additions & 1 deletion src/drivers/vsock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod pci;
use alloc::rc::Rc;
use alloc::vec::Vec;

use pci_types::InterruptLine;
use virtio::FeatureBits;

use crate::config::VIRTIO_MAX_QUEUE_SIZE;
Expand All @@ -23,14 +24,15 @@ use crate::drivers::vsock::pci::VsockDevCfgRaw;
pub(crate) struct VsockDevCfg {
pub raw: &'static VsockDevCfgRaw,
pub dev_id: u16,
pub features: virtio::net::F,
pub features: virtio::vsock::F,
}

pub(crate) struct VirtioVsockDriver {
pub(super) dev_cfg: VsockDevCfg,
pub(super) com_cfg: ComCfg,
pub(super) isr_stat: IsrStatus,
pub(super) notif_cfg: NotifCfg,
pub(super) irq: InterruptLine,
pub(super) vqueues: Vec<Rc<dyn Virtq>>,
}

Expand Down
1 change: 1 addition & 0 deletions src/drivers/vsock/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl VirtioVsockDriver {
com_cfg,
isr_stat,
notif_cfg,
irq: device.get_irq().unwrap(),
vqueues: Vec::new(),
})
}
Expand Down
Loading

0 comments on commit 77a0ff7

Please sign in to comment.