Skip to content

Commit

Permalink
rework create vm
Browse files Browse the repository at this point in the history
  • Loading branch information
NunoDasNeves committed Jun 18, 2024
1 parent 5fcbb7f commit fc0e698
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 240 deletions.
270 changes: 32 additions & 238 deletions mshv-ioctls/src/ioctls/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,220 +19,6 @@ pub struct Mshv {
hv: File,
}

/// Builder for MSHV Partition
#[derive(Default)]
pub struct MshvPartitionBuilder {
mshv_partition: mshv_create_partition,
}

/// Synthetic processor features
#[derive(Debug)]
pub enum SyntheticProcessorFeature {
/// Report a hypervisor is present.
HypervisorPresent,
/// Report support for Hv1.
Hv1,
/// Access to HV_X64_MSR_TIME_REF_COUNT.Corresponds to access_partition_reference_counter privilege.
AccessPartitionReferenceCounter,
/// Access to SINT-related registers (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15). Corresponds to access_synic_regs privilege.
AccessSynicRegs,
/// Access to synthetic timers and associated MSRs (HV_X64_MSR_STIMER0_CONFIG through HV_X64_MSR_STIMER3_COUNT).Corresponds to access_synthetic_timer_regs privilege.
AccessSyntheticTimerRegs,
/// Access to Synthetic timers in direct mode
DirectSyntheticTimers,
/// Access to the reference TSC. Corresponds to access_partition_reference_tsc privilege.
AccessPartitionReferenceTsc,
/// Partition has access to frequency regs. corresponds to access_frequency_regs privilege.
AccessFrequencyRegs,
/// Access to APIC MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) as well as the VP assist page. Corresponds to access_intr_ctrl_regs privilege.
AccessIntrCtrlRegs,
/// VP index can be queried. corresponds to access_vp_index privilege.
AccessVpIndex,
/// Access to registers associated with hypercalls (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL).Corresponds to access_hypercall_msrs privilege.
AccessHypercallRegs,
/// Partition has access to the guest idle reg. Corresponds to access_guest_idle_reg privilege.
AccessGuestIdleReg,
/// HvCallFlushVirtualAddressSpace / HvCallFlushVirtualAddressList are supported.
TbFlushHypercalls,
/// HvCallSendSyntheticClusterIpi is supported.
SyntheticClusterIpi,
}

impl MshvPartitionBuilder {
/// Creates a new MshvPartitionBuilder
pub fn new() -> MshvPartitionBuilder {
MshvPartitionBuilder {
mshv_partition: mshv_create_partition {
partition_creation_properties: hv_partition_creation_properties {
disabled_processor_features: hv_partition_processor_features {
#[cfg(target_arch = "x86_64")]
as_uint64: [0; 2],
#[cfg(target_arch = "aarch64")]
as_uint64: [0; 1],
},
#[cfg(target_arch = "x86_64")]
disabled_processor_xsave_features: hv_partition_processor_xsave_features {
as_uint64: 0_u64,
},
},
synthetic_processor_features: hv_partition_synthetic_processor_features {
as_uint64: [0; 1],
},
isolation_properties: hv_partition_isolation_properties { as_uint64: 0_u64 },
flags: 0_u64,
},
}
}

/// Updates partition flags
pub fn set_partition_creation_flag(mut self, flag: u64) -> MshvPartitionBuilder {
self.mshv_partition.flags |= flag;
self
}

/// Set isolation type
pub fn set_isolation_type(mut self, val: u64) -> MshvPartitionBuilder {
// SAFETY: Setting a bunch of bitfields. Functions and unions are generated by bindgen
// so we have to use unsafe here. We trust bindgen to generate the correct accessors.
unsafe {
self.mshv_partition
.isolation_properties
.__bindgen_anon_1
.set_isolation_type(val);
}
self
}

/// Set shared GPA boundary page number
pub fn set_shared_gpa_boundary_page_number(mut self, val: u64) -> MshvPartitionBuilder {
// SAFETY: Setting a bunch of bitfields. Functions and unions are generated by bindgen
// so we have to use unsafe here. We trust bindgen to generate the correct accessors.
unsafe {
self.mshv_partition
.isolation_properties
.__bindgen_anon_1
.set_shared_gpa_boundary_page_number(val);
}
self
}

/// Sets a synthetic_processor_feature for the partition
pub fn set_synthetic_processor_feature(
mut self,
feature: SyntheticProcessorFeature,
) -> MshvPartitionBuilder {
// SAFETY: Setting a bunch of bitfields. Functions and unions are generated by bindgen
// so we have to use unsafe here. We trust bindgen to generate the correct accessors.
match feature {
SyntheticProcessorFeature::HypervisorPresent => {
#[cfg(target_arch = "x86_64")]
unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_hypervisor_present(1);
}
}
SyntheticProcessorFeature::Hv1 => {
#[cfg(target_arch = "x86_64")]
unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_hv1(1);
}
}
SyntheticProcessorFeature::AccessPartitionReferenceCounter => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_partition_reference_counter(1);
},
SyntheticProcessorFeature::AccessSynicRegs => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_synic_regs(1);
},
SyntheticProcessorFeature::AccessSyntheticTimerRegs => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_synthetic_timer_regs(1);
},
SyntheticProcessorFeature::DirectSyntheticTimers => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_direct_synthetic_timers(1);
},
SyntheticProcessorFeature::AccessPartitionReferenceTsc => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_partition_reference_tsc(1);
},
SyntheticProcessorFeature::AccessFrequencyRegs => unsafe {
/* Need this for linux on CH, as there's no PIT or HPET */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_frequency_regs(1);
},
SyntheticProcessorFeature::AccessIntrCtrlRegs => unsafe {
/* Linux I'm using appears to require vp assist page... */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_intr_ctrl_regs(1);
},
SyntheticProcessorFeature::AccessVpIndex => unsafe {
/* According to Hv#1 spec, these must be set also, but they aren't in KVM? */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_vp_index(1);
},
SyntheticProcessorFeature::AccessHypercallRegs => unsafe {
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_hypercall_regs(1);
},
SyntheticProcessorFeature::AccessGuestIdleReg => {
#[cfg(target_arch = "x86_64")]
unsafe {
/* Windows requires this */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_access_guest_idle_reg(1);
}
}
SyntheticProcessorFeature::TbFlushHypercalls => unsafe {
/* Enable TLB flush hypercalls */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_tb_flush_hypercalls(1);
},
SyntheticProcessorFeature::SyntheticClusterIpi => unsafe {
/* Enable synthetic cluster ipi */
self.mshv_partition
.synthetic_processor_features
.__bindgen_anon_1
.set_synthetic_cluster_ipi(1);
},
}
self
}

/// Builds the partition
pub fn build(&self) -> mshv_create_partition {
self.mshv_partition
}
}

impl Mshv {
/// Opens `/dev/mshv` and returns a `Mshv` object on success.
#[allow(clippy::new_ret_no_self)]
Expand Down Expand Up @@ -288,34 +74,42 @@ impl Mshv {

/// Helper function to creates a VM fd using the MSHV fd with provided configuration.
pub fn create_vm_with_type(&self, vm_type: VmType) -> Result<VmFd> {
let mut mshv_builder = MshvPartitionBuilder::new()
.set_partition_creation_flag(HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED as u64)
.set_partition_creation_flag(HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE as u64)
.set_synthetic_processor_feature(SyntheticProcessorFeature::HypervisorPresent)
.set_synthetic_processor_feature(SyntheticProcessorFeature::Hv1)
.set_synthetic_processor_feature(
SyntheticProcessorFeature::AccessPartitionReferenceCounter,
)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessSynicRegs)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessSyntheticTimerRegs)
.set_synthetic_processor_feature(SyntheticProcessorFeature::DirectSyntheticTimers)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessPartitionReferenceTsc)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessFrequencyRegs)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessIntrCtrlRegs)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessVpIndex)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessHypercallRegs)
.set_synthetic_processor_feature(SyntheticProcessorFeature::AccessGuestIdleReg)
.set_synthetic_processor_feature(SyntheticProcessorFeature::TbFlushHypercalls)
.set_synthetic_processor_feature(SyntheticProcessorFeature::SyntheticClusterIpi);
let mut features: hv_partition_synthetic_processor_features = Default::default();
unsafe {
let feature_bits = &mut features.__bindgen_anon_1;
feature_bits.set_hypervisor_present(1);
feature_bits.set_hv1(1);
feature_bits.set_access_partition_reference_counter(1);
feature_bits.set_access_synic_regs(1);
feature_bits.set_direct_synthetic_timers(1);
feature_bits.set_access_partition_reference_tsc(1);
feature_bits.set_access_frequency_regs(1);
feature_bits.set_access_intr_ctrl_regs(1);
feature_bits.set_access_vp_index(1);
feature_bits.set_access_hypercall_regs(1);
feature_bits.set_access_guest_idle_reg(1);
feature_bits.set_tb_flush_hypercalls(1);
feature_bits.set_synthetic_cluster_ipi(1);
}
let pt_flags: u64 = set_bits!(u64, MSHV_PT_BIT_LAPIC, MSHV_PT_BIT_X2APIC, MSHV_PT_BIT_GPA_SUPER_PAGES);
let mut pt_isolation: u64 = MSHV_PT_ISOLATION_NONE as u64;

if vm_type == VmType::Snp {
mshv_builder = mshv_builder
.set_isolation_type(HV_PARTITION_ISOLATION_TYPE_SNP as u64)
.set_shared_gpa_boundary_page_number(0_u64);
pt_isolation = MSHV_PT_ISOLATION_SNP as u64;
}

let partition_config = mshv_builder.build();
self.create_vm_with_config(&partition_config)
let partition_config = mshv_create_partition{
pt_flags,
pt_isolation,
..Default::default()
};
let vm = self.create_vm_with_config(&partition_config)?;
vm.hvcall_set_partition_property(
hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES,
unsafe{ features.as_uint64[0] })?;
vm.initialize()?;

Ok(vm)
}

/// Creates a VM fd using the MSHV fd.
Expand Down
2 changes: 0 additions & 2 deletions mshv-ioctls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,6 @@
mod ioctls;
pub use ioctls::device::DeviceFd;
pub use ioctls::system::Mshv;
pub use ioctls::system::MshvPartitionBuilder;
pub use ioctls::system::SyntheticProcessorFeature;
pub use ioctls::vcpu::VcpuFd;
pub use ioctls::vm::InterruptRequest;
pub use ioctls::vm::IoEventAddress;
Expand Down

0 comments on commit fc0e698

Please sign in to comment.