From d2d2ba7c6602e73dc2e3dbd0aa4215e4c412a688 Mon Sep 17 00:00:00 2001 From: johannst Date: Wed, 2 Jun 2021 22:38:57 +0000 Subject: deploy: d2e2063cb2b5a82709e9c5188602a9fc0f7dadbd --- src/kvm_rs/vcpu.rs.html | 279 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 src/kvm_rs/vcpu.rs.html (limited to 'src/kvm_rs/vcpu.rs.html') diff --git a/src/kvm_rs/vcpu.rs.html b/src/kvm_rs/vcpu.rs.html new file mode 100644 index 0000000..df4a7bc --- /dev/null +++ b/src/kvm_rs/vcpu.rs.html @@ -0,0 +1,279 @@ +vcpu.rs - source + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+
+//! VCPU system ioctls.
+
+use std::fs;
+use std::io;
+
+use crate::{ioctl, kvm_sys, KvmRun};
+
+/// Exit reasons for the [`Vcpu::kvm_run`][crate::vcpu::Vcpu::kvm_run] function.
+///
+/// Details for the different exit reasons can be found in the [`kvm_run`
+/// structure][kvm-run-struct] description.
+///
+/// [kvm-run]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-run
+/// [kvm-run-struct]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#the-kvm-run-structure
+pub enum KvmExit<'cpu> {
+    Halt,
+    IoIn(u16, &'cpu mut [u8]),
+    IoOut(u16, &'cpu [u8]),
+    MmioRead(u64, &'cpu mut [u8]),
+    MmioWrite(u64, &'cpu [u8]),
+}
+
+/// Wrapper for VCPU ioctls.
+///
+/// Representation of the file descriptor obtained by the [`KVM_CREATE_VCPU`][kvm-create-vcpu] ioctl.
+/// This wrapper provides access to the `VCPU ioctls` as described in [KVM API][kvm].
+///
+/// [kvm]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#general-description
+/// [kvm-create-vcpu]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-create-vcpu
+pub struct Vcpu {
+    vcpu: fs::File,
+    kvm_run: KvmRun,
+}
+
+impl Vcpu {
+    pub(crate) fn new(vcpu: fs::File, kvm_run: KvmRun) -> Vcpu {
+        Vcpu { vcpu, kvm_run }
+    }
+
+    /// Get the general purpose registers with the [`KVM_GET_REGS`][kvm-get-regs] ioctl in form of
+    /// [`kvm_regs`](crate::kvm_sys::kvm_regs).
+    ///
+    /// [kvm-get-regs]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-get-regs
+    pub fn get_regs(&self) -> io::Result<kvm_sys::kvm_regs> {
+        let mut regs = kvm_sys::kvm_regs::default();
+        ioctl(
+            &self.vcpu,
+            kvm_sys::KVM_GET_REGS,
+            &mut regs as *mut _ as u64,
+        )?;
+        Ok(regs)
+    }
+
+    /// Set the general purpose registers with the [`KVM_SET_REGS`][kvm-set-regs] ioctl in form of
+    /// [`kvm_regs`](crate::kvm_sys::kvm_regs).
+    ///
+    /// [kvm-set-regs]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-set-regs
+    pub fn set_regs(&self, regs: kvm_sys::kvm_regs) -> io::Result<()> {
+        ioctl(&self.vcpu, kvm_sys::KVM_SET_REGS, &regs as *const _ as u64).map(|_| ())
+    }
+
+    /// Get the special registers with the [`KVM_GET_SREGS`][kvm-get-sregs] ioctl in form of
+    /// [`kvm_sregs`](crate::kvm_sys::kvm_sregs).
+    ///
+    /// [kvm-get-sregs]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-get-sregs
+    pub fn get_sregs(&self) -> io::Result<kvm_sys::kvm_sregs> {
+        let mut sregs = kvm_sys::kvm_sregs::default();
+        ioctl(
+            &self.vcpu,
+            kvm_sys::KVM_GET_SREGS,
+            &mut sregs as *mut _ as u64,
+        )?;
+        Ok(sregs)
+    }
+
+    /// Set the special registers with the [`KVM_SET_SREGS`][kvm-set-sregs] ioctl in form of
+    /// [`kvm_sregs`](crate::kvm_sys::kvm_sregs).
+    ///
+    /// [kvm-set-sregs]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-set-sregs
+    pub fn set_sregs(&self, sregs: kvm_sys::kvm_sregs) -> io::Result<()> {
+        ioctl(
+            &self.vcpu,
+            kvm_sys::KVM_SET_SREGS,
+            &sregs as *const _ as u64,
+        )
+        .map(|_| ())
+    }
+
+    /// Run the guest VCPU with the [`KVM_RUN`][kvm-run] ioctl until it exits with one of the exit
+    /// reasons described in [`KvmExit`](crate::vcpu::KvmExit).
+    ///
+    /// [kvm-run]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-run
+    pub fn run(&mut self) -> io::Result<KvmExit<'_>> {
+        ioctl(&self.vcpu, kvm_sys::KVM_RUN, 0)?;
+
+        let kvm_run = self.kvm_run.as_mut();
+
+        match kvm_run.exit_reason as u64 {
+            kvm_sys::KVM_EXIT_HLT => Ok(KvmExit::Halt),
+            kvm_sys::KVM_EXIT_IO => {
+                // Safe to use union `io` field, as Kernel instructed us to.
+                let io = unsafe { kvm_run.inner.io };
+
+                let kvm_run_ptr = kvm_run as *mut kvm_sys::kvm_run as *mut u8;
+
+                // Create IO buffer located at `kvm_run + io.offset`.
+                let data = unsafe {
+                    std::slice::from_raw_parts_mut(
+                        kvm_run_ptr.offset(io.data_offset as isize),
+                        io.count /* num blocks */ as usize * io.size /* bytes per block */ as usize,
+                    )
+                };
+
+                match io.direction as u64 {
+                    kvm_sys::KVM_EXIT_IO_IN => Ok(KvmExit::IoIn(io.port, data)),
+                    kvm_sys::KVM_EXIT_IO_OUT => Ok(KvmExit::IoOut(io.port, data)),
+                    _ => unreachable!(),
+                }
+            }
+            kvm_sys::KVM_EXIT_MMIO => {
+                // Safe to use union `mmio` filed, as Kernel instructed us to.
+                let mmio = unsafe { &mut kvm_run.inner.mmio };
+                let len = mmio.len as usize;
+
+                match mmio.is_write {
+                    0 => Ok(KvmExit::MmioRead(mmio.phys_addr, &mut mmio.data[..len])),
+                    1 => Ok(KvmExit::MmioWrite(mmio.phys_addr, &mmio.data[..len])),
+                    _ => unreachable!(),
+                }
+            }
+            r @ _ => {
+                todo!("KVM_EXIT_... (exit_reason={}) not implemented!", r)
+            }
+        }
+    }
+}
+
+
+ \ No newline at end of file -- cgit v1.2.3