Skip to content

Commit c8f7155

Browse files
author
Alexandru-Cezar Sardan
committed
interrupt: add common triggers
Add a triggers module containing common implementations for triggers. Add EventFdTrigger which is a Trigger that uses an underlying EventFd. EventFds are commonly used with KVM based VMMs. Signed-off-by: Alexandru-Cezar Sardan <alsardan@amazon.com>
1 parent c04210b commit c8f7155

File tree

4 files changed

+88
-15
lines changed

4 files changed

+88
-15
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ repository = "https://github.com/rust-vmm/vm-device"
99
license = "Apache-2.0 OR BSD-3-Clause"
1010

1111
[dependencies]
12+
vmm-sys-util = { version = "0.8.0" }

src/interrupt/mod.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,13 @@
4444
pub mod legacy;
4545
pub mod msi;
4646

47+
pub mod trigger;
48+
4749
use std::fmt::{self, Display};
4850
use std::io;
4951
use std::ops::Deref;
5052

51-
/// Abstraction for a simple, push-button like interrupt mechanism.
52-
/// This helps in abstracting away how events/interrupts are generated when
53-
/// working with the emulated devices.
54-
///
55-
/// The user has to provide a `Trigger` object to the device's constructor when
56-
/// initializing that device. The generic type `T: Trigger` is used in the
57-
/// device's structure definition to mark the fact that the events notification
58-
/// mechanism is done via the Trigger interface.
59-
pub trait Trigger {
60-
/// Underlying type for the potential error conditions returned by `Self::trigger`.
61-
type E: std::fmt::Debug;
62-
63-
/// Trigger an event.
64-
fn trigger(&self) -> std::result::Result<(), Self::E>;
65-
}
53+
use crate::interrupt::trigger::Trigger;
6654

6755
/// Errors associated with handling interrupts
6856
#[derive(Debug)]

src/interrupt/trigger/eventfd.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (C) 2021 Amazon.com, Inc. or its affiliates.
2+
// All Rights Reserved.
3+
4+
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
5+
6+
//! Implementation for a Trigger based on EventFd.
7+
8+
use std::io;
9+
use std::ops::Deref;
10+
use vmm_sys_util::eventfd::EventFd;
11+
12+
use crate::interrupt::trigger::Trigger;
13+
14+
/// Trait used for creating an EventFd from an object.
15+
pub trait AsEventFd {
16+
/// Convert this object to an EventFd.
17+
fn as_event_fd(&self) -> io::Result<EventFd>;
18+
}
19+
20+
/// Newtype for implementing the trigger functionality for `EventFd`.
21+
pub struct EventFdTrigger(EventFd);
22+
23+
impl Trigger for EventFdTrigger {
24+
type E = io::Error;
25+
26+
fn trigger(&self) -> io::Result<()> {
27+
self.write(1)
28+
}
29+
}
30+
impl Deref for EventFdTrigger {
31+
type Target = EventFd;
32+
fn deref(&self) -> &Self::Target {
33+
&self.0
34+
}
35+
}
36+
37+
impl EventFdTrigger {
38+
/// Try to clone this EventFdTrigger into a new object.
39+
/// Returns an error if the underlying EventFd cannot be cloned.
40+
pub fn try_clone(&self) -> io::Result<Self> {
41+
Ok(EventFdTrigger((**self).try_clone()?))
42+
}
43+
44+
/// Construct a new EventFdTrigger using the EventFd passed as parameter.
45+
pub fn new(evt: EventFd) -> Self {
46+
Self(evt)
47+
}
48+
49+
/// Get a clone of the underlying EventFd of this Trigger.
50+
pub fn get_event(&self) -> io::Result<EventFd> {
51+
self.0.try_clone()
52+
}
53+
}
54+
55+
impl AsEventFd for EventFdTrigger {
56+
fn as_event_fd(&self) -> io::Result<EventFd> {
57+
self.get_event()
58+
}
59+
}

src/interrupt/trigger/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (C) 2021 Amazon.com, Inc. or its affiliates.
2+
// All Rights Reserved.
3+
4+
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
5+
6+
//! Triggers that are commonly used by multiple VMMs.
7+
8+
#[cfg(target_os = "linux")]
9+
pub mod eventfd;
10+
11+
/// Abstraction for a simple, push-button like interrupt mechanism.
12+
/// This helps in abstracting away how events/interrupts are generated when
13+
/// working with the emulated devices.
14+
///
15+
/// The user has to provide a `Trigger` object to the device's constructor when
16+
/// initializing that device. The generic type `T: Trigger` is used in the
17+
/// device's structure definition to mark the fact that the events notification
18+
/// mechanism is done via the Trigger interface.
19+
pub trait Trigger {
20+
/// Underlying type for the potential error conditions returned by `Self::trigger`.
21+
type E: std::fmt::Debug;
22+
23+
/// Trigger an event.
24+
fn trigger(&self) -> std::result::Result<(), Self::E>;
25+
}

0 commit comments

Comments
 (0)