()
| 3903 | |
| 3904 | #[test] |
| 3905 | pub fn test_vm() { |
| 3906 | use hypervisor::VmExit; |
| 3907 | use vm_memory::{Address, GuestMemory, GuestMemoryRegion}; |
| 3908 | // This example based on https://lwn.net/Articles/658511/ |
| 3909 | let code = [ |
| 3910 | 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */ |
| 3911 | 0x00, 0xd8, /* add %bl, %al */ |
| 3912 | 0x04, b'0', /* add $'0', %al */ |
| 3913 | 0xee, /* out %al, (%dx) */ |
| 3914 | 0xb0, b'\n', /* mov $'\n', %al */ |
| 3915 | 0xee, /* out %al, (%dx) */ |
| 3916 | 0xf4, /* hlt */ |
| 3917 | ]; |
| 3918 | |
| 3919 | let mem_size = 0x1000; |
| 3920 | let load_addr = GuestAddress(0x1000); |
| 3921 | let mem = GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap(); |
| 3922 | |
| 3923 | let hv = hypervisor::new().unwrap(); |
| 3924 | let vm = hv |
| 3925 | .create_vm(HypervisorVmConfig::default()) |
| 3926 | .expect("new VM creation failed"); |
| 3927 | |
| 3928 | for (index, region) in mem.iter().enumerate() { |
| 3929 | // SAFETY: inputs are valid |
| 3930 | unsafe { |
| 3931 | vm.create_user_memory_region( |
| 3932 | index as u32, |
| 3933 | region.start_addr().raw_value(), |
| 3934 | region.len().try_into().unwrap(), |
| 3935 | region.as_ptr(), |
| 3936 | false, |
| 3937 | false, |
| 3938 | ) |
| 3939 | .expect("Cannot configure guest memory"); |
| 3940 | } |
| 3941 | } |
| 3942 | mem.write_slice(&code, load_addr) |
| 3943 | .expect("Writing code to memory failed"); |
| 3944 | |
| 3945 | let mut vcpu = vm.create_vcpu(0, None).expect("new Vcpu failed"); |
| 3946 | |
| 3947 | let mut vcpu_sregs = vcpu.get_sregs().expect("get sregs failed"); |
| 3948 | vcpu_sregs.cs.base = 0; |
| 3949 | vcpu_sregs.cs.selector = 0; |
| 3950 | vcpu.set_sregs(&vcpu_sregs).expect("set sregs failed"); |
| 3951 | |
| 3952 | let mut vcpu_regs = vcpu.get_regs().expect("get regs failed"); |
| 3953 | vcpu_regs.set_rip(0x1000); |
| 3954 | vcpu_regs.set_rax(2); |
| 3955 | vcpu_regs.set_rbx(3); |
| 3956 | vcpu_regs.set_rflags(2); |
| 3957 | vcpu.set_regs(&vcpu_regs).expect("set regs failed"); |
| 3958 | |
| 3959 | loop { |
| 3960 | match vcpu.run().expect("run failed") { |
| 3961 | VmExit::Reset => { |
| 3962 | println!("HLT"); |
nothing calls this directly
no test coverage detected