Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zerocopy: move repo to zerocopy 0.8 #735

Merged
merged 19 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
287 changes: 143 additions & 144 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ unix_socket = { path = "support/unix_socket" }
vmsocket = { path = "support/vmsocket" }
win_import_lib = { path = "support/win_import_lib" }
win_prng_support = { path = "support/win_prng_support" }
zerocopy_helpers = { path = "support/zerocopy_helpers" }

azure_profiler_proto = { path = "openhcl/azure_profiler_proto" }
bootloader_fdt_parser = { path = "openhcl/bootloader_fdt_parser" }
Expand Down Expand Up @@ -437,10 +436,8 @@ iced-x86 = { version = "1.17", default-features = false, features = [
"no_d3now",
] }
ignore = "0.4"
igvm = "0.3.3"
mattkur marked this conversation as resolved.
Show resolved Hide resolved
igvm_defs = { version = "0.3.3", default-features = false, features = [
"unstable",
] }
igvm = {git = "https://github.com/microsoft/igvm", rev = "365065d7e31da0a0116e7934de3ecd85f00bab70"}
igvm_defs = {git = "https://github.com/microsoft/igvm", rev = "365065d7e31da0a0116e7934de3ecd85f00bab70", default-features = false, features = [ "unstable" ]}
image = { version = "0.24", default-features = false }
io-uring = "0.6"
kvm-bindings = "0.7"
Expand Down Expand Up @@ -523,7 +520,8 @@ windows-sys = "0.52"
xshell = "=0.2.2" # pin to 0.2.2 to work around https://github.com/matklad/xshell/issues/63
xshell-macros = "0.2"
# We add the derive feature here since the vast majority of our crates use it.
zerocopy = { version = "0.7.32", features = ["derive"] }
#zerocopy = { version = "0.7.32", features = ["derive"]}
zerocopy = { version = "0.8.14", features = ["derive"]}

[workspace.metadata.xtask.unused-deps]
# Pulled in through "tracing", but we need to pin the version
Expand Down
14 changes: 8 additions & 6 deletions Guide/src/dev_guide/contrib/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,18 @@ intrinsic (such as CPUID, or a SIMD instruction), or when implementing a

...otherwise, use `cfg(guest_arch = ...)`!

## Avoid `Default` when using `zerocopy::FromZeroes`
## Avoid `Default` when using `zerocopy::FromZeros`

_Checked Automatically:_ **No**

The rule:

- A type can `derive(Default)` **XOR** `derive(FromZeroes)`.
- A type that is `FromZeroes` can also `impl Default`, but it must be a
- A type can `derive(Default)` **XOR** `derive(FromZeros)`.
- A type that is `FromZeros` can also `impl Default`, but it must be a
conscious, explicit choice, with justification (read: inline comment) as to
why that particular default value was chosen.
- N.B. `derive(IntoBytes)` or `derive(FromBytes)` imply `derive(FromZeros)`. That is:
this convention applies to those types as well.

The why:

Expand Down Expand Up @@ -349,15 +351,15 @@ init a "uninitialized" struct in-memory is quite handy...
In OpenVMM, we don't do this. Instead, we use a separate trait to init all-zero
structs.

**In OpenVMM, we use `FromZeroes` and `FromZeroes::new_zeroed()` to work with types
**In OpenVMM, we use `FromZeros` and `FromZeros::new_zeroed()` to work with types
that have valid all-zero representations, _without_ implying that those types
also have valid all-zero _default_ values!**

So, for the example above:

```rust
#[repr(C)]
#[derive(zerocopy::FromZeroes)]
#[derive(zerocopy::FromZeros)]
struct Handle {
opaque_handle: u16
}
Expand All @@ -373,7 +375,7 @@ Now, it's impossible for code elsewhere to obtain a `Handle` via
do so by _manually_ implementing `derive(Default)` ourselves:

```rust
// Default + FromZeroes: `default` returns fully initialized handle
// Default + FromZeros: `default` returns fully initialized handle
impl Default for Handle {
fn default() -> Handle {
let mut handle = Handle::new_zeroed();
Expand Down
1 change: 0 additions & 1 deletion openhcl/hcl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ thiserror.workspace = true
tracelimit.workspace = true
tracing.workspace = true
zerocopy.workspace = true

fs-err.workspace = true
libc.workspace = true
nix = { workspace = true, features = ["ioctl"] }
Expand Down
30 changes: 16 additions & 14 deletions openhcl/hcl/src/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ use std::sync::Once;
use thiserror::Error;
use x86defs::snp::SevVmsa;
use x86defs::tdx::TdCallResultCode;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use zerocopy::Immutable;
use zerocopy::IntoBytes;
use zerocopy::KnownLayout;

/// Error returned by HCL operations.
#[derive(Error, Debug)]
Expand Down Expand Up @@ -1105,8 +1107,8 @@ impl MshvHvcall {
output: &mut O,
) -> Result<HypercallOutput, HvcallError>
where
I: AsBytes + Sized,
O: AsBytes + FromBytes + Sized,
I: IntoBytes + Sized + Immutable + KnownLayout,
O: IntoBytes + FromBytes + Sized + Immutable + KnownLayout,
{
const fn assert_size<I, O>()
where
Expand All @@ -1124,7 +1126,7 @@ impl MshvHvcall {
control,
input_data: input.as_bytes().as_ptr().cast(),
input_size: size_of::<I>(),
status: FromZeroes::new_zeroed(),
status: FromZeros::new_zeroed(),
output_data: output.as_bytes().as_ptr().cast(),
output_size: size_of::<O>(),
};
Expand Down Expand Up @@ -1173,9 +1175,9 @@ impl MshvHvcall {
output_rep: Option<&mut [O]>,
) -> Result<HypercallOutput, HvcallError>
where
InputHeader: AsBytes + Sized,
InputRep: AsBytes + Sized,
O: AsBytes + FromBytes + Sized,
InputHeader: IntoBytes + Sized + Immutable + KnownLayout,
InputRep: IntoBytes + Sized + Immutable + KnownLayout,
O: IntoBytes + FromBytes + Sized + Immutable + KnownLayout,
{
// Construct input buffer.
let (input, count) = match input_rep {
Expand Down Expand Up @@ -1252,8 +1254,8 @@ impl MshvHvcall {
output: &mut O,
) -> Result<HypercallOutput, HvcallError>
where
I: AsBytes + Sized,
O: AsBytes + FromBytes + Sized,
I: IntoBytes + Sized + Immutable + KnownLayout,
O: IntoBytes + FromBytes + Sized + Immutable + KnownLayout,
{
const fn assert_size<I, O>()
where
Expand All @@ -1279,7 +1281,7 @@ impl MshvHvcall {
control,
input_data: input.as_bytes().as_ptr().cast(),
input_size: input.len(),
status: FromZeroes::new_zeroed(),
status: FromZeros::new_zeroed(),
output_data: output.as_bytes().as_ptr().cast(),
output_size: size_of::<O>(),
};
Expand Down Expand Up @@ -1992,7 +1994,7 @@ impl<T: Backing> ProcessorRunner<'_, T> {
assoc.push(HvRegisterAssoc {
name: name.into(),
pad: Default::default(),
value: FromZeroes::new_zeroed(),
value: FromZeros::new_zeroed(),
});
offset.push(i);
}
Expand Down Expand Up @@ -2622,7 +2624,7 @@ impl Hcl {
gva_page: gva >> hvdef::HV_PAGE_SHIFT,
};

let mut output: hypercall::TranslateVirtualAddressExOutputArm64 = FromZeroes::new_zeroed();
let mut output: hypercall::TranslateVirtualAddressExOutputArm64 = FromZeros::new_zeroed();

// SAFETY: The input header and slice are the correct types for this hypercall.
// The hypercall output is validated right after the hypercall is issued.
Expand Down Expand Up @@ -3097,7 +3099,7 @@ impl Hcl {
reserved_z0: 0,
};

let mut output: hvdef::hypercall::MemoryMappedIoReadOutput = FromZeroes::new_zeroed();
let mut output: hvdef::hypercall::MemoryMappedIoReadOutput = FromZeros::new_zeroed();

// SAFETY: The input header and slice are the correct types for this hypercall.
// The hypercall output is validated right after the hypercall is issued.
Expand Down
2 changes: 1 addition & 1 deletion openhcl/hcl/src/ioctl/deferred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::protocol;
use crate::protocol::hcl_run;
use std::ptr::addr_of_mut;
use std::ptr::NonNull;
use zerocopy::AsBytes;
use zerocopy::IntoBytes;

#[derive(Debug, Default)]
pub struct DeferredActions {
Expand Down
5 changes: 2 additions & 3 deletions openhcl/hcl/src/ioctl/x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use hvdef::HV_PARTITION_ID_SELF;
use hvdef::HV_VP_INDEX_SELF;
use sidecar_client::SidecarVp;
use std::ptr::NonNull;
use zerocopy::FromZeroes;
use zerocopy::FromZeros;

/// Result when the translate gva hypercall returns a code indicating
/// the translation was unsuccessful.
Expand Down Expand Up @@ -132,8 +132,7 @@ impl ProcessorRunner<'_, MshvX64> {
gva_page: gvn,
};

let mut output: hypercall::TranslateVirtualAddressExOutputX64 =
FromZeroes::new_zeroed();
let mut output: hypercall::TranslateVirtualAddressExOutputX64 = FromZeros::new_zeroed();

// SAFETY: The input header and slice are the correct types for this hypercall.
// The hypercall output is validated right after the hypercall is issued.
Expand Down
21 changes: 11 additions & 10 deletions openhcl/hcl/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ use bitfield_struct::bitfield;
use hvdef::hypercall::HvInputVtl;
use hvdef::HV_MESSAGE_SIZE;
use libc::c_void;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
use zerocopy::FromZeroes;
use zerocopy::Immutable;
use zerocopy::IntoBytes;
use zerocopy::KnownLayout;

#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
Expand All @@ -43,7 +44,7 @@ pub const HV_VP_ASSIST_PAGE_SIGNAL_EVENT_COUNT: usize = 16;
pub const HV_VP_ASSIST_PAGE_ACTION_TYPE_SIGNAL_EVENT: u64 = 1;

#[repr(C)]
#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)]
#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct hv_vp_assist_page_signal_event {
pub action_type: u64,
pub vp: u32,
Expand Down Expand Up @@ -71,7 +72,7 @@ pub struct hcl_pfn_range_t {
pub last_pfn: u64,
}

#[derive(FromBytes, FromZeroes, AsBytes)]
#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct hcl_cpu_context_x64 {
pub gps: [u64; 16],
Expand All @@ -81,7 +82,7 @@ pub struct hcl_cpu_context_x64 {

const _: () = assert!(size_of::<hcl_cpu_context_x64>() == 1024);

#[derive(FromBytes, FromZeroes, AsBytes)]
#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
// NOTE: x18 is managed by the hypervisor. It is assumed here be available
// for easier offset arithmetic.
Expand Down Expand Up @@ -115,7 +116,7 @@ pub const VTL_RETURN_ACTION_SIZE: usize = 256;

/// Kernel IPI offloading flags
#[bitfield(u8)]
#[derive(AsBytes, FromBytes, FromZeroes)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct hcl_intr_offload_flags {
/// Enable the base level of kernel offloading support. Requires vAPIC to be enabled.
/// HLT and Idle are accelerated by the kernel. When halted, an interrupt may be injected
Expand Down Expand Up @@ -224,7 +225,7 @@ pub struct EnterModes {
/// ioctl exit. See the TDX ABI specification for output operands for
/// TDG.VP.ENTER.
#[repr(C)]
#[derive(Debug, AsBytes, FromBytes, FromZeroes)]
#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct tdx_tdg_vp_enter_exit_info {
pub rax: u64,
pub rcx: u64,
Expand All @@ -240,7 +241,7 @@ pub struct tdx_tdg_vp_enter_exit_info {
}

#[bitfield(u64)]
#[derive(AsBytes, FromBytes, FromZeroes)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct tdx_vp_state_flags {
/// Issue a cache flush for a WBINVD before calling VP.ENTER.
pub wbinvd: bool,
Expand All @@ -252,7 +253,7 @@ pub struct tdx_vp_state_flags {

/// Additional VP state that is save/restored across TDG.VP.ENTER.
#[repr(C)]
#[derive(Debug, AsBytes, FromBytes, FromZeroes)]
#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct tdx_vp_state {
pub msr_kernel_gs_base: u64,
pub msr_star: u64,
Expand All @@ -265,7 +266,7 @@ pub struct tdx_vp_state {
}

#[repr(C)]
#[derive(Debug, AsBytes, FromBytes, FromZeroes)]
#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
pub struct tdx_vp_context {
pub exit_info: tdx_tdg_vp_enter_exit_info,
pub pad1: [u8; 48],
Expand Down
14 changes: 7 additions & 7 deletions openhcl/hcl/src/vmsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use x86defs::snp::SevSelector;
use x86defs::snp::SevVirtualInterruptControl;
use x86defs::snp::SevVmsa;
use x86defs::snp::SevXmmRegister;
use zerocopy::AsBytes;
use zerocopy::FromZeroes;
use zerocopy::FromZeros;
use zerocopy::IntoBytes;

/// VMSA and register tweak bitmap.
pub struct VmsaWrapper<'a, T> {
Expand Down Expand Up @@ -98,16 +98,16 @@ impl<T: DerefMut<Target = SevVmsa>> VmsaWrapper<'_, T> {

/// Create a new VMSA
pub fn reset(&mut self, vmsa_reg_prot: bool) {
*self.vmsa = FromZeroes::new_zeroed();
*self.vmsa = FromZeros::new_zeroed();
if vmsa_reg_prot {
// Initialize nonce and all protected fields.
getrandom::getrandom(self.vmsa.register_protection_nonce.as_bytes_mut())
getrandom::getrandom(self.vmsa.register_protection_nonce.as_mut_bytes())
.expect("rng failure");
let nonce = self.vmsa.register_protection_nonce;
let chunk_size = 8;
for (i, b) in self
.vmsa
.as_bytes_mut()
.as_mut_bytes()
.chunks_exact_mut(chunk_size)
.enumerate()
{
Expand Down Expand Up @@ -338,7 +338,7 @@ mod tests {
fn test_reg_access() {
let nonce = 0xffff_ffff_ffff_ffffu64;
let nonce128 = ((nonce as u128) << 64) | nonce as u128;
let mut vmsa: SevVmsa = FromZeroes::new_zeroed();
let mut vmsa: SevVmsa = FromZeros::new_zeroed();
vmsa.register_protection_nonce = nonce;
let bitmap = [0xffu8; 64];
let mut vmsa_wrapper = VmsaWrapper {
Expand Down Expand Up @@ -387,7 +387,7 @@ mod tests {

#[test]
fn test_init() {
let mut vmsa: SevVmsa = FromZeroes::new_zeroed();
let mut vmsa: SevVmsa = FromZeros::new_zeroed();
let mut bitmap = [0x0u8; 64];
let xmm_idx = 1;
bitmap[5] = 0x80u8; // rip
Expand Down
1 change: 0 additions & 1 deletion openhcl/minimal_rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ hvdef.workspace = true
arrayvec.workspace = true
cfg-if.workspace = true
zerocopy.workspace = true

[build-dependencies]
minimal_rt_build.workspace = true

Expand Down
9 changes: 5 additions & 4 deletions openhcl/minimal_rt/src/arch/aarch64/hypercall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@
use hvdef::HvRegisterName;
use hvdef::HvRegisterValue;
use hvdef::HvResult;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
use zerocopy::FromZeroes;
use zerocopy::Immutable;
use zerocopy::IntoBytes;
use zerocopy::KnownLayout;

/// Invokes a standard hypercall, or a fast hypercall with at most two input
/// words and zero output words.
Expand Down Expand Up @@ -106,7 +107,7 @@ unsafe fn invoke_hypercall_fast_6_2(
/// Sets a register for the current VTL using a fast hypercall.
pub fn set_register_fast(name: HvRegisterName, value: HvRegisterValue) -> HvResult<()> {
#[repr(C)]
#[derive(AsBytes, FromBytes, FromZeroes)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
struct Input {
header: hvdef::hypercall::GetSetVpRegisters,
assoc: hvdef::hypercall::HvRegisterAssoc,
Expand Down Expand Up @@ -144,7 +145,7 @@ pub fn set_register_fast(name: HvRegisterName, value: HvRegisterValue) -> HvResu
/// Gets a register for the current VTL using a fast hypercall.
pub fn get_register_fast(name: HvRegisterName) -> HvResult<HvRegisterValue> {
#[repr(C)]
#[derive(AsBytes, FromBytes, FromZeroes)]
#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
struct Input {
header: hvdef::hypercall::GetSetVpRegisters,
name: HvRegisterName,
Expand Down
Loading