diff options
-rw-r--r-- | examples/long_mode.rs | 12 | ||||
-rw-r--r-- | examples/real_mode.rs | 12 | ||||
-rw-r--r-- | guest/guest16.S | 15 | ||||
-rw-r--r-- | guest/guest64.S | 8 |
4 files changed, 43 insertions, 4 deletions
diff --git a/examples/long_mode.rs b/examples/long_mode.rs index 67c014a..668364f 100644 --- a/examples/long_mode.rs +++ b/examples/long_mode.rs @@ -126,7 +126,7 @@ fn setup_long_mode(sregs: &mut kvm_sys::kvm_sregs, mem: &mut UserMem) { fn main() -> std::io::Result<()> { // Create VM & VCPU. let vm = Kvm::new()?.create_vm()?; - let vcpu = vm.create_vpcu(0)?; + let mut vcpu = vm.create_vpcu(0)?; // Map memory for guest VM. let mut mem = UserMem::new(0x8000)?; @@ -155,10 +155,20 @@ fn main() -> std::io::Result<()> { while let Ok(exit) = vcpu.run() { match exit { KvmExit::Halt => break, + KvmExit::IoIn(port, data) => { + println!("IO_IN: port={} len={}", port, data.len()); + // Provide some input data. + data.fill(0xaa); + } KvmExit::IoOut(_port, data) => { let s = std::str::from_utf8(data).unwrap(); print!("{}", s); } + KvmExit::MmioRead(addr, data) => { + println!("MMIO_READ: addr={:#x} len={}", addr, data.len()); + // Provide some read data. + data.fill(0xbb); + } KvmExit::MmioWrite(addr, data) => { println!( "MMIO_WRITE: addr={:#x} len={} data={:#x?}", diff --git a/examples/real_mode.rs b/examples/real_mode.rs index 70f3e1d..f37d45c 100644 --- a/examples/real_mode.rs +++ b/examples/real_mode.rs @@ -5,7 +5,7 @@ use kvm_rs::{PhysAddr, UserMem}; fn main() -> std::io::Result<()> { // Create VM & VCPU. let vm = Kvm::new()?.create_vm()?; - let vcpu = vm.create_vpcu(0)?; + let mut vcpu = vm.create_vpcu(0)?; // Map memory for guest VM and initialize with guest image. let mem = UserMem::with_init(0x1000, include_bytes!("../guest/guest16"))?; @@ -29,10 +29,20 @@ fn main() -> std::io::Result<()> { while let Ok(exit) = vcpu.run() { match exit { KvmExit::Halt => break, + KvmExit::IoIn(port, data) => { + println!("IO_IN: port={} len={}", port, data.len()); + // Provide some input data. + data.fill(0xaa); + } KvmExit::IoOut(_port, data) => { let s = std::str::from_utf8(data).unwrap(); print!("{}", s); } + KvmExit::MmioRead(addr, data) => { + println!("MMIO_READ: addr={:#x} len={}", addr, data.len()); + // Provide some read data. + data.fill(0xbb); + } KvmExit::MmioWrite(addr, data) => { println!( "MMIO_WRITE: addr={:#x} len={} data={:#x?}", diff --git a/guest/guest16.S b/guest/guest16.S index 4851694..9877ea9 100644 --- a/guest/guest16.S +++ b/guest/guest16.S @@ -6,11 +6,19 @@ mov dx, 0x1000 // Output port. lea si, [msg] // Address of string. mov cx, [msg_len] // Len of string. - rep outsb // Write ds:si to output port dx. + rep outsb // Write byte from ds:si to output port dx. - // Trigger `KVM_EXIT_MMIO` by writing to non mapped physical address. + // Trigger `KVM_EXIT_IO:KVM_EXIT_IO_IN` by reading byte to memory from input port. + mov dx, 0x1000 // Input port. + lea di, [in_dest] // Destination address. + insb // Read byte from input port dx to ds:di. + + // Trigger `KVM_EXIT_MMIO (w)` by writing to non mapped physical address. mov byte ptr ds:[0x2000], 0xaa + // Trigger `KVM_EXIT_MMIO (r)` by reading from non mapped physical address. + mov al, byte ptr ds:[0x2000] + // Trigger `KVM_EXIT_HLT`. hlt @@ -19,3 +27,6 @@ msg: .asciz "Hello from Real Mode!\n" msg_len: .2byte .-msg + +in_dest: + .byte 0x00 diff --git a/guest/guest64.S b/guest/guest64.S index 1862749..6629273 100644 --- a/guest/guest64.S +++ b/guest/guest64.S @@ -7,6 +7,11 @@ mov rcx, [rip + msg_len] // Len of string. rep outsb // Write ds:rsi to output port rdx. + // Trigger `KVM_EXIT_IO:KVM_EXIT_IO_IN` by reading byte to memory from input port. + mov dx, 0x1000 // Input port. + lea di, [in_dest] // Destination address. + insb // Read byte from input port dx to ds:di. + // Trigger `KVM_EXIT_HLT`. hlt @@ -15,3 +20,6 @@ msg: .asciz "Hello from Long Mode!\n" msg_len: .byte .-msg + +in_dest: + .byte 0x00 |