diff --git a/Cargo.lock b/Cargo.lock index cc82093..6e18215 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,12 +145,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "cc" version = "1.0.104" @@ -785,19 +779,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "6129d25825e874589a0e529175dd060c13dab4f3d960c6a0b711e5535b598bb2" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "d917df3784b4e2f5deb708d14623b2c02833890e1aa7a5dd1088998e8e9402b1" dependencies = [ "proc-macro2", "quote", diff --git a/alioth/Cargo.toml b/alioth/Cargo.toml index 9799758..3b2220c 100644 --- a/alioth/Cargo.toml +++ b/alioth/Cargo.toml @@ -11,7 +11,7 @@ license.workspace = true test-hv = [] [dependencies] -zerocopy = { version = "0.7.32", features = ["derive", "alloc"] } +zerocopy = { version = "0.8.5", features = ["derive", "alloc"] } bitflags = "2.4.0" bitfield = "0.17.0" log = "0.4" diff --git a/alioth/src/board/x86_64.rs b/alioth/src/board/x86_64.rs index a64bf1b..bf8c164 100644 --- a/alioth/src/board/x86_64.rs +++ b/alioth/src/board/x86_64.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use parking_lot::Mutex; use snafu::ResultExt; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::arch::cpuid::CpuidIn; use crate::arch::layout::{ @@ -34,7 +34,7 @@ use crate::arch::reg::{Reg, SegAccess, SegReg, SegRegVal}; use crate::arch::sev::SnpPageType; use crate::board::{error, Board, BoardConfig, Result, VcpuGuard, PCIE_MMIO_64_SIZE}; use crate::firmware::acpi::bindings::{ - AcpiTableFadt, AcpiTableHeader, AcpiTableRsdp, AcpiTableXsdt, + AcpiTableFadt, AcpiTableHeader, AcpiTableRsdp, AcpiTableXsdt3, }; use crate::firmware::acpi::reg::{FadtReset, FadtSleepControl}; use crate::firmware::acpi::{ @@ -130,7 +130,7 @@ where let mut cpuid_table = SnpCpuidInfo::new_zeroed(); let ram_bus = self.memory.ram_bus(); let ram = ram_bus.lock_layout(); - let desc = SevMetadataDesc::read_from_prefix(&fw_range[offset..]).unwrap(); + let (desc, _) = SevMetadataDesc::read_from_prefix(&fw_range[offset..]).unwrap(); let snp_page_type = match desc.type_ { SEV_DESC_TYPE_SNP_SEC_MEM => SnpPageType::Unmeasured, SEV_DESC_TYPE_SNP_SECRETS => SnpPageType::Secrets, @@ -183,7 +183,8 @@ where let metadata_offset_r: u32 = parse_data_from_fw(fw_range, &SEV_METADATA_GUID).unwrap(); let metadata_offset = fw_range.len() - metadata_offset_r as usize; - let metadata = SevMetaData::read_from_prefix(&fw_range[metadata_offset..]).unwrap(); + let (metadata, _) = + SevMetaData::read_from_prefix(&fw_range[metadata_offset..]).unwrap(); let desc_offset = metadata_offset + size_of::(); for i in 0..metadata.num_desc as usize { let offset = desc_offset + i * size_of::(); @@ -355,7 +356,7 @@ where let mut pointers = vec![]; let mut checksums = vec![]; - let mut xsdt: AcpiTableXsdt<3> = FromZeroes::new_zeroed(); + let mut xsdt: AcpiTableXsdt3 = AcpiTableXsdt3::new_zeroed(); let offset_xsdt = 0; table_bytes.extend(xsdt.as_bytes()); @@ -389,9 +390,9 @@ where debug_assert_eq!(offset_xsdt % 4, 0); let xsdt_entries = [offset_fadt as u64, offset_madt as u64, offset_mcfg as u64]; xsdt = create_xsdt(xsdt_entries); - xsdt.write_to_prefix(&mut table_bytes); + xsdt.write_to_prefix(&mut table_bytes).unwrap(); for index in 0..xsdt_entries.len() { - pointers.push(offset_xsdt + offset_of!(AcpiTableXsdt<3>, entries) + index * 8); + pointers.push(offset_xsdt + offset_of!(AcpiTableXsdt3, entries) + index * 8); } checksums.push((offset_xsdt, size_of_val(&xsdt))); @@ -481,7 +482,7 @@ const SEV_METADATA_GUID: [u8; GUID_SIZE] = [ 0x66, 0x65, 0x88, 0xdc, 0x4a, 0x98, 0x98, 0x47, 0xA7, 0x5e, 0x55, 0x85, 0xa7, 0xbf, 0x67, 0xcc, ]; -#[derive(Debug, FromZeroes, FromBytes, AsBytes)] +#[derive(Debug, FromBytes, IntoBytes, Immutable)] #[repr(C)] struct SevMetaData { signature: u32, @@ -494,7 +495,7 @@ pub const SEV_DESC_TYPE_SNP_SEC_MEM: u32 = 1; pub const SEV_DESC_TYPE_SNP_SECRETS: u32 = 2; pub const SEV_DESC_TYPE_CPUID: u32 = 3; -#[derive(Debug, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, FromBytes, IntoBytes, Immutable)] #[repr(C)] struct SevMetadataDesc { @@ -512,9 +513,9 @@ where return None; } let offset_table_len = offset_table_footer.checked_sub(size_of::())?; - let table_len = u16::read_from_prefix(&blob[offset_table_len..])? as usize; + let (table_len, _) = u16::read_from_prefix(&blob[offset_table_len..]).ok()?; let offset_table_end = offset_table_len.checked_sub( - table_len + (table_len as usize) .checked_sub(size_of::())? .checked_sub(GUID_SIZE)?, )?; @@ -522,16 +523,18 @@ where while current > offset_table_end { let offset_len = current.checked_sub(GUID_SIZE + size_of::())?; if blob[(offset_len + 2)..].starts_with(guid) { - return T::read_from_prefix(&blob[offset_len.checked_sub(size_of::())?..]); + return T::read_from_prefix(&blob[offset_len.checked_sub(size_of::())?..]) + .map(|(n, _)| n) + .ok(); } - let table_len = u16::read_from_prefix(&blob[offset_len..])? as usize; - current = current.checked_sub(table_len)?; + let (table_len, _) = u16::read_from_prefix(&blob[offset_len..]).ok()?; + current = current.checked_sub(table_len as usize)?; } None } #[repr(C)] -#[derive(Debug, Clone, PartialEq, Eq, FromZeroes, FromBytes, AsBytes)] +#[derive(Debug, Clone, PartialEq, Eq, FromBytes, IntoBytes, Immutable)] pub struct SnpCpuidFunc { pub eax_in: u32, pub ecx_in: u32, @@ -545,7 +548,7 @@ pub struct SnpCpuidFunc { } #[repr(C)] -#[derive(Debug, Clone, FromZeroes, FromBytes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable)] pub struct SnpCpuidInfo { pub count: u32, pub _reserved1: u32, diff --git a/alioth/src/device/fw_cfg/acpi.rs b/alioth/src/device/fw_cfg/acpi.rs index 7639484..be2db46 100644 --- a/alioth/src/device/fw_cfg/acpi.rs +++ b/alioth/src/device/fw_cfg/acpi.rs @@ -14,7 +14,7 @@ use std::mem::{offset_of, size_of}; -use zerocopy::AsBytes; +use zerocopy::{Immutable, IntoBytes}; use crate::device::fw_cfg::{create_file_name, FwCfgContent, FwCfgItem, FILE_NAME_SIZE}; use crate::firmware::acpi::bindings::{AcpiTableHeader, AcpiTableRsdp}; @@ -32,7 +32,7 @@ pub const FW_CFG_FILENAME_RSDP: &str = "acpi/rsdp"; pub const FW_CFG_FILENAME_ACPI_TABLES: &str = "acpi/tables"; #[repr(C, align(4))] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] pub struct Allocate { command: u32, file: [u8; FILE_NAME_SIZE], @@ -42,7 +42,7 @@ pub struct Allocate { } #[repr(C, align(4))] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] pub struct AddPointer { command: u32, dst: [u8; FILE_NAME_SIZE], @@ -53,7 +53,7 @@ pub struct AddPointer { } #[repr(C, align(4))] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] pub struct AddChecksum { command: u32, file: [u8; FILE_NAME_SIZE], diff --git a/alioth/src/device/fw_cfg/fw_cfg.rs b/alioth/src/device/fw_cfg/fw_cfg.rs index 5741d46..494dc4e 100644 --- a/alioth/src/device/fw_cfg/fw_cfg.rs +++ b/alioth/src/device/fw_cfg/fw_cfg.rs @@ -32,7 +32,7 @@ use parking_lot::Mutex; use serde::de::{self, MapAccess, Visitor}; use serde::{Deserialize, Deserializer}; use serde_aco::Help; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; #[cfg(target_arch = "x86_64")] use crate::arch::layout::{ @@ -175,7 +175,7 @@ pub struct FwCfg { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Layout)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, Layout)] struct FwCfgDmaAccess { control_be: u32, length_be: u32, @@ -194,13 +194,13 @@ bitfield! { } #[repr(C)] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] struct FwCfgFilesHeader { count_be: u32, } #[repr(C)] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] struct FwCfgFile { size_be: u32, select_be: u16, @@ -281,8 +281,8 @@ impl FwCfg { #[cfg(target_arch = "x86_64")] pub fn add_kernel_data(&mut self, file: File) -> Result<()> { let mut buffer = vec![0u8; size_of::()]; - file.read_exact_at(buffer.as_bytes_mut(), 0)?; - let bp = BootParams::mut_from(&mut buffer).unwrap(); + file.read_exact_at(&mut buffer, 0)?; + let bp = BootParams::mut_from_bytes(&mut buffer).unwrap(); if bp.hdr.setup_sects == 0 { bp.hdr.setup_sects = 4; } diff --git a/alioth/src/firmware/acpi/acpi.rs b/alioth/src/firmware/acpi/acpi.rs index 7658607..6050e6a 100644 --- a/alioth/src/firmware/acpi/acpi.rs +++ b/alioth/src/firmware/acpi/acpi.rs @@ -17,28 +17,24 @@ pub mod reg; use std::mem::{offset_of, size_of}; -use zerocopy::{transmute, AsBytes, FromBytes}; +use zerocopy::{transmute, FromBytes, IntoBytes}; use crate::arch::layout::PCIE_CONFIG_START; #[cfg(target_arch = "x86_64")] use crate::arch::layout::{ APIC_START, IOAPIC_START, PORT_ACPI_RESET, PORT_ACPI_SLEEP_CONTROL, PORT_ACPI_SLEEP_STATUS, }; -use crate::unsafe_impl_zerocopy; use crate::utils::wrapping_sum; use bindings::{ AcpiGenericAddress, AcpiMadtIoApic, AcpiMadtLocalX2apic, AcpiMcfgAllocation, - AcpiSubtableHeader, AcpiTableFadt, AcpiTableHeader, AcpiTableMadt, AcpiTableMcfg, - AcpiTableRsdp, AcpiTableXsdt, FADT_MAJOR_VERSION, FADT_MINOR_VERSION, MADT_IO_APIC, + AcpiSubtableHeader, AcpiTableFadt, AcpiTableHeader, AcpiTableMadt, AcpiTableMcfg1, + AcpiTableRsdp, AcpiTableXsdt3, FADT_MAJOR_VERSION, FADT_MINOR_VERSION, MADT_IO_APIC, MADT_LOCAL_X2APIC, MADT_REVISION, MCFG_REVISION, RSDP_REVISION, SIG_FADT, SIG_MADT, SIG_MCFG, SIG_RSDP, SIG_XSDT, XSDT_REVISION, }; use reg::FADT_RESET_VAL; -unsafe_impl_zerocopy!(AcpiTableMcfg<1>, FromBytes, FromZeroes, AsBytes); -unsafe_impl_zerocopy!(AcpiTableXsdt<3>, FromBytes, FromZeroes, AsBytes); - const OEM_ID: [u8; 6] = *b"ALIOTH"; fn default_header() -> AcpiTableHeader { @@ -66,10 +62,10 @@ pub fn create_rsdp(xsdt_addr: u64) -> AcpiTableRsdp { } // https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#extended-system-description-table-fields-xsdt -pub fn create_xsdt(entries: [u64; N]) -> AcpiTableXsdt { - let total_length = size_of::() + size_of::() * N; +pub fn create_xsdt(entries: [u64; 3]) -> AcpiTableXsdt3 { + let total_length = size_of::() + size_of::() * 3; let entries = entries.map(|e| transmute!(e)); - AcpiTableXsdt { + AcpiTableXsdt3 { header: AcpiTableHeader { signature: SIG_XSDT, length: total_length as u32, @@ -171,11 +167,11 @@ pub fn create_madt(num_cpu: u32) -> (AcpiTableMadt, AcpiMadtIoApic, Vec AcpiTableMcfg<1> { - let mut mcfg = AcpiTableMcfg { +pub fn create_mcfg() -> AcpiTableMcfg1 { + let mut mcfg = AcpiTableMcfg1 { header: AcpiTableHeader { signature: SIG_MCFG, - length: size_of::>() as u32, + length: size_of::() as u32, revision: MCFG_REVISION, ..default_header() }, @@ -210,9 +206,9 @@ impl AcpiTable { self.rsdp.extended_checksum = self.rsdp.extended_checksum.wrapping_sub(ext_sum); for pointer in self.table_pointers.iter() { - let old_val: u64 = FromBytes::read_from_prefix(&self.tables[*pointer..]).unwrap(); + let (old_val, _) = u64::read_from_prefix(&self.tables[*pointer..]).unwrap(); let new_val = old_val.wrapping_sub(old_addr).wrapping_add(table_addr); - AsBytes::write_to_prefix(&new_val, &mut self.tables[*pointer..]).unwrap(); + IntoBytes::write_to_prefix(&new_val, &mut self.tables[*pointer..]).unwrap(); } for (start, len) in self.table_checksums.iter() { diff --git a/alioth/src/firmware/acpi/bindings.rs b/alioth/src/firmware/acpi/bindings.rs index d799a92..60b49e8 100644 --- a/alioth/src/firmware/acpi/bindings.rs +++ b/alioth/src/firmware/acpi/bindings.rs @@ -13,7 +13,7 @@ // limitations under the License. use bitfield::bitfield; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; pub const SIG_RSDP: [u8; 8] = *b"RSD PTR "; pub const SIG_XSDT: [u8; 4] = *b"XSDT"; @@ -26,7 +26,7 @@ pub const SIG_DSDT: [u8; 4] = *b"DSDT"; pub const RSDP_REVISION: u8 = 2; #[repr(C, align(4))] -#[derive(Debug, Clone, Default, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiTableRsdp { pub signature: [u8; 8], pub checksum: u8, @@ -40,7 +40,7 @@ pub struct AcpiTableRsdp { } #[repr(C, align(4))] -#[derive(Debug, Clone, Default, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiTableHeader { pub signature: [u8; 4], pub length: u32, @@ -55,15 +55,22 @@ pub struct AcpiTableHeader { pub const XSDT_REVISION: u8 = 1; +#[derive(Debug, FromBytes)] #[repr(C, align(4))] -#[derive(Debug, Clone)] pub struct AcpiTableXsdt { pub header: AcpiTableHeader, pub entries: [[u32; 2]; N], } #[repr(C, align(4))] -#[derive(Debug, Clone, AsBytes, Default, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] +pub struct AcpiTableXsdt3 { + pub header: AcpiTableHeader, + pub entries: [[u32; 2]; 3], +} + +#[repr(C, align(4))] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiGenericAddress { pub space_id: u8, pub bit_width: u8, @@ -76,7 +83,7 @@ pub const FADT_MAJOR_VERSION: u8 = 6; pub const FADT_MINOR_VERSION: u8 = 4; #[repr(C, align(4))] -#[derive(Debug, Clone, Default, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiTableFadt { pub header: AcpiTableHeader, pub facs: u32, @@ -141,7 +148,7 @@ pub struct AcpiTableFadt { pub const MADT_REVISION: u8 = 6; #[repr(C, align(4))] -#[derive(Debug, Clone, Default, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiTableMadt { pub header: AcpiTableHeader, pub address: u32, @@ -152,14 +159,14 @@ pub const MADT_IO_APIC: u8 = 1; pub const MADT_LOCAL_X2APIC: u8 = 9; #[repr(C)] -#[derive(Debug, Clone, AsBytes, Default, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiSubtableHeader { pub type_: u8, pub length: u8, } #[repr(C, align(4))] -#[derive(Debug, Clone, AsBytes, Default, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiMadtLocalX2apic { pub header: AcpiSubtableHeader, pub reserved: u16, @@ -169,7 +176,7 @@ pub struct AcpiMadtLocalX2apic { } #[repr(C, align(4))] -#[derive(Debug, Clone, AsBytes, Default, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiMadtIoApic { pub header: AcpiSubtableHeader, pub id: u8, @@ -179,7 +186,7 @@ pub struct AcpiMadtIoApic { } #[repr(C, align(4))] -#[derive(Debug, Clone, AsBytes, Default, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct AcpiMcfgAllocation { pub address: [u32; 2], pub pci_segment: u16, @@ -198,6 +205,22 @@ pub struct AcpiTableMcfg { pub allocations: [AcpiMcfgAllocation; N], } +#[repr(C, align(4))] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] +pub struct AcpiTableMcfg1 { + pub header: AcpiTableHeader, + pub reserved: [u8; 8], + pub allocations: [AcpiMcfgAllocation; 1], +} + +#[repr(C, align(4))] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] +pub struct AcpiTableMcfg3 { + pub header: AcpiTableHeader, + pub reserved: [u8; 8], + pub allocations: [AcpiMcfgAllocation; 3], +} + bitfield! { /// Sleep Control Register /// @@ -219,7 +242,7 @@ mod test { use super::{ AcpiGenericAddress, AcpiMadtIoApic, AcpiMadtLocalX2apic, AcpiMcfgAllocation, AcpiTableFadt, - AcpiTableHeader, AcpiTableMadt, AcpiTableMcfg, AcpiTableRsdp, AcpiTableXsdt, + AcpiTableHeader, AcpiTableMadt, AcpiTableMcfg1, AcpiTableRsdp, AcpiTableXsdt, }; #[test] @@ -232,7 +255,7 @@ mod test { assert_eq!(size_of::(), 12); assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); - assert_eq!(size_of::>(), 60); + assert_eq!(size_of::(), 60); assert_eq!(size_of::>(), 36); assert_eq!(size_of::>(), 36 + 4 * 8); } diff --git a/alioth/src/firmware/dt/dtb.rs b/alioth/src/firmware/dt/dtb.rs index c4b4812..6f60f1a 100644 --- a/alioth/src/firmware/dt/dtb.rs +++ b/alioth/src/firmware/dt/dtb.rs @@ -15,7 +15,7 @@ use std::collections::HashMap; use std::mem::size_of; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::align_up; use crate::firmware::dt::{DeviceTree, Node, PropVal}; @@ -77,7 +77,7 @@ impl PropVal { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(IntoBytes, FromBytes, Immutable, Debug)] pub struct FdtHeader { magic: Bu32, total_size: Bu32, @@ -91,14 +91,14 @@ pub struct FdtHeader { size_dt_struct: Bu32, } -#[derive(AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(IntoBytes, FromBytes, Immutable, Debug)] #[repr(C)] pub struct FdtProp { len: Bu32, name_off: Bu32, } -#[derive(AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(IntoBytes, FromBytes, Immutable, Debug)] #[repr(C)] struct FdtReserveEntry { address: Bu64, @@ -199,7 +199,7 @@ impl DeviceTree { size_dt_strings: Bu32::from(size_dt_strings as u32), size_dt_struct: Bu32::from(size_dt_struct as u32), }; - header.write_to_prefix(&mut data); + header.write_to_prefix(&mut data).unwrap(); data } } diff --git a/alioth/src/loader/elf.rs b/alioth/src/loader/elf.rs index 96da17e..70adece 100644 --- a/alioth/src/loader/elf.rs +++ b/alioth/src/loader/elf.rs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, IntoBytes, KnownLayout}; pub const ELF_HEADER_MAGIC: [u8; 4] = *b"\x7fELF"; pub const ELF_IDENT_CLASS_64: u8 = 2; pub const ELF_IDENT_LITTLE_ENDIAN: u8 = 1; #[repr(C)] -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, Clone, FromBytes, IntoBytes)] pub struct Elf64Header { pub ident_magic: [u8; 4], pub ident_class: u8, @@ -43,7 +43,7 @@ pub struct Elf64Header { pub sh_str_ndx: u16, } #[repr(C)] -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, Clone, FromBytes, IntoBytes, KnownLayout)] pub struct Elf64ProgramHeader { pub type_: u32, pub flags: u32, @@ -58,7 +58,7 @@ pub struct Elf64ProgramHeader { pub const SHT_NOTE: u32 = 7; #[repr(C)] -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, Clone, FromBytes, IntoBytes)] pub struct Elf64SectionHeader { pub name: u32, pub type_: u32, @@ -76,7 +76,7 @@ pub const PT_LOAD: u32 = 1; pub const PT_NOTE: u32 = 4; #[repr(C)] -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, Clone, FromBytes, IntoBytes)] pub struct Elf64Note { pub name_sz: u32, pub desc_sz: u32, diff --git a/alioth/src/loader/linux/aarch64.rs b/alioth/src/loader/linux/aarch64.rs index 33e4c2d..80f6db9 100644 --- a/alioth/src/loader/linux/aarch64.rs +++ b/alioth/src/loader/linux/aarch64.rs @@ -17,7 +17,7 @@ use std::io::{BufReader, Read, Seek, SeekFrom}; use std::path::Path; use snafu::ResultExt; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::arch::layout::{DEVICE_TREE_START, KERNEL_IMAGE_START}; use crate::arch::reg::{Pstate, Reg}; @@ -26,7 +26,7 @@ use crate::mem::mapped::RamBus; use crate::mem::MemRegionEntry; #[repr(C)] -#[derive(Debug, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, FromBytes, Immutable, IntoBytes)] struct ImageHeader { code0: u32, code1: u32, @@ -57,7 +57,7 @@ pub fn load>( let mut kernel = BufReader::new(kernel); let mut header = ImageHeader::new_zeroed(); kernel - .read_exact(header.as_bytes_mut()) + .read_exact(header.as_mut_bytes()) .context(access_kernel)?; if header.magic != IMAGE_MAGIC { return error::MissingMagic { diff --git a/alioth/src/loader/linux/bootparams.rs b/alioth/src/loader/linux/bootparams.rs index 0ab8938..8ef04cd 100644 --- a/alioth/src/loader/linux/bootparams.rs +++ b/alioth/src/loader/linux/bootparams.rs @@ -13,7 +13,7 @@ // limitations under the License. use bitflags::bitflags; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; pub const MAGIC_AA55: u16 = 0xaa55; pub const MAGIC_HDRS: u32 = 0x53726448; // "HdrS" @@ -45,7 +45,7 @@ bitflags! { } #[repr(C, packed)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable)] pub struct SetupHeader { pub setup_sects: u8, pub root_flags: u16, @@ -97,7 +97,7 @@ pub const E820_PMEM: u32 = 7; pub const E820_RESERVED_KERN: u32 = 128; #[repr(C, packed)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable)] pub struct BootE820Entry { pub addr: u64, pub size: u64, @@ -105,7 +105,7 @@ pub struct BootE820Entry { } #[repr(C, packed)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BootParams { pub screen_info: [u8; 64], pub apm_bios_info: [u8; 20], diff --git a/alioth/src/loader/linux/x86_64.rs b/alioth/src/loader/linux/x86_64.rs index 7e1d5c3..a5c4be5 100644 --- a/alioth/src/loader/linux/x86_64.rs +++ b/alioth/src/loader/linux/x86_64.rs @@ -24,7 +24,7 @@ use crate::arch::reg::{ }; use crate::mem::mapped::RamBus; use snafu::ResultExt; -use zerocopy::{AsBytes, FromZeroes}; +use zerocopy::{FromZeros, IntoBytes}; use crate::arch::layout::{ BOOT_GDT_START, BOOT_PAGING_START, EBDA_START, KERNEL_CMD_LINE_LIMIT, KERNEL_CMD_LINE_START, @@ -60,7 +60,7 @@ pub fn load>( .seek(SeekFrom::Start(SETUP_HEADER_OFFSET)) .context(access_kernel)?; kernel - .read_exact(boot_params.hdr.as_bytes_mut()) + .read_exact(boot_params.hdr.as_mut_bytes()) .context(access_kernel)?; // For backwards compatibility, if the setup_sects field contains 0, diff --git a/alioth/src/loader/xen/start_info.rs b/alioth/src/loader/xen/start_info.rs index 6aafa95..be2409e 100644 --- a/alioth/src/loader/xen/start_info.rs +++ b/alioth/src/loader/xen/start_info.rs @@ -11,13 +11,13 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromZeros, Immutable, IntoBytes}; pub const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578; pub const XEN_HVM_START_INFO_V1: u32 = 1; #[repr(C)] -#[derive(Debug, Clone, Default, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, Clone, Default, IntoBytes, FromZeros, Immutable)] pub struct HvmStartInfo { pub magic: u32, pub version: u32, @@ -32,7 +32,7 @@ pub struct HvmStartInfo { } #[repr(C)] -#[derive(Debug, Clone, Default, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, Clone, Default, IntoBytes, FromZeros, Immutable)] pub struct HvmModlistEntry { pub paddr: u64, pub size: u64, @@ -49,7 +49,7 @@ pub const XEN_HVM_MEMMAP_TYPE_DISABLED: u32 = 6; pub const XEN_HVM_MEMMAP_TYPE_PMEM: u32 = 7; #[repr(C)] -#[derive(Debug, Clone, Default, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, Clone, Default, IntoBytes, FromZeros, Immutable)] pub struct HvmMemmapTableEntry { pub addr: u64, pub size: u64, diff --git a/alioth/src/loader/xen/xen.rs b/alioth/src/loader/xen/xen.rs index 9575265..f74c656 100644 --- a/alioth/src/loader/xen/xen.rs +++ b/alioth/src/loader/xen/xen.rs @@ -18,7 +18,7 @@ use std::mem::{offset_of, size_of, size_of_val}; use std::path::Path; use snafu::ResultExt; -use zerocopy::{AsBytes, FromZeroes}; +use zerocopy::{FromZeros, Immutable, IntoBytes}; use crate::align_up; use crate::arch::layout::{ @@ -44,7 +44,7 @@ use start_info::{HvmMemmapTableEntry, HvmModlistEntry, HvmStartInfo}; pub const XEN_ELFNOTE_PHYS32_ENTRY: u32 = 18; #[repr(C)] -#[derive(Debug, AsBytes, Default)] +#[derive(Debug, IntoBytes, Default, Immutable)] struct StartInfoPage { start_info: HvmStartInfo, initramfs: HvmModlistEntry, @@ -61,7 +61,7 @@ fn search_pvh_note( while pos < size { file.seek(SeekFrom::Start(offset + pos))?; let mut header = Elf64Note::new_zeroed(); - file.read_exact(header.as_bytes_mut())?; + file.read_exact(header.as_mut_bytes())?; pos += size_of::() as u64; pos += align_up!(header.desc_sz as u64, align); pos += align_up!(header.name_sz as u64, align); @@ -74,12 +74,12 @@ fn search_pvh_note( match header.desc_sz { 4 => { let mut entry_point = 0u32; - file.read_exact(entry_point.as_bytes_mut())?; + file.read_exact(entry_point.as_mut_bytes())?; return Ok(Some(entry_point as u64)); } 8 => { let mut entry_point = 0u64; - file.read_exact(entry_point.as_bytes_mut())?; + file.read_exact(entry_point.as_mut_bytes())?; return Ok(Some(entry_point)); } _ => {} @@ -105,7 +105,7 @@ pub fn load>( // load kernel let mut elf_header = Elf64Header::new_zeroed(); kernel - .read_exact(elf_header.as_bytes_mut()) + .read_exact(elf_header.as_mut_bytes()) .context(access_kernel)?; if elf_header.ident_magic != ELF_HEADER_MAGIC { return error::MissingMagic { @@ -124,9 +124,10 @@ pub fn load>( kernel .seek(SeekFrom::Start(elf_header.ph_off)) .context(access_kernel)?; - let mut program_header = Elf64ProgramHeader::new_vec_zeroed(elf_header.ph_num as usize); + let mut program_header = + Elf64ProgramHeader::new_vec_zeroed(elf_header.ph_num as usize).unwrap(); kernel - .read_exact(program_header.as_bytes_mut()) + .read_exact(program_header.as_mut_bytes()) .context(access_kernel)?; for program_header in program_header.iter() { if program_header.type_ == PT_NOTE && pvh_entry.is_none() { @@ -153,9 +154,9 @@ pub fn load>( kernel .seek(SeekFrom::Start(elf_header.sh_off)) .context(access_kernel)?; - let mut sections = Elf64SectionHeader::new_vec_zeroed(elf_header.sh_num as usize); + let mut sections = Elf64SectionHeader::new_vec_zeroed(elf_header.sh_num as usize).unwrap(); kernel - .read_exact(sections.as_bytes_mut()) + .read_exact(sections.as_mut_bytes()) .context(access_kernel)?; for section in sections.iter() { if section.type_ != SHT_NOTE { diff --git a/alioth/src/mem/emulated.rs b/alioth/src/mem/emulated.rs index 00c6ea0..a9f1905 100644 --- a/alioth/src/mem/emulated.rs +++ b/alioth/src/mem/emulated.rs @@ -68,15 +68,23 @@ macro_rules! impl_mmio_for_zerocopy { } fn read(&self, offset: u64, size: u8) -> $crate::mem::Result { - let bytes = AsBytes::as_bytes(self); + fn read_from_prefix>( + bytes: &[u8], + ) -> ::core::option::Option { + let (n, _) = T::read_from_prefix(bytes).ok()?; + Some(n.into()) + } + + let bytes = ::zerocopy::IntoBytes::as_bytes(self); let offset = offset as usize; let val = match size { 1 => bytes.get(offset).map(|b| *b as u64), - 2 => u16::read_from_prefix(&bytes[offset..]).map(|w| w as u64), - 4 => u32::read_from_prefix(&bytes[offset..]).map(|d| d as u64), - 8 => u64::read_from_prefix(&bytes[offset..]), + 2 => bytes.get(offset..).and_then(read_from_prefix::), + 4 => bytes.get(offset..).and_then(read_from_prefix::), + 8 => bytes.get(offset..).and_then(read_from_prefix::), _ => ::core::option::Option::None, }; + if let ::core::option::Option::Some(val) = val { ::core::result::Result::Ok(val) } else { diff --git a/alioth/src/mem/mapped.rs b/alioth/src/mem/mapped.rs index 068509a..55c957e 100644 --- a/alioth/src/mem/mapped.rs +++ b/alioth/src/mem/mapped.rs @@ -33,7 +33,7 @@ use libc::{ use libc::{madvise, MADV_HUGEPAGE, MFD_CLOEXEC}; use parking_lot::{RwLock, RwLockReadGuard}; use snafu::ResultExt; -use zerocopy::{AsBytes, FromBytes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; use crate::ffi; use crate::mem::addressable::{Addressable, SlotBackend}; @@ -163,28 +163,28 @@ impl ArcMemPages { T: FromBytes, { let s = self.get_partial_slice(offset, size_of::())?; - match FromBytes::read_from(s) { - None => error::ExceedsLimit { + match FromBytes::read_from_bytes(s) { + Err(_) => error::ExceedsLimit { addr: offset as u64, size: size_of::() as u64, } .fail(), - Some(v) => Ok(v), + Ok(v) => Ok(v), } } pub fn write(&self, offset: usize, val: &T) -> Result<(), Error> where - T: AsBytes, + T: IntoBytes + Immutable, { let s = self.get_partial_slice_mut(offset, size_of::())?; - match AsBytes::write_to(val, s) { - None => error::ExceedsLimit { + match IntoBytes::write_to(val, s) { + Err(_) => error::ExceedsLimit { addr: offset as u64, size: size_of::() as u64, } .fail(), - Some(()) => Ok(()), + Ok(()) => Ok(()), } } @@ -335,10 +335,10 @@ impl Ram { pub fn read(&self, gpa: u64) -> Result where - T: FromBytes + AsBytes, + T: FromBytes + IntoBytes, { let mut val = T::new_zeroed(); - let buf = val.as_bytes_mut(); + let buf = val.as_mut_bytes(); let host_ref = self.get_partial_slice(gpa, size_of::() as u64)?; if host_ref.len() == buf.len() { buf.copy_from_slice(host_ref); @@ -357,7 +357,7 @@ impl Ram { pub fn write(&self, gpa: u64, val: &T) -> Result<(), Error> where - T: AsBytes, + T: IntoBytes + Immutable, { let buf = val.as_bytes(); let host_ref = self.get_partial_slice_mut(gpa, size_of::() as u64)?; @@ -438,7 +438,7 @@ impl RamBus { pub fn read(&self, gpa: u64) -> Result where - T: FromBytes + AsBytes, + T: FromBytes + IntoBytes, { let ram = self.ram.read(); ram.read(gpa) @@ -446,7 +446,7 @@ impl RamBus { pub fn write(&self, gpa: u64, val: &T) -> Result<(), Error> where - T: AsBytes, + T: IntoBytes + Immutable, { let ram = self.ram.read(); ram.write(gpa, val) @@ -504,11 +504,11 @@ mod test { use std::mem::size_of; use libc::{PROT_READ, PROT_WRITE}; - use zerocopy::{AsBytes, FromBytes, FromZeroes}; + use zerocopy::{FromBytes, Immutable, IntoBytes}; use super::{ArcMemPages, RamBus}; - #[derive(Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] + #[derive(Debug, IntoBytes, FromBytes, Immutable, PartialEq, Eq)] #[repr(C)] struct MyStruct { data: [u32; 8], diff --git a/alioth/src/net/net.rs b/alioth/src/net/net.rs index bab7d64..6b34073 100644 --- a/alioth/src/net/net.rs +++ b/alioth/src/net/net.rs @@ -15,9 +15,9 @@ use serde::de::{self, Visitor}; use serde::Deserialize; use serde_aco::{Help, TypedHelp}; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes, PartialEq, Eq)] +#[derive(Debug, Default, FromBytes, Immutable, IntoBytes, PartialEq, Eq)] #[repr(transparent)] pub struct MacAddr([u8; 6]); diff --git a/alioth/src/pci/cap.rs b/alioth/src/pci/cap.rs index 8c21c20..e9d3520 100644 --- a/alioth/src/pci/cap.rs +++ b/alioth/src/pci/cap.rs @@ -18,7 +18,7 @@ use std::mem::size_of; use bitfield::bitfield; use macros::Layout; use parking_lot::{RwLock, RwLockWriteGuard}; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use crate::hv::IrqFd; use crate::mem::addressable::SlotBackend; @@ -36,7 +36,7 @@ pub enum PciCapId { } #[repr(C)] -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes, Layout)] +#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Layout)] pub struct PciCapHdr { pub id: u8, pub next: u8, @@ -53,7 +53,7 @@ bitfield! { } bitfield! { - #[derive(Copy, Clone, Default, FromBytes, FromZeroes, AsBytes)] + #[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)] #[repr(C)] pub struct MsixMsgCtrl(u16); impl Debug; @@ -70,7 +70,7 @@ impl MsixMsgCtrl { } bitfield! { - #[derive(Copy, Clone, Default, FromBytes, FromZeroes, AsBytes)] + #[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes)] #[repr(C)] pub struct MsixCapOffset(u32); impl Debug; @@ -87,7 +87,7 @@ impl MsixCapOffset { } } -#[derive(Debug, Default, Clone, FromBytes, FromZeroes, AsBytes, Layout)] +#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, Layout)] #[repr(C)] pub struct MsixCap { pub header: PciCapHdr, diff --git a/alioth/src/pci/config.rs b/alioth/src/pci/config.rs index 5138fb2..68dc245 100644 --- a/alioth/src/pci/config.rs +++ b/alioth/src/pci/config.rs @@ -19,16 +19,19 @@ use std::sync::Arc; use bitflags::bitflags; use macros::Layout; use parking_lot::RwLock; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use crate::mem::emulated::{Action, ChangeLayout, Mmio}; use crate::pci::cap::PciCapList; use crate::pci::{Bdf, PciBar}; -use crate::{assign_bits, mask_bits, mem, unsafe_impl_zerocopy}; +use crate::{assign_bits, impl_mmio_for_zerocopy, mask_bits, mem}; + +#[derive(Clone, Copy, Default, IntoBytes, FromBytes, KnownLayout, Immutable)] +#[repr(transparent)] +pub struct Command(u16); bitflags! { - #[derive(Debug, Clone, Copy, Default)] - pub struct Command: u16 { + impl Command: u16 { const INTX_DISABLE = 1 << 10; const SERR = 1 << 8; const PARITY_ERR = 1 << 6; @@ -43,11 +46,19 @@ bitflags! { | Self::IO.bits(); } } -unsafe_impl_zerocopy!(Command, FromBytes, FromZeroes, AsBytes); + +impl std::fmt::Debug for Command { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + bitflags::parser::to_writer(self, f) + } +} + +#[derive(Clone, Copy, Default, IntoBytes, FromBytes, KnownLayout, Immutable)] +#[repr(transparent)] +pub struct Status(u16); bitflags! { - #[derive(Debug, Clone, Copy, Default)] - pub struct Status: u16 { + impl Status: u16 { const PARITY_ERR = 1 << 15; const SYSTEM_ERR = 1 << 14; const RECEIVED_MASTER_ABORT = 1 << 13; @@ -65,7 +76,12 @@ bitflags! { | Self::MASTER_PARITY_ERR.bits(); } } -unsafe_impl_zerocopy!(Status, FromBytes, FromZeroes, AsBytes); + +impl std::fmt::Debug for Status { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + bitflags::parser::to_writer(self, f) + } +} #[derive(Debug, Clone, Copy)] #[repr(u8)] @@ -74,7 +90,7 @@ pub enum HeaderType { Bridge = 1, } -#[derive(Debug, Clone, Default, FromBytes, FromZeroes, AsBytes, Layout)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, KnownLayout, IntoBytes, Layout)] #[repr(C, align(8))] pub struct CommonHeader { pub vendor: u16, @@ -91,7 +107,7 @@ pub struct CommonHeader { pub bist: u8, } -#[derive(Debug, Clone, Default, FromBytes, FromZeroes, AsBytes, Layout)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, KnownLayout, IntoBytes, Layout)] #[repr(C, align(8))] pub struct DeviceHeader { pub common: CommonHeader, @@ -107,6 +123,7 @@ pub struct DeviceHeader { pub min_gnt: u8, pub max_lat: u8, } +impl_mmio_for_zerocopy!(DeviceHeader); pub const OFFSET_BAR0: usize = DeviceHeader::OFFSET_BARS; pub const OFFSET_BAR5: usize = OFFSET_BAR0 + 5 * size_of::(); @@ -376,19 +393,10 @@ impl Mmio for EmulatedHeader { } fn read(&self, offset: u64, size: u8) -> mem::Result { - let offset = offset as usize; let data = self.data.read(); - let bytes = match &data.header { - ConfigHeader::Device(header) => AsBytes::as_bytes(header), - }; - let ret = match size { - 1 => bytes.get(offset).map(|b| *b as u64), - 2 => u16::read_from_prefix(&bytes[offset..]).map(|w| w as u64), - 4 => u32::read_from_prefix(&bytes[offset..]).map(|d| d as u64), - 8 => u64::read_from_prefix(&bytes[offset..]), - _ => Some(0), - }; - Ok(ret.unwrap_or(0)) + match &data.header { + ConfigHeader::Device(header) => Mmio::read(header, offset, size), + } } fn write(&self, offset: u64, size: u8, val: u64) -> mem::Result { diff --git a/alioth/src/utils/endian.rs b/alioth/src/utils/endian.rs index b8038a1..3f29631 100644 --- a/alioth/src/utils/endian.rs +++ b/alioth/src/utils/endian.rs @@ -16,7 +16,7 @@ macro_rules! endian_impl { ($ne_type:ident, $ed_type:ident, $endian:expr, $opposite:expr) => { #[repr(transparent)] #[derive( - ::zerocopy::AsBytes, ::zerocopy::FromBytes, ::zerocopy::FromZeroes, Copy, Clone, + ::zerocopy::Immutable, ::zerocopy::IntoBytes, ::zerocopy::FromBytes, Copy, Clone, )] pub struct $ed_type { v: $ne_type, diff --git a/alioth/src/utils/utils.rs b/alioth/src/utils/utils.rs index a78fae2..8a7ffe6 100644 --- a/alioth/src/utils/utils.rs +++ b/alioth/src/utils/utils.rs @@ -172,21 +172,6 @@ macro_rules! c_enum { } } -#[macro_export] -macro_rules! unsafe_impl_zerocopy { - ($ty:ty, $($name:ident), +) => { - $( - unsafe impl ::zerocopy::$name for $ty { - fn only_derive_is_allowed_to_implement_this_trait() - where - Self: Sized, - { - } - } - )+ - }; -} - #[cfg(test)] mod test { #[test] diff --git a/alioth/src/vfio/pci.rs b/alioth/src/vfio/pci.rs index 462ad7b..fd13c0a 100644 --- a/alioth/src/vfio/pci.rs +++ b/alioth/src/vfio/pci.rs @@ -420,14 +420,13 @@ where let mut buf: [u8; 4096] = transmute!([0u32; 1024]); cdev.dev.fd().read_at(&mut buf, region_config.offset)?; - let header = CommonHeader::ref_from_prefix(&buf).unwrap(); - if header.header_type != HeaderType::Device as u8 { + let (mut dev_header, _) = DeviceHeader::read_from_prefix(&buf).unwrap(); + if dev_header.common.header_type != HeaderType::Device as u8 { return error::NotSupportedHeader { - ty: header.header_type, + ty: dev_header.common.header_type, } .fail(); } - let mut dev_header = DeviceHeader::read_from_prefix(&buf).unwrap(); dev_header.intx_pin = 0; dev_header.common.command = Command::empty(); @@ -438,9 +437,11 @@ where if dev_header.common.status.contains(Status::CAP) { let mut cap_offset = dev_header.capability_pointer as usize; while cap_offset != 0 { - let cap_header = PciCapHdr::ref_from_prefix(&buf[cap_offset..]).unwrap(); + let (cap_header, _) = PciCapHdr::ref_from_prefix(&buf[cap_offset..]).unwrap(); if cap_header.id == PciCapId::Msix as u8 { - msix_cap = MsixCap::read_from_prefix(&buf[cap_offset..]); + if let Ok((c, _)) = MsixCap::read_from_prefix(&buf[cap_offset..]) { + msix_cap = Some(c) + } msix_msg_ctrl_offset = cap_offset + MsixCap::OFFSET_CONTROL; } else if cap_header.id == PciCapId::Msi as u8 { log::trace!("{}: hiding MSI cap at {cap_offset:#x}", cdev.name); diff --git a/alioth/src/virtio/dev/blk.rs b/alioth/src/virtio/dev/blk.rs index 8e24c6c..5e91c3c 100644 --- a/alioth/src/virtio/dev/blk.rs +++ b/alioth/src/virtio/dev/blk.rs @@ -34,7 +34,7 @@ use mio::Registry; use serde::Deserialize; use serde_aco::Help; use snafu::ResultExt; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::hv::IoeventFd; use crate::mem::mapped::{Ram, RamBus}; @@ -49,7 +49,7 @@ use crate::virtio::{error, DeviceId, IrqSender, Result, FEATURE_BUILT_IN}; use crate::{c_enum, impl_mmio_for_zerocopy}; c_enum! { - #[derive(FromBytes, FromZeroes)] + #[derive(FromBytes)] pub struct RequestType(u32); { IN = 0; @@ -64,7 +64,7 @@ c_enum! { } c_enum! { - #[derive(FromBytes, FromZeroes)] + #[derive(FromBytes)] pub struct Status(u8); { OK = 0; @@ -74,7 +74,7 @@ c_enum! { } #[repr(C)] -#[derive(Debug, FromZeroes, FromBytes)] +#[derive(Debug, FromBytes)] pub struct Request { type_: RequestType, reserved: u32, @@ -104,7 +104,7 @@ bitflags! { } } -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, FromZeros, Immutable, IntoBytes)] #[repr(C)] pub struct BlockConfig { capacity: u64, @@ -222,7 +222,7 @@ impl Block { let [hdr, data_out @ ..] = &desc.readable[..] else { return error::InvalidBuffer.fail(); }; - let Some(request) = Request::read_from(hdr) else { + let Ok(request) = Request::read_from_bytes(hdr) else { return error::InvalidBuffer.fail(); }; let [data_in @ .., status_buf] = &mut desc.writable[..] else { diff --git a/alioth/src/virtio/dev/fs.rs b/alioth/src/virtio/dev/fs.rs index 0820b0f..2ad1a54 100644 --- a/alioth/src/virtio/dev/fs.rs +++ b/alioth/src/virtio/dev/fs.rs @@ -32,7 +32,7 @@ use mio::unix::SourceFd; use mio::{Interest, Registry, Token}; use serde::Deserialize; use serde_aco::Help; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::hv::IoeventFd; use crate::mem::mapped::{ArcMemPages, Ram, RamBus}; @@ -48,7 +48,7 @@ use crate::virtio::{error, DeviceId, IrqSender, Result, VirtioFeature}; use crate::{align_up, ffi, impl_mmio_for_zerocopy}; #[repr(C, align(4))] -#[derive(Debug, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, FromBytes, Immutable, IntoBytes)] pub struct FsConfig { tag: [u8; 36], num_request_queues: u32, @@ -64,7 +64,7 @@ bitflags! { } } -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, Immutable, IntoBytes)] #[repr(C)] struct VuFsMap { pub fd_offset: [u64; 8], @@ -135,7 +135,7 @@ impl VuFs { let mut empty_cfg = DeviceConfig::new_zeroed(); empty_cfg.size = size_of_val(&empty_cfg.region) as _; let dev_config = vu_dev.get_config(&empty_cfg)?; - FsConfig::read_from_prefix(&dev_config.region).unwrap() + FsConfig::read_from_prefix(&dev_config.region).unwrap().0 }; let dax_region = if param.dax_window > 0 { vu_dev.setup_channel()?; @@ -345,7 +345,7 @@ impl VirtioMio for VuFs { let mut fds = [None, None, None, None, None, None, None, None]; let ret = self .vu_dev - .receive_from_channel(fs_map.as_bytes_mut(), &mut fds); + .receive_from_channel(fs_map.as_mut_bytes(), &mut fds); let (request, size) = match ret { Ok((r, s)) => (r, s), Err(Error::System { error, .. }) if error.kind() == ErrorKind::WouldBlock => break, diff --git a/alioth/src/virtio/dev/net/net.rs b/alioth/src/virtio/dev/net/net.rs index 2dd37b7..07e7112 100644 --- a/alioth/src/virtio/dev/net/net.rs +++ b/alioth/src/virtio/dev/net/net.rs @@ -34,7 +34,7 @@ use mio::unix::SourceFd; use mio::{Interest, Registry, Token}; use serde::Deserialize; use serde_aco::Help; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; use crate::hv::IoeventFd; use crate::mem::mapped::{Ram, RamBus}; @@ -53,7 +53,7 @@ pub mod tap; use tap::{tun_set_iff, tun_set_offload, tun_set_vnet_hdr_sz, TunFeature}; #[repr(C, align(8))] -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, FromBytes, Immutable, IntoBytes)] pub struct NetConfig { mac: MacAddr, status: u16, @@ -69,7 +69,7 @@ pub struct NetConfig { impl_mmio_for_zerocopy!(NetConfig); c_enum! { - #[derive(FromBytes, FromZeroes)] + #[derive(Default, FromBytes, Immutable, IntoBytes)] struct CtrlAck(u8); { OK = 0; @@ -78,7 +78,7 @@ c_enum! { } c_enum! { - #[derive(FromBytes, FromZeroes)] + #[derive(Default, FromBytes, Immutable, IntoBytes)] struct CtrlClass(u8); { MQ = 4; @@ -86,6 +86,7 @@ c_enum! { } c_enum! { + #[derive(Default, FromBytes, Immutable, IntoBytes)] struct CtrlMq(u8); { VQ_PARIS_SET = 0; @@ -93,13 +94,13 @@ c_enum! { } #[repr(C)] -#[derive(Debug, FromBytes, FromZeroes)] +#[derive(Debug, Default, FromBytes, Immutable, IntoBytes)] struct CtrlMqParisSet { virtq_pairs: u16, } #[repr(C)] -#[derive(Debug, FromBytes, FromZeroes)] +#[derive(Debug, Default, FromBytes, Immutable, IntoBytes)] struct CtrlHdr { class: CtrlClass, command: u8, @@ -241,7 +242,11 @@ impl Net { desc: &mut Descriptor, registry: Option<&Registry>, ) -> Result { - let Some(header) = desc.readable.first().and_then(|b| CtrlHdr::ref_from(b)) else { + let Some(header) = desc + .readable + .first() + .and_then(|b| CtrlHdr::read_from_bytes(b).ok()) + else { return error::InvalidBuffer.fail(); }; let Some(ack_byte) = desc.writable.first_mut().and_then(|v| v.first_mut()) else { @@ -250,7 +255,7 @@ impl Net { let ack = match header.class { CtrlClass::MQ => match CtrlMq(header.command) { CtrlMq::VQ_PARIS_SET => { - let to_set = |b: &IoSlice| CtrlMqParisSet::read_from(b); + let to_set = |b: &IoSlice| CtrlMqParisSet::read_from_bytes(b).ok(); let Some(data) = desc.readable.get(1).and_then(to_set) else { return error::InvalidBuffer.fail(); }; @@ -500,7 +505,7 @@ fn setup_socket(file: &mut File, if_name: Option<&str>, mq: bool) -> Result<()> if let Some(name) = if_name { let name_len = std::cmp::min(tap_ifconfig.ifr_name.len() - 1, name.len()); - tap_ifconfig.ifr_name.as_bytes_mut()[0..name_len] + tap_ifconfig.ifr_name.as_mut_bytes()[0..name_len] .copy_from_slice(&name.as_bytes()[0..name_len]); } diff --git a/alioth/src/virtio/dev/vsock/vsock.rs b/alioth/src/virtio/dev/vsock/vsock.rs index 8efcc5c..00789c5 100644 --- a/alioth/src/virtio/dev/vsock/vsock.rs +++ b/alioth/src/virtio/dev/vsock/vsock.rs @@ -15,13 +15,13 @@ mod vhost_vsock; use bitflags::bitflags; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromZeros, Immutable, IntoBytes}; use crate::impl_mmio_for_zerocopy; pub use vhost_vsock::{VhostVsock, VhostVsockParam}; -#[derive(Debug, Clone, Copy, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, Copy, Default, FromZeros, Immutable, IntoBytes)] #[repr(C)] pub struct VsockConfig { pub guest_cid: u32, diff --git a/alioth/src/virtio/pci.rs b/alioth/src/virtio/pci.rs index 9946b3c..1358121 100644 --- a/alioth/src/virtio/pci.rs +++ b/alioth/src/virtio/pci.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use macros::Layout; use parking_lot::{Mutex, RwLock}; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromZeros, Immutable, IntoBytes}; use crate::hv::{IoeventFd, IoeventFdRegistry, IrqFd, MsiSender}; use crate::mem::emulated::{Action, Mmio}; @@ -577,7 +577,7 @@ pub enum VirtioPciCfg { } #[repr(C, align(4))] -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, FromZeros, Immutable, IntoBytes)] pub struct VirtioPciCap { header: PciCapHdr, cap_len: u8, @@ -599,7 +599,7 @@ impl PciCap for VirtioPciCap { } #[repr(C, align(4))] -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, FromZeros, Immutable, IntoBytes)] pub struct VirtioPciCap64 { cap: VirtioPciCap, offset_hi: u32, @@ -615,7 +615,7 @@ impl PciCap for VirtioPciCap64 { } #[repr(C, align(4))] -#[derive(Debug, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Default, FromZeros, Immutable, IntoBytes)] pub struct VirtioPciNotifyCap { cap: VirtioPciCap, multiplier: u32, diff --git a/alioth/src/virtio/queue/split.rs b/alioth/src/virtio/queue/split.rs index 44992a8..30e4eb0 100644 --- a/alioth/src/virtio/queue/split.rs +++ b/alioth/src/virtio/queue/split.rs @@ -17,14 +17,14 @@ use std::sync::atomic::{fence, Ordering}; use bitflags::bitflags; use macros::Layout; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, Immutable, IntoBytes}; use crate::mem::mapped::Ram; use crate::virtio::queue::{Descriptor, Queue, VirtQueue}; use crate::virtio::{error, Result, VirtioFeature}; #[repr(C, align(16))] -#[derive(Debug, Clone, Default, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, Default, FromBytes, Immutable, IntoBytes)] pub struct Desc { pub addr: u64, pub len: u32, diff --git a/alioth/src/virtio/vu.rs b/alioth/src/virtio/vu.rs index 98e520a..40d92d5 100644 --- a/alioth/src/virtio/vu.rs +++ b/alioth/src/virtio/vu.rs @@ -25,7 +25,7 @@ use bitfield::bitfield; use bitflags::bitflags; use parking_lot::Mutex; use snafu::{ResultExt, Snafu}; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes}; use crate::errors::{boxed_debug_trace, trace_error, DebugTrace}; use crate::mem::mapped::ArcMemPages; @@ -104,7 +104,7 @@ pub const VHOST_USER_SET_DEVICE_STATE_FD: u32 = 42; pub const VHOST_USER_CHECK_DEVICE_STATE: u32 = 43; bitfield! { - #[derive(Copy, Clone, Default, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Default, IntoBytes, FromBytes, Immutable)] #[repr(transparent)] pub struct MessageFlag(u32); impl Debug; @@ -125,14 +125,14 @@ impl MessageFlag { } } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct VirtqState { pub index: u32, pub val: u32, } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct VirtqAddr { pub index: u32, @@ -143,7 +143,7 @@ pub struct VirtqAddr { pub log_guest_addr: u64, } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct MemoryRegion { pub gpa: u64, @@ -152,14 +152,14 @@ pub struct MemoryRegion { pub mmap_offset: u64, } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct MemorySingleRegion { pub _padding: u64, pub region: MemoryRegion, } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct MemoryMultipleRegion { pub num: u32, @@ -167,7 +167,7 @@ pub struct MemoryMultipleRegion { pub regions: [MemoryRegion; 8], } -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct DeviceConfig { pub offset: u32, @@ -176,7 +176,7 @@ pub struct DeviceConfig { pub region: [u8; 256], } -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable)] #[repr(C)] pub struct Message { pub request: u32, @@ -251,7 +251,7 @@ impl VuDev { self.channel.as_ref() } - fn send_msg( + fn send_msg( &self, req: u32, payload: &T, @@ -306,13 +306,13 @@ impl VuDev { let mut ret_code = u64::MAX; let mut bufs = if size_of::() == 0 { [ - IoSliceMut::new(resp.as_bytes_mut()), - IoSliceMut::new(ret_code.as_bytes_mut()), + IoSliceMut::new(resp.as_mut_bytes()), + IoSliceMut::new(ret_code.as_mut_bytes()), ] } else { [ - IoSliceMut::new(resp.as_bytes_mut()), - IoSliceMut::new(payload.as_bytes_mut()), + IoSliceMut::new(resp.as_mut_bytes()), + IoSliceMut::new(payload.as_mut_bytes()), ] }; let read_size = conn.read_vectored(&mut bufs)?; @@ -425,7 +425,7 @@ impl VuDev { fds: &mut [Option], ) -> Result<(u32, u32)> { let mut msg = Message::new_zeroed(); - let mut bufs = [IoSliceMut::new(msg.as_bytes_mut()), IoSliceMut::new(buf)]; + let mut bufs = [IoSliceMut::new(msg.as_mut_bytes()), IoSliceMut::new(buf)]; const CMSG_BUF_LEN: usize = unsafe { libc::CMSG_SPACE(8) } as usize; debug_assert_eq!(CMSG_BUF_LEN % size_of::(), 0); let mut cmsg_buf = [0u64; CMSG_BUF_LEN / size_of::()]; @@ -480,7 +480,7 @@ impl VuDev { Ok((msg.request, msg.size)) } - pub fn ack_request(&self, req: u32, payload: &T) -> Result<()> { + pub fn ack_request(&self, req: u32, payload: &T) -> Result<()> { let Some(channel) = &self.channel else { return error::ProtocolFeature { feature: VuFeature::BACKEND_REQ,