xref: /aosp_15_r20/external/crosvm/devices/tests/irqchip/userspace.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(target_arch = "x86_64")]
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::thread;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration;
11*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Instant;
12*bb4ee6a4SAndroid Build Coastguard Worker 
13*bb4ee6a4SAndroid Build Coastguard Worker use base::Clock;
14*bb4ee6a4SAndroid Build Coastguard Worker use base::EventWaitResult;
15*bb4ee6a4SAndroid Build Coastguard Worker use base::Result;
16*bb4ee6a4SAndroid Build Coastguard Worker use base::Tube;
17*bb4ee6a4SAndroid Build Coastguard Worker use devices::Bus;
18*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusAccessInfo;
19*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusDeviceSync;
20*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusType;
21*bb4ee6a4SAndroid Build Coastguard Worker use devices::CrosvmDeviceId;
22*bb4ee6a4SAndroid Build Coastguard Worker use devices::DestinationShorthand;
23*bb4ee6a4SAndroid Build Coastguard Worker use devices::DeviceId;
24*bb4ee6a4SAndroid Build Coastguard Worker use devices::Interrupt;
25*bb4ee6a4SAndroid Build Coastguard Worker use devices::InterruptData;
26*bb4ee6a4SAndroid Build Coastguard Worker use devices::InterruptDestination;
27*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqChip;
28*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqChipX86_64;
29*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqEdgeEvent;
30*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqEventSource;
31*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqLevelEvent;
32*bb4ee6a4SAndroid Build Coastguard Worker use devices::UserspaceIrqChip;
33*bb4ee6a4SAndroid Build Coastguard Worker use devices::VcpuRunState;
34*bb4ee6a4SAndroid Build Coastguard Worker use devices::APIC_BASE_ADDRESS;
35*bb4ee6a4SAndroid Build Coastguard Worker use devices::IOAPIC_BASE_ADDRESS;
36*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::CpuId;
37*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::CpuIdEntry;
38*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::DebugRegs;
39*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::DeliveryMode;
40*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::DestinationMode;
41*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Fpu;
42*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IoParams;
43*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IoapicRedirectionTableEntry;
44*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqRoute;
45*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqSource;
46*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Level;
47*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::PicSelect;
48*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::PitRWMode;
49*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Regs;
50*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Sregs;
51*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::TriggerMode;
52*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Vcpu;
53*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuExit;
54*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuSnapshot;
55*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuX86_64;
56*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Xsave;
57*bb4ee6a4SAndroid Build Coastguard Worker use resources::AddressRange;
58*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator;
59*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocatorConfig;
60*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
61*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
62*bb4ee6a4SAndroid Build Coastguard Worker 
63*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_get_ioapic;
64*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_get_pit;
65*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_route_irq;
66*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_set_ioapic;
67*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_set_pic;
68*bb4ee6a4SAndroid Build Coastguard Worker use crate::x86_64::test_set_pit;
69*bb4ee6a4SAndroid Build Coastguard Worker 
70*bb4ee6a4SAndroid Build Coastguard Worker const APIC_ID: u64 = 0x20;
71*bb4ee6a4SAndroid Build Coastguard Worker const TPR: u64 = 0x80;
72*bb4ee6a4SAndroid Build Coastguard Worker const EOI: u64 = 0xB0;
73*bb4ee6a4SAndroid Build Coastguard Worker const TEST_SLEEP_DURATION: Duration = Duration::from_millis(50);
74*bb4ee6a4SAndroid Build Coastguard Worker 
75*bb4ee6a4SAndroid Build Coastguard Worker /// Helper function for setting up a UserspaceIrqChip.
get_chip(num_vcpus: usize) -> UserspaceIrqChip<FakeVcpu>76*bb4ee6a4SAndroid Build Coastguard Worker fn get_chip(num_vcpus: usize) -> UserspaceIrqChip<FakeVcpu> {
77*bb4ee6a4SAndroid Build Coastguard Worker     get_chip_with_clock(num_vcpus, Arc::new(Mutex::new(Clock::new())))
78*bb4ee6a4SAndroid Build Coastguard Worker }
79*bb4ee6a4SAndroid Build Coastguard Worker 
get_chip_with_clock(num_vcpus: usize, clock: Arc<Mutex<Clock>>) -> UserspaceIrqChip<FakeVcpu>80*bb4ee6a4SAndroid Build Coastguard Worker fn get_chip_with_clock(num_vcpus: usize, clock: Arc<Mutex<Clock>>) -> UserspaceIrqChip<FakeVcpu> {
81*bb4ee6a4SAndroid Build Coastguard Worker     let (_, irq_tube) = Tube::pair().unwrap();
82*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = UserspaceIrqChip::<FakeVcpu>::new_with_clock(num_vcpus, irq_tube, None, clock)
83*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to instantiate UserspaceIrqChip");
84*bb4ee6a4SAndroid Build Coastguard Worker 
85*bb4ee6a4SAndroid Build Coastguard Worker     for i in 0..num_vcpus {
86*bb4ee6a4SAndroid Build Coastguard Worker         let vcpu = FakeVcpu {
87*bb4ee6a4SAndroid Build Coastguard Worker             id: i,
88*bb4ee6a4SAndroid Build Coastguard Worker             requested: Arc::new(Mutex::new(false)),
89*bb4ee6a4SAndroid Build Coastguard Worker             ready: Arc::new(Mutex::new(true)),
90*bb4ee6a4SAndroid Build Coastguard Worker             injected: Arc::new(Mutex::new(None)),
91*bb4ee6a4SAndroid Build Coastguard Worker         };
92*bb4ee6a4SAndroid Build Coastguard Worker         chip.add_vcpu(i, &vcpu).expect("failed to add vcpu");
93*bb4ee6a4SAndroid Build Coastguard Worker         chip.apics[i].lock().set_enabled(true);
94*bb4ee6a4SAndroid Build Coastguard Worker     }
95*bb4ee6a4SAndroid Build Coastguard Worker 
96*bb4ee6a4SAndroid Build Coastguard Worker     chip
97*bb4ee6a4SAndroid Build Coastguard Worker }
98*bb4ee6a4SAndroid Build Coastguard Worker 
99*bb4ee6a4SAndroid Build Coastguard Worker /// Helper function for cloning vcpus from a UserspaceIrqChip.
get_vcpus(chip: &UserspaceIrqChip<FakeVcpu>) -> Vec<FakeVcpu>100*bb4ee6a4SAndroid Build Coastguard Worker fn get_vcpus(chip: &UserspaceIrqChip<FakeVcpu>) -> Vec<FakeVcpu> {
101*bb4ee6a4SAndroid Build Coastguard Worker     chip.vcpus
102*bb4ee6a4SAndroid Build Coastguard Worker         .lock()
103*bb4ee6a4SAndroid Build Coastguard Worker         .iter()
104*bb4ee6a4SAndroid Build Coastguard Worker         .map(|v| v.as_ref().unwrap().try_clone().unwrap())
105*bb4ee6a4SAndroid Build Coastguard Worker         .collect()
106*bb4ee6a4SAndroid Build Coastguard Worker }
107*bb4ee6a4SAndroid Build Coastguard Worker 
108*bb4ee6a4SAndroid Build Coastguard Worker #[test]
set_pic()109*bb4ee6a4SAndroid Build Coastguard Worker fn set_pic() {
110*bb4ee6a4SAndroid Build Coastguard Worker     test_set_pic(get_chip(1));
111*bb4ee6a4SAndroid Build Coastguard Worker }
112*bb4ee6a4SAndroid Build Coastguard Worker 
113*bb4ee6a4SAndroid Build Coastguard Worker #[test]
get_ioapic()114*bb4ee6a4SAndroid Build Coastguard Worker fn get_ioapic() {
115*bb4ee6a4SAndroid Build Coastguard Worker     test_get_ioapic(get_chip(1));
116*bb4ee6a4SAndroid Build Coastguard Worker }
117*bb4ee6a4SAndroid Build Coastguard Worker 
118*bb4ee6a4SAndroid Build Coastguard Worker #[test]
set_ioapic()119*bb4ee6a4SAndroid Build Coastguard Worker fn set_ioapic() {
120*bb4ee6a4SAndroid Build Coastguard Worker     test_set_ioapic(get_chip(1));
121*bb4ee6a4SAndroid Build Coastguard Worker }
122*bb4ee6a4SAndroid Build Coastguard Worker 
123*bb4ee6a4SAndroid Build Coastguard Worker #[test]
get_pit()124*bb4ee6a4SAndroid Build Coastguard Worker fn get_pit() {
125*bb4ee6a4SAndroid Build Coastguard Worker     test_get_pit(get_chip(1));
126*bb4ee6a4SAndroid Build Coastguard Worker }
127*bb4ee6a4SAndroid Build Coastguard Worker 
128*bb4ee6a4SAndroid Build Coastguard Worker #[test]
set_pit()129*bb4ee6a4SAndroid Build Coastguard Worker fn set_pit() {
130*bb4ee6a4SAndroid Build Coastguard Worker     test_set_pit(get_chip(1));
131*bb4ee6a4SAndroid Build Coastguard Worker }
132*bb4ee6a4SAndroid Build Coastguard Worker 
133*bb4ee6a4SAndroid Build Coastguard Worker #[test]
route_irq()134*bb4ee6a4SAndroid Build Coastguard Worker fn route_irq() {
135*bb4ee6a4SAndroid Build Coastguard Worker     test_route_irq(get_chip(1));
136*bb4ee6a4SAndroid Build Coastguard Worker }
137*bb4ee6a4SAndroid Build Coastguard Worker 
138*bb4ee6a4SAndroid Build Coastguard Worker #[test]
pit_uses_speaker_port()139*bb4ee6a4SAndroid Build Coastguard Worker fn pit_uses_speaker_port() {
140*bb4ee6a4SAndroid Build Coastguard Worker     let chip = get_chip(1);
141*bb4ee6a4SAndroid Build Coastguard Worker     assert!(chip.pit_uses_speaker_port());
142*bb4ee6a4SAndroid Build Coastguard Worker }
143*bb4ee6a4SAndroid Build Coastguard Worker 
144*bb4ee6a4SAndroid Build Coastguard Worker #[test]
routes_conflict()145*bb4ee6a4SAndroid Build Coastguard Worker fn routes_conflict() {
146*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(1);
147*bb4ee6a4SAndroid Build Coastguard Worker     chip.route_irq(IrqRoute {
148*bb4ee6a4SAndroid Build Coastguard Worker         gsi: 32,
149*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Msi {
150*bb4ee6a4SAndroid Build Coastguard Worker             address: 4276092928,
151*bb4ee6a4SAndroid Build Coastguard Worker             data: 0,
152*bb4ee6a4SAndroid Build Coastguard Worker         },
153*bb4ee6a4SAndroid Build Coastguard Worker     })
154*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to set msi rout");
155*bb4ee6a4SAndroid Build Coastguard Worker     // this second route should replace the first
156*bb4ee6a4SAndroid Build Coastguard Worker     chip.route_irq(IrqRoute {
157*bb4ee6a4SAndroid Build Coastguard Worker         gsi: 32,
158*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Msi {
159*bb4ee6a4SAndroid Build Coastguard Worker             address: 4276092928,
160*bb4ee6a4SAndroid Build Coastguard Worker             data: 32801,
161*bb4ee6a4SAndroid Build Coastguard Worker         },
162*bb4ee6a4SAndroid Build Coastguard Worker     })
163*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to set msi rout");
164*bb4ee6a4SAndroid Build Coastguard Worker }
165*bb4ee6a4SAndroid Build Coastguard Worker 
166*bb4ee6a4SAndroid Build Coastguard Worker #[test]
irq_event_tokens()167*bb4ee6a4SAndroid Build Coastguard Worker fn irq_event_tokens() {
168*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(1);
169*bb4ee6a4SAndroid Build Coastguard Worker     let tokens = chip
170*bb4ee6a4SAndroid Build Coastguard Worker         .irq_event_tokens()
171*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get irq_event_tokens");
172*bb4ee6a4SAndroid Build Coastguard Worker 
173*bb4ee6a4SAndroid Build Coastguard Worker     // there should be one token on a fresh split irqchip, for the pit
174*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(tokens.len(), 1);
175*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(tokens[0].1.device_name, "userspace PIT");
176*bb4ee6a4SAndroid Build Coastguard Worker 
177*bb4ee6a4SAndroid Build Coastguard Worker     // register another irq event
178*bb4ee6a4SAndroid Build Coastguard Worker     let evt = IrqEdgeEvent::new().expect("failed to create eventfd");
179*bb4ee6a4SAndroid Build Coastguard Worker     let source = IrqEventSource {
180*bb4ee6a4SAndroid Build Coastguard Worker         device_id: CrosvmDeviceId::Cmos.into(),
181*bb4ee6a4SAndroid Build Coastguard Worker         queue_id: 0,
182*bb4ee6a4SAndroid Build Coastguard Worker         device_name: "test".to_owned(),
183*bb4ee6a4SAndroid Build Coastguard Worker     };
184*bb4ee6a4SAndroid Build Coastguard Worker     chip.register_edge_irq_event(6, &evt, source)
185*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to register irq event");
186*bb4ee6a4SAndroid Build Coastguard Worker 
187*bb4ee6a4SAndroid Build Coastguard Worker     let tokens = chip
188*bb4ee6a4SAndroid Build Coastguard Worker         .irq_event_tokens()
189*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get irq_event_tokens");
190*bb4ee6a4SAndroid Build Coastguard Worker 
191*bb4ee6a4SAndroid Build Coastguard Worker     // now there should be two tokens
192*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(tokens.len(), 2);
193*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(tokens[0].1.device_name, "userspace PIT");
194*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
195*bb4ee6a4SAndroid Build Coastguard Worker         tokens[1].1.device_id,
196*bb4ee6a4SAndroid Build Coastguard Worker         DeviceId::PlatformDeviceId(CrosvmDeviceId::Cmos)
197*bb4ee6a4SAndroid Build Coastguard Worker     );
198*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(tokens[1].2, evt.get_trigger().try_clone().unwrap());
199*bb4ee6a4SAndroid Build Coastguard Worker }
200*bb4ee6a4SAndroid Build Coastguard Worker 
201*bb4ee6a4SAndroid Build Coastguard Worker // TODO(srichman): Factor out of UserspaceIrqChip and KvmSplitIrqChip.
202*bb4ee6a4SAndroid Build Coastguard Worker #[test]
finalize_devices()203*bb4ee6a4SAndroid Build Coastguard Worker fn finalize_devices() {
204*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(1);
205*bb4ee6a4SAndroid Build Coastguard Worker 
206*bb4ee6a4SAndroid Build Coastguard Worker     let mmio_bus = Bus::new(BusType::Mmio);
207*bb4ee6a4SAndroid Build Coastguard Worker     let io_bus = Bus::new(BusType::Io);
208*bb4ee6a4SAndroid Build Coastguard Worker     let mut resources = SystemAllocator::new(
209*bb4ee6a4SAndroid Build Coastguard Worker         SystemAllocatorConfig {
210*bb4ee6a4SAndroid Build Coastguard Worker             io: Some(AddressRange {
211*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0xc000,
212*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0xFFFF,
213*bb4ee6a4SAndroid Build Coastguard Worker             }),
214*bb4ee6a4SAndroid Build Coastguard Worker             low_mmio: AddressRange {
215*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0,
216*bb4ee6a4SAndroid Build Coastguard Worker                 end: 2047,
217*bb4ee6a4SAndroid Build Coastguard Worker             },
218*bb4ee6a4SAndroid Build Coastguard Worker             high_mmio: AddressRange {
219*bb4ee6a4SAndroid Build Coastguard Worker                 start: 2048,
220*bb4ee6a4SAndroid Build Coastguard Worker                 end: 6143,
221*bb4ee6a4SAndroid Build Coastguard Worker             },
222*bb4ee6a4SAndroid Build Coastguard Worker             platform_mmio: None,
223*bb4ee6a4SAndroid Build Coastguard Worker             first_irq: 5,
224*bb4ee6a4SAndroid Build Coastguard Worker         },
225*bb4ee6a4SAndroid Build Coastguard Worker         None,
226*bb4ee6a4SAndroid Build Coastguard Worker         &[],
227*bb4ee6a4SAndroid Build Coastguard Worker     )
228*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to create SystemAllocator");
229*bb4ee6a4SAndroid Build Coastguard Worker 
230*bb4ee6a4SAndroid Build Coastguard Worker     // Setup an event and a resample event for irq line 1.
231*bb4ee6a4SAndroid Build Coastguard Worker     let evt = IrqLevelEvent::new().expect("failed to create event");
232*bb4ee6a4SAndroid Build Coastguard Worker 
233*bb4ee6a4SAndroid Build Coastguard Worker     let source = IrqEventSource {
234*bb4ee6a4SAndroid Build Coastguard Worker         device_id: CrosvmDeviceId::Cmos.into(),
235*bb4ee6a4SAndroid Build Coastguard Worker         device_name: "test".to_owned(),
236*bb4ee6a4SAndroid Build Coastguard Worker         queue_id: 0,
237*bb4ee6a4SAndroid Build Coastguard Worker     };
238*bb4ee6a4SAndroid Build Coastguard Worker 
239*bb4ee6a4SAndroid Build Coastguard Worker     let evt_index = chip
240*bb4ee6a4SAndroid Build Coastguard Worker         .register_level_irq_event(1, &evt, source)
241*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to register_level_irq_event")
242*bb4ee6a4SAndroid Build Coastguard Worker         .expect("register_level_irq_event should not return None");
243*bb4ee6a4SAndroid Build Coastguard Worker 
244*bb4ee6a4SAndroid Build Coastguard Worker     // Once we finalize devices, the pic/pit/ioapic should be attached to io and mmio busses.
245*bb4ee6a4SAndroid Build Coastguard Worker     chip.finalize_devices(&mut resources, &io_bus, &mmio_bus)
246*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to finalize devices");
247*bb4ee6a4SAndroid Build Coastguard Worker 
248*bb4ee6a4SAndroid Build Coastguard Worker     // Should not be able to allocate an irq < 24 now.
249*bb4ee6a4SAndroid Build Coastguard Worker     assert!(resources.allocate_irq().expect("failed to allocate irq") >= 24);
250*bb4ee6a4SAndroid Build Coastguard Worker 
251*bb4ee6a4SAndroid Build Coastguard Worker     // Set PIT counter 2 to "SquareWaveGen" (aka 3) mode and "Both" access mode.
252*bb4ee6a4SAndroid Build Coastguard Worker     io_bus.write(0x43, &[0b10110110]);
253*bb4ee6a4SAndroid Build Coastguard Worker 
254*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_pit().expect("failed to get pit state");
255*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.channels[2].mode, 3);
256*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.channels[2].rw_mode, PitRWMode::Both);
257*bb4ee6a4SAndroid Build Coastguard Worker 
258*bb4ee6a4SAndroid Build Coastguard Worker     // ICW1 0x11: Edge trigger, cascade mode, ICW4 needed.
259*bb4ee6a4SAndroid Build Coastguard Worker     // ICW2 0x08: Interrupt vector base address 0x08.
260*bb4ee6a4SAndroid Build Coastguard Worker     // ICW3 0xff: Value written does not matter.
261*bb4ee6a4SAndroid Build Coastguard Worker     // ICW4 0x13: Special fully nested mode, auto EOI.
262*bb4ee6a4SAndroid Build Coastguard Worker     io_bus.write(0x20, &[0x11]);
263*bb4ee6a4SAndroid Build Coastguard Worker     io_bus.write(0x21, &[0x08]);
264*bb4ee6a4SAndroid Build Coastguard Worker     io_bus.write(0x21, &[0xff]);
265*bb4ee6a4SAndroid Build Coastguard Worker     io_bus.write(0x21, &[0x13]);
266*bb4ee6a4SAndroid Build Coastguard Worker 
267*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip
268*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(PicSelect::Primary)
269*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to get pic state");
270*bb4ee6a4SAndroid Build Coastguard Worker 
271*bb4ee6a4SAndroid Build Coastguard Worker     // Auto eoi and special fully nested mode should be turned on.
272*bb4ee6a4SAndroid Build Coastguard Worker     assert!(state.auto_eoi);
273*bb4ee6a4SAndroid Build Coastguard Worker     assert!(state.special_fully_nested_mode);
274*bb4ee6a4SAndroid Build Coastguard Worker 
275*bb4ee6a4SAndroid Build Coastguard Worker     // Need to write to the irq event before servicing it.
276*bb4ee6a4SAndroid Build Coastguard Worker     evt.trigger().expect("failed to write to eventfd");
277*bb4ee6a4SAndroid Build Coastguard Worker 
278*bb4ee6a4SAndroid Build Coastguard Worker     // If we assert irq line one, and then get the resulting interrupt, an auto-eoi should occur
279*bb4ee6a4SAndroid Build Coastguard Worker     // and cause the resample_event to be written to.
280*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq_event(evt_index)
281*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to service irq");
282*bb4ee6a4SAndroid Build Coastguard Worker 
283*bb4ee6a4SAndroid Build Coastguard Worker     let vcpu = get_vcpus(&chip).remove(0);
284*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpu).unwrap();
285*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
286*bb4ee6a4SAndroid Build Coastguard Worker         vcpu.clear_injected(),
287*bb4ee6a4SAndroid Build Coastguard Worker         // Vector is 9 because the interrupt vector base address is 0x08 and this is irq line 1
288*bb4ee6a4SAndroid Build Coastguard Worker         // and 8+1 = 9.
289*bb4ee6a4SAndroid Build Coastguard Worker         Some(0x9)
290*bb4ee6a4SAndroid Build Coastguard Worker     );
291*bb4ee6a4SAndroid Build Coastguard Worker 
292*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
293*bb4ee6a4SAndroid Build Coastguard Worker         evt.get_resample()
294*bb4ee6a4SAndroid Build Coastguard Worker             .wait_timeout(std::time::Duration::from_secs(1))
295*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to read_timeout"),
296*bb4ee6a4SAndroid Build Coastguard Worker         EventWaitResult::Signaled
297*bb4ee6a4SAndroid Build Coastguard Worker     );
298*bb4ee6a4SAndroid Build Coastguard Worker 
299*bb4ee6a4SAndroid Build Coastguard Worker     // Setup a ioapic redirection table entry 14.
300*bb4ee6a4SAndroid Build Coastguard Worker     let mut entry = IoapicRedirectionTableEntry::default();
301*bb4ee6a4SAndroid Build Coastguard Worker     entry.set_vector(44);
302*bb4ee6a4SAndroid Build Coastguard Worker 
303*bb4ee6a4SAndroid Build Coastguard Worker     let irq_14_offset = 0x10 + 14 * 2;
304*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(IOAPIC_BASE_ADDRESS, &[irq_14_offset]);
305*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(
306*bb4ee6a4SAndroid Build Coastguard Worker         IOAPIC_BASE_ADDRESS + 0x10,
307*bb4ee6a4SAndroid Build Coastguard Worker         &(entry.get(0, 32) as u32).to_ne_bytes(),
308*bb4ee6a4SAndroid Build Coastguard Worker     );
309*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(IOAPIC_BASE_ADDRESS, &[irq_14_offset + 1]);
310*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(
311*bb4ee6a4SAndroid Build Coastguard Worker         IOAPIC_BASE_ADDRESS + 0x10,
312*bb4ee6a4SAndroid Build Coastguard Worker         &(entry.get(32, 32) as u32).to_ne_bytes(),
313*bb4ee6a4SAndroid Build Coastguard Worker     );
314*bb4ee6a4SAndroid Build Coastguard Worker 
315*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("failed to get ioapic state");
316*bb4ee6a4SAndroid Build Coastguard Worker 
317*bb4ee6a4SAndroid Build Coastguard Worker     // Redirection table entry 14 should have a vector of 44.
318*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.redirect_table[14].get_vector(), 44);
319*bb4ee6a4SAndroid Build Coastguard Worker }
320*bb4ee6a4SAndroid Build Coastguard Worker 
321*bb4ee6a4SAndroid Build Coastguard Worker #[test]
inject_pic_interrupt()322*bb4ee6a4SAndroid Build Coastguard Worker fn inject_pic_interrupt() {
323*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(2);
324*bb4ee6a4SAndroid Build Coastguard Worker     let vcpus = get_vcpus(&chip);
325*bb4ee6a4SAndroid Build Coastguard Worker 
326*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), None);
327*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), None);
328*bb4ee6a4SAndroid Build Coastguard Worker 
329*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(0, true).expect("failed to service irq");
330*bb4ee6a4SAndroid Build Coastguard Worker 
331*bb4ee6a4SAndroid Build Coastguard Worker     // Should not inject PIC interrupt for vcpu_id != 0.
332*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[1]).unwrap();
333*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), None);
334*bb4ee6a4SAndroid Build Coastguard Worker 
335*bb4ee6a4SAndroid Build Coastguard Worker     // Should inject Some interrupt.
336*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[0]).unwrap();
337*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), Some(0));
338*bb4ee6a4SAndroid Build Coastguard Worker 
339*bb4ee6a4SAndroid Build Coastguard Worker     // Interrupt is not injected twice.
340*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[0]).unwrap();
341*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), None);
342*bb4ee6a4SAndroid Build Coastguard Worker }
343*bb4ee6a4SAndroid Build Coastguard Worker 
344*bb4ee6a4SAndroid Build Coastguard Worker #[test]
inject_msi()345*bb4ee6a4SAndroid Build Coastguard Worker fn inject_msi() {
346*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(2);
347*bb4ee6a4SAndroid Build Coastguard Worker     let vcpus = get_vcpus(&chip);
348*bb4ee6a4SAndroid Build Coastguard Worker 
349*bb4ee6a4SAndroid Build Coastguard Worker     let evt = IrqEdgeEvent::new().unwrap();
350*bb4ee6a4SAndroid Build Coastguard Worker     let source = IrqEventSource {
351*bb4ee6a4SAndroid Build Coastguard Worker         device_id: CrosvmDeviceId::Cmos.into(),
352*bb4ee6a4SAndroid Build Coastguard Worker         device_name: "test".to_owned(),
353*bb4ee6a4SAndroid Build Coastguard Worker         queue_id: 0,
354*bb4ee6a4SAndroid Build Coastguard Worker     };
355*bb4ee6a4SAndroid Build Coastguard Worker     let event_idx = chip
356*bb4ee6a4SAndroid Build Coastguard Worker         .register_edge_irq_event(30, &evt, source)
357*bb4ee6a4SAndroid Build Coastguard Worker         .unwrap()
358*bb4ee6a4SAndroid Build Coastguard Worker         .unwrap();
359*bb4ee6a4SAndroid Build Coastguard Worker     chip.route_irq(IrqRoute {
360*bb4ee6a4SAndroid Build Coastguard Worker         gsi: 30,
361*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Msi {
362*bb4ee6a4SAndroid Build Coastguard Worker             address: 0xFEE01000, // physical addressing, send to apic 1
363*bb4ee6a4SAndroid Build Coastguard Worker             data: 0x000000F1,    // edge-triggered, fixed interrupt, vector 0xF1
364*bb4ee6a4SAndroid Build Coastguard Worker         },
365*bb4ee6a4SAndroid Build Coastguard Worker     })
366*bb4ee6a4SAndroid Build Coastguard Worker     .unwrap();
367*bb4ee6a4SAndroid Build Coastguard Worker     evt.trigger().unwrap();
368*bb4ee6a4SAndroid Build Coastguard Worker 
369*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!vcpus[0].window_requested());
370*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!vcpus[1].window_requested());
371*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq_event(event_idx).unwrap();
372*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!vcpus[0].window_requested());
373*bb4ee6a4SAndroid Build Coastguard Worker     assert!(vcpus[1].window_requested());
374*bb4ee6a4SAndroid Build Coastguard Worker 
375*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[0]).unwrap();
376*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), None);
377*bb4ee6a4SAndroid Build Coastguard Worker 
378*bb4ee6a4SAndroid Build Coastguard Worker     vcpus[1].set_ready(false);
379*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[1]).unwrap();
380*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), None);
381*bb4ee6a4SAndroid Build Coastguard Worker     vcpus[1].set_ready(true);
382*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[1]).unwrap();
383*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), Some(0xF1));
384*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!vcpus[1].window_requested());
385*bb4ee6a4SAndroid Build Coastguard Worker }
386*bb4ee6a4SAndroid Build Coastguard Worker 
387*bb4ee6a4SAndroid Build Coastguard Worker #[test]
lowest_priority_destination()388*bb4ee6a4SAndroid Build Coastguard Worker fn lowest_priority_destination() {
389*bb4ee6a4SAndroid Build Coastguard Worker     let chip = get_chip(2);
390*bb4ee6a4SAndroid Build Coastguard Worker     let vcpus = get_vcpus(&chip);
391*bb4ee6a4SAndroid Build Coastguard Worker 
392*bb4ee6a4SAndroid Build Coastguard Worker     // Make vcpu 0 higher priority.
393*bb4ee6a4SAndroid Build Coastguard Worker     chip.write(
394*bb4ee6a4SAndroid Build Coastguard Worker         BusAccessInfo {
395*bb4ee6a4SAndroid Build Coastguard Worker             id: 0,
396*bb4ee6a4SAndroid Build Coastguard Worker             address: APIC_BASE_ADDRESS + TPR,
397*bb4ee6a4SAndroid Build Coastguard Worker             offset: TPR,
398*bb4ee6a4SAndroid Build Coastguard Worker         },
399*bb4ee6a4SAndroid Build Coastguard Worker         &[0x10, 0, 0, 0],
400*bb4ee6a4SAndroid Build Coastguard Worker     );
401*bb4ee6a4SAndroid Build Coastguard Worker     chip.send_irq_to_apics(&Interrupt {
402*bb4ee6a4SAndroid Build Coastguard Worker         dest: InterruptDestination {
403*bb4ee6a4SAndroid Build Coastguard Worker             source_id: 0,
404*bb4ee6a4SAndroid Build Coastguard Worker             dest_id: 0,
405*bb4ee6a4SAndroid Build Coastguard Worker             shorthand: DestinationShorthand::All,
406*bb4ee6a4SAndroid Build Coastguard Worker             mode: DestinationMode::Physical,
407*bb4ee6a4SAndroid Build Coastguard Worker         },
408*bb4ee6a4SAndroid Build Coastguard Worker         data: InterruptData {
409*bb4ee6a4SAndroid Build Coastguard Worker             vector: 111,
410*bb4ee6a4SAndroid Build Coastguard Worker             delivery: DeliveryMode::Lowest,
411*bb4ee6a4SAndroid Build Coastguard Worker             trigger: TriggerMode::Edge,
412*bb4ee6a4SAndroid Build Coastguard Worker             level: Level::Deassert,
413*bb4ee6a4SAndroid Build Coastguard Worker         },
414*bb4ee6a4SAndroid Build Coastguard Worker     });
415*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[0]).unwrap();
416*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[1]).unwrap();
417*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), None);
418*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), Some(111));
419*bb4ee6a4SAndroid Build Coastguard Worker     chip.write(
420*bb4ee6a4SAndroid Build Coastguard Worker         BusAccessInfo {
421*bb4ee6a4SAndroid Build Coastguard Worker             id: 1,
422*bb4ee6a4SAndroid Build Coastguard Worker             address: APIC_BASE_ADDRESS + EOI,
423*bb4ee6a4SAndroid Build Coastguard Worker             offset: EOI,
424*bb4ee6a4SAndroid Build Coastguard Worker         },
425*bb4ee6a4SAndroid Build Coastguard Worker         &[0, 0, 0, 0],
426*bb4ee6a4SAndroid Build Coastguard Worker     );
427*bb4ee6a4SAndroid Build Coastguard Worker 
428*bb4ee6a4SAndroid Build Coastguard Worker     // Make vcpu 1 higher priority.
429*bb4ee6a4SAndroid Build Coastguard Worker     chip.write(
430*bb4ee6a4SAndroid Build Coastguard Worker         BusAccessInfo {
431*bb4ee6a4SAndroid Build Coastguard Worker             id: 1,
432*bb4ee6a4SAndroid Build Coastguard Worker             address: APIC_BASE_ADDRESS + TPR,
433*bb4ee6a4SAndroid Build Coastguard Worker             offset: TPR,
434*bb4ee6a4SAndroid Build Coastguard Worker         },
435*bb4ee6a4SAndroid Build Coastguard Worker         &[0x20, 0, 0, 0],
436*bb4ee6a4SAndroid Build Coastguard Worker     );
437*bb4ee6a4SAndroid Build Coastguard Worker     chip.send_irq_to_apics(&Interrupt {
438*bb4ee6a4SAndroid Build Coastguard Worker         dest: InterruptDestination {
439*bb4ee6a4SAndroid Build Coastguard Worker             source_id: 0,
440*bb4ee6a4SAndroid Build Coastguard Worker             dest_id: 0,
441*bb4ee6a4SAndroid Build Coastguard Worker             shorthand: DestinationShorthand::All,
442*bb4ee6a4SAndroid Build Coastguard Worker             mode: DestinationMode::Physical,
443*bb4ee6a4SAndroid Build Coastguard Worker         },
444*bb4ee6a4SAndroid Build Coastguard Worker         data: InterruptData {
445*bb4ee6a4SAndroid Build Coastguard Worker             vector: 222,
446*bb4ee6a4SAndroid Build Coastguard Worker             delivery: DeliveryMode::Lowest,
447*bb4ee6a4SAndroid Build Coastguard Worker             trigger: TriggerMode::Edge,
448*bb4ee6a4SAndroid Build Coastguard Worker             level: Level::Deassert,
449*bb4ee6a4SAndroid Build Coastguard Worker         },
450*bb4ee6a4SAndroid Build Coastguard Worker     });
451*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[0]).unwrap();
452*bb4ee6a4SAndroid Build Coastguard Worker     chip.inject_interrupts(&vcpus[1]).unwrap();
453*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[0].clear_injected(), Some(222));
454*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(vcpus[1].clear_injected(), None);
455*bb4ee6a4SAndroid Build Coastguard Worker }
456*bb4ee6a4SAndroid Build Coastguard Worker 
457*bb4ee6a4SAndroid Build Coastguard Worker // TODO(srichman): Factor out of UserspaceIrqChip and KvmSplitIrqChip.
458*bb4ee6a4SAndroid Build Coastguard Worker #[test]
broadcast_eoi()459*bb4ee6a4SAndroid Build Coastguard Worker fn broadcast_eoi() {
460*bb4ee6a4SAndroid Build Coastguard Worker     let mut chip = get_chip(1);
461*bb4ee6a4SAndroid Build Coastguard Worker 
462*bb4ee6a4SAndroid Build Coastguard Worker     let mmio_bus = Bus::new(BusType::Mmio);
463*bb4ee6a4SAndroid Build Coastguard Worker     let io_bus = Bus::new(BusType::Io);
464*bb4ee6a4SAndroid Build Coastguard Worker     let mut resources = SystemAllocator::new(
465*bb4ee6a4SAndroid Build Coastguard Worker         SystemAllocatorConfig {
466*bb4ee6a4SAndroid Build Coastguard Worker             io: Some(AddressRange {
467*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0xc000,
468*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0xFFFF,
469*bb4ee6a4SAndroid Build Coastguard Worker             }),
470*bb4ee6a4SAndroid Build Coastguard Worker             low_mmio: AddressRange {
471*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0,
472*bb4ee6a4SAndroid Build Coastguard Worker                 end: 2047,
473*bb4ee6a4SAndroid Build Coastguard Worker             },
474*bb4ee6a4SAndroid Build Coastguard Worker             high_mmio: AddressRange {
475*bb4ee6a4SAndroid Build Coastguard Worker                 start: 2048,
476*bb4ee6a4SAndroid Build Coastguard Worker                 end: 6143,
477*bb4ee6a4SAndroid Build Coastguard Worker             },
478*bb4ee6a4SAndroid Build Coastguard Worker             platform_mmio: None,
479*bb4ee6a4SAndroid Build Coastguard Worker             first_irq: 5,
480*bb4ee6a4SAndroid Build Coastguard Worker         },
481*bb4ee6a4SAndroid Build Coastguard Worker         None,
482*bb4ee6a4SAndroid Build Coastguard Worker         &[],
483*bb4ee6a4SAndroid Build Coastguard Worker     )
484*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to create SystemAllocator");
485*bb4ee6a4SAndroid Build Coastguard Worker 
486*bb4ee6a4SAndroid Build Coastguard Worker     // setup an event for irq line 1
487*bb4ee6a4SAndroid Build Coastguard Worker     let evt = IrqLevelEvent::new().expect("failed to create event");
488*bb4ee6a4SAndroid Build Coastguard Worker 
489*bb4ee6a4SAndroid Build Coastguard Worker     let source = IrqEventSource {
490*bb4ee6a4SAndroid Build Coastguard Worker         device_id: CrosvmDeviceId::Cmos.into(),
491*bb4ee6a4SAndroid Build Coastguard Worker         device_name: "test".to_owned(),
492*bb4ee6a4SAndroid Build Coastguard Worker         queue_id: 0,
493*bb4ee6a4SAndroid Build Coastguard Worker     };
494*bb4ee6a4SAndroid Build Coastguard Worker 
495*bb4ee6a4SAndroid Build Coastguard Worker     chip.register_level_irq_event(1, &evt, source)
496*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to register_level_irq_event");
497*bb4ee6a4SAndroid Build Coastguard Worker 
498*bb4ee6a4SAndroid Build Coastguard Worker     // Once we finalize devices, the pic/pit/ioapic should be attached to io and mmio busses
499*bb4ee6a4SAndroid Build Coastguard Worker     chip.finalize_devices(&mut resources, &io_bus, &mmio_bus)
500*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to finalize devices");
501*bb4ee6a4SAndroid Build Coastguard Worker 
502*bb4ee6a4SAndroid Build Coastguard Worker     // setup a ioapic redirection table entry 1 with a vector of 123
503*bb4ee6a4SAndroid Build Coastguard Worker     let mut entry = IoapicRedirectionTableEntry::default();
504*bb4ee6a4SAndroid Build Coastguard Worker     entry.set_vector(123);
505*bb4ee6a4SAndroid Build Coastguard Worker     entry.set_trigger_mode(TriggerMode::Level);
506*bb4ee6a4SAndroid Build Coastguard Worker 
507*bb4ee6a4SAndroid Build Coastguard Worker     let irq_write_offset = 0x10 + 1 * 2;
508*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(IOAPIC_BASE_ADDRESS, &[irq_write_offset]);
509*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(
510*bb4ee6a4SAndroid Build Coastguard Worker         IOAPIC_BASE_ADDRESS + 0x10,
511*bb4ee6a4SAndroid Build Coastguard Worker         &(entry.get(0, 32) as u32).to_ne_bytes(),
512*bb4ee6a4SAndroid Build Coastguard Worker     );
513*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(IOAPIC_BASE_ADDRESS, &[irq_write_offset + 1]);
514*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus.write(
515*bb4ee6a4SAndroid Build Coastguard Worker         IOAPIC_BASE_ADDRESS + 0x10,
516*bb4ee6a4SAndroid Build Coastguard Worker         &(entry.get(32, 32) as u32).to_ne_bytes(),
517*bb4ee6a4SAndroid Build Coastguard Worker     );
518*bb4ee6a4SAndroid Build Coastguard Worker 
519*bb4ee6a4SAndroid Build Coastguard Worker     // Assert line 1
520*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, true).expect("failed to service irq");
521*bb4ee6a4SAndroid Build Coastguard Worker 
522*bb4ee6a4SAndroid Build Coastguard Worker     // resample event should not be written to
523*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
524*bb4ee6a4SAndroid Build Coastguard Worker         evt.get_resample()
525*bb4ee6a4SAndroid Build Coastguard Worker             .wait_timeout(std::time::Duration::from_millis(10))
526*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to read_timeout"),
527*bb4ee6a4SAndroid Build Coastguard Worker         EventWaitResult::TimedOut
528*bb4ee6a4SAndroid Build Coastguard Worker     );
529*bb4ee6a4SAndroid Build Coastguard Worker 
530*bb4ee6a4SAndroid Build Coastguard Worker     // irq line 1 should be asserted
531*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("failed to get ioapic state");
532*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, 1 << 1);
533*bb4ee6a4SAndroid Build Coastguard Worker 
534*bb4ee6a4SAndroid Build Coastguard Worker     // Now broadcast an eoi for vector 123
535*bb4ee6a4SAndroid Build Coastguard Worker     chip.broadcast_eoi(123).expect("failed to broadcast eoi");
536*bb4ee6a4SAndroid Build Coastguard Worker 
537*bb4ee6a4SAndroid Build Coastguard Worker     // irq line 1 should be deasserted
538*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("failed to get ioapic state");
539*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, 0);
540*bb4ee6a4SAndroid Build Coastguard Worker 
541*bb4ee6a4SAndroid Build Coastguard Worker     // resample event should be written to by ioapic
542*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
543*bb4ee6a4SAndroid Build Coastguard Worker         evt.get_resample()
544*bb4ee6a4SAndroid Build Coastguard Worker             .wait_timeout(std::time::Duration::from_millis(10))
545*bb4ee6a4SAndroid Build Coastguard Worker             .expect("failed to read_timeout"),
546*bb4ee6a4SAndroid Build Coastguard Worker         EventWaitResult::Signaled
547*bb4ee6a4SAndroid Build Coastguard Worker     );
548*bb4ee6a4SAndroid Build Coastguard Worker }
549*bb4ee6a4SAndroid Build Coastguard Worker 
550*bb4ee6a4SAndroid Build Coastguard Worker #[test]
apic_mmio()551*bb4ee6a4SAndroid Build Coastguard Worker fn apic_mmio() {
552*bb4ee6a4SAndroid Build Coastguard Worker     let chip = get_chip(2);
553*bb4ee6a4SAndroid Build Coastguard Worker     let mut data = [0u8; 4];
554*bb4ee6a4SAndroid Build Coastguard Worker     chip.read(
555*bb4ee6a4SAndroid Build Coastguard Worker         BusAccessInfo {
556*bb4ee6a4SAndroid Build Coastguard Worker             id: 0,
557*bb4ee6a4SAndroid Build Coastguard Worker             address: APIC_BASE_ADDRESS + APIC_ID,
558*bb4ee6a4SAndroid Build Coastguard Worker             offset: APIC_ID,
559*bb4ee6a4SAndroid Build Coastguard Worker         },
560*bb4ee6a4SAndroid Build Coastguard Worker         &mut data,
561*bb4ee6a4SAndroid Build Coastguard Worker     );
562*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(data, [0, 0, 0, 0]);
563*bb4ee6a4SAndroid Build Coastguard Worker     chip.read(
564*bb4ee6a4SAndroid Build Coastguard Worker         BusAccessInfo {
565*bb4ee6a4SAndroid Build Coastguard Worker             id: 1,
566*bb4ee6a4SAndroid Build Coastguard Worker             address: APIC_BASE_ADDRESS + APIC_ID,
567*bb4ee6a4SAndroid Build Coastguard Worker             offset: APIC_ID,
568*bb4ee6a4SAndroid Build Coastguard Worker         },
569*bb4ee6a4SAndroid Build Coastguard Worker         &mut data,
570*bb4ee6a4SAndroid Build Coastguard Worker     );
571*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(data, [0, 0, 0, 1]);
572*bb4ee6a4SAndroid Build Coastguard Worker }
573*bb4ee6a4SAndroid Build Coastguard Worker 
574*bb4ee6a4SAndroid Build Coastguard Worker #[test]
575*bb4ee6a4SAndroid Build Coastguard Worker #[ignore = "TODO(b/237977699): remove reliance on sleep"]
runnable_vcpu_unhalts()576*bb4ee6a4SAndroid Build Coastguard Worker fn runnable_vcpu_unhalts() {
577*bb4ee6a4SAndroid Build Coastguard Worker     let chip = get_chip(1);
578*bb4ee6a4SAndroid Build Coastguard Worker     let vcpu = get_vcpus(&chip).remove(0);
579*bb4ee6a4SAndroid Build Coastguard Worker     let chip_copy = chip.try_clone().unwrap();
580*bb4ee6a4SAndroid Build Coastguard Worker     // BSP starts runnable.
581*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(chip.wait_until_runnable(&vcpu), Ok(VcpuRunState::Runnable));
582*bb4ee6a4SAndroid Build Coastguard Worker     let start = Instant::now();
583*bb4ee6a4SAndroid Build Coastguard Worker     let handle = thread::spawn(move || {
584*bb4ee6a4SAndroid Build Coastguard Worker         thread::sleep(TEST_SLEEP_DURATION);
585*bb4ee6a4SAndroid Build Coastguard Worker         chip_copy.send_irq_to_apic(
586*bb4ee6a4SAndroid Build Coastguard Worker             0,
587*bb4ee6a4SAndroid Build Coastguard Worker             &InterruptData {
588*bb4ee6a4SAndroid Build Coastguard Worker                 vector: 123,
589*bb4ee6a4SAndroid Build Coastguard Worker                 delivery: DeliveryMode::Fixed,
590*bb4ee6a4SAndroid Build Coastguard Worker                 trigger: TriggerMode::Level,
591*bb4ee6a4SAndroid Build Coastguard Worker                 level: Level::Assert,
592*bb4ee6a4SAndroid Build Coastguard Worker             },
593*bb4ee6a4SAndroid Build Coastguard Worker         );
594*bb4ee6a4SAndroid Build Coastguard Worker     });
595*bb4ee6a4SAndroid Build Coastguard Worker     chip.halted(0);
596*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(chip.wait_until_runnable(&vcpu), Ok(VcpuRunState::Runnable));
597*bb4ee6a4SAndroid Build Coastguard Worker     assert!(Instant::now() - start > Duration::from_millis(5));
598*bb4ee6a4SAndroid Build Coastguard Worker     handle.join().unwrap();
599*bb4ee6a4SAndroid Build Coastguard Worker }
600*bb4ee6a4SAndroid Build Coastguard Worker 
601*bb4ee6a4SAndroid Build Coastguard Worker #[test]
602*bb4ee6a4SAndroid Build Coastguard Worker #[ignore = "TODO(b/237977699): remove reliance on sleep"]
kicked_vcpu_unhalts()603*bb4ee6a4SAndroid Build Coastguard Worker fn kicked_vcpu_unhalts() {
604*bb4ee6a4SAndroid Build Coastguard Worker     let chip = get_chip(1);
605*bb4ee6a4SAndroid Build Coastguard Worker     let vcpu = get_vcpus(&chip).remove(0);
606*bb4ee6a4SAndroid Build Coastguard Worker     let chip_copy = chip.try_clone().unwrap();
607*bb4ee6a4SAndroid Build Coastguard Worker     // BSP starts runnable.
608*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(chip.wait_until_runnable(&vcpu), Ok(VcpuRunState::Runnable));
609*bb4ee6a4SAndroid Build Coastguard Worker     let start = Instant::now();
610*bb4ee6a4SAndroid Build Coastguard Worker     let handle = thread::spawn(move || {
611*bb4ee6a4SAndroid Build Coastguard Worker         thread::sleep(TEST_SLEEP_DURATION);
612*bb4ee6a4SAndroid Build Coastguard Worker         chip_copy.kick_halted_vcpus();
613*bb4ee6a4SAndroid Build Coastguard Worker     });
614*bb4ee6a4SAndroid Build Coastguard Worker     chip.halted(0);
615*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
616*bb4ee6a4SAndroid Build Coastguard Worker         chip.wait_until_runnable(&vcpu),
617*bb4ee6a4SAndroid Build Coastguard Worker         Ok(VcpuRunState::Interrupted)
618*bb4ee6a4SAndroid Build Coastguard Worker     );
619*bb4ee6a4SAndroid Build Coastguard Worker     assert!(Instant::now() - start > Duration::from_millis(5));
620*bb4ee6a4SAndroid Build Coastguard Worker     handle.join().unwrap();
621*bb4ee6a4SAndroid Build Coastguard Worker }
622*bb4ee6a4SAndroid Build Coastguard Worker 
623*bb4ee6a4SAndroid Build Coastguard Worker /// Mock vcpu for testing interrupt injection.
624*bb4ee6a4SAndroid Build Coastguard Worker struct FakeVcpu {
625*bb4ee6a4SAndroid Build Coastguard Worker     id: usize,
626*bb4ee6a4SAndroid Build Coastguard Worker     requested: Arc<Mutex<bool>>,
627*bb4ee6a4SAndroid Build Coastguard Worker     ready: Arc<Mutex<bool>>,
628*bb4ee6a4SAndroid Build Coastguard Worker     injected: Arc<Mutex<Option<u8>>>,
629*bb4ee6a4SAndroid Build Coastguard Worker }
630*bb4ee6a4SAndroid Build Coastguard Worker 
631*bb4ee6a4SAndroid Build Coastguard Worker impl FakeVcpu {
632*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns and clears the last interrupt set by `interrupt`.
clear_injected(&self) -> Option<u8>633*bb4ee6a4SAndroid Build Coastguard Worker     fn clear_injected(&self) -> Option<u8> {
634*bb4ee6a4SAndroid Build Coastguard Worker         self.injected.lock().take()
635*bb4ee6a4SAndroid Build Coastguard Worker     }
636*bb4ee6a4SAndroid Build Coastguard Worker 
637*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns true if an interrupt window was requested with `set_interrupt_window_requested`.
window_requested(&self) -> bool638*bb4ee6a4SAndroid Build Coastguard Worker     fn window_requested(&self) -> bool {
639*bb4ee6a4SAndroid Build Coastguard Worker         *self.requested.lock()
640*bb4ee6a4SAndroid Build Coastguard Worker     }
641*bb4ee6a4SAndroid Build Coastguard Worker 
642*bb4ee6a4SAndroid Build Coastguard Worker     /// Sets the value to be returned by `ready_for_interrupt`.
set_ready(&self, val: bool)643*bb4ee6a4SAndroid Build Coastguard Worker     fn set_ready(&self, val: bool) {
644*bb4ee6a4SAndroid Build Coastguard Worker         *self.ready.lock() = val;
645*bb4ee6a4SAndroid Build Coastguard Worker     }
646*bb4ee6a4SAndroid Build Coastguard Worker }
647*bb4ee6a4SAndroid Build Coastguard Worker 
648*bb4ee6a4SAndroid Build Coastguard Worker impl Vcpu for FakeVcpu {
try_clone(&self) -> Result<Self>649*bb4ee6a4SAndroid Build Coastguard Worker     fn try_clone(&self) -> Result<Self> {
650*bb4ee6a4SAndroid Build Coastguard Worker         Ok(FakeVcpu {
651*bb4ee6a4SAndroid Build Coastguard Worker             id: self.id,
652*bb4ee6a4SAndroid Build Coastguard Worker             requested: self.requested.clone(),
653*bb4ee6a4SAndroid Build Coastguard Worker             ready: self.ready.clone(),
654*bb4ee6a4SAndroid Build Coastguard Worker             injected: self.injected.clone(),
655*bb4ee6a4SAndroid Build Coastguard Worker         })
656*bb4ee6a4SAndroid Build Coastguard Worker     }
657*bb4ee6a4SAndroid Build Coastguard Worker 
id(&self) -> usize658*bb4ee6a4SAndroid Build Coastguard Worker     fn id(&self) -> usize {
659*bb4ee6a4SAndroid Build Coastguard Worker         self.id
660*bb4ee6a4SAndroid Build Coastguard Worker     }
661*bb4ee6a4SAndroid Build Coastguard Worker 
as_vcpu(&self) -> &dyn Vcpu662*bb4ee6a4SAndroid Build Coastguard Worker     fn as_vcpu(&self) -> &dyn Vcpu {
663*bb4ee6a4SAndroid Build Coastguard Worker         self
664*bb4ee6a4SAndroid Build Coastguard Worker     }
665*bb4ee6a4SAndroid Build Coastguard Worker 
run(&mut self) -> Result<VcpuExit>666*bb4ee6a4SAndroid Build Coastguard Worker     fn run(&mut self) -> Result<VcpuExit> {
667*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
668*bb4ee6a4SAndroid Build Coastguard Worker     }
669*bb4ee6a4SAndroid Build Coastguard Worker 
set_immediate_exit(&self, _exit: bool)670*bb4ee6a4SAndroid Build Coastguard Worker     fn set_immediate_exit(&self, _exit: bool) {}
671*bb4ee6a4SAndroid Build Coastguard Worker 
672*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(any(target_os = "android", target_os = "linux"))]
signal_handle(&self) -> hypervisor::VcpuSignalHandle673*bb4ee6a4SAndroid Build Coastguard Worker     fn signal_handle(&self) -> hypervisor::VcpuSignalHandle {
674*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
675*bb4ee6a4SAndroid Build Coastguard Worker     }
676*bb4ee6a4SAndroid Build Coastguard Worker 
handle_mmio(&self, _handle_fn: &mut dyn FnMut(IoParams) -> Result<()>) -> Result<()>677*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_mmio(&self, _handle_fn: &mut dyn FnMut(IoParams) -> Result<()>) -> Result<()> {
678*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
679*bb4ee6a4SAndroid Build Coastguard Worker     }
handle_io(&self, _handle_fn: &mut dyn FnMut(IoParams)) -> Result<()>680*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_io(&self, _handle_fn: &mut dyn FnMut(IoParams)) -> Result<()> {
681*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
682*bb4ee6a4SAndroid Build Coastguard Worker     }
on_suspend(&self) -> Result<()>683*bb4ee6a4SAndroid Build Coastguard Worker     fn on_suspend(&self) -> Result<()> {
684*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
685*bb4ee6a4SAndroid Build Coastguard Worker     }
enable_raw_capability(&self, _cap: u32, _args: &[u64; 4]) -> Result<()>686*bb4ee6a4SAndroid Build Coastguard Worker     unsafe fn enable_raw_capability(&self, _cap: u32, _args: &[u64; 4]) -> Result<()> {
687*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
688*bb4ee6a4SAndroid Build Coastguard Worker     }
689*bb4ee6a4SAndroid Build Coastguard Worker }
690*bb4ee6a4SAndroid Build Coastguard Worker 
691*bb4ee6a4SAndroid Build Coastguard Worker impl VcpuX86_64 for FakeVcpu {
set_interrupt_window_requested(&self, requested: bool)692*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_window_requested(&self, requested: bool) {
693*bb4ee6a4SAndroid Build Coastguard Worker         *self.requested.lock() = requested;
694*bb4ee6a4SAndroid Build Coastguard Worker     }
695*bb4ee6a4SAndroid Build Coastguard Worker 
ready_for_interrupt(&self) -> bool696*bb4ee6a4SAndroid Build Coastguard Worker     fn ready_for_interrupt(&self) -> bool {
697*bb4ee6a4SAndroid Build Coastguard Worker         *self.ready.lock()
698*bb4ee6a4SAndroid Build Coastguard Worker     }
699*bb4ee6a4SAndroid Build Coastguard Worker 
interrupt(&self, irq: u8) -> Result<()>700*bb4ee6a4SAndroid Build Coastguard Worker     fn interrupt(&self, irq: u8) -> Result<()> {
701*bb4ee6a4SAndroid Build Coastguard Worker         *self.injected.lock() = Some(irq);
702*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
703*bb4ee6a4SAndroid Build Coastguard Worker     }
704*bb4ee6a4SAndroid Build Coastguard Worker 
inject_nmi(&self) -> Result<()>705*bb4ee6a4SAndroid Build Coastguard Worker     fn inject_nmi(&self) -> Result<()> {
706*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
707*bb4ee6a4SAndroid Build Coastguard Worker     }
708*bb4ee6a4SAndroid Build Coastguard Worker 
get_regs(&self) -> Result<Regs>709*bb4ee6a4SAndroid Build Coastguard Worker     fn get_regs(&self) -> Result<Regs> {
710*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
711*bb4ee6a4SAndroid Build Coastguard Worker     }
set_regs(&self, _regs: &Regs) -> Result<()>712*bb4ee6a4SAndroid Build Coastguard Worker     fn set_regs(&self, _regs: &Regs) -> Result<()> {
713*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
714*bb4ee6a4SAndroid Build Coastguard Worker     }
get_sregs(&self) -> Result<Sregs>715*bb4ee6a4SAndroid Build Coastguard Worker     fn get_sregs(&self) -> Result<Sregs> {
716*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
717*bb4ee6a4SAndroid Build Coastguard Worker     }
set_sregs(&self, _sregs: &Sregs) -> Result<()>718*bb4ee6a4SAndroid Build Coastguard Worker     fn set_sregs(&self, _sregs: &Sregs) -> Result<()> {
719*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
720*bb4ee6a4SAndroid Build Coastguard Worker     }
get_fpu(&self) -> Result<Fpu>721*bb4ee6a4SAndroid Build Coastguard Worker     fn get_fpu(&self) -> Result<Fpu> {
722*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
723*bb4ee6a4SAndroid Build Coastguard Worker     }
set_fpu(&self, _fpu: &Fpu) -> Result<()>724*bb4ee6a4SAndroid Build Coastguard Worker     fn set_fpu(&self, _fpu: &Fpu) -> Result<()> {
725*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
726*bb4ee6a4SAndroid Build Coastguard Worker     }
get_xsave(&self) -> Result<Xsave>727*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xsave(&self) -> Result<Xsave> {
728*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
729*bb4ee6a4SAndroid Build Coastguard Worker     }
set_xsave(&self, _xsave: &Xsave) -> Result<()>730*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xsave(&self, _xsave: &Xsave) -> Result<()> {
731*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
732*bb4ee6a4SAndroid Build Coastguard Worker     }
get_interrupt_state(&self) -> Result<serde_json::Value>733*bb4ee6a4SAndroid Build Coastguard Worker     fn get_interrupt_state(&self) -> Result<serde_json::Value> {
734*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
735*bb4ee6a4SAndroid Build Coastguard Worker     }
set_interrupt_state(&self, _data: serde_json::Value) -> Result<()>736*bb4ee6a4SAndroid Build Coastguard Worker     fn set_interrupt_state(&self, _data: serde_json::Value) -> Result<()> {
737*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
738*bb4ee6a4SAndroid Build Coastguard Worker     }
get_debugregs(&self) -> Result<DebugRegs>739*bb4ee6a4SAndroid Build Coastguard Worker     fn get_debugregs(&self) -> Result<DebugRegs> {
740*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
741*bb4ee6a4SAndroid Build Coastguard Worker     }
set_debugregs(&self, _debugregs: &DebugRegs) -> Result<()>742*bb4ee6a4SAndroid Build Coastguard Worker     fn set_debugregs(&self, _debugregs: &DebugRegs) -> Result<()> {
743*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
744*bb4ee6a4SAndroid Build Coastguard Worker     }
get_xcrs(&self) -> Result<BTreeMap<u32, u64>>745*bb4ee6a4SAndroid Build Coastguard Worker     fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>> {
746*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
747*bb4ee6a4SAndroid Build Coastguard Worker     }
set_xcr(&self, _xcr_index: u32, _value: u64) -> Result<()>748*bb4ee6a4SAndroid Build Coastguard Worker     fn set_xcr(&self, _xcr_index: u32, _value: u64) -> Result<()> {
749*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
750*bb4ee6a4SAndroid Build Coastguard Worker     }
get_msr(&self, _msr_index: u32) -> Result<u64>751*bb4ee6a4SAndroid Build Coastguard Worker     fn get_msr(&self, _msr_index: u32) -> Result<u64> {
752*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
753*bb4ee6a4SAndroid Build Coastguard Worker     }
get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>754*bb4ee6a4SAndroid Build Coastguard Worker     fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>> {
755*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
756*bb4ee6a4SAndroid Build Coastguard Worker     }
set_msr(&self, _msr_index: u32, _value: u64) -> Result<()>757*bb4ee6a4SAndroid Build Coastguard Worker     fn set_msr(&self, _msr_index: u32, _value: u64) -> Result<()> {
758*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
759*bb4ee6a4SAndroid Build Coastguard Worker     }
set_cpuid(&self, _cpuid: &CpuId) -> Result<()>760*bb4ee6a4SAndroid Build Coastguard Worker     fn set_cpuid(&self, _cpuid: &CpuId) -> Result<()> {
761*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
762*bb4ee6a4SAndroid Build Coastguard Worker     }
handle_cpuid(&mut self, _entry: &CpuIdEntry) -> Result<()>763*bb4ee6a4SAndroid Build Coastguard Worker     fn handle_cpuid(&mut self, _entry: &CpuIdEntry) -> Result<()> {
764*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
765*bb4ee6a4SAndroid Build Coastguard Worker     }
set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()>766*bb4ee6a4SAndroid Build Coastguard Worker     fn set_guest_debug(&self, _addrs: &[GuestAddress], _enable_singlestep: bool) -> Result<()> {
767*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
768*bb4ee6a4SAndroid Build Coastguard Worker     }
snapshot(&self) -> anyhow::Result<VcpuSnapshot>769*bb4ee6a4SAndroid Build Coastguard Worker     fn snapshot(&self) -> anyhow::Result<VcpuSnapshot> {
770*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
771*bb4ee6a4SAndroid Build Coastguard Worker     }
restore( &mut self, _snapshot: &VcpuSnapshot, _host_tsc_reference_moment: u64, ) -> anyhow::Result<()>772*bb4ee6a4SAndroid Build Coastguard Worker     fn restore(
773*bb4ee6a4SAndroid Build Coastguard Worker         &mut self,
774*bb4ee6a4SAndroid Build Coastguard Worker         _snapshot: &VcpuSnapshot,
775*bb4ee6a4SAndroid Build Coastguard Worker         _host_tsc_reference_moment: u64,
776*bb4ee6a4SAndroid Build Coastguard Worker     ) -> anyhow::Result<()> {
777*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
778*bb4ee6a4SAndroid Build Coastguard Worker     }
restore_timekeeping(&self, _host_tsc_reference_moment: u64, _tsc_offset: u64) -> Result<()>779*bb4ee6a4SAndroid Build Coastguard Worker     fn restore_timekeeping(&self, _host_tsc_reference_moment: u64, _tsc_offset: u64) -> Result<()> {
780*bb4ee6a4SAndroid Build Coastguard Worker         unimplemented!()
781*bb4ee6a4SAndroid Build Coastguard Worker     }
782*bb4ee6a4SAndroid Build Coastguard Worker }
783