Skip to content

Commit 269219e

Browse files
committed
Use bitflags for flag fields
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
1 parent 7051671 commit 269219e

6 files changed

Lines changed: 85 additions & 71 deletions

File tree

hv/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ license-file = "../LICENSE"
99
readme = "../README.md"
1010

1111
[dependencies]
12+
bitflags = "1.2"
13+
1214
hv-sys = { path = "../hv-sys", version = "0.1.0" }
1315

1416
[features]

hv/examples/caps.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
fn main() {
2-
hv::vm_create().unwrap();
2+
hv::vm_create(hv::VmOptions::default()).unwrap();
33

44
println!(
55
"Max vCPUs: {}",
6-
hv::capability(hv::Capability::VCpuMax).unwrap()
6+
hv::capability(hv::Capability::VCPU_MAX).unwrap()
77
);
88

99
println!(
1010
"Available address spaces: {}",
11-
hv::capability(hv::Capability::AddrSpaceMax).unwrap()
11+
hv::capability(hv::Capability::ADDR_SPAC_EMAX).unwrap()
1212
);
1313

1414
hv::vm_destroy().unwrap();

hv/src/lib.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@ macro_rules! call {
2424
}};
2525
}
2626

27-
/// The type of system capabilities.
28-
#[repr(u32)]
29-
#[non_exhaustive]
30-
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
31-
pub enum Capability {
32-
VCpuMax = sys::HV_CAP_VCPUMAX,
33-
AddrSpaceMax = sys::HV_CAP_ADDRSPACEMAX,
27+
bitflags::bitflags! {
28+
/// The type of system capabilities.
29+
pub struct Capability: u32 {
30+
const VCPU_MAX = sys::HV_CAP_VCPUMAX;
31+
const ADDR_SPAC_EMAX = sys::HV_CAP_ADDRSPACEMAX;
32+
}
3433
}
3534

3635
/// Type of a user virtual address.
@@ -44,25 +43,42 @@ pub type Space = sys::hv_vm_space_t;
4443

4544
pub const VM_SPACE_DEFAULT: Space = sys::HV_VM_SPACE_DEFAULT;
4645

47-
/// Guest physical memory region permissions.
48-
#[repr(u32)]
49-
#[non_exhaustive]
50-
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
51-
pub enum Memory {
52-
Read = sys::HV_MEMORY_READ,
53-
Write = sys::HV_MEMORY_WRITE,
54-
Exec = sys::HV_MEMORY_EXEC,
46+
bitflags::bitflags! {
47+
/// Guest physical memory region permissions.
48+
pub struct Memory: u32 {
49+
const READ = sys::HV_MEMORY_READ;
50+
const WRITE = sys::HV_MEMORY_WRITE;
51+
const EXEC = sys::HV_MEMORY_EXEC;
52+
}
53+
}
54+
55+
bitflags::bitflags! {
56+
pub struct VmOptions: u64 {
57+
const DEFAULT = sys::HV_VM_DEFAULT as _;
58+
const SPECIFY_MITIGATIONS = sys::HV_VM_SPECIFY_MITIGATIONS as _;
59+
const MITIGATION_A_ENABLE = sys::HV_VM_MITIGATION_A_ENABLE as _;
60+
const MITIGATION_B_ENABLE = sys::HV_VM_MITIGATION_B_ENABLE as _;
61+
const MITIGATION_C_ENABLE = sys::HV_VM_MITIGATION_C_ENABLE as _;
62+
const MITIGATION_D_ENABLE = sys::HV_VM_MITIGATION_D_ENABLE as _;
63+
const MITIGATION_E_ENABLE = sys::HV_VM_MITIGATION_E_ENABLE as _;
64+
}
65+
}
66+
67+
impl Default for VmOptions {
68+
fn default() -> Self {
69+
VmOptions::DEFAULT
70+
}
5571
}
5672

5773
/// Creates a VM instance for the current process.
58-
pub fn vm_create() -> Result<(), Error> {
59-
call!(sys::hv_vm_create(0))
74+
pub fn vm_create(options: VmOptions) -> Result<(), Error> {
75+
call!(sys::hv_vm_create(options.bits))
6076
}
6177

6278
/// Gets the value of capabilities of the system.
6379
pub fn capability(cap: Capability) -> Result<u64, Error> {
6480
let mut out = 0_u64;
65-
call!(sys::hv_capability(cap as sys::hv_capability_t, &mut out))?;
81+
call!(sys::hv_capability(cap.bits as u64, &mut out))?;
6682
Ok(out)
6783
}
6884

@@ -92,12 +108,7 @@ pub fn vm_space_destroy(asid: Space) -> Result<(), Error> {
92108
/// * `size` - Size in bytes of the region to be mapped.
93109
/// * `flags` - READ, WRITE and EXECUTE permissions of the region
94110
pub fn vm_map(uva: UVAddr, gpa: GPAddr, size: u64, flags: Memory) -> Result<(), Error> {
95-
call!(sys::hv_vm_map(
96-
uva,
97-
gpa,
98-
size,
99-
flags as sys::hv_memory_flags_t
100-
))
111+
call!(sys::hv_vm_map(uva, gpa, size, flags.bits.into()))
101112
}
102113

103114
/// Unmaps a region in the guest physical address space of the VM
@@ -116,11 +127,7 @@ pub fn vm_unmap(gpa: GPAddr, size: u64) -> Result<(), Error> {
116127
/// * `size` - Size in bytes of the region to be modified.
117128
/// * `flags` - New READ, WRITE and EXECUTE permissions of the region.
118129
pub fn vm_protect(gpa: GPAddr, size: u64, flags: Memory) -> Result<(), Error> {
119-
call!(sys::hv_vm_protect(
120-
gpa,
121-
size,
122-
flags as sys::hv_memory_flags_t
123-
))
130+
call!(sys::hv_vm_protect(gpa, size, flags.bits.into()))
124131
}
125132

126133
/// Maps a region in the virtual address space of the current task
@@ -145,7 +152,7 @@ pub fn vm_map_space(
145152
uva,
146153
gpa,
147154
size,
148-
flags as sys::hv_memory_flags_t
155+
flags.bits.into()
149156
))
150157
}
151158

@@ -169,12 +176,7 @@ pub fn vm_unmap_space(asid: Space, gpa: GPAddr, size: u64) -> Result<(), Error>
169176
/// * `flags` - New READ, WRITE and EXECUTE permissions of the region.
170177
#[cfg(feature = "hv_10_15")]
171178
pub fn vm_protect_space(asid: Space, gpa: GPAddr, size: u64, flags: Memory) -> Result<(), Error> {
172-
call!(sys::hv_vm_protect_space(
173-
asid,
174-
gpa,
175-
size,
176-
flags as sys::hv_memory_flags_t
177-
))
179+
call!(sys::hv_vm_protect_space(asid, gpa, size, flags.bits.into()))
178180
}
179181

180182
/// Synchronizes guest TSC across all vCPUs.

hv/src/vcpu.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ffi::c_void;
22
use std::mem;
33

4-
use crate::{call, sys, vmx, x86, Error, Space};
4+
use crate::{call, sys, Error, Space};
55

66
/// Represents a single virtual CPU.
77
///
@@ -81,7 +81,9 @@ impl Drop for Vcpu {
8181
}
8282
}
8383

84-
impl x86::VcpuExt for Vcpu {
84+
use crate::x86;
85+
86+
impl x86::VCpuX86Ext for Vcpu {
8587
/// Returns the current value of an architectural x86 register of a vCPU.
8688
fn read_register(&self, reg: x86::Reg) -> Result<u64, Error> {
8789
let mut value = 0_u64;
@@ -122,40 +124,50 @@ impl x86::VcpuExt for Vcpu {
122124
}
123125
}
124126

125-
impl vmx::VcpuExt for Vcpu {
127+
use crate::vmx;
128+
129+
impl vmx::VCpuVmxExt for Vcpu {
126130
/// Returns the current value of a VMCS field of a vCPU.
127-
fn read_vmcs(&self, field: u32) -> Result<u64, Error> {
131+
fn read_vmcs(&self, field: vmx::Vmcs) -> Result<u64, Error> {
128132
let mut out = 0_u64;
129-
call!(sys::hv_vmx_vcpu_read_vmcs(self.0, field, &mut out))?;
133+
call!(sys::hv_vmx_vcpu_read_vmcs(self.0, field as u32, &mut out))?;
130134
Ok(out)
131135
}
132136

133137
/// Set the value of a VMCS field of a vCPU.
134-
fn write_vmcs(&self, field: u32, value: u64) -> Result<(), Error> {
135-
call!(sys::hv_vmx_vcpu_write_vmcs(self.0, field, value))
138+
fn write_vmcs(&self, field: vmx::Vmcs, value: u64) -> Result<(), Error> {
139+
call!(sys::hv_vmx_vcpu_write_vmcs(self.0, field as u32, value))
136140
}
137141

138142
/// Returns the current value of a shadow VMCS field of a vCPU.
139143
#[cfg(feature = "hv_10_15")]
140-
fn read_shadow_vmcs(&self, field: u32) -> Result<u64, Error> {
144+
fn read_shadow_vmcs(&self, field: vmx::Vmcs) -> Result<u64, Error> {
141145
let mut out = 0_u64;
142-
call!(sys::hv_vmx_vcpu_read_shadow_vmcs(self.0, field, &mut out))?;
146+
call!(sys::hv_vmx_vcpu_read_shadow_vmcs(
147+
self.0,
148+
field as u32,
149+
&mut out
150+
))?;
143151
Ok(out)
144152
}
145153

146154
/// Set the value of a shadow VMCS field of a vCPU.
147155
#[cfg(feature = "hv_10_15")]
148-
fn write_shadow_vmcs(&self, field: u32, value: u64) -> Result<(), Error> {
149-
call!(sys::hv_vmx_vcpu_write_shadow_vmcs(self.0, field, value))
156+
fn write_shadow_vmcs(&self, field: vmx::Vmcs, value: u64) -> Result<(), Error> {
157+
call!(sys::hv_vmx_vcpu_write_shadow_vmcs(
158+
self.0,
159+
field as u32,
160+
value
161+
))
150162
}
151163

152164
/// Set the access permissions of a shadow VMCS field of a vCPU.
153165
#[cfg(feature = "hv_10_15")]
154-
fn set_shadow_access(&self, field: u32, flags: crate::vmx::ShadowFlags) -> Result<(), Error> {
166+
fn set_shadow_access(&self, field: vmx::Vmcs, flags: vmx::ShadowFlags) -> Result<(), Error> {
155167
call!(sys::hv_vmx_vcpu_set_shadow_access(
156168
self.0,
157-
field,
158-
flags as sys::hv_shadow_flags_t
169+
field as u32,
170+
flags.bits() as u64
159171
))
160172
}
161173
}

hv/src/vmx.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
33
use crate::{call, sys, Error};
44

5-
pub type Capacility = sys::hv_vmx_capability_t;
6-
75
/// Enum type of VMX cabability fields
86
#[repr(u32)]
97
#[non_exhaustive]
@@ -24,39 +22,39 @@ pub enum Capability {
2422
}
2523

2624
/// Returns the VMX capabilities of the host processor.
27-
pub fn read_capability(field: Capacility) -> Result<u64, Error> {
25+
pub fn read_capability(field: Capability) -> Result<u64, Error> {
2826
let mut out = 0_u64;
29-
call!(sys::hv_vmx_read_capability(field, &mut out))?;
27+
call!(sys::hv_vmx_read_capability(field as u32, &mut out))?;
3028
Ok(out)
3129
}
3230

33-
#[cfg(feature = "hv_10_15")]
34-
#[repr(u32)]
35-
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
36-
pub enum ShadowFlags {
37-
None = sys::HV_SHADOW_VMCS_NONE,
38-
Read = sys::HV_SHADOW_VMCS_READ,
39-
Write = sys::HV_SHADOW_VMCS_WRITE,
31+
bitflags::bitflags! {
32+
#[cfg(feature = "hv_10_15")]
33+
pub struct ShadowFlags: u32 {
34+
const NONE = sys::HV_SHADOW_VMCS_NONE;
35+
const READ = sys::HV_SHADOW_VMCS_READ;
36+
const WRITE = sys::HV_SHADOW_VMCS_WRITE;
37+
}
4038
}
4139

42-
pub trait VcpuExt {
40+
pub trait VCpuVmxExt {
4341
/// Returns the current value of a VMCS field of a vCPU.
44-
fn read_vmcs(&self, field: u32) -> Result<u64, Error>;
42+
fn read_vmcs(&self, field: Vmcs) -> Result<u64, Error>;
4543

4644
/// Set the value of a VMCS field of a vCPU.
47-
fn write_vmcs(&self, field: u32, value: u64) -> Result<(), Error>;
45+
fn write_vmcs(&self, field: Vmcs, value: u64) -> Result<(), Error>;
4846

4947
/// Returns the current value of a shadow VMCS field of a vCPU.
5048
#[cfg(feature = "hv_10_15")]
51-
fn read_shadow_vmcs(&self, field: u32) -> Result<u64, Error>;
49+
fn read_shadow_vmcs(&self, field: Vmcs) -> Result<u64, Error>;
5250

5351
/// Set the value of a shadow VMCS field of a vCPU.
5452
#[cfg(feature = "hv_10_15")]
55-
fn write_shadow_vmcs(&self, field: u32, value: u64) -> Result<(), Error>;
53+
fn write_shadow_vmcs(&self, field: Vmcs, value: u64) -> Result<(), Error>;
5654

5755
/// Set the access permissions of a shadow VMCS field of a vCPU.
5856
#[cfg(feature = "hv_10_15")]
59-
fn set_shadow_access(&self, field: u32, flags: ShadowFlags) -> Result<(), Error>;
57+
fn set_shadow_access(&self, field: Vmcs, flags: ShadowFlags) -> Result<(), Error>;
6058
}
6159

6260
/// Virtual Machine Control Structure (VMCS) Field IDs.

hv/src/x86.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{sys, Error};
44

55
/// x86 specific routines for vCPU.
6-
pub trait VcpuExt {
6+
pub trait VCpuX86Ext {
77
/// Returns the current value of an architectural x86 register of a vCPU.
88
fn read_register(&self, reg: Reg) -> Result<u64, Error>;
99

0 commit comments

Comments
 (0)