Skip to content

Commit 999068a

Browse files
committed
Pin static references to VCpu and VirtualMachine
1 parent c64ef8a commit 999068a

File tree

4 files changed

+20
-12
lines changed

4 files changed

+20
-12
lines changed

mythril/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(get_mut_unchecked)]
66
#![feature(fixed_size_array)]
77
#![feature(panic_info_message)]
8+
#![feature(pin_static_ref)]
89
#![feature(array_value_iter)]
910
#![feature(alloc_error_handler)]
1011
#![feature(lang_items)]

mythril/src/vcpu.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn mp_entry_point() -> ! {
5151
vm
5252
};
5353

54-
let vcpu = VCpu::new(vm).expect("Failed to create vcpu");
54+
let mut vcpu = VCpu::new(vm).expect("Failed to create vcpu");
5555

5656
let vm_id = vm.id;
5757
let is_vm_bsp = vm.bsp_id() == core_id;
@@ -99,7 +99,7 @@ pub enum InjectedInterruptType {
9999
/// ultimate handling will occur within an emulated device in the `VirtualMachine`'s
100100
/// `DeviceMap`)
101101
pub struct VCpu {
102-
pub vm: &'static VirtualMachine,
102+
pub vm: Pin<&'static VirtualMachine>,
103103
pub vmcs: vmcs::ActiveVmcs,
104104
pub local_apic: virtdev::lapic::LocalApic,
105105
pending_interrupts: BTreeMap<u8, InjectedInterruptType>,
@@ -112,7 +112,9 @@ impl VCpu {
112112
/// Note that the result must be `Pin`, as the `VCpu` pushes its own
113113
/// address on to the per-core host stack so it can be retrieved on
114114
/// VMEXIT.
115-
pub fn new(vm: &'static VirtualMachine) -> Result<&'static mut Self> {
115+
pub fn new(
116+
vm: Pin<&'static VirtualMachine>,
117+
) -> Result<Pin<&'static mut Self>> {
116118
let vmx = vmx::Vmx::enable()?;
117119
let vmcs = vmcs::Vmcs::new()?.activate(vmx)?;
118120

@@ -155,7 +157,7 @@ impl VCpu {
155157
Self::initialize_guest_vmcs(vcpu)?;
156158
Self::initialize_ctrl_vmcs(&mut vcpu.vmcs)?;
157159

158-
Ok(vcpu)
160+
Ok(Pin::new(vcpu))
159161
}
160162

161163
pub fn inject_interrupt(

mythril/src/virtdev/lapic.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::memory;
44
use crate::percore;
55
use crate::vm;
66
use core::convert::TryFrom;
7+
use core::pin::Pin;
78
use core::sync::atomic::AtomicU32;
89
use num_enum::TryFromPrimitive;
910

@@ -141,7 +142,7 @@ impl LocalApic {
141142

142143
fn process_interrupt_command(
143144
&mut self,
144-
vm: &vm::VirtualMachine,
145+
vm: Pin<&vm::VirtualMachine>,
145146
value: u32,
146147
) -> Result<()> {
147148
let mode = DeliveryMode::try_from((value >> 8) as u8 & 0b111)?;
@@ -221,7 +222,7 @@ impl LocalApic {
221222

222223
pub fn register_write(
223224
&mut self,
224-
vm: &vm::VirtualMachine,
225+
vm: Pin<&vm::VirtualMachine>,
225226
offset: u16,
226227
value: u32,
227228
) -> Result<()> {

mythril/src/vm.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use arraydeque::ArrayDeque;
2323
use arrayvec::ArrayVec;
2424
use core::default::Default;
2525
use core::mem;
26+
use core::pin::Pin;
2627
use core::sync::atomic::AtomicU32;
2728
use spin::RwLock;
2829

@@ -92,7 +93,7 @@ pub enum VirtualMachineMsg {
9293
struct VirtualMachineContext {
9394
core_id: percore::CoreId,
9495

95-
vm: &'static VirtualMachine,
96+
vm: Pin<&'static VirtualMachine>,
9697

9798
/// The per-core RX message queue
9899
msgqueue: RwLock<ArrayDeque<[VirtualMachineMsg; MAX_PENDING_MSG]>>,
@@ -138,13 +139,13 @@ impl VirtualMachineSet {
138139
}
139140

140141
// Initialize the per-VM local apic access page
141-
vm.setup_guest_local_apic_page()?;
142+
Pin::static_ref(vm).setup_guest_local_apic_page()?;
142143

143144
// Create the communication queues
144145
for cpu in vm.cpus.iter() {
145146
self.contexts.push(VirtualMachineContext {
146147
core_id: *cpu,
147-
vm: vm,
148+
vm: Pin::static_ref(vm),
148149
msgqueue: RwLock::new(ArrayDeque::new()),
149150
})
150151
}
@@ -194,12 +195,15 @@ impl VirtualMachineSet {
194195
pub unsafe fn get_by_core_id(
195196
&self,
196197
core_id: percore::CoreId,
197-
) -> Option<&'static VirtualMachine> {
198+
) -> Option<Pin<&'static VirtualMachine>> {
198199
self.context_by_core_id(core_id).map(|context| context.vm)
199200
}
200201

201202
/// Get a VirtualMachine by its vmid
202-
pub fn get_by_vm_id(&self, vmid: u32) -> Option<&'static VirtualMachine> {
203+
pub fn get_by_vm_id(
204+
&self,
205+
vmid: u32,
206+
) -> Option<Pin<&'static VirtualMachine>> {
203207
self.context_by_vm_id(vmid).map(|context| context.vm)
204208
}
205209

@@ -479,7 +483,7 @@ impl VirtualMachine {
479483

480484
/// Setup the local APIC access page for the guest. This _must_ be called
481485
/// only once the VirtualMachine is in a final location.
482-
pub fn setup_guest_local_apic_page(&'static self) -> Result<()> {
486+
pub fn setup_guest_local_apic_page(self: Pin<&'static Self>) -> Result<()> {
483487
// Map the guest local apic addr to the access page. This will be set in each
484488
// core's vmcs
485489
let apic_frame = memory::HostPhysFrame::from_start_address(

0 commit comments

Comments
 (0)