userspace.rs 22 KB

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