From 3240a0e93cafee93a17868cd43dd293340a9de9f Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Tue, 21 Jan 2025 12:40:04 -0800 Subject: [PATCH 01/14] zerocopy: move to zerocopy 0.8 This is a massive commit. Thankfully, much of the change is mechanical. This change leaves some classes of improvements & fix-ups: * map_err: These are cases where an error was already returned. Now that zerocopy 0.8 methods return a Result<...> rather than an Option<...>, those errors could be enriched with the details returned from the zerocopy methods. * err, option-to-err, unwrap, etc.: These are cases where an error is turned into a panic or None (Option). In these cases, the calling code could better leverage the zerocopy error handling. * review carefully: this is due to some cases where the changes are less mechanical, so should be treated as suspect. * *use-rest-of-range*: these are cases where the zerocopy support functions now return a tuple (T, &[u8]), where the slice is the rest of the buffer. In some cases, the code calling the zerocopy methods could use the resulting slice rather than walking the data type manually. --- Cargo.lock | 287 ++++++++-------- Cargo.toml | 14 +- Guide/src/dev_guide/contrib/code.md | 14 +- openhcl/hcl/Cargo.toml | 1 - openhcl/hcl/src/ioctl.rs | 30 +- openhcl/hcl/src/ioctl/deferred.rs | 2 +- openhcl/hcl/src/ioctl/x64.rs | 5 +- openhcl/hcl/src/protocol.rs | 21 +- openhcl/hcl/src/vmsa.rs | 14 +- openhcl/minimal_rt/Cargo.toml | 1 - .../minimal_rt/src/arch/aarch64/hypercall.rs | 10 +- .../src/igvm_attest/get.rs | 23 +- .../openhcl_attestation_protocol/src/vmgs.rs | 21 +- openhcl/openhcl_boot/Cargo.toml | 1 - .../src/arch/x86_64/address_space.rs | 9 +- openhcl/openhcl_boot/src/hypercall.rs | 50 ++- openhcl/openhcl_boot/src/main.rs | 62 ++-- openhcl/sidecar/Cargo.toml | 1 - openhcl/sidecar/src/arch/x86_64/init.rs | 4 +- openhcl/sidecar/src/arch/x86_64/mod.rs | 4 +- openhcl/sidecar/src/arch/x86_64/vp.rs | 32 +- openhcl/sidecar_client/src/lib.rs | 30 +- openhcl/sidecar_defs/Cargo.toml | 1 - openhcl/sidecar_defs/src/lib.rs | 30 +- openhcl/underhill_attestation/Cargo.toml | 1 - .../src/hardware_key_sealing.rs | 6 +- .../src/igvm_attest/ak_cert.rs | 16 +- .../src/igvm_attest/mod.rs | 4 +- .../src/igvm_attest/wrapped_key.rs | 4 +- .../src/key_protector.rs | 12 +- openhcl/underhill_attestation/src/lib.rs | 4 +- openhcl/underhill_attestation/src/vmgs.rs | 27 +- openhcl/underhill_core/Cargo.toml | 1 - .../src/get_tracing/json_layer.rs | 10 +- openhcl/underhill_core/src/loader/mod.rs | 7 +- .../underhill_core/src/loader/vtl0_config.rs | 8 +- .../src/loader/vtl2_config/mod.rs | 9 +- openhcl/underhill_core/src/worker.rs | 2 +- openhcl/underhill_crash/Cargo.toml | 1 - openhcl/underhill_crash/src/elf.rs | 11 +- openhcl/underhill_crash/src/lib.rs | 19 +- openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs | 7 +- .../virt_mshv_vtl/src/cvm_cpuid/tests/mod.rs | 4 +- .../src/cvm_cpuid/tests/topology.rs | 1 + .../virt_mshv_vtl/src/cvm_cpuid/tests/xfem.rs | 2 +- openhcl/virt_mshv_vtl/src/lib.rs | 8 +- .../src/processor/hardware_cvm/mod.rs | 2 +- .../virt_mshv_vtl/src/processor/mshv/arm64.rs | 6 +- .../virt_mshv_vtl/src/processor/mshv/x64.rs | 111 ++++-- .../virt_mshv_vtl/src/processor/snp/mod.rs | 19 +- .../src/processor/tdx/tlb_flush.rs | 2 +- openvmm/hvlite_core/Cargo.toml | 1 - .../hvlite_core/src/worker/vm_loaders/igvm.rs | 4 +- .../hvlite_core/src/worker/vm_loaders/uefi.rs | 2 +- rules/.gitkeep | 0 rules/cargo-toml-fixups.pl | 24 ++ rules/fixup_read_from_prefix_split.pl | 97 ++++++ rules/remove-from-zeroes.yaml | 24 ++ rules/replace-asbytes-derive-macro.yaml | 29 ++ rules/replace-asbytes-derive.yaml | 29 ++ rules/replace-use-asbytes.yml | 11 + rules/unwrap-header-for-x64.rs.pl | 24 ++ sgconfig.yml | 2 + support/fdt/Cargo.toml | 2 - support/fdt/src/builder.rs | 13 +- support/fdt/src/parser.rs | 59 ++-- support/fdt/src/spec.rs | 11 +- support/guid/Cargo.toml | 1 - support/guid/src/lib.rs | 12 +- support/mesh/mesh_node/Cargo.toml | 1 - support/mesh/mesh_node/src/local_node.rs | 17 +- .../mesh/mesh_node/src/local_node/protocol.rs | 17 +- support/mesh/mesh_protobuf/Cargo.toml | 1 - support/mesh/mesh_protobuf/src/encoding.rs | 10 +- support/mesh/mesh_remote/Cargo.toml | 1 - support/mesh/mesh_remote/src/alpc_node.rs | 10 +- .../mesh/mesh_remote/src/point_to_point.rs | 10 +- support/mesh/mesh_remote/src/protocol.rs | 11 +- support/mesh/mesh_remote/src/unix_node.rs | 15 +- support/mesh/mesh_rpc/Cargo.toml | 1 - support/mesh/mesh_rpc/src/message.rs | 10 +- support/pal/pal_async/Cargo.toml | 1 - .../pal/pal_async/src/windows/overlapped.rs | 13 +- support/safeatomic/Cargo.toml | 1 - support/safeatomic/src/lib.rs | 18 +- support/sev_guest_device/Cargo.toml | 1 - support/sev_guest_device/src/ioctl.rs | 4 +- support/sev_guest_device/src/protocol.rs | 18 +- support/sparse_mmap/src/lib.rs | 32 +- support/tdx_guest_device/Cargo.toml | 1 - support/tdx_guest_device/src/ioctl.rs | 2 +- support/tdx_guest_device/src/protocol.rs | 19 +- support/tee_call/Cargo.toml | 1 - support/tee_call/src/lib.rs | 2 +- support/zerocopy_helpers/Cargo.toml | 13 - support/zerocopy_helpers/src/lib.rs | 32 -- vm/aarch64/aarch64defs/Cargo.toml | 1 - vm/aarch64/aarch64defs/src/lib.rs | 9 +- vm/acpi/Cargo.toml | 1 - vm/acpi/src/builder.rs | 2 +- vm/acpi/src/dsdt.rs | 7 +- vm/acpi_spec/Cargo.toml | 1 - vm/acpi_spec/src/aspt.rs | 23 +- vm/acpi_spec/src/fadt.rs | 12 +- vm/acpi_spec/src/lib.rs | 11 +- vm/acpi_spec/src/madt.rs | 38 ++- vm/acpi_spec/src/pptt.rs | 20 +- vm/acpi_spec/src/srat.rs | 40 +-- vm/chipset_device_fuzz/src/lib.rs | 2 +- vm/devices/firmware/firmware_pcat/Cargo.toml | 1 - vm/devices/firmware/firmware_pcat/src/lib.rs | 2 +- .../firmware_pcat/src/root_cpu_data.rs | 18 +- vm/devices/firmware/firmware_uefi/Cargo.toml | 1 - .../firmware/firmware_uefi/fuzz/Cargo.toml | 1 - .../firmware_uefi/fuzz/fuzz_firmware_uefi.rs | 4 +- .../firmware_uefi/src/service/event_log.rs | 6 +- .../firmware_uefi/src/service/nvram/mod.rs | 4 +- .../nvram/spec_services/auth_var_crypto.rs | 2 +- .../src/service/nvram/spec_services/mod.rs | 10 +- .../hcl_compat_uefi_nvram_storage/Cargo.toml | 2 - .../hcl_compat_uefi_nvram_storage/src/lib.rs | 28 +- .../hyperv_uefi_custom_vars_json/Cargo.toml | 1 - .../hyperv_uefi_custom_vars_json/src/lib.rs | 2 +- .../firmware/uefi_nvram_specvars/Cargo.toml | 2 - .../uefi_nvram_specvars/src/boot_order.rs | 32 +- .../uefi_nvram_specvars/src/signature_list.rs | 16 +- .../firmware/uefi_nvram_storage/Cargo.toml | 1 - .../uefi_nvram_storage/src/in_memory.rs | 4 +- vm/devices/firmware/uefi_specs/Cargo.toml | 1 - .../uefi_specs/src/hyperv/bios_event_log.rs | 9 +- .../uefi_specs/src/hyperv/boot_bios_log.rs | 9 +- .../firmware/uefi_specs/src/hyperv/common.rs | 7 +- .../firmware/uefi_specs/src/hyperv/crypto.rs | 11 +- .../firmware/uefi_specs/src/hyperv/nvram.rs | 19 +- .../firmware/uefi_specs/src/hyperv/time.rs | 7 +- vm/devices/firmware/uefi_specs/src/lib.rs | 2 +- .../firmware/uefi_specs/src/uefi/boot.rs | 35 +- .../firmware/uefi_specs/src/uefi/common.rs | 9 +- .../firmware/uefi_specs/src/uefi/nvram.rs | 26 +- .../firmware/uefi_specs/src/uefi/signing.rs | 9 +- .../firmware/uefi_specs/src/uefi/time.rs | 12 +- vm/devices/get/get_helpers/Cargo.toml | 1 - vm/devices/get/get_helpers/src/lib.rs | 2 +- vm/devices/get/get_protocol/Cargo.toml | 1 - vm/devices/get/get_protocol/src/crash.rs | 37 +- vm/devices/get/get_protocol/src/lib.rs | 234 ++++++------- vm/devices/get/guest_crash_device/Cargo.toml | 1 - vm/devices/get/guest_crash_device/src/lib.rs | 15 +- .../get/guest_emulation_device/Cargo.toml | 2 - .../get/guest_emulation_device/src/lib.rs | 72 ++-- .../src/test_utilities.rs | 32 +- vm/devices/get/guest_emulation_log/Cargo.toml | 2 - vm/devices/get/guest_emulation_log/src/lib.rs | 10 +- .../get/guest_emulation_transport/Cargo.toml | 2 - .../get/guest_emulation_transport/src/api.rs | 3 +- .../guest_emulation_transport/src/client.rs | 2 +- .../get/guest_emulation_transport/src/lib.rs | 6 +- .../src/process_loop.rs | 101 +++--- vm/devices/hyperv_ic/Cargo.toml | 2 - vm/devices/hyperv_ic/src/shutdown.rs | 20 +- vm/devices/hyperv_ic_guest/Cargo.toml | 2 - vm/devices/hyperv_ic_guest/src/shutdown.rs | 28 +- vm/devices/hyperv_ic_protocol/Cargo.toml | 1 - vm/devices/hyperv_ic_protocol/src/lib.rs | 33 +- vm/devices/net/gdma/Cargo.toml | 1 - vm/devices/net/gdma/src/bnic.rs | 18 +- vm/devices/net/gdma/src/hwc.rs | 12 +- vm/devices/net/gdma/src/lib.rs | 8 +- vm/devices/net/gdma/src/queues.rs | 14 +- vm/devices/net/gdma_defs/Cargo.toml | 1 - vm/devices/net/gdma_defs/src/bnic.rs | 61 ++-- vm/devices/net/gdma_defs/src/lib.rs | 89 ++--- vm/devices/net/mana_driver/Cargo.toml | 1 - vm/devices/net/mana_driver/src/bnic_driver.rs | 10 +- vm/devices/net/mana_driver/src/gdma_driver.rs | 34 +- vm/devices/net/mana_driver/src/queues.rs | 10 +- vm/devices/net/net_mana/Cargo.toml | 1 - vm/devices/net/net_mana/src/lib.rs | 6 +- vm/devices/net/netvsp/src/buffers.rs | 10 +- vm/devices/net/netvsp/src/lib.rs | 36 +- vm/devices/net/netvsp/src/protocol.rs | 55 +-- vm/devices/net/netvsp/src/rndisprot.rs | 95 +++--- vm/devices/net/netvsp/src/test.rs | 16 +- vm/devices/net/vmswitch/Cargo.toml | 2 - vm/devices/net/vmswitch/src/dio.rs | 11 +- vm/devices/pci/pci_bus/Cargo.toml | 1 - vm/devices/pci/pci_bus/src/lib.rs | 10 +- vm/devices/pci/pci_core/Cargo.toml | 1 - .../pci_core/src/capabilities/read_only.rs | 10 +- vm/devices/pci/pci_core/src/spec.rs | 9 +- vm/devices/pci/vpci/Cargo.toml | 1 - vm/devices/pci/vpci/src/device.rs | 81 +++-- vm/devices/pci/vpci/src/protocol.rs | 136 +++++--- .../serial/vmbus_serial_guest/Cargo.toml | 1 - .../serial/vmbus_serial_guest/src/lib.rs | 19 +- .../serial/vmbus_serial_host/Cargo.toml | 1 - .../serial/vmbus_serial_host/src/lib.rs | 31 +- .../serial/vmbus_serial_protocol/Cargo.toml | 1 - .../serial/vmbus_serial_protocol/src/lib.rs | 32 +- vm/devices/storage/disk_blob/Cargo.toml | 1 - vm/devices/storage/disk_blob/src/lib.rs | 6 +- .../storage/disk_blockdevice/src/ioctl.rs | 7 +- .../storage/disk_blockdevice/src/nvme.rs | 33 +- .../storage/disk_nvme/nvme_driver/Cargo.toml | 1 - .../disk_nvme/nvme_driver/src/driver.rs | 14 +- .../disk_nvme/nvme_driver/src/namespace.rs | 14 +- .../disk_nvme/nvme_driver/src/queue_pair.rs | 4 +- .../disk_nvme/nvme_driver/src/tests.rs | 4 +- vm/devices/storage/disk_vhd1/Cargo.toml | 1 - vm/devices/storage/disk_vhd1/src/lib.rs | 12 +- vm/devices/storage/disklayer_ram/Cargo.toml | 1 - vm/devices/storage/disklayer_ram/src/lib.rs | 4 +- vm/devices/storage/ide/Cargo.toml | 1 - .../storage/ide/src/drive/atapi_drive.rs | 10 +- .../storage/ide/src/drive/hard_drive.rs | 6 +- vm/devices/storage/ide/src/lib.rs | 18 +- vm/devices/storage/ide/src/protocol.rs | 17 +- vm/devices/storage/nvme/src/namespace.rs | 19 +- .../nvme/src/namespace/reservations.rs | 18 +- vm/devices/storage/nvme/src/prp.rs | 4 +- .../nvme/src/tests/controller_tests.rs | 36 +- .../nvme/src/tests/shadow_doorbell_tests.rs | 4 +- vm/devices/storage/nvme/src/workers/admin.rs | 12 +- vm/devices/storage/nvme_spec/Cargo.toml | 1 - vm/devices/storage/nvme_spec/src/lib.rs | 29 +- vm/devices/storage/nvme_spec/src/nvm.rs | 37 +- vm/devices/storage/scsi_buffers/src/lib.rs | 9 +- vm/devices/storage/scsi_defs/src/lib.rs | 289 ++++++++-------- vm/devices/storage/scsi_defs/src/srb.rs | 9 +- vm/devices/storage/scsidisk/src/atapi_scsi.rs | 14 +- .../storage/scsidisk/src/getlbastatus.rs | 8 +- vm/devices/storage/scsidisk/src/inquiry.rs | 22 +- vm/devices/storage/scsidisk/src/lib.rs | 74 ++-- .../storage/scsidisk/src/reservation.rs | 22 +- .../storage/scsidisk/src/scsidvd/mod.rs | 109 ++++-- .../storage/scsidisk/src/tests/basic_tests.rs | 2 +- .../storage/scsidisk/src/tests/pr_tests.rs | 8 +- .../scsidisk/src/tests/test_helpers.rs | 2 +- vm/devices/storage/scsidisk/src/unmap.rs | 11 +- vm/devices/storage/storage_string/Cargo.toml | 1 - vm/devices/storage/storage_string/src/lib.rs | 7 +- vm/devices/storage/storvsp/Cargo.toml | 1 - vm/devices/storage/storvsp/fuzz/Cargo.toml | 1 - .../storage/storvsp/fuzz/fuzz_storvsp.rs | 8 +- vm/devices/storage/storvsp/src/ioperf.rs | 5 +- vm/devices/storage/storvsp/src/lib.rs | 29 +- vm/devices/storage/storvsp/src/protocol.rs | 23 +- .../storage/storvsp/src/save_restore.rs | 6 +- .../storage/storvsp/src/test_helpers.rs | 16 +- vm/devices/support/fs/fuse/Cargo.toml | 1 - vm/devices/support/fs/fuse/src/lib.rs | 7 +- vm/devices/support/fs/fuse/src/protocol.rs | 129 +++---- vm/devices/support/fs/fuse/src/reply.rs | 14 +- vm/devices/support/fs/fuse/src/request.rs | 8 +- vm/devices/support/fs/fuse/src/session.rs | 8 +- .../support/fs/fuse/tests/fuse_hello.rs | 2 +- vm/devices/support/fs/lxutil/Cargo.toml | 1 - .../support/fs/lxutil/src/windows/mod.rs | 8 +- .../support/fs/lxutil/src/windows/util.rs | 10 +- vm/devices/tpm/Cargo.toml | 1 - vm/devices/tpm/src/lib.rs | 31 +- vm/devices/tpm/src/tpm20proto.rs | 298 ++++++++-------- vm/devices/tpm/src/tpm_helper.rs | 29 +- vm/devices/uidevices/Cargo.toml | 2 - vm/devices/uidevices/src/keyboard/mod.rs | 24 +- vm/devices/uidevices/src/keyboard/protocol.rs | 15 +- vm/devices/uidevices/src/mouse/mod.rs | 31 +- vm/devices/uidevices/src/mouse/protocol.rs | 25 +- vm/devices/uidevices/src/video/mod.rs | 42 ++- vm/devices/uidevices/src/video/protocol.rs | 53 +-- vm/devices/user_driver/Cargo.toml | 1 - vm/devices/user_driver/src/lockmem.rs | 4 +- vm/devices/user_driver/src/memory.rs | 8 +- vm/devices/user_driver/src/vfio.rs | 8 +- vm/devices/vga/Cargo.toml | 1 - vm/devices/vga/src/emu.rs | 16 +- vm/devices/vga/src/render.rs | 4 +- vm/devices/virtio/virtio/Cargo.toml | 1 - vm/devices/virtio/virtio/src/spec.rs | 11 +- vm/devices/virtio/virtio/src/transport/pci.rs | 12 +- vm/devices/virtio/virtio_net/Cargo.toml | 1 - vm/devices/virtio/virtio_net/src/buffers.rs | 6 +- vm/devices/virtio/virtio_net/src/lib.rs | 17 +- vm/devices/virtio/virtiofs/Cargo.toml | 1 - vm/devices/virtio/virtiofs/src/file.rs | 2 +- vm/devices/virtio/virtiofs/src/virtio.rs | 6 +- vm/devices/vmbus/vmbfs/Cargo.toml | 2 - vm/devices/vmbus/vmbfs/src/lib.rs | 16 +- vm/devices/vmbus/vmbfs/src/protocol.rs | 33 +- vm/devices/vmbus/vmbus_async/Cargo.toml | 1 - vm/devices/vmbus/vmbus_async/src/pipe.rs | 16 +- vm/devices/vmbus/vmbus_async/src/queue.rs | 14 +- vm/devices/vmbus/vmbus_client/Cargo.toml | 1 - vm/devices/vmbus/vmbus_client/src/hvsock.rs | 4 +- vm/devices/vmbus/vmbus_client/src/lib.rs | 33 +- vm/devices/vmbus/vmbus_client_hcl/Cargo.toml | 1 - vm/devices/vmbus/vmbus_client_hcl/src/lib.rs | 4 +- vm/devices/vmbus/vmbus_core/Cargo.toml | 2 - vm/devices/vmbus/vmbus_core/src/lib.rs | 11 +- vm/devices/vmbus/vmbus_core/src/protocol.rs | 144 ++++---- .../vmbus/vmbus_core/src/protocol/macros.rs | 10 +- vm/devices/vmbus/vmbus_proxy/Cargo.toml | 1 - vm/devices/vmbus/vmbus_proxy/src/lib.rs | 12 +- .../vmbus_relay_intercept_device/Cargo.toml | 1 - .../vmbus_relay_intercept_device/src/lib.rs | 2 +- vm/devices/vmbus/vmbus_ring/Cargo.toml | 1 - vm/devices/vmbus/vmbus_ring/src/gparange.rs | 14 +- vm/devices/vmbus/vmbus_ring/src/lib.rs | 32 +- vm/devices/vmbus/vmbus_server/Cargo.toml | 2 - vm/devices/vmbus/vmbus_server/src/channels.rs | 50 +-- vm/devices/vmbus/vmbus_server/src/lib.rs | 24 +- .../vmbus_server/src/proxyintegration.rs | 5 +- .../vmbus/vmbus_user_channel/Cargo.toml | 1 - .../vmbus/vmbus_user_channel/src/lib.rs | 2 +- vm/hv1/hv1_emulator/Cargo.toml | 1 - vm/hv1/hv1_emulator/src/hv.rs | 4 +- vm/hv1/hv1_emulator/src/synic.rs | 2 +- vm/hv1/hv1_hypercall/Cargo.toml | 1 - vm/hv1/hv1_hypercall/src/imp.rs | 2 +- vm/hv1/hv1_hypercall/src/support.rs | 80 +++-- vm/hv1/hv1_hypercall/src/tests.rs | 85 ++--- vm/hv1/hvdef/Cargo.toml | 1 - vm/hv1/hvdef/src/lib.rs | 320 +++++++++--------- vm/loader/Cargo.toml | 2 +- vm/loader/igvmfilegen/Cargo.toml | 1 - vm/loader/igvmfilegen/src/file_loader.rs | 4 +- vm/loader/igvmfilegen/src/main.rs | 5 +- .../igvmfilegen/src/signed_measurement/snp.rs | 2 +- .../igvmfilegen/src/signed_measurement/tdx.rs | 9 +- .../igvmfilegen/src/signed_measurement/vbs.rs | 2 +- .../igvmfilegen/src/vp_context_builder/snp.rs | 8 +- .../igvmfilegen/src/vp_context_builder/tdx.rs | 6 +- vm/loader/loader_defs/Cargo.toml | 1 - vm/loader/loader_defs/src/linux.rs | 38 ++- vm/loader/loader_defs/src/paravisor.rs | 25 +- vm/loader/loader_defs/src/shim.rs | 9 +- vm/loader/page_table/Cargo.toml | 1 - vm/loader/page_table/src/x64.rs | 10 +- vm/loader/src/common.rs | 4 +- vm/loader/src/cpuid.rs | 12 +- vm/loader/src/elf.rs | 4 +- vm/loader/src/linux.rs | 16 +- vm/loader/src/paravisor.rs | 8 +- vm/loader/src/uefi/config.rs | 41 +-- vm/loader/src/uefi/mod.rs | 64 ++-- vm/vbs_defs/Cargo.toml | 1 - vm/vbs_defs/src/lib.rs | 16 +- vm/vhd1_defs/Cargo.toml | 1 - vm/vhd1_defs/src/lib.rs | 10 +- vm/vmcore/Cargo.toml | 1 - vm/vmcore/guestmem/src/lib.rs | 44 ++- vm/vmcore/src/monitor.rs | 6 +- vm/vmgs/vmgs/Cargo.toml | 1 - vm/vmgs/vmgs/src/encrypt/win.rs | 4 +- vm/vmgs/vmgs/src/vmgs_impl.rs | 19 +- vm/vmgs/vmgs_format/Cargo.toml | 1 - vm/vmgs/vmgs_format/src/lib.rs | 21 +- vm/whp/Cargo.toml | 1 - vm/whp/src/lib.rs | 7 +- vm/x86/x86defs/Cargo.toml | 1 - vm/x86/x86defs/src/cpuid.rs | 5 +- vm/x86/x86defs/src/lib.rs | 22 +- vm/x86/x86defs/src/snp.rs | 45 +-- vm/x86/x86defs/src/tdx.rs | 13 +- vm/x86/x86defs/src/vmx.rs | 9 +- vm/x86/x86defs/src/xsave.rs | 9 +- vm/x86/x86emu/tests/tests/rep/lods.rs | 2 +- vmm_core/Cargo.toml | 1 - vmm_core/src/acpi_builder.rs | 2 +- vmm_core/virt/Cargo.toml | 1 - vmm_core/virt/src/x86/vp.rs | 48 +-- vmm_core/virt_kvm/Cargo.toml | 1 - vmm_core/virt_kvm/src/arch/x86_64/mod.rs | 2 +- vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs | 4 +- vmm_core/virt_mshv/Cargo.toml | 1 - vmm_core/virt_mshv/src/lib.rs | 2 +- vmm_core/virt_mshv/src/vp_state.rs | 6 +- vmm_core/virt_support_aarch64emu/Cargo.toml | 1 - .../virt_support_aarch64emu/src/emulate.rs | 4 +- vmm_core/virt_support_x86emu/Cargo.toml | 1 - vmm_core/virt_support_x86emu/src/emulate.rs | 4 +- .../tests/tests/checkvtlaccess.rs | 4 +- .../tests/tests/translate.rs | 2 +- vmm_core/virt_whp/Cargo.toml | 1 - vmm_core/virt_whp/src/hypercalls.rs | 17 +- vmm_core/virt_whp/src/vp.rs | 27 +- vmm_core/virt_whp/src/vp_state.rs | 9 +- workers/vnc_worker/vnc/examples/vncserver.rs | 2 +- workers/vnc_worker/vnc/src/lib.rs | 36 +- workers/vnc_worker/vnc/src/rfb.rs | 47 +-- xtask/Cargo.toml | 1 - .../src/tasks/guest_test/uefi/gpt_efi_disk.rs | 2 +- 392 files changed, 3886 insertions(+), 3086 deletions(-) create mode 100644 rules/.gitkeep create mode 100644 rules/cargo-toml-fixups.pl create mode 100644 rules/fixup_read_from_prefix_split.pl create mode 100644 rules/remove-from-zeroes.yaml create mode 100644 rules/replace-asbytes-derive-macro.yaml create mode 100644 rules/replace-asbytes-derive.yaml create mode 100644 rules/replace-use-asbytes.yml create mode 100644 rules/unwrap-header-for-x64.rs.pl create mode 100644 sgconfig.yml delete mode 100644 support/zerocopy_helpers/Cargo.toml delete mode 100644 support/zerocopy_helpers/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9b8218ee1f..4707a9a14d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.0.0" dependencies = [ "bitfield-struct", "open_enum", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -32,7 +32,7 @@ dependencies = [ "acpi_spec", "memory_range", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -43,7 +43,7 @@ dependencies = [ "open_enum", "static_assertions", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -70,7 +70,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -517,7 +517,7 @@ dependencies = [ "parking_lot", "range_map_vec", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1132,7 +1132,7 @@ dependencies = [ "tokio", "vhd1_defs", "vm_resource", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1167,7 +1167,7 @@ dependencies = [ "tracing", "uevent", "vm_resource", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1310,7 +1310,7 @@ dependencies = [ "thiserror 2.0.0", "vhd1_defs", "vm_resource", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1352,7 +1352,7 @@ dependencies = [ "thiserror 2.0.0", "tracing", "vm_resource", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1399,7 +1399,7 @@ dependencies = [ "smallvec", "thiserror 1.0.68", "tracing", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -1595,8 +1595,7 @@ name = "fdt" version = "0.0.0" dependencies = [ "thiserror 2.0.0", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -1628,7 +1627,7 @@ dependencies = [ "tracing", "vm_topology", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1662,7 +1661,7 @@ dependencies = [ "vmcore", "watchdog_core", "wchar", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -1907,7 +1906,7 @@ dependencies = [ "test_with_tracing", "thiserror 2.0.0", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2050,7 +2049,7 @@ dependencies = [ "ucs2 0.0.0", "uefi_nvram_specvars", "xtask_fuzz", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2175,7 +2174,7 @@ dependencies = [ "vmbus_channel", "vmbus_ring", "xtask_fuzz", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2248,7 +2247,7 @@ dependencies = [ "tracing", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2259,7 +2258,7 @@ dependencies = [ "guestmem", "inspect", "open_enum", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2300,7 +2299,7 @@ version = "0.0.0" dependencies = [ "get_protocol", "guid", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2326,7 +2325,7 @@ dependencies = [ "serde_helpers", "serde_json", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2442,7 +2441,7 @@ dependencies = [ "vmbus_async", "vmbus_channel", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2476,8 +2475,7 @@ dependencies = [ "vmbus_channel", "vmbus_ring", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -2499,8 +2497,7 @@ dependencies = [ "vmbus_channel", "vmbus_ring", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -2535,8 +2532,7 @@ dependencies = [ "vmbus_ring", "vmbus_user_channel", "vpci", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -2567,7 +2563,7 @@ dependencies = [ "pal_event", "sparse_mmap", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2580,7 +2576,7 @@ dependencies = [ "thiserror 2.0.0", "winapi", "windows-sys 0.52.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2651,7 +2647,7 @@ dependencies = [ "tracing", "vtl_array", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2670,8 +2666,7 @@ dependencies = [ "ucs2 0.0.0", "uefi_nvram_storage", "wchar", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -2779,7 +2774,7 @@ dependencies = [ "vmcore", "vtl_array", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2794,7 +2789,7 @@ dependencies = [ "thiserror 2.0.0", "tracelimit", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2804,7 +2799,7 @@ dependencies = [ "bitfield-struct", "open_enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -2891,7 +2886,7 @@ dependencies = [ "vpci", "watchdog_core", "watchdog_vmgs_format", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3039,8 +3034,7 @@ dependencies = [ "vmbus_async", "vmbus_channel", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -3062,8 +3056,7 @@ dependencies = [ "vmbus_relay_intercept_device", "vmbus_ring", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -3073,7 +3066,7 @@ dependencies = [ "bitfield-struct", "guid", "open_enum", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3104,7 +3097,7 @@ dependencies = [ "serde_helpers", "serde_json", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3166,7 +3159,7 @@ dependencies = [ "tracing", "tracing_helpers", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3197,9 +3190,8 @@ dependencies = [ [[package]] name = "igvm" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7984b10433b50e06a06bd50c69bca4888a5d7de8975f64ea4c2a7687eb99b09d" +version = "0.3.4" +source = "git+https://github.com/microsoft/igvm?branch=main#365065d7e31da0a0116e7934de3ecd85f00bab70" dependencies = [ "bitfield-struct", "crc32fast", @@ -3207,21 +3199,21 @@ dependencies = [ "igvm_defs", "open-enum", "range_map_vec", + "static_assertions", "thiserror 1.0.68", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] name = "igvm_defs" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64ec5588c475372ae830475d3ee9a7bd255407dcb9f03faf6d493556eb6105a" +version = "0.3.4" +source = "git+https://github.com/microsoft/igvm?branch=main#365065d7e31da0a0116e7934de3ecd85f00bab70" dependencies = [ "bitfield-struct", "open-enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3249,7 +3241,7 @@ dependencies = [ "underhill_confidentiality", "vbs_defs", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3552,7 +3544,7 @@ dependencies = [ "tracing", "vm_topology", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3564,7 +3556,7 @@ dependencies = [ "inspect", "open_enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3623,7 +3615,7 @@ dependencies = [ "tracing", "widestring", "winapi", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3662,7 +3654,7 @@ dependencies = [ "tracing", "user_driver", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3829,7 +3821,7 @@ dependencies = [ "test_with_tracing", "thiserror 2.0.0", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3866,7 +3858,7 @@ dependencies = [ "prost-types", "socket2", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3892,7 +3884,7 @@ dependencies = [ "tracing_helpers", "unicycle", "unix_socket", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3920,7 +3912,7 @@ dependencies = [ "unicycle", "unix_socket", "urlencoding", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -3970,7 +3962,7 @@ dependencies = [ "cfg-if", "hvdef", "minimal_rt_build", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4043,7 +4035,7 @@ dependencies = [ "serde", "serde_derive", "vmm-sys-util", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -4170,7 +4162,7 @@ dependencies = [ "tracing", "user_driver", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4245,7 +4237,7 @@ dependencies = [ "vmbus_core", "vmbus_ring", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4373,7 +4365,7 @@ dependencies = [ "user_driver", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4414,7 +4406,7 @@ dependencies = [ "tracing", "user_driver", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4434,7 +4426,7 @@ dependencies = [ "inspect", "open_enum", "storage_string", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4520,7 +4512,7 @@ dependencies = [ "serde_json", "sev_guest_device", "tdx_guest_device", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4545,7 +4537,7 @@ dependencies = [ "tdcall", "underhill_confidentiality", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4843,7 +4835,7 @@ version = "0.0.0" dependencies = [ "bitfield-struct", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -4889,7 +4881,7 @@ dependencies = [ "unix_socket", "winapi", "windows-sys 0.52.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5024,7 +5016,7 @@ dependencies = [ "tracelimit", "tracing", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5042,7 +5034,7 @@ dependencies = [ "tracelimit", "tracing", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5657,7 +5649,7 @@ version = "0.0.0" name = "safeatomic" version = "0.0.0" dependencies = [ - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5708,7 +5700,7 @@ dependencies = [ "guestmem", "safeatomic", "smallvec", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5731,7 +5723,7 @@ dependencies = [ "arbitrary", "bitfield-struct", "open_enum", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -5762,7 +5754,7 @@ dependencies = [ "tracing_helpers", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6008,7 +6000,7 @@ dependencies = [ "nix 0.26.4", "static_assertions", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6054,7 +6046,7 @@ dependencies = [ "minimal_rt_build", "sidecar_defs", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6070,7 +6062,7 @@ dependencies = [ "sidecar_defs", "thiserror 2.0.0", "tracing", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6080,7 +6072,7 @@ dependencies = [ "hvdef", "open_enum", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6173,7 +6165,7 @@ dependencies = [ "parking_lot", "thiserror 2.0.0", "windows-sys 0.52.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6213,7 +6205,7 @@ dependencies = [ "inspect", "mesh_protobuf", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6256,7 +6248,7 @@ dependencies = [ "vmbus_core", "vmbus_ring", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6340,7 +6332,7 @@ dependencies = [ "nix 0.26.4", "static_assertions", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6351,7 +6343,7 @@ dependencies = [ "static_assertions", "tdx_guest_device", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6630,7 +6622,7 @@ dependencies = [ "tracing", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6825,8 +6817,7 @@ dependencies = [ "thiserror 2.0.0", "ucs2 0.0.0", "uefi_specs", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -6841,7 +6832,7 @@ dependencies = [ "ucs2 0.0.0", "uefi_specs", "wchar", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6855,7 +6846,7 @@ dependencies = [ "static_assertions", "ucs2 0.0.0", "wchar", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -6907,8 +6898,7 @@ dependencies = [ "vmbus_channel", "vmbus_ring", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -6945,7 +6935,7 @@ dependencies = [ "tracing", "vmgs", "vmgs_format", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7110,7 +7100,7 @@ dependencies = [ "watchdog_core", "watchdog_vmgs_format", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7130,7 +7120,7 @@ dependencies = [ "vergen", "vmbus_async", "vmbus_user_channel", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7296,7 +7286,7 @@ dependencies = [ "vfio-bindings", "vfio_sys", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7319,7 +7309,7 @@ dependencies = [ "igvm_defs", "open_enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7382,7 +7372,7 @@ dependencies = [ "tracing", "video_core", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7402,7 +7392,7 @@ name = "vhd1_defs" version = "0.0.0" dependencies = [ "guid", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7437,7 +7427,7 @@ dependencies = [ "vm_topology", "vmcore", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7490,7 +7480,7 @@ dependencies = [ "vm_topology", "vmcore", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7521,7 +7511,7 @@ dependencies = [ "vmm-sys-util", "x86defs", "x86emu", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7566,7 +7556,7 @@ dependencies = [ "vtl_array", "x86defs", "x86emu", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7581,7 +7571,7 @@ dependencies = [ "tracing", "virt", "vm_topology", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7630,7 +7620,7 @@ dependencies = [ "vm_topology", "x86defs", "x86emu", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7670,7 +7660,7 @@ dependencies = [ "winapi", "x86defs", "x86emu", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7700,7 +7690,7 @@ dependencies = [ "virtio_resources", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7728,7 +7718,7 @@ dependencies = [ "virtio_resources", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7807,7 +7797,7 @@ dependencies = [ "virtio_resources", "vm_resource", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7888,8 +7878,7 @@ dependencies = [ "vmbus_async", "vmbus_channel", "vmcore", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -7913,7 +7902,7 @@ dependencies = [ "thiserror 2.0.0", "vmbus_channel", "vmbus_ring", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7957,7 +7946,7 @@ dependencies = [ "vmbus_async", "vmbus_channel", "vmbus_core", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7973,7 +7962,7 @@ dependencies = [ "tracing", "vmbus_async", "vmbus_client", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -7989,8 +7978,7 @@ dependencies = [ "open_enum", "static_assertions", "thiserror 2.0.0", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -8007,7 +7995,7 @@ dependencies = [ "tracing", "vmbus_core", "winapi", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8057,7 +8045,7 @@ dependencies = [ "vmbus_ring", "vmbus_server", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8070,7 +8058,7 @@ dependencies = [ "safeatomic", "smallvec", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8095,7 +8083,7 @@ dependencies = [ "vmbus_serial_host", "vmbus_serial_protocol", "vmbus_user_channel", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8118,7 +8106,7 @@ dependencies = [ "vmbus_serial_protocol", "vmbus_serial_resources", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8128,7 +8116,7 @@ dependencies = [ "guid", "open_enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8170,8 +8158,7 @@ dependencies = [ "vmbus_ring", "vmcore", "winapi", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -8191,7 +8178,7 @@ dependencies = [ "vmbus_async", "vmbus_channel", "vmbus_ring", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8216,7 +8203,7 @@ dependencies = [ "tracelimit", "tracing", "vm_resource", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8247,7 +8234,7 @@ dependencies = [ "tracing", "vmgs_format", "windows", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8275,7 +8262,7 @@ dependencies = [ "inspect", "open_enum", "static_assertions", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8377,7 +8364,7 @@ dependencies = [ "vmotherboard", "vpci", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8524,8 +8511,7 @@ dependencies = [ "tracing", "widestring", "winapi", - "zerocopy", - "zerocopy_helpers", + "zerocopy 0.8.14", ] [[package]] @@ -8536,7 +8522,7 @@ dependencies = [ "pal_async", "socket2", "thiserror 2.0.0", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8598,7 +8584,7 @@ dependencies = [ "vmbus_channel", "vmbus_ring", "vmcore", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8750,7 +8736,7 @@ dependencies = [ "criterion", "win_import_lib", "winapi", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -8778,7 +8764,7 @@ dependencies = [ "widestring", "win_etw_metadata", "winapi", - "zerocopy", + "zerocopy 0.7.32", ] [[package]] @@ -9080,7 +9066,7 @@ dependencies = [ "arbitrary", "bitfield-struct", "open_enum", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -9092,7 +9078,7 @@ dependencies = [ "thiserror 2.0.0", "tracing", "x86defs", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -9138,7 +9124,7 @@ dependencies = [ "walkdir", "which 6.0.0", "xshell", - "zerocopy", + "zerocopy 0.8.14", ] [[package]] @@ -9156,7 +9142,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.32", +] + +[[package]] +name = "zerocopy" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468" +dependencies = [ + "zerocopy-derive 0.8.14", ] [[package]] @@ -9171,10 +9166,14 @@ dependencies = [ ] [[package]] -name = "zerocopy_helpers" -version = "0.0.0" +name = "zerocopy-derive" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1" dependencies = [ - "zerocopy", + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4cd4aa9260..2aee087334 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -143,7 +143,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" } @@ -436,10 +435,12 @@ iced-x86 = { version = "1.17", default-features = false, features = [ "no_d3now", ] } ignore = "0.4" -igvm = "0.3.3" -igvm_defs = { version = "0.3.3", default-features = false, features = [ - "unstable", -] } +#igvm = "0.3.3" +igvm = {git = "https://github.com/microsoft/igvm", branch = "main"} +#igvm_defs = { version = "0.3.3", default-features = false, features = [ +# "unstable", +#] } +igvm_defs = {git = "https://github.com/microsoft/igvm", branch = "main", default-features = false, features = [ "unstable" ]} image = { version = "0.24", default-features = false } io-uring = "0.6" kvm-bindings = "0.7" @@ -522,7 +523,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 diff --git a/Guide/src/dev_guide/contrib/code.md b/Guide/src/dev_guide/contrib/code.md index fe4fa135bd..decd3c1720 100644 --- a/Guide/src/dev_guide/contrib/code.md +++ b/Guide/src/dev_guide/contrib/code.md @@ -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: @@ -349,7 +351,7 @@ 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!** @@ -357,7 +359,7 @@ So, for the example above: ```rust #[repr(C)] -#[derive(zerocopy::FromZeroes)] +#[derive(zerocopy::FromZeros)] struct Handle { opaque_handle: u16 } @@ -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(); diff --git a/openhcl/hcl/Cargo.toml b/openhcl/hcl/Cargo.toml index 6ea173cef8..2bd4b608c9 100644 --- a/openhcl/hcl/Cargo.toml +++ b/openhcl/hcl/Cargo.toml @@ -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"] } diff --git a/openhcl/hcl/src/ioctl.rs b/openhcl/hcl/src/ioctl.rs index 6336e67e04..f0a280cce9 100644 --- a/openhcl/hcl/src/ioctl.rs +++ b/openhcl/hcl/src/ioctl.rs @@ -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)] @@ -1105,8 +1107,8 @@ impl MshvHvcall { output: &mut O, ) -> Result where - I: AsBytes + Sized, - O: AsBytes + FromBytes + Sized, + I: IntoBytes + Sized + Immutable + KnownLayout, + O: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, { const fn assert_size() where @@ -1124,7 +1126,7 @@ impl MshvHvcall { control, input_data: input.as_bytes().as_ptr().cast(), input_size: size_of::(), - status: FromZeroes::new_zeroed(), + status: FromZeros::new_zeroed(), output_data: output.as_bytes().as_ptr().cast(), output_size: size_of::(), }; @@ -1173,9 +1175,9 @@ impl MshvHvcall { output_rep: Option<&mut [O]>, ) -> Result 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 { @@ -1252,8 +1254,8 @@ impl MshvHvcall { output: &mut O, ) -> Result where - I: AsBytes + Sized, - O: AsBytes + FromBytes + Sized, + I: IntoBytes + Sized + Immutable + KnownLayout, + O: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, { const fn assert_size() where @@ -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::(), }; @@ -1988,7 +1990,7 @@ impl ProcessorRunner<'_, T> { assoc.push(HvRegisterAssoc { name: name.into(), pad: Default::default(), - value: FromZeroes::new_zeroed(), + value: FromZeros::new_zeroed(), }); offset.push(i); } @@ -2618,7 +2620,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. @@ -3093,7 +3095,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. diff --git a/openhcl/hcl/src/ioctl/deferred.rs b/openhcl/hcl/src/ioctl/deferred.rs index c8b36f8e85..e028c5d6a4 100644 --- a/openhcl/hcl/src/ioctl/deferred.rs +++ b/openhcl/hcl/src/ioctl/deferred.rs @@ -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 { diff --git a/openhcl/hcl/src/ioctl/x64.rs b/openhcl/hcl/src/ioctl/x64.rs index ac1244622d..007d3904ea 100644 --- a/openhcl/hcl/src/ioctl/x64.rs +++ b/openhcl/hcl/src/ioctl/x64.rs @@ -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. @@ -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. diff --git a/openhcl/hcl/src/protocol.rs b/openhcl/hcl/src/protocol.rs index 9e68dc0615..59f97a23c5 100644 --- a/openhcl/hcl/src/protocol.rs +++ b/openhcl/hcl/src/protocol.rs @@ -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)] @@ -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, @@ -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], @@ -81,7 +82,7 @@ pub struct hcl_cpu_context_x64 { const _: () = assert!(size_of::() == 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. @@ -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 @@ -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, @@ -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, @@ -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, @@ -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], diff --git a/openhcl/hcl/src/vmsa.rs b/openhcl/hcl/src/vmsa.rs index 702da19349..0ac04c772d 100644 --- a/openhcl/hcl/src/vmsa.rs +++ b/openhcl/hcl/src/vmsa.rs @@ -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> { @@ -98,16 +98,16 @@ impl> 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() { @@ -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 { @@ -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 diff --git a/openhcl/minimal_rt/Cargo.toml b/openhcl/minimal_rt/Cargo.toml index 2b312f8e76..aaa27752cf 100644 --- a/openhcl/minimal_rt/Cargo.toml +++ b/openhcl/minimal_rt/Cargo.toml @@ -12,7 +12,6 @@ hvdef.workspace = true arrayvec.workspace = true cfg-if.workspace = true zerocopy.workspace = true - [build-dependencies] minimal_rt_build.workspace = true diff --git a/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs b/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs index 1ad5a0cc3a..2cf9088125 100644 --- a/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs +++ b/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs @@ -44,9 +44,11 @@ use hvdef::HvRegisterName; use hvdef::HvRegisterValue; use hvdef::HvResult; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +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. @@ -106,7 +108,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, @@ -144,7 +146,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 { #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct Input { header: hvdef::hypercall::GetSetVpRegisters, name: HvRegisterName, diff --git a/openhcl/openhcl_attestation_protocol/src/igvm_attest/get.rs b/openhcl/openhcl_attestation_protocol/src/igvm_attest/get.rs index de0bf2de74..3b03eb3973 100644 --- a/openhcl/openhcl_attestation_protocol/src/igvm_attest/get.rs +++ b/openhcl/openhcl_attestation_protocol/src/igvm_attest/get.rs @@ -6,9 +6,10 @@ //! `IGVM_ATTEST` host request. use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const ATTESTATION_VERSION: u32 = 2; const ATTESTATION_SIGNATURE: u32 = 0x414c4348; // 'HCLA' @@ -41,7 +42,7 @@ pub const AK_CERT_RESPONSE_HEADER_VERSION: u32 = 1; /// The struct (includes the appended [`runtime_claims::RuntimeClaims`]) also serves as the /// attestation report in vTPM guest attestation. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestRequest { /// Header (unmeasured) pub header: IgvmAttestRequestHeader, @@ -57,7 +58,7 @@ pub struct IgvmAttestRequest { open_enum! { /// TEE attestation report type (C-style enum) - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum IgvmAttestReportType: u32 { /// Invalid report INVALID_REPORT = 0, @@ -74,7 +75,7 @@ open_enum! { open_enum! { /// Request type (C-style enum) - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum IgvmAttestRequestType: u32 { /// Invalid request INVALID_REQUEST = 0, @@ -89,7 +90,7 @@ open_enum! { open_enum! { /// Hash algorithm used for content of report data (C-style enum) - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum IgvmAttestHashType: u32 { /// Invalid hash INVALID_HASH = 0, @@ -104,7 +105,7 @@ open_enum! { /// Unmeasured data used to provide transport sanity and versioning (C-style struct) #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestRequestHeader { /// Signature pub signature: u32, @@ -138,7 +139,7 @@ const IGVM_ATTEST_VERSION_CURRENT: u32 = 1; /// Unmeasured user data, used for host attestation requests (C-style struct) #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestRequestData { /// Data size pub data_size: u32, @@ -174,7 +175,7 @@ impl IgvmAttestRequestData { /// /// reSearch query: `IGVM_KEY_MESSAGE_HEADER` #[repr(C)] -#[derive(Default, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Default, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestKeyReleaseResponseHeader { /// Data size pub data_size: u32, @@ -187,7 +188,7 @@ pub struct IgvmAttestKeyReleaseResponseHeader { /// /// reSearch query: `IGVM_KEY_MESSAGE_HEADER` #[repr(C)] -#[derive(Default, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Default, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestWrappedKeyResponseHeader { /// Data size pub data_size: u32, @@ -199,7 +200,7 @@ pub struct IgvmAttestWrappedKeyResponseHeader { /// /// reSearch query: `IGVM_CERT_MESSAGE_HEADER` #[repr(C)] -#[derive(Default, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Default, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IgvmAttestAkCertResponseHeader { /// Data size pub data_size: u32, diff --git a/openhcl/openhcl_attestation_protocol/src/vmgs.rs b/openhcl/openhcl_attestation_protocol/src/vmgs.rs index 07016e2f56..0a72629705 100644 --- a/openhcl/openhcl_attestation_protocol/src/vmgs.rs +++ b/openhcl/openhcl_attestation_protocol/src/vmgs.rs @@ -3,9 +3,10 @@ //! Include modules that define the data structures of VMGS entries. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Number of the key protector entries. /// One for ingress, and one for egress @@ -22,7 +23,7 @@ pub const KEY_PROTECTOR_SIZE: usize = size_of::(); /// DEK key protector entry. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DekKp { /// DEK buffer pub dek_buffer: [u8; DEK_BUFFER_SIZE], @@ -30,7 +31,7 @@ pub struct DekKp { /// GSP key protector entry. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GspKp { /// GSP data size pub gsp_length: u32, @@ -40,7 +41,7 @@ pub struct GspKp { /// The data format of the `FileId::KEY_PROTECTOR` entry in the VMGS file. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct KeyProtector { /// Array of DEK entries pub dek: [DekKp; NUMBER_KP], @@ -52,7 +53,7 @@ pub struct KeyProtector { /// The data format of the host/fabric-provided key protector. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct KeyProtectorById { /// Id pub id_guid: guid::Guid, @@ -67,7 +68,7 @@ pub const AGENT_DATA_MAX_SIZE: usize = 2048; /// The data format of the `FileId::ATTEST` entry in the VMGS file. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SecurityProfile { /// the agent data used during attestation requests pub agent_data: [u8; AGENT_DATA_MAX_SIZE], @@ -96,7 +97,7 @@ pub const HMAC_SHA_256_KEY_LENGTH: usize = 32; /// The header of [`HardwareKeyProtector`]. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HardwareKeyProtectorHeader { /// Version of the format pub version: u32, @@ -122,7 +123,7 @@ impl HardwareKeyProtectorHeader { /// The data format of the `FileId::HW_KEY_PROTECTOR` entry in the VMGS file. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HardwareKeyProtector { /// Header pub header: HardwareKeyProtectorHeader, @@ -139,7 +140,7 @@ pub const GUEST_SECRET_KEY_MAX_SIZE: usize = 2048; /// The data format of the `FileId::GUEST_SECRET_KEY` entry in the VMGS file. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GuestSecretKey { /// the guest secret key to be provisioned to vTPM pub guest_secret_key: [u8; GUEST_SECRET_KEY_MAX_SIZE], diff --git a/openhcl/openhcl_boot/Cargo.toml b/openhcl/openhcl_boot/Cargo.toml index 7f464e164c..f8d8a70e0a 100644 --- a/openhcl/openhcl_boot/Cargo.toml +++ b/openhcl/openhcl_boot/Cargo.toml @@ -27,7 +27,6 @@ crc32fast.workspace = true # implementation of the hashing algorithms that does not use cpuid. sha2 = { workspace = true, features = ["force-soft"] } zerocopy.workspace = true - [target.'cfg(target_arch = "x86_64")'.dependencies] safe_intrinsics.workspace = true tdcall.workspace = true diff --git a/openhcl/openhcl_boot/src/arch/x86_64/address_space.rs b/openhcl/openhcl_boot/src/arch/x86_64/address_space.rs index a555c99728..2ec7e567da 100644 --- a/openhcl/openhcl_boot/src/arch/x86_64/address_space.rs +++ b/openhcl/openhcl_boot/src/arch/x86_64/address_space.rs @@ -19,9 +19,10 @@ use core::sync::atomic::AtomicU64; use core::sync::atomic::Ordering; use memory_range::MemoryRange; use x86defs::X64_LARGE_PAGE_SIZE; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const X64_PTE_PRESENT: u64 = 1; const X64_PTE_READ_WRITE: u64 = 1 << 1; @@ -35,7 +36,7 @@ const PAGE_TABLE_ENTRY_COUNT: usize = 512; const X64_PAGE_SHIFT: u64 = 12; const X64_PTE_BITS: u64 = 9; -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(transparent)] struct PageTableEntry { entry: u64, @@ -103,7 +104,7 @@ impl PageTableEntry { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] struct PageTable { entries: [PageTableEntry; PAGE_TABLE_ENTRY_COUNT], } diff --git a/openhcl/openhcl_boot/src/hypercall.rs b/openhcl/openhcl_boot/src/hypercall.rs index a33993af81..df6159710a 100644 --- a/openhcl/openhcl_boot/src/hypercall.rs +++ b/openhcl/openhcl_boot/src/hypercall.rs @@ -13,8 +13,8 @@ use hvdef::Vtl; use hvdef::HV_PAGE_SIZE; use memory_range::MemoryRange; use minimal_rt::arch::hypercall::invoke_hypercall; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// Page-aligned, page-sized buffer for use with hypercalls #[repr(C, align(4096))] @@ -167,7 +167,9 @@ impl HvCall { rsvd: [0; 3], }; - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page let reg = hvdef::hypercall::HvRegisterAssoc { name, @@ -175,7 +177,8 @@ impl HvCall { value, }; - reg.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]); + reg.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]) + .unwrap(); // PANIC: Infallable, since the hypercall parameter is less than the size of a page let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallSetVpRegisters, Some(1)); @@ -196,13 +199,17 @@ impl HvCall { rsvd: [0; 3], }; - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); - name.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + name.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]) + .unwrap(); // PANIC: Infallable, since the hypercall payload is less than the size of a page let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallGetVpRegisters, Some(1)); output.result()?; - let value = hvdef::HvRegisterValue::read_from_prefix(&Self::output_page().buffer).unwrap(); - + let value = hvdef::HvRegisterValue::read_from_prefix(&Self::output_page().buffer) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range Ok(value) } @@ -224,12 +231,16 @@ impl HvCall { let remaining_pages = range.end_4k_gpn() - current_page; let count = remaining_pages.min(MAX_INPUT_ELEMENTS as u64); - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page let mut input_offset = HEADER_SIZE; for i in 0..count { let page_num = current_page + i; - page_num.write_to_prefix(&mut Self::input_page().buffer[input_offset..]); + page_num + .write_to_prefix(&mut Self::input_page().buffer[input_offset..]) + .unwrap(); // PANIC: Infallable, since the hypercall data is less than the size of a page input_offset += size_of::(); } @@ -256,10 +267,12 @@ impl HvCall { // HvInputVtl value. target_vtl: Vtl::Vtl2.into(), reserved: [0; 3], - vp_vtl_context: zerocopy::FromZeroes::new_zeroed(), + vp_vtl_context: zerocopy::FromZeros::new_zeroed(), }; - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallEnableVpVtl, None); match output.result() { @@ -296,7 +309,9 @@ impl HvCall { let remaining_pages = range.end_4k_gpn() - current_page; let count = remaining_pages.min(MAX_INPUT_ELEMENTS as u64); - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page let output = self.dispatch_hvcall( hvdef::HypercallCode::HvCallAcceptGpaPages, @@ -332,8 +347,12 @@ impl HvCall { const MAX_PER_CALL: usize = 512; for hw_ids in hw_ids.chunks(MAX_PER_CALL) { - header.write_to_prefix(Self::input_page().buffer.as_mut_slice()); - hw_ids.write_to_prefix(&mut Self::input_page().buffer[header.as_bytes().len()..]); + header + .write_to_prefix(Self::input_page().buffer.as_mut_slice()) + .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + hw_ids + .write_to_prefix(&mut Self::input_page().buffer[header.as_bytes().len()..]) + .unwrap(); // PANIC: Infallable, since the hypercall parameters are less than the size of a page // SAFETY: The input header and rep slice are the correct types for this hypercall. // The hypercall output is validated right after the hypercall is issued. @@ -343,8 +362,9 @@ impl HvCall { ); let n = r.elements_processed() as usize; + //todo: zerocopy: review carefully! output.extend( - u32::slice_from(&Self::output_page().buffer[..n * 4]) + <[u32]>::ref_from_bytes(&Self::output_page().buffer[..n * 4]) .unwrap() .iter() .copied(), diff --git a/openhcl/openhcl_boot/src/main.rs b/openhcl/openhcl_boot/src/main.rs index 8f24903336..d47979d0c9 100644 --- a/openhcl/openhcl_boot/src/main.rs +++ b/openhcl/openhcl_boot/src/main.rs @@ -51,7 +51,11 @@ use sidecar::SidecarConfig; use sidecar_defs::SidecarOutput; use sidecar_defs::SidecarParams; use single_threaded::OffStackRef; -use zerocopy::FromZeroes; +use zerocopy::FromBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug)] struct CommandLineTooLong; @@ -268,7 +272,7 @@ fn build_kernel_command_line( const FDT_SIZE: usize = 256 * 1024; #[repr(C, align(4096))] -#[derive(zerocopy::FromBytes, zerocopy::FromZeroes)] +#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] struct Fdt { header: setup_data, data: [u8; FDT_SIZE - size_of::()], @@ -389,10 +393,12 @@ mod x86_boot { use memory_range::walk_ranges; use memory_range::MemoryRange; use memory_range::RangeWalkResult; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::KnownLayout; #[repr(C)] - #[derive(FromZeroes)] + #[derive(FromZeros, Immutable, KnownLayout)] pub struct E820Ext { pub header: setup_data, pub entries: [e820entry; 512], @@ -532,11 +538,11 @@ fn build_cc_blob_sev_info( } #[repr(C, align(4096))] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] struct PageAlign(T); -const fn zeroed() -> T { - // SAFETY: `T` implements `FromZeroes`, so this is a safe initialization of `T`. +const fn zeroed() -> T { + // SAFETY: `T` implements `FromZeros`, so this is a safe initialization of `T`. unsafe { core::mem::MaybeUninit::::zeroed().assume_init() } } @@ -871,7 +877,7 @@ mod test { use memory_range::walk_ranges; use memory_range::MemoryRange; use memory_range::RangeWalkResult; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; const HIGH_MMIO_GAP_END: u64 = 0x1000000000; // 64 GiB const VMBUS_MMIO_GAP_SIZE: u64 = 0x10000000; // 256 MiB @@ -1105,8 +1111,8 @@ mod test { #[test] fn test_e820_basic() { // memmap with no param reclaim - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..3 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges(&[ONE_MB..4 * ONE_MB], parameter_range, None); @@ -1130,8 +1136,8 @@ mod test { ); // memmap with reclaim - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..5 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges( &[ONE_MB..6 * ONE_MB], @@ -1160,8 +1166,8 @@ mod test { ); // two mem ranges - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..5 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges( &[ONE_MB..4 * ONE_MB, 4 * ONE_MB..10 * ONE_MB], @@ -1190,8 +1196,8 @@ mod test { ); // memmap in 1 mb chunks - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..5 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges( &[ @@ -1233,8 +1239,8 @@ mod test { #[test] fn test_e820_param_not_covered() { // parameter range not covered by ram at all - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(5 * ONE_MB..6 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges(&[ONE_MB..4 * ONE_MB], parameter_range, None); @@ -1248,8 +1254,8 @@ mod test { .is_err()); // parameter range start partial coverage - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(3 * ONE_MB..6 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges(&[ONE_MB..4 * ONE_MB], parameter_range, None); @@ -1263,8 +1269,8 @@ mod test { .is_err()); // parameter range end partial coverage - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..5 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges(&[4 * ONE_MB..6 * ONE_MB], parameter_range, None); @@ -1278,8 +1284,8 @@ mod test { .is_err()); // parameter range larger than ram - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..8 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges(&[4 * ONE_MB..6 * ONE_MB], parameter_range, None); @@ -1293,8 +1299,8 @@ mod test { .is_err()); // ram has gap inside param range - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let parameter_range = MemoryRange::try_new(2 * ONE_MB..8 * ONE_MB).unwrap(); let partition_info = partition_info_ram_ranges( &[ONE_MB..6 * ONE_MB, 7 * ONE_MB..10 * ONE_MB], @@ -1314,8 +1320,8 @@ mod test { #[test] fn test_e820_huge() { // memmap with no param reclaim - let mut boot_params: boot_params = FromZeroes::new_zeroed(); - let mut ext = FromZeroes::new_zeroed(); + let mut boot_params: boot_params = FromZeros::new_zeroed(); + let mut ext = FromZeros::new_zeroed(); let ram = MemoryRange::new(0..32 * ONE_MB); let partition_info = partition_info_ram_ranges(&[ram.into()], MemoryRange::EMPTY, None); let reserved = (0..256) diff --git a/openhcl/sidecar/Cargo.toml b/openhcl/sidecar/Cargo.toml index a1e66b8169..098ed43955 100644 --- a/openhcl/sidecar/Cargo.toml +++ b/openhcl/sidecar/Cargo.toml @@ -23,7 +23,6 @@ x86defs.workspace = true arrayvec.workspace = true zerocopy.workspace = true - [build-dependencies] minimal_rt_build.workspace = true diff --git a/openhcl/sidecar/src/arch/x86_64/init.rs b/openhcl/sidecar/src/arch/x86_64/init.rs index dc2422ff36..af1ca9b559 100644 --- a/openhcl/sidecar/src/arch/x86_64/init.rs +++ b/openhcl/sidecar/src/arch/x86_64/init.rs @@ -53,7 +53,7 @@ use x86defs::GdtEntry; use x86defs::IdtAttributes; use x86defs::IdtEntry64; use x86defs::Pte; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; unsafe extern "C" { static IMAGE_PDE: Pte; @@ -526,7 +526,7 @@ impl NodeDefinition { selector: 0, attributes: x86defs::X64_BUSY_TSS_SEGMENT_ATTRIBUTES.into(), }, - ldtr: FromZeroes::new_zeroed(), + ldtr: FromZeros::new_zeroed(), idtr, gdtr, efer: x86defs::X64_EFER_LMA | x86defs::X64_EFER_LME | x86defs::X64_EFER_NXE, diff --git a/openhcl/sidecar/src/arch/x86_64/mod.rs b/openhcl/sidecar/src/arch/x86_64/mod.rs index 1918de2a41..11de30ed11 100644 --- a/openhcl/sidecar/src/arch/x86_64/mod.rs +++ b/openhcl/sidecar/src/arch/x86_64/mod.rs @@ -19,8 +19,8 @@ use hvdef::HypercallCode; use minimal_rt::arch::msr::write_msr; use minimal_rt::arch::Serial; use x86defs::Exception; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; mod addr_space { use super::VpGlobals; @@ -257,7 +257,7 @@ fn get_hv_vp_register( hypercall(HypercallCode::HvCallGetVpRegisters, 1)?; // SAFETY: the output is not concurrently accessed. let output = unsafe { &*addr_space::hypercall_output() }; - Ok(HvRegisterValue::read_from_prefix(output).unwrap()) + Ok(HvRegisterValue::read_from_prefix(output).unwrap().0) // todo: zerocopy: use-rest-of-range } fn set_hv_vp_register( diff --git a/openhcl/sidecar/src/arch/x86_64/vp.rs b/openhcl/sidecar/src/arch/x86_64/vp.rs index d875bfb4e8..80bca3f321 100644 --- a/openhcl/sidecar/src/arch/x86_64/vp.rs +++ b/openhcl/sidecar/src/arch/x86_64/vp.rs @@ -43,9 +43,9 @@ use sidecar_defs::SidecarCommand; use sidecar_defs::TranslateGvaRequest; use sidecar_defs::TranslateGvaResponse; use x86defs::apic::ApicBase; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Entry point for an AP. Called with per-VP state (page tables, stack, /// globals) already initialized, and IDT and GDT set appropriately. @@ -252,7 +252,8 @@ fn run_vp(globals: &mut VpGlobals, command_page: &mut CommandPage, cpu_status: & RunVpResponse { intercept: intercept as u8, } - .write_to_prefix(command_page.request_data.as_bytes_mut()); + .write_to_prefix(command_page.request_data.as_mut_bytes()) + .unwrap(); // PANIC: will not panic, since sizeof(RunVpResponse) is 1, whereas the buffer is statically declared as 16 bytes long. } fn run_vp_once(command_page: &mut CommandPage) -> Result { @@ -394,7 +395,7 @@ fn get_debug_register(name: HvX64RegisterName) -> Option { fn get_vp_registers(command_page: &mut CommandPage) { let (request, regs) = command_page .request_data - .as_bytes_mut() + .as_mut_bytes() .split_at_mut(size_of::()); let &mut GetSetVpRegisterRequest { count, @@ -403,9 +404,10 @@ fn get_vp_registers(command_page: &mut CommandPage) { ref mut result, rsvd2: _, regs: [], - } = FromBytes::mut_from(request).unwrap(); + } = FromBytes::mut_from_bytes(request).unwrap(); - let Some((regs, _)) = FromBytes::mut_slice_from_prefix(regs, count.into()) else { + let Ok((regs, _)) = <[HvRegisterAssoc]>::mut_from_prefix_with_elems(regs, count.into()) else { + // todo: zerocopy: err set_error( command_page, format_args!("invalid register name count: {count}"), @@ -444,7 +446,7 @@ fn get_vp_registers(command_page: &mut CommandPage) { fn set_vp_registers(command_page: &mut CommandPage) { let (request, regs) = command_page .request_data - .as_bytes_mut() + .as_mut_bytes() .split_at_mut(size_of::()); let &mut GetSetVpRegisterRequest { count, @@ -453,9 +455,10 @@ fn set_vp_registers(command_page: &mut CommandPage) { ref mut result, rsvd2: _, regs: [], - } = FromBytes::mut_from(request).unwrap(); + } = FromBytes::mut_from_bytes(request).unwrap(); - let Some((assoc, _)) = FromBytes::slice_from_prefix(regs, count.into()) else { + let Ok((assoc, _)) = <[HvRegisterAssoc]>::ref_from_prefix_with_elems(regs, count.into()) else { + // todo: zerocopy: err set_error( command_page, format_args!("invalid register count: {count}"), @@ -491,8 +494,9 @@ fn set_vp_registers(command_page: &mut CommandPage) { fn translate_gva(command_page: &mut CommandPage) { let TranslateGvaRequest { gvn, control_flags } = - FromBytes::read_from_prefix(command_page.request_data.as_bytes()).unwrap(); - + FromBytes::read_from_prefix(command_page.request_data.as_bytes()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range, zerocopy: err { // SAFETY: the input page is not concurrently accessed. let input = unsafe { &mut *addr_space::hypercall_input() }; @@ -513,9 +517,9 @@ fn translate_gva(command_page: &mut CommandPage) { Ok(()) => { // SAFETY: the output is not concurrently accessed let output = unsafe { &*addr_space::hypercall_output() }; - (HvError(0), FromBytes::read_from_prefix(output).unwrap()) + (HvError(0), FromBytes::read_from_prefix(output).unwrap().0) // todo: zerocopy: use-rest-of-range } - Err(err) => (err, FromZeroes::new_zeroed()), + Err(err) => (err, FromZeros::new_zeroed()), }; TranslateGvaResponse { @@ -523,7 +527,7 @@ fn translate_gva(command_page: &mut CommandPage) { rsvd: [0; 7], output, } - .write_to_prefix(command_page.request_data.as_bytes_mut()) + .write_to_prefix(command_page.request_data.as_mut_bytes()) .unwrap(); } diff --git a/openhcl/sidecar_client/src/lib.rs b/openhcl/sidecar_client/src/lib.rs index 07c69eb7b7..f8bf860922 100644 --- a/openhcl/sidecar_client/src/lib.rs +++ b/openhcl/sidecar_client/src/lib.rs @@ -47,8 +47,10 @@ use std::sync::Arc; use std::task::Poll; use std::task::Waker; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; mod ioctl { const BASE: u8 = 0xb8; @@ -299,7 +301,7 @@ async fn sidecar_wait_loop( let err = loop { poll_fn(|cx| fd_ready.poll_fd_ready(cx, InterestSlot::Read, PollEvents::IN)).await; let mut cpu = 0u32; - let n = match (&state.file).read(cpu.as_bytes_mut()) { + let n = match (&state.file).read(cpu.as_mut_bytes()) { Ok(n) => n, Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { fd_ready.clear_fd_ready(InterestSlot::Read); @@ -504,7 +506,10 @@ impl<'a> SidecarVp<'a> { Ok(output) } - fn set_command( + fn set_command< + T: IntoBytes + Immutable + KnownLayout, + S: IntoBytes + FromBytes + Immutable + KnownLayout, + >( &mut self, command: SidecarCommand, input: T, @@ -515,20 +520,20 @@ impl<'a> SidecarVp<'a> { let shmem = unsafe { self.shmem.as_mut() }; shmem.command_page.command = command; input - .write_to_prefix(shmem.command_page.request_data.as_bytes_mut()) + .write_to_prefix(shmem.command_page.request_data.as_mut_bytes()) .unwrap(); - S::mut_slice_from_prefix( - &mut shmem.command_page.request_data.as_bytes_mut()[input.as_bytes().len()..], + <[S]>::mut_from_prefix_with_elems( + &mut shmem.command_page.request_data.as_mut_bytes()[input.as_bytes().len()..], n, ) .unwrap() .0 } - fn dispatch_sync( + fn dispatch_sync( &mut self, command: SidecarCommand, - input: impl AsBytes, + input: impl IntoBytes + Immutable + KnownLayout, ) -> Result<&O, SidecarError> { self.set_command::<_, u8>(command, input, 0); self.run_sync()?; @@ -586,7 +591,10 @@ impl<'a> SidecarVp<'a> { .await } - fn command_result( + fn command_result< + O: FromBytes + Immutable + KnownLayout, + S: FromBytes + Immutable + KnownLayout, + >( &mut self, n: usize, ) -> Result<(&O, &[S]), SidecarError> { @@ -604,8 +612,8 @@ impl<'a> SidecarVp<'a> { .request_data .as_bytes() .split_at(size_of::()); - let output = O::ref_from(output).unwrap(); - let (slice, _) = S::slice_from_prefix(slice, n).unwrap(); + let output = O::ref_from_bytes(output).unwrap(); + let (slice, _) = <[S]>::ref_from_prefix_with_elems(slice, n).unwrap(); Ok((output, slice)) } } diff --git a/openhcl/sidecar_defs/Cargo.toml b/openhcl/sidecar_defs/Cargo.toml index 5bb81e5064..a2920b8c04 100644 --- a/openhcl/sidecar_defs/Cargo.toml +++ b/openhcl/sidecar_defs/Cargo.toml @@ -12,6 +12,5 @@ open_enum.workspace = true x86defs.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/openhcl/sidecar_defs/src/lib.rs b/openhcl/sidecar_defs/src/lib.rs index ce42d18a1c..8d3462964d 100644 --- a/openhcl/sidecar_defs/src/lib.rs +++ b/openhcl/sidecar_defs/src/lib.rs @@ -13,13 +13,15 @@ use hvdef::hypercall::HvInputVtl; use hvdef::HvError; use hvdef::HvMessage; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Sidecar start input parameters. #[repr(C, align(4096))] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] pub struct SidecarParams { /// The physical address of the x86-64 hypercall page. pub hypercall_page: u64, @@ -33,7 +35,7 @@ pub struct SidecarParams { /// Node-specific input parameters. #[repr(C)] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] pub struct SidecarNodeParams { /// The physical address of the beginning of the reserved memory for this /// node. Must be page aligned. @@ -53,7 +55,7 @@ const _: () = assert!(size_of::() <= PAGE_SIZE); /// The output of the sidecar kernel boot process. #[repr(C)] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] pub struct SidecarOutput { /// The boot error. This is only set if the entry point returns false. pub error: CommandError, @@ -63,7 +65,7 @@ pub struct SidecarOutput { /// The per-node output of the sidecar kernel boot process. #[repr(C)] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] pub struct SidecarNodeOutput { /// The physical address of the control page for the node. pub control_page: u64, @@ -148,7 +150,7 @@ pub const fn required_memory(vp_count: u32) -> usize { /// The sidecar command page, containing command requests and responses. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CommandPage { /// The command to run. pub command: SidecarCommand, @@ -172,7 +174,7 @@ const REQUEST_DATA_SIZE: usize = 64 * size_of::(); /// A string error. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CommandError { /// The length of the error string, in bytes. pub len: u8, @@ -184,7 +186,7 @@ const _: () = assert!(size_of::() == PAGE_SIZE); open_enum! { /// The sidecar command. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SidecarCommand: u32 { /// No command. NONE = 0, @@ -205,7 +207,7 @@ open_enum! { /// Followed by an array of [`hvdef::hypercall::HvRegisterAssoc`], which are /// updated in place for the get request. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetSetVpRegisterRequest { /// The number of registers to get. pub count: u16, @@ -230,7 +232,7 @@ pub const MAX_GET_SET_VP_REGISTERS: usize = (REQUEST_DATA_SIZE /// A request for [`SidecarCommand::TRANSLATE_GVA`]. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaRequest { /// The guest virtual address page number. pub gvn: u64, @@ -240,7 +242,7 @@ pub struct TranslateGvaRequest { /// A response for [`SidecarCommand::TRANSLATE_GVA`]. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaResponse { /// The hypervisor result. pub result: HvError, @@ -252,7 +254,7 @@ pub struct TranslateGvaResponse { /// A response for [`SidecarCommand::RUN_VP`]. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RunVpResponse { /// If true, the VP was stopped due to an intercept. pub intercept: u8, @@ -260,7 +262,7 @@ pub struct RunVpResponse { /// The CPU context for x86-64. #[repr(C, align(16))] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CpuContextX64 { /// The general purpose registers, in the usual order, except CR2 is in /// RSP's position. diff --git a/openhcl/underhill_attestation/Cargo.toml b/openhcl/underhill_attestation/Cargo.toml index e1ff020ad1..aa69252b3f 100644 --- a/openhcl/underhill_attestation/Cargo.toml +++ b/openhcl/underhill_attestation/Cargo.toml @@ -32,7 +32,6 @@ static_assertions.workspace = true thiserror.workspace = true time = { workspace = true, features = ["macros"] } zerocopy.workspace = true - [target.'cfg(target_os = "linux")'.dev-dependencies] disklayer_ram.workspace = true disk_backend.workspace = true diff --git a/openhcl/underhill_attestation/src/hardware_key_sealing.rs b/openhcl/underhill_attestation/src/hardware_key_sealing.rs index 765c214969..3251c7ad88 100644 --- a/openhcl/underhill_attestation/src/hardware_key_sealing.rs +++ b/openhcl/underhill_attestation/src/hardware_key_sealing.rs @@ -12,7 +12,7 @@ use openhcl_attestation_protocol::vmgs; use openhcl_attestation_protocol::vmgs::HardwareKeyProtector; use openssl_kdf::kdf::Kbkdf; use thiserror::Error; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub(crate) enum HardwareDerivedKeysError { @@ -249,8 +249,8 @@ mod tests { let output = result.unwrap(); let result = HardwareKeyProtector::read_from_prefix(output.as_bytes()); - assert!(result.is_some()); - let hardware_key_protector = result.unwrap(); + assert!(result.is_ok()); + let hardware_key_protector = result.unwrap().0; let result = hardware_key_protector.unseal_key(&hardware_derived_keys); assert!(result.is_ok()); diff --git a/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs b/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs index c174278683..b6e5ebe0c7 100644 --- a/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs +++ b/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs @@ -30,12 +30,12 @@ pub enum AkCertError { pub fn parse_response(response: &[u8]) -> Result, AkCertError> { const HEADER_SIZE: usize = size_of::(); - let Some(header) = IgvmAttestAkCertResponseHeader::read_from_prefix(response) else { - Err(AkCertError::SizeTooSmall { + let header = IgvmAttestAkCertResponseHeader::read_from_prefix(response) + .map_err(|_| AkCertError::SizeTooSmall { size: response.len(), minimum_size: HEADER_SIZE, - })? - }; + })? // todo: zerocopy: map_err + .0; let size = header.data_size as usize; if size > response.len() { @@ -106,8 +106,8 @@ mod tests { const HEADER_SIZE: usize = size_of::(); let result = IgvmAttestAkCertResponseHeader::read_from_prefix(&VALID_RESPONSE); - assert!(result.is_some()); - let header = result.unwrap(); + assert!(result.is_ok()); + let header = result.unwrap().0; let result = parse_response(&VALID_RESPONSE); assert!(result.is_ok()); @@ -132,8 +132,8 @@ mod tests { const HEADER_SIZE: usize = size_of::(); let result = IgvmAttestAkCertResponseHeader::read_from_prefix(&VALID_RESPONSE); - assert!(result.is_some()); - let header = result.unwrap(); + assert!(result.is_ok()); + let header = result.unwrap().0; let result = parse_response(&VALID_RESPONSE); assert!(result.is_ok()); diff --git a/openhcl/underhill_attestation/src/igvm_attest/mod.rs b/openhcl/underhill_attestation/src/igvm_attest/mod.rs index f5d5192d5e..fae391027a 100644 --- a/openhcl/underhill_attestation/src/igvm_attest/mod.rs +++ b/openhcl/underhill_attestation/src/igvm_attest/mod.rs @@ -12,8 +12,8 @@ use openhcl_attestation_protocol::igvm_attest::get::IgvmAttestReportType; use openhcl_attestation_protocol::igvm_attest::get::IgvmAttestRequestType; use tee_call::TeeType; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; pub mod ak_cert; pub mod key_release; diff --git a/openhcl/underhill_attestation/src/igvm_attest/wrapped_key.rs b/openhcl/underhill_attestation/src/igvm_attest/wrapped_key.rs index ce8d0ccaca..373b2b0793 100644 --- a/openhcl/underhill_attestation/src/igvm_attest/wrapped_key.rs +++ b/openhcl/underhill_attestation/src/igvm_attest/wrapped_key.rs @@ -76,8 +76,8 @@ pub fn parse_response(response: &[u8]) -> Result() KeyProtector::read_from_prefix(&data[..]) - .ok_or(ReadFromVmgsError::InvalidFormat(file_id)) + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id)) + .map(|k| k.0) // todo: zerocopy: map_err } Err(vmgs::Error::FileInfoAllocated) => Ok(KeyProtector::new_zeroed()), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { vmgs_err, file_id }), @@ -126,15 +127,19 @@ pub async fn read_key_protector_by_id( let file_id = FileId::VM_UNIQUE_ID; match vmgs.read_file(file_id).await { - Ok(data) => match KeyProtectorById::read_from_prefix(&data[..]) { + Ok(data) => match KeyProtectorById::read_from_prefix(&data[..]) + .ok() // todo: zerocopy: ok + .map(|k| k.0) + { Some(key_protector_by_id) => Ok(key_protector_by_id), None => { let id_guid = Guid::read_from_prefix(&data[..]) - .ok_or_else(|| ReadFromVmgsError::InvalidFormat(file_id))?; + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? // todo: zerocopy: map_err + .0; Ok(KeyProtectorById { id_guid, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) } }, @@ -189,7 +194,8 @@ pub async fn read_security_profile(vmgs: &mut Vmgs) -> Result() Ok(SecurityProfile::read_from_prefix(&data[..]) - .ok_or(ReadFromVmgsError::InvalidFormat(file_id))?) + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? + .0) // todo: zerocopy: map_err } Err(vmgs::Error::FileInfoAllocated) => Ok(SecurityProfile::new_zeroed()), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { file_id, vmgs_err })?, @@ -216,7 +222,9 @@ pub async fn read_hardware_key_protector( })? } - HardwareKeyProtector::read_from_prefix(&data).ok_or(ReadFromVmgsError::InvalidFormat(file_id)) + HardwareKeyProtector::read_from_prefix(&data) + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id)) + .map(|k| k.0) // todo: zerocopy: map_err } /// Write Key Protector Id (current Id) to the VMGS file. @@ -254,7 +262,8 @@ pub async fn read_guest_secret_key(vmgs: &mut Vmgs) -> Result() Ok(GuestSecretKey::read_from_prefix(&data[..]) - .ok_or(ReadFromVmgsError::InvalidFormat(file_id))?) + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? + .0) // todo: zerocopy: map_err } Err(vmgs::Error::FileInfoAllocated) => Err(ReadFromVmgsError::EntryNotFound(file_id)), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { file_id, vmgs_err }), diff --git a/openhcl/underhill_core/Cargo.toml b/openhcl/underhill_core/Cargo.toml index 9e7751c06f..6dc1baa2cf 100644 --- a/openhcl/underhill_core/Cargo.toml +++ b/openhcl/underhill_core/Cargo.toml @@ -168,7 +168,6 @@ time = { workspace = true, features = ["macros"] } tracing-subscriber = { workspace = true, features = ["registry"] } tracing.workspace = true zerocopy.workspace = true - [target.'cfg(target_arch = "x86_64")'.dependencies] firmware_pcat.workspace = true diff --git a/openhcl/underhill_core/src/get_tracing/json_layer.rs b/openhcl/underhill_core/src/get_tracing/json_layer.rs index 576c9c0be2..0e4ae98244 100644 --- a/openhcl/underhill_core/src/get_tracing/json_layer.rs +++ b/openhcl/underhill_core/src/get_tracing/json_layer.rs @@ -25,8 +25,8 @@ use tracing::Id; use tracing::Subscriber; use tracing_subscriber::registry::LookupSpan; use tracing_subscriber::Layer; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// A JSON layer wrapping a [`TraceWriter`]. pub struct JsonMeshLayer { @@ -206,9 +206,9 @@ fn generate_tracing_luid(time: pal_async::timer::Instant, span_id: u64) -> Guid let process_id = std::process::id() as u16; - guid.as_bytes_mut()[..6].copy_from_slice(&time.as_nanos().to_le_bytes()[..6]); - guid.as_bytes_mut()[6..8].copy_from_slice(&process_id.to_ne_bytes()); - guid.as_bytes_mut()[8..].copy_from_slice(&span_id.to_ne_bytes()); + guid.as_mut_bytes()[..6].copy_from_slice(&time.as_nanos().to_le_bytes()[..6]); + guid.as_mut_bytes()[6..8].copy_from_slice(&process_id.to_ne_bytes()); + guid.as_mut_bytes()[8..].copy_from_slice(&span_id.to_ne_bytes()); guid } diff --git a/openhcl/underhill_core/src/loader/mod.rs b/openhcl/underhill_core/src/loader/mod.rs index e57ac21584..bb73fc489c 100644 --- a/openhcl/underhill_core/src/loader/mod.rs +++ b/openhcl/underhill_core/src/loader/mod.rs @@ -24,8 +24,8 @@ use vm_topology::memory::MemoryLayout; use vm_topology::memory::MemoryRangeWithNode; use vm_topology::processor::ProcessorTopology; use vmm_core::acpi_builder::AcpiTablesBuilder; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; pub mod vtl0_config; pub mod vtl2_config; @@ -424,8 +424,9 @@ pub fn write_uefi_config( // We can only trust these tables from the host if this is not an isolated VM if !isolated { for table in &platform_config.acpi_tables { - let header = - acpi_spec::Header::ref_from_prefix(table).ok_or(Error::InvalidAcpiTableLength)?; + let header = acpi_spec::Header::ref_from_prefix(table) + .map_err(|_| Error::InvalidAcpiTableLength)? // todo: zerocopy: map_err + .0; match &header.signature { b"APIC" => { build_madt = false; diff --git a/openhcl/underhill_core/src/loader/vtl0_config.rs b/openhcl/underhill_core/src/loader/vtl0_config.rs index 1c00d65e5f..2de5f434dd 100644 --- a/openhcl/underhill_core/src/loader/vtl0_config.rs +++ b/openhcl/underhill_core/src/loader/vtl0_config.rs @@ -19,8 +19,8 @@ use std::ffi::CString; use std::io::Read; use thiserror::Error; use tracing::instrument; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Errors returned when reading measured config. #[derive(Debug, Error)] @@ -212,13 +212,13 @@ fn parse_vtl0_vp_context(raw: Vec) -> Result { let mut reader = std::io::Cursor::new(raw); let mut registers = Vec::new(); reader - .read_exact(header.as_bytes_mut()) + .read_exact(header.as_mut_bytes()) .map_err(|_| Error::InvalidVtl0VpContext)?; for _ in 0..header.register_count { let mut reg = igvm_defs::VbsVpContextRegister::new_zeroed(); reader - .read_exact(reg.as_bytes_mut()) + .read_exact(reg.as_mut_bytes()) .map_err(|_| Error::InvalidVtl0VpContext)?; #[cfg(guest_arch = "x86_64")] diff --git a/openhcl/underhill_core/src/loader/vtl2_config/mod.rs b/openhcl/underhill_core/src/loader/vtl2_config/mod.rs index 38d94c5423..9fd90cfeb8 100644 --- a/openhcl/underhill_core/src/loader/vtl2_config/mod.rs +++ b/openhcl/underhill_core/src/loader/vtl2_config/mod.rs @@ -24,7 +24,9 @@ use loader_defs::paravisor::PARAVISOR_RESERVED_VTL2_SNP_SECRETS_SIZE_PAGES; use memory_range::MemoryRange; use sparse_mmap::SparseMapping; use vm_topology::memory::MemoryRangeWithNode; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Structure that holds parameters provided at runtime. Some are read from the /// guest address space, and others from openhcl_boot provided via devicetree. @@ -152,7 +154,10 @@ impl<'a> Vtl2ParamsMap<'a> { Ok(self.mapping.read_at(offset, buf)?) } - fn read_plain(&self, offset: usize) -> anyhow::Result { + fn read_plain( + &self, + offset: usize, + ) -> anyhow::Result { Ok(self.mapping.read_plain(offset)?) } } diff --git a/openhcl/underhill_core/src/worker.rs b/openhcl/underhill_core/src/worker.rs index 5f83efc585..a2361dffd2 100644 --- a/openhcl/underhill_core/src/worker.rs +++ b/openhcl/underhill_core/src/worker.rs @@ -167,7 +167,7 @@ use vmotherboard::options::BaseChipsetFoundation; use vmotherboard::BaseChipsetBuilder; use vmotherboard::BaseChipsetBuilderOutput; use vmotherboard::ChipsetDeviceHandle; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; pub(crate) const PM_BASE: u16 = 0x400; pub(crate) const SYSTEM_IRQ_ACPI: u32 = 9; diff --git a/openhcl/underhill_crash/Cargo.toml b/openhcl/underhill_crash/Cargo.toml index adf86be36e..fdaeeaf369 100644 --- a/openhcl/underhill_crash/Cargo.toml +++ b/openhcl/underhill_crash/Cargo.toml @@ -21,7 +21,6 @@ thiserror.workspace = true tracing.workspace = true tracing-subscriber.workspace = true zerocopy.workspace = true - [build-dependencies] vergen = { workspace = true, features = ["git", "gitcl"] } diff --git a/openhcl/underhill_crash/src/elf.rs b/openhcl/underhill_crash/src/elf.rs index a99751dec3..e3cca53af0 100644 --- a/openhcl/underhill_crash/src/elf.rs +++ b/openhcl/underhill_crash/src/elf.rs @@ -3,12 +3,13 @@ //! Definitions for elf core dump handling. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// ELF header -#[derive(AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] #[repr(C)] pub struct Elf64_Ehdr { pub e_ident: [u8; 16], @@ -28,7 +29,7 @@ pub struct Elf64_Ehdr { } /// Program header -#[derive(AsBytes, FromBytes, FromZeroes, Copy, Clone, Debug)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Copy, Clone, Debug)] #[repr(C)] pub struct Elf64_Phdr { pub p_type: u32, @@ -42,7 +43,7 @@ pub struct Elf64_Phdr { } /// ELF note header -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] #[repr(C)] pub struct Elf64_Nhdr { pub namesz: u32, diff --git a/openhcl/underhill_crash/src/lib.rs b/openhcl/underhill_crash/src/lib.rs index d40be21b3d..9d09746aff 100644 --- a/openhcl/underhill_crash/src/lib.rs +++ b/openhcl/underhill_crash/src/lib.rs @@ -46,9 +46,11 @@ use vmbus_async::pipe::MessagePipe; use vmbus_async::pipe::MessageReadHalf; use vmbus_async::pipe::MessageWriteHalf; use vmbus_user_channel::MappedRingMem; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const CRASHDMP_VDEV_MAX_TX_BYTES: usize = 4096 * 4; // 16 KB const KMSG_NOTE_BYTES: usize = 1024 * 256; // 256 KB @@ -108,12 +110,12 @@ impl OsVersionInfo { } } -async fn read_message( +async fn read_message( pipe: &mut MessageReadHalf<'_, MappedRingMem>, ) -> anyhow::Result { let mut message = T::new_zeroed(); - pipe.recv_exact(message.as_bytes_mut()).await?; - let header = Header::read_from_prefix(message.as_bytes()).unwrap(); + pipe.recv_exact(message.as_mut_bytes()).await?; + let header = Header::read_from_prefix(message.as_bytes()).unwrap().0; // todo: zerocopy: use-rest-of-range check_header(&header)?; Ok(message) } @@ -495,7 +497,7 @@ impl<'a> DumpStreamer<'a> { async fn insert_kmsg_note(&mut self, buf: &mut [u8]) -> anyhow::Result<()> { // elf header let mut ehdr: Elf64_Ehdr = Elf64_Ehdr::new_zeroed(); - self.read(ehdr.as_bytes_mut(), true).await; + self.read(ehdr.as_mut_bytes(), true).await; self.write(ehdr.as_bytes()).await?; tracing::trace!("ehdr: {:#x?}", &ehdr); @@ -507,7 +509,7 @@ impl<'a> DumpStreamer<'a> { // notes program header let mut notes_phdr: Elf64_Phdr = Elf64_Phdr::new_zeroed(); - self.read(notes_phdr.as_bytes_mut(), true).await; + self.read(notes_phdr.as_mut_bytes(), true).await; tracing::trace!("initial notes_phdr: {:#x?}", notes_phdr); if notes_phdr.p_type != PT_NOTE { @@ -526,8 +528,9 @@ impl<'a> DumpStreamer<'a> { let phnum = std::cmp::min(phnum_remaining, max); let phdrs_size = phnum * size_of::(); self.read(&mut buf[..phdrs_size], true).await; + // todo: zerocopy: review carefully! let phdrs: &mut [Elf64_Phdr] = - Elf64_Phdr::mut_slice_from(&mut buf[..phdrs_size]).unwrap(); + <[Elf64_Phdr]>::mut_from_bytes(&mut buf[..phdrs_size]).unwrap(); tracing::trace!("initial phdrs: {:#x?}", phdrs); for phdr in &mut phdrs[..] { diff --git a/openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs b/openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs index 6b19b08736..3470ec2393 100644 --- a/openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs +++ b/openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs @@ -18,8 +18,8 @@ use x86defs::cpuid; use x86defs::cpuid::CpuidFunction; use x86defs::snp::HvPspCpuidPage; use x86defs::xsave; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; enum CpuidPageIndexErr { OutOfBounds, @@ -106,7 +106,7 @@ impl SnpCpuidInitializer { ]; cpuid_pages .as_mut_slice() - .as_bytes_mut() + .as_mut_bytes() .copy_from_slice(cpuid_pages_data); Self { cpuid_pages } @@ -498,7 +498,6 @@ impl CpuidArchSupport for SnpCpuidSupport { mod tests { use super::*; use x86defs::snp::HvPspCpuidLeaf; - use zerocopy::FromZeroes; // Tests the increment and validation implementations of CpuidPageIndex #[test] diff --git a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/mod.rs b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/mod.rs index 2909c1a27f..e7e5d46087 100644 --- a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/mod.rs +++ b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/mod.rs @@ -10,8 +10,8 @@ use super::*; use x86defs::cpuid::Vendor; use x86defs::snp::HvPspCpuidLeaf; use x86defs::snp::HvPspCpuidPage; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; // Because of the filtering logic, besides subleaves 0 and 1, these are the // extended state enumeration subleaves that can be tested on. diff --git a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/topology.rs b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/topology.rs index fd558212d5..c3c9688224 100644 --- a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/topology.rs +++ b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/topology.rs @@ -4,6 +4,7 @@ //! Tests for the cpu topology-related subleaves. use super::super::*; use super::*; +use zerocopy::FromZeros; #[test] fn real_topology() { diff --git a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/xfem.rs b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/xfem.rs index 407ec0aa67..c7f2cf1925 100644 --- a/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/xfem.rs +++ b/openhcl/virt_mshv_vtl/src/cvm_cpuid/tests/xfem.rs @@ -9,7 +9,7 @@ use super::*; use x86defs::snp::HvPspCpuidLeaf; use x86defs::snp::HvPspCpuidPage; use x86defs::snp::HV_PSP_CPUID_LEAF_COUNT_MAX; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; /// Tests that xfem results put into page 0 are ignored #[test] diff --git a/openhcl/virt_mshv_vtl/src/lib.rs b/openhcl/virt_mshv_vtl/src/lib.rs index e412e3632b..cf121127df 100644 --- a/openhcl/virt_mshv_vtl/src/lib.rs +++ b/openhcl/virt_mshv_vtl/src/lib.rs @@ -113,9 +113,11 @@ use vtl_array::VtlArray; use x86defs::snp::REG_TWEAK_BITMAP_OFFSET; use x86defs::snp::REG_TWEAK_BITMAP_SIZE; use x86defs::tdx::TdCallResult; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// General error returned by operations. #[derive(Error, Debug)] @@ -638,7 +640,7 @@ impl TlbLockInfo { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct WakeReason { extint: bool, message_queues: bool, diff --git a/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs b/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs index c3b6570d6f..e54e00b356 100644 --- a/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs @@ -36,7 +36,7 @@ use virt::Processor; use virt_support_x86emu::emulate::TranslateGvaSupport; use virt_support_x86emu::translate::TranslateCachingInfo; use virt_support_x86emu::translate::TranslationRegisters; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; impl UhHypercallHandler<'_, '_, T, B> { pub fn hcvm_enable_partition_vtl( diff --git a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs index 460e9abeab..5bb87e12a1 100644 --- a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs +++ b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs @@ -51,9 +51,11 @@ use virt_support_aarch64emu::emulate::EmuCheckVtlAccessError; use virt_support_aarch64emu::emulate::EmuTranslateError; use virt_support_aarch64emu::emulate::EmuTranslateResult; use virt_support_aarch64emu::emulate::EmulatorSupport; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A backing for hypervisor-backed partitions (non-isolated and /// software-isolated). diff --git a/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs b/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs index cd14f2322f..89bbb0fc3a 100644 --- a/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs +++ b/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs @@ -83,9 +83,11 @@ use x86defs::xsave::XFEATURE_SSE; use x86defs::xsave::XFEATURE_X87; use x86defs::RFlags; use x86defs::SegmentRegister; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A backing for hypervisor-backed partitions (non-isolated and /// software-isolated). @@ -427,24 +429,27 @@ impl BackingPrivate for HypervisorBackedX86 { fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { match message.header.typ { HvMessageType::HvMessageTypeX64IoPortIntercept => { - let message = - hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + let message = hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range SidecarRemoveExit::Io { port: message.port_number, write: message.header.intercept_access_type == HvInterceptAccessType::WRITE, } } HvMessageType::HvMessageTypeUnmappedGpa | HvMessageType::HvMessageTypeGpaIntercept => { - let message = - hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range SidecarRemoveExit::Mmio { gpa: message.guest_physical_address, write: message.header.intercept_access_type == HvInterceptAccessType::WRITE, } } HvMessageType::HvMessageTypeHypercallIntercept => { - let message = - hvdef::HvX64HypercallInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + let message = hvdef::HvX64HypercallInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range let is_64bit = message.header.execution_state.cr0_pe() && message.header.execution_state.efer_lma(); let control = if is_64bit { @@ -457,16 +462,18 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { } } HvMessageType::HvMessageTypeX64CpuidIntercept => { - let message = - hvdef::HvX64CpuidInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + let message = hvdef::HvX64CpuidInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range SidecarRemoveExit::Cpuid { leaf: message.rax as u32, subleaf: message.rcx as u32, } } HvMessageType::HvMessageTypeMsrIntercept => { - let message = - hvdef::HvX64MsrInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + let message = hvdef::HvX64MsrInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range SidecarRemoveExit::Msr { msr: message.msr_number, value: (message.header.intercept_access_type == HvInterceptAccessType::WRITE) @@ -507,6 +514,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeUnmappedGpa @@ -515,6 +523,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeUnacceptedGpa => { @@ -522,6 +531,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeHypercallIntercept => { @@ -529,6 +539,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeSynicSintDeliverable => { @@ -536,6 +547,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeX64InterruptionDeliverable => { @@ -543,6 +555,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeX64CpuidIntercept => { @@ -550,6 +563,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeMsrIntercept => { @@ -557,6 +571,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeUnrecoverableException => { @@ -564,6 +579,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeX64Halt => { @@ -571,6 +587,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } &HvMessageType::HvMessageTypeExceptionIntercept => { @@ -578,6 +595,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro .header } reason => unreachable!("unknown exit reason: {:#x?}", reason), @@ -603,7 +621,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64InterruptionDeliverableMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err assert_eq!( message.deliverable_type, @@ -643,7 +662,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64SynicSintDeliverableMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -672,7 +692,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64HypercallInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!(msg = %format_args!("{:x?}", message), "hypercall"); @@ -701,7 +722,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!(msg = %format_args!("{:x?}", message), "mmio"); @@ -751,7 +773,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64IoPortInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!(msg = %format_args!("{:x?}", message), "io_port"); @@ -788,6 +811,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err .guest_physical_address; if self.vp.partition.is_gpa_lower_vtl_ram(gpa) { @@ -813,7 +837,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64CpuidInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err let default_result = [ message.default_result_rax as u32, @@ -843,7 +868,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64MsrInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err let rip = next_rip(&message.header); tracing::trace!(msg = %format_args!("{:x?}", message), "msr"); @@ -922,7 +948,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { fn handle_eoi(&self, dev: &impl CpuIo) -> Result<(), VpHaltReason> { let message = hvdef::HvX64ApicEoiMessage::ref_from_prefix(self.vp.runner.exit_message().payload()) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!(msg = %format_args!("{:x?}", message), "eoi"); @@ -945,7 +972,8 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64ExceptionInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err match x86defs::Exception(message.vector as u8) { x86defs::Exception::DEBUG if cfg!(feature = "gdb") => { @@ -1279,7 +1307,7 @@ impl UhProcessor<'_, HypervisorBackedX86> { HvX64RegisterName::Cr0, HvX64RegisterName::Efer, ]; - let mut values = [FromZeroes::new_zeroed(); NAMES.len()]; + let mut values = [FromZeros::new_zeroed(); NAMES.len()]; self.runner .get_vp_registers(vtl, NAMES, &mut values) .expect("register query should not fail"); @@ -1287,7 +1315,9 @@ impl UhProcessor<'_, HypervisorBackedX86> { let [rsp, es, ds, fs, gs, ss, cr0, efer] = values; let message = self.runner.exit_message(); - let header = HvX64InterceptMessageHeader::ref_from_prefix(message.payload()).unwrap(); + let header = HvX64InterceptMessageHeader::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range MshvEmulationCache { rsp: rsp.as_u64(), @@ -1374,8 +1404,9 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX match index { x86emu::Segment::CS => { let message = self.vp.runner.exit_message(); - let header = - HvX64InterceptMessageHeader::ref_from_prefix(message.payload()).unwrap(); + let header = HvX64InterceptMessageHeader::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range from_seg(header.cs_segment) } x86emu::Segment::ES => self.cache.es, @@ -1409,12 +1440,16 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX | HvMessageType::HvMessageTypeUnmappedGpa | HvMessageType::HvMessageTypeUnacceptedGpa => { let message = - hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range &message.instruction_bytes[..message.instruction_byte_count as usize] } HvMessageType::HvMessageTypeX64IoPortIntercept => { let message = - hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range &message.instruction_bytes[..message.instruction_byte_count as usize] } _ => unreachable!(), @@ -1428,7 +1463,9 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX | HvMessageType::HvMessageTypeUnmappedGpa | HvMessageType::HvMessageTypeUnacceptedGpa => { let message = - hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()).unwrap(); + hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range Some(message.guest_physical_address) } _ => None, @@ -1447,7 +1484,8 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err if !message.memory_access_info.gva_gpa_valid() { tracing::trace!(?message.guest_virtual_address, ?message.guest_physical_address, "gva gpa not valid {:?}", self.vp.runner.exit_message().payload()); @@ -1671,6 +1709,7 @@ impl hv1_hypercall::X64RegisterState for UhHypercallHandler<'_, '_, T, Hyperv fn rip(&mut self) -> u64 { HvX64InterceptMessageHeader::ref_from_prefix(self.vp.runner.exit_message().payload()) .unwrap() + .0 .rip } @@ -1829,7 +1868,7 @@ impl AccessVpState for UhVpStateAccess<'_, '_, HypervisorBackedX86> { // // This is just used for debugging, so this should not be a problem. #[repr(C)] - #[derive(AsBytes)] + #[derive(IntoBytes, Immutable, KnownLayout)] struct XsaveStandard { fxsave: Fxsave, xsave_header: XsaveHeader, @@ -1838,7 +1877,7 @@ impl AccessVpState for UhVpStateAccess<'_, '_, HypervisorBackedX86> { fxsave: self.vp.runner.cpu_context().fx_state.clone(), xsave_header: XsaveHeader { xstate_bv: XFEATURE_X87 | XFEATURE_SSE, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, }; Ok(vp::Xsave::from_standard(state.as_bytes(), self.caps())) @@ -2163,8 +2202,8 @@ mod save_restore { use vmcore::save_restore::RestoreError; use vmcore::save_restore::SaveError; use vmcore::save_restore::SaveRestore; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::IntoBytes; mod state { use mesh::payload::Protobuf; @@ -2262,7 +2301,7 @@ mod save_restore { .map_err(SaveError::Other)?; let dr6_shared = self.partition.hcl.dr6_shared(); - let mut values = [FromZeroes::new_zeroed(); SHARED_REGISTERS.len()]; + let mut values = [FromZeros::new_zeroed(); SHARED_REGISTERS.len()]; let len = if dr6_shared { SHARED_REGISTERS.len() } else { @@ -2457,7 +2496,7 @@ mod save_restore { self.runner .cpu_context_mut() .fx_state - .as_bytes_mut() + .as_mut_bytes() .copy_from_slice(&fx_state); self.crash_reg = crash_reg.unwrap_or_default(); @@ -2505,7 +2544,7 @@ mod save_restore { HvX64RegisterName::Cr0, HvX64RegisterName::Efer, ]; - let mut values = [FromZeroes::new_zeroed(); NAMES.len()]; + let mut values = [FromZeros::new_zeroed(); NAMES.len()]; self.runner // Non-VTL0 VPs should never be in startup suspend, so we only need to handle VTL0. .get_vp_registers(GuestVtl::Vtl0, &NAMES, &mut values) diff --git a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs index ffdd0a803b..b5bdc07439 100644 --- a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs @@ -71,9 +71,9 @@ use x86defs::snp::SevStatusMsr; use x86defs::snp::SevVmsa; use x86defs::snp::Vmpl; use x86defs::RFlags; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// A backing for SNP partitions. #[derive(InspectMut)] @@ -517,7 +517,7 @@ fn virt_table_to_snp(val: TableRegister) -> SevSelector { SevSelector { limit: val.limit as u32, base: val.base, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } @@ -779,7 +779,8 @@ impl UhProcessor<'_, SnpBacked> { let message = hvdef::HvX64SynicSintDeliverableMessage::ref_from_prefix( self.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -800,7 +801,8 @@ impl UhProcessor<'_, SnpBacked> { let message = hvdef::HvX64VmgexitInterceptMessage::ref_from_prefix( self.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err let ghcb_msr = x86defs::snp::GhcbMsr::from(message.ghcb_msr); tracing::trace!(?ghcb_msr, "vmgexit intercept"); @@ -1179,7 +1181,8 @@ impl UhProcessor<'_, SnpBacked> { HvMessageType::HvMessageTypeExceptionIntercept => { let exception_message = hvdef::HvX64ExceptionInterceptMessage::ref_from_prefix(payload) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err exception_message.vector == x86defs::Exception::SEV_VMM_COMMUNICATION.0 as u16 @@ -1191,7 +1194,9 @@ impl UhProcessor<'_, SnpBacked> { // - determine whether the intercept message should be delivered to VTL 1 // - determine whether emulation is appropriate for this gpa let gpa_message: &hvdef::HvX64MemoryInterceptMessage = - hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(payload).unwrap(); + hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(payload) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range // Only the page numbers need to match. (gpa_message.guest_physical_address >> hvdef::HV_PAGE_SHIFT) diff --git a/openhcl/virt_mshv_vtl/src/processor/tdx/tlb_flush.rs b/openhcl/virt_mshv_vtl/src/processor/tdx/tlb_flush.rs index 8bd49e73aa..2bcb30523c 100644 --- a/openhcl/virt_mshv_vtl/src/processor/tdx/tlb_flush.rs +++ b/openhcl/virt_mshv_vtl/src/processor/tdx/tlb_flush.rs @@ -14,7 +14,7 @@ use std::collections::VecDeque; use std::num::Wrapping; use x86defs::tdx::TdGlaVmAndFlags; use x86defs::tdx::TdxGlaListInfo; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; pub(super) const FLUSH_GVA_LIST_SIZE: usize = 32; diff --git a/openvmm/hvlite_core/Cargo.toml b/openvmm/hvlite_core/Cargo.toml index c1eb88dc73..4194230207 100644 --- a/openvmm/hvlite_core/Cargo.toml +++ b/openvmm/hvlite_core/Cargo.toml @@ -97,7 +97,6 @@ getrandom.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] virt_whp = { workspace = true, optional = true } vmswitch.workspace = true diff --git a/openvmm/hvlite_core/src/worker/vm_loaders/igvm.rs b/openvmm/hvlite_core/src/worker/vm_loaders/igvm.rs index fa623c9b65..dfa44f14a4 100644 --- a/openvmm/hvlite_core/src/worker/vm_loaders/igvm.rs +++ b/openvmm/hvlite_core/src/worker/vm_loaders/igvm.rs @@ -42,7 +42,7 @@ use vm_topology::processor::aarch64::Aarch64Topology; use vm_topology::processor::x86::X86Topology; use vm_topology::processor::ArchTopology; use vm_topology::processor::ProcessorTopology; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub enum Error { @@ -282,7 +282,7 @@ pub fn vtl2_memory_range( // Select a random base within the alignment let possible_bases = (aligned_max_addr - aligned_min_addr) / alignment; let mut num: u64 = 0; - getrandom::getrandom(num.as_bytes_mut()).expect("crng failure"); + getrandom::getrandom(num.as_mut_bytes()).expect("crng failure"); let selected_base = num % (possible_bases - 1); let selected_addr = aligned_min_addr + (selected_base * alignment); tracing::trace!(possible_bases, selected_base, selected_addr); diff --git a/openvmm/hvlite_core/src/worker/vm_loaders/uefi.rs b/openvmm/hvlite_core/src/worker/vm_loaders/uefi.rs index cbfaf4d363..a501c799ce 100644 --- a/openvmm/hvlite_core/src/worker/vm_loaders/uefi.rs +++ b/openvmm/hvlite_core/src/worker/vm_loaders/uefi.rs @@ -14,7 +14,7 @@ use thiserror::Error; use vm_loader::Loader; use vm_topology::memory::MemoryLayout; use vm_topology::processor::ProcessorTopology; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub enum Error { diff --git a/rules/.gitkeep b/rules/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rules/cargo-toml-fixups.pl b/rules/cargo-toml-fixups.pl new file mode 100644 index 0000000000..8de69b9b4f --- /dev/null +++ b/rules/cargo-toml-fixups.pl @@ -0,0 +1,24 @@ +use strict; +use warnings; +use diagnostics; + +# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; + +# Check if filename is provided +if (@ARGV != 1) { + die "Usage: $0 filename\n"; +} + +my $filename = $ARGV[0]; + +# Open the file for reading +open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; + +# Read the entire file content into a single string +my $content = do { local $/; <$fh> }; +close $fh; + +$content =~ s/zerocopy_helpers.workspace = true[\r\n]//g; + +# Print the updated content +print $content; diff --git a/rules/fixup_read_from_prefix_split.pl b/rules/fixup_read_from_prefix_split.pl new file mode 100644 index 0000000000..3604ad1d9c --- /dev/null +++ b/rules/fixup_read_from_prefix_split.pl @@ -0,0 +1,97 @@ +use strict; +use warnings; +use diagnostics; + +# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; + +# Check if filename is provided +if (@ARGV != 1) { + die "Usage: $0 filename\n"; +} + +my $filename = $ARGV[0]; + +# Open the file for reading +open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; + +# Read the entire file content into a single string +my $content = do { local $/; <$fh> }; +close $fh; + +# Apply regex substitutions +# 127,128c127,128 +# < let (vendor_guid, path_data) = Guid::read_from_prefix_split(path_data) +# < .ok_or(Error::InvalidLength)?; +# --- +# > let (vendor_guid, path_data) = Guid::read_from_prefix(path_data) +# > .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err +# 248c248 +$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.ok_or\(([^)]+)\)([;]?)([?]?)([;)]?)/read_from_prefix($1).map_err(|_| $2)$3$4$5 \/\/ todo: zerocopy: map_err/g; + +# - let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix_split(self.buf) +# - .expect("buf size validated in `new`"); +# --- +# + let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix(self.buf) +# + .expect("buf size validated in `new`"); // TODO: zerocopy: expect +$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.expect\(([^)]+)\)([;]?)/read_from_prefix($1).expect($2)$3 \/\/ TODO: zerocopy: expect/g; + +# - boot::EfiExpandedAcpiDevice::read_from_prefix_split(path_data) +# - .unwrap(); +# + boot::EfiExpandedAcpiDevice::read_from_prefix(path_data) +# + .unwrap(); // TODO: zerocopy: unwrap +$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.unwrap\(\)([;]?)/read_from_prefix($1).unwrap()$2 \/\/ TODO: zerocopy: unwrap/g; + +# Adjust use statements: +# * rename AsBytes -> IntoBytes +# * add KnownLayout, Immutable, FromZeros +# * remove references to FromZeroes +# +# We can't just replace FromZeroes -> FromZeros: each module that calls T::from_zeroes now needs to use `zerocopy::FromZeros`, which +# was not true for `zerocopy::FromZeroes`. +$content =~ s/use zerocopy::AsBytes;/use zerocopy::IntoBytes; use zerocopy::Immutable; use zerocopy::KnownLayout; use zerocopy::FromZeros;/g; +$content =~ s/use zerocopy::FromZeroes;[\r\n]//g; + +# Fixup derive(...FromZeroes...) (remove FromZeroes; it is no longer needed in zerocopy 0.8) +# But, if the *only* derive is FromZeroes, replace that with the standard zerocopy 0.8 derives. +$content =~ s/derive\(FromZeroes\)/derive(FromZeros, Immutable, KnownLayout)/g; +$content =~ s/(derive\(.*)\s*FromZeroes[,]?\s*([^)]*)/$1$2/g; + +# Now rename FromZeroes -> FromZeros (for example, for cases where smallvec![FromZeroes::new_zeroed(); len]) +$content =~ s/FromZeroes/FromZeros/g; + +# Fixup derive(...AsBytes...) (rename AsBytes -> IntoBytes, add Immutable, KnownLayout) +$content =~ s/(derive\(.*)\s*AsBytes([,]?)\s*([^)]*)/$1IntoBytes, Immutable, KnownLayout$2$3/g; + +# Fixup type bounds to include Immutable and KnownLayout if IntoBytes or FromBytes are present +#$content =~ s/([^\:][\:][^\:][^,>)]*AsBytes[^,>)]*|[^\:][\:][^\:][^,>)]*FromBytes([^,>)]*))/add_immutable_knownlayout_bounds($1)/egx; +$content =~ s/([^\:][\:][^\:][^,>){;]*AsBytes[^,>){]*|[^\:][\:][^\:][^,>){;]*FromBytes[^,>){]*)([>,){])/add_immutable_knownlayout_bounds($1, $2)/egx; + +sub add_immutable_knownlayout_bounds { + my ($bounds, $suffix) = @_; + $bounds .= ' + Immutable' unless $bounds =~ /Immutable/; + $bounds .= ' + KnownLayout' unless $bounds =~ /KnownLayout/; + return "$bounds$suffix"; +} + +$content =~ s/([^\:]\:[^\),>]*)AsBytes([^\),>]*)/$1IntoBytes$2/g; + +# Add .0 to read_from_prefix calls, e.g. +# let hdr = GpaRange::read_from_prefix(self.buf[0].as_bytes()).unwrap(); +$content =~ s/(read_from_prefix\(.*\.unwrap\(\))[^\.][^0](;?)/$1.0$2 \/\/ todo: zerocopy: use-rest-of-range/g; + +# let fh = EFI_FFS_FILE_HEADER::read_from_prefix(&image[image_offset as usize..])?; +$content =~ s/(read_from_prefix\([^)]*\))(\?)(;?)/$1.ok()$2.0$3 \/\/ todo: zerocopy: use-rest-of-range, option-to-error/g; + +$content =~ s/(read_from_prefix\([^)]*\)\s*)\.ok_or\(([^)]*\))([?]?)([;)]?)/$1.map_err(|_| $2$3.0$4 \/\/ todo: zerocopy: map_err/g; + +# < *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]).unwrap() = XsaveHeader { +# > *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]).unwrap().0 = XsaveHeader { // todo: zerocopy: mut-from-prefix unwrap +$content =~ s/((mut_from_prefix|read_from_prefix)\((?:[^)(]|\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\))*\)[\n\s]*.unwrap\(\))[^\.][^0]([^\n;]*)(;?)/$1.0$3$4 \/\/ todo: zerocopy: from-prefix ($2): use-rest-of-range/g; + +$content =~ s/(ref_from_prefix\(.*\.unwrap\(\))(;?)/$1.0$2 \/\/ todo: zerocopy: ref-from-prefix: use-rest-of-range/g; + + +$content =~ s/([\w_]+)\.into_ref\(\)/Ref::into_ref($1)/g; + +# Print the updated content +print $content; diff --git a/rules/remove-from-zeroes.yaml b/rules/remove-from-zeroes.yaml new file mode 100644 index 0000000000..675aa44efa --- /dev/null +++ b/rules/remove-from-zeroes.yaml @@ -0,0 +1,24 @@ +id: remove-from-zeroes +language: rust +rule: + all: + - pattern: + context: "#[derive($$$ARGS)]" + selector: attribute +transform: + ARGS_NO_FROMZEROES: + replace: + source: $$$ARGS + replace: FromZeroes, + by: "" + COMMA_FIXUPS: + replace: + source: $ARGS_NO_FROMZEROES + replace: ", FromZeroes" + by: "" + COMMA_FIXUPS_2: + replace: + source: $COMMA_FIXUPS + replace: "FromZeroes" + by: "" +fix: 'derive($COMMA_FIXUPS_2)' diff --git a/rules/replace-asbytes-derive-macro.yaml b/rules/replace-asbytes-derive-macro.yaml new file mode 100644 index 0000000000..e405a3a4f1 --- /dev/null +++ b/rules/replace-asbytes-derive-macro.yaml @@ -0,0 +1,29 @@ +id: replace-asbytes-derive-macro +language: rust +rule: + all: + - pattern: + context: "#[derive($$$ARGS)]" + selector: token_tree +transform: + ARGS_NO_ASBYTES: + replace: + source: $$$ARGS + replace: AsBytes + by: IntoBytes, Immutable, KnownLayout + ARGS_NO_FROMZEROES: + replace: + source: $ARGS_NO_ASBYTES + replace: FromZeroes, + by: "" + COMMA_FIXUPS: + replace: + source: $ARGS_NO_FROMZEROES + replace: ", FromZeroes" + by: "" + COMMA_FIXUPS_2: + replace: + source: $COMMA_FIXUPS + replace: "FromZeroes" + by: "" +fix: '($COMMA_FIXUPS_2)' diff --git a/rules/replace-asbytes-derive.yaml b/rules/replace-asbytes-derive.yaml new file mode 100644 index 0000000000..4b5463de34 --- /dev/null +++ b/rules/replace-asbytes-derive.yaml @@ -0,0 +1,29 @@ +id: replace-asbytes-derive +language: rust +rule: + all: + - pattern: + context: "#[derive($$$ARGS)]" + selector: attribute +transform: + ARGS_NO_ASBYTES: + replace: + source: $$$ARGS + replace: AsBytes + by: IntoBytes, Immutable, KnownLayout + ARGS_NO_FROMZEROES: + replace: + source: $ARGS_NO_ASBYTES + replace: FromZeroes, + by: "" + COMMA_FIXUPS: + replace: + source: $ARGS_NO_FROMZEROES + replace: ", FromZeroes" + by: "" + COMMA_FIXUPS_2: + replace: + source: $COMMA_FIXUPS + replace: "FromZeroes" + by: "" +fix: 'derive($COMMA_FIXUPS_2)' diff --git a/rules/replace-use-asbytes.yml b/rules/replace-use-asbytes.yml new file mode 100644 index 0000000000..d85cda7d22 --- /dev/null +++ b/rules/replace-use-asbytes.yml @@ -0,0 +1,11 @@ +id: replace-use-asbytes +language: rust +rule: + pattern: use zerocopy::AsBytes; +fix: |- + use zerocopy::IntoBytes; + use zerocopy::Immutable; + use zerocopy::KnownLayout; + use zerocopy::FromZeros; + +#--- diff --git a/rules/unwrap-header-for-x64.rs.pl b/rules/unwrap-header-for-x64.rs.pl new file mode 100644 index 0000000000..2df0f4bbbd --- /dev/null +++ b/rules/unwrap-header-for-x64.rs.pl @@ -0,0 +1,24 @@ +use strict; +use warnings; +use diagnostics; + +# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; + +# Check if filename is provided +if (@ARGV != 1) { + die "Usage: $0 filename\n"; +} + +my $filename = $ARGV[0]; + +# Open the file for reading +open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; + +# Read the entire file content into a single string +my $content = do { local $/; <$fh> }; +close $fh; + +$content =~ s/\.unwrap\(\)(\s*)\.header/.unwrap().0$1.header/gm; + +# Print the updated content +print $content; diff --git a/sgconfig.yml b/sgconfig.yml new file mode 100644 index 0000000000..96c1084251 --- /dev/null +++ b/sgconfig.yml @@ -0,0 +1,2 @@ +ruleDirs: +- rules diff --git a/support/fdt/Cargo.toml b/support/fdt/Cargo.toml index 6f2aede75c..4cbd452e99 100644 --- a/support/fdt/Cargo.toml +++ b/support/fdt/Cargo.toml @@ -9,7 +9,5 @@ rust-version.workspace = true [dependencies] thiserror.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [lints] workspace = true diff --git a/support/fdt/src/builder.rs b/support/fdt/src/builder.rs index 876c456ef7..e3f932e31f 100644 --- a/support/fdt/src/builder.rs +++ b/support/fdt/src/builder.rs @@ -7,8 +7,8 @@ use crate::spec; use core::marker::PhantomData; use core::mem::size_of; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// The FDT builder. /// @@ -187,7 +187,7 @@ where ) .ok_or(Error::OutOfSpace)?, ) - .ok_or(Error::OutOfSpace)?; + .map_err(|_| Error::OutOfSpace)?; // Write the required empty reservation entry to end the reserve map. spec::ReserveEntry { @@ -203,7 +203,7 @@ where ) .ok_or(Error::OutOfSpace)?, ) - .ok_or(Error::OutOfSpace)?; + .map_err(|_| Error::OutOfSpace)?; // Determine how many bytes were used. The struct table is the last // thing stored in buffer. @@ -224,7 +224,7 @@ where }; header .write_to_prefix(self.inner.buffer) - .ok_or(Error::OutOfSpace)?; + .map_err(|_| Error::OutOfSpace)?; Ok(total_size) } @@ -377,7 +377,8 @@ impl Inner<'_> { len: (n as u32).into(), nameoff: name.0, } - .write_to_prefix(&mut self.buffer[header_offset..]); + .write_to_prefix(&mut self.buffer[header_offset..]) + .unwrap(); // PANIC: May panic if the buffer is too small (a programming error). self.align_struct()?; Ok(()) } diff --git a/support/fdt/src/parser.rs b/support/fdt/src/parser.rs index c80abaaf7a..9d546cf550 100644 --- a/support/fdt/src/parser.rs +++ b/support/fdt/src/parser.rs @@ -9,8 +9,8 @@ use super::spec::U64b; use core::fmt::Display; use core::mem::size_of; use zerocopy::FromBytes; -use zerocopy::Ref; -use zerocopy_helpers::FromBytesExt; +use zerocopy::Immutable; +use zerocopy::KnownLayout; /// Errors returned when parsing a FDT. #[derive(Debug)] @@ -172,7 +172,9 @@ impl<'a> Parser<'a> { /// Read just the `totalsize` field of a FDT header. This is useful when /// attempting to determine the overall size of a device tree. pub fn read_total_size(buf: &[u8]) -> Result> { - let header = spec::Header::read_from_prefix(buf).ok_or(Error(ErrorKind::NoHeader))?; + let header = spec::Header::read_from_prefix(buf) + .map_err(|_| Error(ErrorKind::NoHeader))? + .0; // todo: zerocopy: map_err if u32::from(header.magic) != spec::MAGIC { Err(Error(ErrorKind::HeaderMagic)) @@ -187,7 +189,9 @@ impl<'a> Parser<'a> { return Err(Error(ErrorKind::BufferAlignment)); } - let header = spec::Header::read_from_prefix(buf).ok_or(Error(ErrorKind::NoHeader))?; + let header = spec::Header::read_from_prefix(buf) + .map_err(|_| Error(ErrorKind::NoHeader))? + .0; // todo: zerocopy: map_err if u32::from(header.magic) != spec::MAGIC { return Err(Error(ErrorKind::HeaderMagic)); @@ -213,8 +217,8 @@ impl<'a> Parser<'a> { .get(mem_rsvmap_offset..) .ok_or(Error(ErrorKind::MemoryReservationBlock))?; loop { - let (entry, rest) = spec::ReserveEntry::read_from_prefix_split(mem_rsvmap) - .ok_or(Error(ErrorKind::MemoryReservationBlockEnd))?; + let (entry, rest) = spec::ReserveEntry::read_from_prefix(mem_rsvmap) + .map_err(|_| Error(ErrorKind::MemoryReservationBlockEnd))?; // todo: zerocopy: map_err if u64::from(entry.address) == 0 && u64::from(entry.size) == 0 { break; @@ -357,7 +361,7 @@ impl Display for ParseTokenError { /// Read to the next token from `buf`, returning `(token, remaining_buffer)`. fn read_token(buf: &[u8]) -> Result<(ParsedToken<'_>, &[u8]), ParseTokenError> { - let (token, rest) = U32b::read_from_prefix_split(buf).ok_or(ParseTokenError::BufLen)?; + let (token, rest) = U32b::read_from_prefix(buf).map_err(|_| ParseTokenError::BufLen)?; // todo: zerocopy: map_err let token = u32::from(token); match token { spec::BEGIN_NODE => { @@ -378,8 +382,8 @@ fn read_token(buf: &[u8]) -> Result<(ParsedToken<'_>, &[u8]), ParseTokenError> { } spec::PROP => { // Read the property header - let (header, rest) = spec::PropHeader::read_from_prefix_split(rest) - .ok_or(ParseTokenError::PropHeader)?; + let (header, rest) = spec::PropHeader::read_from_prefix(rest) + .map_err(|_| ParseTokenError::PropHeader)?; // todo: zerocopy: map_err let len = u32::from(header.len) as usize; let align_up_len = (len + 4 - 1) & !(4 - 1); @@ -620,7 +624,7 @@ pub struct Property<'a> { impl<'a> Property<'a> { /// Read a value at a given offset, indexed by `size_of::() * index`. /// T must be BigEndian. - fn read_val( + fn read_val( &self, index: usize, ) -> Result> { @@ -633,17 +637,21 @@ impl<'a> Property<'a> { // read types that are greater than 4 bytes, we must bound T to accept // unaligned types so LayoutVerified does not apply alignment and read // incorrect values. - Ok(*Ref::new_slice_unaligned(self.data) - .ok_or(Error(ErrorKind::PropertyDataTypeBuffer { - node_name: self.node_name, - prop_name: self.name, - }))? - .into_slice() + // todo: zerocopy: review carefully! (manual) + <[T]>::ref_from_bytes(self.data) + .map_err(|_| { + // todo: zerocopy: map_err + Error(ErrorKind::PropertyDataTypeBuffer { + node_name: self.node_name, + prop_name: self.name, + }) + })? .get(index) .ok_or(Error(ErrorKind::PropertyOffset { node_name: self.node_name, prop_name: self.name, - }))?) + })) + .copied() } /// Read a u32 from this property, at a given u32 index. @@ -672,11 +680,14 @@ impl<'a> Property<'a> { /// Read data as an iterator of u64 values. pub fn as_64_list(&self) -> Result + use<'a>, Error<'a>> { - Ok(U64b::slice_from(self.data) - .ok_or(Error(ErrorKind::PropertyDataTypeBuffer { - node_name: self.node_name, - prop_name: self.name, - }))? + Ok(<[U64b]>::ref_from_bytes(self.data) + .map_err(|_| { + // todo: zerocopy: map_err + Error(ErrorKind::PropertyDataTypeBuffer { + node_name: self.node_name, + prop_name: self.name, + }) + })? .iter() .map(|v| v.get())) } @@ -714,8 +725,8 @@ impl<'a> MemoryReserveIter<'a> { return Ok(None); } - let (entry, rest) = spec::ReserveEntry::read_from_prefix_split(self.memory_reservations) - .ok_or(ErrorKind::MemoryReservationBlock)?; + let (entry, rest) = spec::ReserveEntry::read_from_prefix(self.memory_reservations) + .map_err(|_| ErrorKind::MemoryReservationBlock)?; // todo: zerocopy: map_err if u64::from(entry.address) == 0 && u64::from(entry.size) == 0 { return Ok(None); diff --git a/support/fdt/src/spec.rs b/support/fdt/src/spec.rs index efcae7d4c7..5a451c3121 100644 --- a/support/fdt/src/spec.rs +++ b/support/fdt/src/spec.rs @@ -3,17 +3,18 @@ #![allow(dead_code)] -use zerocopy::AsBytes; use zerocopy::BigEndian; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub type U32b = zerocopy::U32; pub type U64b = zerocopy::U64; /// The header for the overall FDT. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Header { pub magic: U32b, pub totalsize: U32b, @@ -28,7 +29,7 @@ pub struct Header { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq, Clone, Copy)] /// A single entry in the memory reservation map, `/memreserve/`. pub struct ReserveEntry { /// The address of the reserved memory. @@ -38,7 +39,7 @@ pub struct ReserveEntry { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PropHeader { pub len: U32b, pub nameoff: U32b, diff --git a/support/guid/Cargo.toml b/support/guid/Cargo.toml index 08ba8ff6e0..fdc2e22b57 100644 --- a/support/guid/Cargo.toml +++ b/support/guid/Cargo.toml @@ -17,7 +17,6 @@ mesh_protobuf = { workspace = true, optional = true } getrandom.workspace = true thiserror.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] windows-sys.workspace = true diff --git a/support/guid/src/lib.rs b/support/guid/src/lib.rs index bc9f6398c5..164aa5cb81 100644 --- a/support/guid/src/lib.rs +++ b/support/guid/src/lib.rs @@ -8,13 +8,17 @@ use std::str::FromStr; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Windows format GUID. #[repr(C)] -#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, AsBytes, FromBytes, FromZeroes)] +#[derive( + Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, IntoBytes, FromBytes, Immutable, KnownLayout, +)] #[cfg_attr( feature = "mesh", derive(mesh_protobuf::Protobuf), @@ -63,7 +67,7 @@ impl Guid { /// Return a new randomly-generated Version 4 UUID pub fn new_random() -> Self { let mut guid = Guid::default(); - getrandom::getrandom(guid.as_bytes_mut()).expect("rng failure"); + getrandom::getrandom(guid.as_mut_bytes()).expect("rng failure"); guid.data3 = guid.data3 & 0xfff | 0x4000; // Variant 1 diff --git a/support/mesh/mesh_node/Cargo.toml b/support/mesh/mesh_node/Cargo.toml index 435debe044..9c2859d987 100644 --- a/support/mesh/mesh_node/Cargo.toml +++ b/support/mesh/mesh_node/Cargo.toml @@ -16,7 +16,6 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] pal.workspace = true diff --git a/support/mesh/mesh_node/src/local_node.rs b/support/mesh/mesh_node/src/local_node.rs index 4826a98257..886cd97c9e 100644 --- a/support/mesh/mesh_node/src/local_node.rs +++ b/support/mesh/mesh_node/src/local_node.rs @@ -37,9 +37,9 @@ use std::sync::Arc; use std::sync::Weak; use std::task::Waker; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; use zerocopy::Ref; use zerocopy::Unalign; @@ -1896,11 +1896,12 @@ impl LocalNode { /// Processes a node event. pub fn event(&self, remote_node_id: &NodeId, event: &[u8], os_resources: &mut Vec) { let parse = || { - let header = protocol::Event::read_from_prefix(event)?; - let (resources, message) = Ref::new_slice_from_prefix( + let header = protocol::Event::read_from_prefix(event).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let (resources, message) = Ref::from_prefix_with_elems( &event[size_of_val(&header)..], header.resource_count as usize, - )?; + ) + .ok()?; // todo: zerocopy: err let message = message.get(..header.message_size as usize)?; Some((header, resources, message)) }; @@ -1970,7 +1971,8 @@ impl LocalNode { protocol::EventType::CLOSE_PORT => NonMessageEvent::ClosePort.into(), protocol::EventType::CHANGE_PEER => { let data = protocol::ChangePeerData::read_from_prefix(message) - .ok_or(EventError::Truncated)?; + .map_err(|_| EventError::Truncated)? + .0; // todo: zerocopy: map_err let port = self .get_port(Address { node: NodeId(data.node.into()), @@ -1990,7 +1992,8 @@ impl LocalNode { } protocol::EventType::FAIL_PORT => { let data = protocol::FailPortData::read_from_prefix(message) - .ok_or(EventError::Truncated)?; + .map_err(|_| EventError::Truncated)? + .0; // todo: zerocopy: map_err NonMessageEvent::FailPort(NodeError::new( remote_node_id, RemotePortError(NodeId(data.node.into())), diff --git a/support/mesh/mesh_node/src/local_node/protocol.rs b/support/mesh/mesh_node/src/local_node/protocol.rs index 01779c0d11..1817ed696e 100644 --- a/support/mesh/mesh_node/src/local_node/protocol.rs +++ b/support/mesh/mesh_node/src/local_node/protocol.rs @@ -3,12 +3,13 @@ //! Protocol definitions for sending events to remote nodes. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Uuid([u8; 16]); impl Uuid { @@ -32,7 +33,7 @@ impl From for crate::common::Uuid { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Event { pub port_id: Uuid, pub event_type: EventType, @@ -43,7 +44,7 @@ pub struct Event { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum EventType: u8 { MESSAGE = 1, CLOSE_PORT = 2, @@ -55,7 +56,7 @@ open_enum::open_enum! { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ChangePeerData { pub node: Uuid, pub port: Uuid, @@ -64,13 +65,13 @@ pub struct ChangePeerData { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FailPortData { pub node: Uuid, } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ResourceData { /// if zero, this is a file descriptor/handle pub id: Uuid, diff --git a/support/mesh/mesh_protobuf/Cargo.toml b/support/mesh/mesh_protobuf/Cargo.toml index e6aeb4a9c6..54c1738226 100644 --- a/support/mesh/mesh_protobuf/Cargo.toml +++ b/support/mesh/mesh_protobuf/Cargo.toml @@ -23,7 +23,6 @@ fs-err = { workspace = true, optional = true } heck = { workspace = true, optional = true } socket2 = { workspace = true, optional = true } zerocopy.workspace = true - [build-dependencies] prost-build = { workspace = true, optional = true } diff --git a/support/mesh/mesh_protobuf/src/encoding.rs b/support/mesh/mesh_protobuf/src/encoding.rs index 7c30884f78..7c51afb8ac 100644 --- a/support/mesh/mesh_protobuf/src/encoding.rs +++ b/support/mesh/mesh_protobuf/src/encoding.rs @@ -58,6 +58,8 @@ use core::num::NonZeroU8; use core::num::NonZeroUsize; use core::time::Duration; use thiserror::Error; +use zerocopy::Immutable; +use zerocopy::KnownLayout; /// An encoding derived by `mesh_derive` for `T`. #[derive(Copy, Clone)] @@ -1436,7 +1438,7 @@ impl DescribeField for ZeroCopyEncoding { #[error("invalid byte size for type")] struct InvalidZeroCopySize; -impl FieldEncode for ZeroCopyEncoding { +impl FieldEncode for ZeroCopyEncoding { fn write_field(item: T, writer: FieldWriter<'_, '_, R>) { writer.bytes(item.as_bytes()); } @@ -1446,9 +1448,11 @@ impl FieldEncode for ZeroCopyEncoding { } } -impl<'a, T: zerocopy::FromBytes, R> FieldDecode<'a, T, R> for ZeroCopyEncoding { +impl<'a, T: zerocopy::FromBytes + Immutable + KnownLayout, R> FieldDecode<'a, T, R> + for ZeroCopyEncoding +{ fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> { - item.set(T::read_from(reader.bytes()?).ok_or_else(|| Error::new(InvalidZeroCopySize))?); + item.set(T::read_from_bytes(reader.bytes()?).map_err(|_| Error::new(InvalidZeroCopySize))?); // todo: zerocopy: better use error here Ok(()) } diff --git a/support/mesh/mesh_remote/Cargo.toml b/support/mesh/mesh_remote/Cargo.toml index 8b95fd0575..887cec132a 100644 --- a/support/mesh/mesh_remote/Cargo.toml +++ b/support/mesh/mesh_remote/Cargo.toml @@ -23,7 +23,6 @@ thiserror.workspace = true tracing.workspace = true unicycle.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] ntapi.workspace = true diff --git a/support/mesh/mesh_remote/src/alpc_node.rs b/support/mesh/mesh_remote/src/alpc_node.rs index a5eeff312d..c74bf44085 100644 --- a/support/mesh/mesh_remote/src/alpc_node.rs +++ b/support/mesh/mesh_remote/src/alpc_node.rs @@ -54,9 +54,11 @@ use std::task::Context; use std::task::Poll; use tracing_helpers::ErrorValueExt; use unicycle::FuturesUnordered; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; type InvitationMap = Arc)>>>; @@ -700,7 +702,7 @@ impl Connection { message = SendMessage::from( protocol::PacketHeader { packet_type: protocol::PacketType::LARGE_EVENT, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } .as_bytes(), ); @@ -715,7 +717,7 @@ impl Connection { message.extend( protocol::PacketHeader { packet_type: protocol::PacketType::EVENT, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } .as_bytes(), ); diff --git a/support/mesh/mesh_remote/src/point_to_point.rs b/support/mesh/mesh_remote/src/point_to_point.rs index 07dde7434f..76e8da4647 100644 --- a/support/mesh/mesh_remote/src/point_to_point.rs +++ b/support/mesh/mesh_remote/src/point_to_point.rs @@ -31,9 +31,11 @@ use std::io; use std::pin::pin; use thiserror::Error; use tracing::Instrument; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A mesh that consists of exactly two nodes, communicating over an arbitrary /// bidirectional byte stream. @@ -170,7 +172,7 @@ async fn exchange_addresses( read: &mut (impl AsyncRead + Unpin), ) -> io::Result
{ #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct Message { magic: [u8; 4], node: [u8; 16], @@ -187,7 +189,7 @@ async fn exchange_addresses( let mut remote_msg = Message::new_zeroed(); try_join( write.write_all(local_msg.as_bytes()), - read.read_exact(remote_msg.as_bytes_mut()), + read.read_exact(remote_msg.as_mut_bytes()), ) .await?; diff --git a/support/mesh/mesh_remote/src/protocol.rs b/support/mesh/mesh_remote/src/protocol.rs index ad6b1d3b12..c0cf8bf7b4 100644 --- a/support/mesh/mesh_remote/src/protocol.rs +++ b/support/mesh/mesh_remote/src/protocol.rs @@ -1,12 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PacketHeader { pub packet_type: PacketType, pub reserved: [u8; 7], @@ -14,14 +15,14 @@ pub struct PacketHeader { #[cfg(unix)] // Only used for unix nodes #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReleaseFds { pub header: PacketHeader, pub count: u64, } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum PacketType: u8 { EVENT = 1, RELEASE_FDS = 2, diff --git a/support/mesh/mesh_remote/src/unix_node.rs b/support/mesh/mesh_remote/src/unix_node.rs index 2bbd2f0753..e921020bf3 100644 --- a/support/mesh/mesh_remote/src/unix_node.rs +++ b/support/mesh/mesh_remote/src/unix_node.rs @@ -66,9 +66,9 @@ use std::sync::Arc; use thiserror::Error; use tracing::instrument; use unicycle::FuturesUnordered; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// If true, use a SOCK_SEQPACKET socket. Otherwise, use a SOCK_STREAM socket. /// @@ -468,7 +468,7 @@ fn serialize_event(event: OutgoingEvent<'_>) -> io::Result<(Vec, Vec) -> io::Result<(Vec, Vec)> { let packet = protocol::PacketHeader { packet_type: protocol::PacketType::LARGE_EVENT, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } .as_bytes() .to_vec(); @@ -631,7 +631,7 @@ async fn run_receive( packet: protocol::ReleaseFds { header: protocol::PacketHeader { packet_type: protocol::PacketType::RELEASE_FDS, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, count: fds.len() as u64, } @@ -642,7 +642,9 @@ async fn run_receive( } let buf = &buf[..len]; - let header = protocol::PacketHeader::read_from_prefix(buf).ok_or(ReceiveError::NoHeader)?; + let header = protocol::PacketHeader::read_from_prefix(buf) + .map_err(|_| ReceiveError::NoHeader)? + .0; // todo: zerocopy: map_err match header.packet_type { protocol::PacketType::EVENT => { local_node.event(remote_id, &buf[size_of_val(&header)..], &mut fds); @@ -650,7 +652,8 @@ async fn run_receive( } protocol::PacketType::RELEASE_FDS => { let release_fds = protocol::ReleaseFds::read_from_prefix(buf) - .ok_or(ReceiveError::BadReleaseFds)?; + .map_err(|_| ReceiveError::BadReleaseFds)? + .0; // todo: zerocopy: map_err let _ = send.unbounded_send(SenderCommand::ReleaseFds { count: release_fds.count as usize, }); diff --git a/support/mesh/mesh_rpc/Cargo.toml b/support/mesh/mesh_rpc/Cargo.toml index 634b5ea8b1..5f65e968d4 100644 --- a/support/mesh/mesh_rpc/Cargo.toml +++ b/support/mesh/mesh_rpc/Cargo.toml @@ -25,7 +25,6 @@ thiserror.workspace = true tracing.workspace = true unicycle.workspace = true zerocopy.workspace = true - # gRPC dependencies base64 = { workspace = true, optional = true } h2 = { workspace = true, optional = true, features = ["stream"] } diff --git a/support/mesh/mesh_rpc/src/message.rs b/support/mesh/mesh_rpc/src/message.rs index f8b0f9aa93..5a6d9e0002 100644 --- a/support/mesh/mesh_rpc/src/message.rs +++ b/support/mesh/mesh_rpc/src/message.rs @@ -12,15 +12,17 @@ use futures::AsyncWriteExt; use mesh::payload::Protobuf; use std::io::ErrorKind; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::BigEndian; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::U32; /// The wire format header for a message. #[repr(C, packed)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] struct MessageHeader { length: U32, stream_id: U32, @@ -64,7 +66,7 @@ pub async fn read_message( reader: &mut (impl AsyncRead + Unpin), ) -> std::io::Result> { let mut header = MessageHeader::new_zeroed(); - match reader.read_exact(header.as_bytes_mut()).await { + match reader.read_exact(header.as_mut_bytes()).await { Ok(_) => (), Err(err) if err.kind() == ErrorKind::UnexpectedEof => { return Ok(None); diff --git a/support/pal/pal_async/Cargo.toml b/support/pal/pal_async/Cargo.toml index d087595148..aa01c26f05 100644 --- a/support/pal/pal_async/Cargo.toml +++ b/support/pal/pal_async/Cargo.toml @@ -29,7 +29,6 @@ socket2 = { workspace = true, features = ["all"] } tempfile = { workspace = true, optional = true } unicycle.workspace = true zerocopy.workspace = true - [target.'cfg(unix)'.dependencies] libc = { workspace = true, features = ["extra_traits"] } diff --git a/support/pal/pal_async/src/windows/overlapped.rs b/support/pal/pal_async/src/windows/overlapped.rs index 6cbe6b9ef9..333cf5f9a1 100644 --- a/support/pal/pal_async/src/windows/overlapped.rs +++ b/support/pal/pal_async/src/windows/overlapped.rs @@ -26,8 +26,11 @@ use winapi::um::fileapi::WriteFile; use winapi::um::ioapiset::CancelIoEx; use winapi::um::ioapiset::DeviceIoControl; use winapi::um::minwinbase::OVERLAPPED; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Driver methods for supporting overlapped files. pub trait OverlappedIoDriver: Unpin { @@ -360,7 +363,7 @@ unsafe impl IoBufMut for () { } } -unsafe impl IoBuf for &'static [T] { +unsafe impl IoBuf for &'static [T] { fn as_ptr(&self) -> *const u8 { self.as_bytes().as_ptr() } @@ -370,7 +373,7 @@ unsafe impl IoBuf for &'static [T] { } } -unsafe impl IoBuf for Vec { +unsafe impl IoBuf for Vec { fn as_ptr(&self) -> *const u8 { self.as_bytes().as_ptr() } @@ -380,9 +383,9 @@ unsafe impl IoBuf for Vec { } } -unsafe impl IoBufMut for Vec { +unsafe impl IoBufMut for Vec { fn as_mut_ptr(&mut self) -> *mut u8 { - self.as_bytes_mut().as_mut_ptr() + self.as_mut_bytes().as_mut_ptr() } } diff --git a/support/safeatomic/Cargo.toml b/support/safeatomic/Cargo.toml index d1125350ea..acec7b1e3f 100644 --- a/support/safeatomic/Cargo.toml +++ b/support/safeatomic/Cargo.toml @@ -8,6 +8,5 @@ rust-version.workspace = true [dependencies] zerocopy.workspace = true - [lints] workspace = true diff --git a/support/safeatomic/src/lib.rs b/support/safeatomic/src/lib.rs index 24ed81fca6..e23e3742d0 100644 --- a/support/safeatomic/src/lib.rs +++ b/support/safeatomic/src/lib.rs @@ -9,16 +9,18 @@ use core::mem; use core::sync::atomic; use core::sync::atomic::AtomicU8; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A helper trait for types that can be safely transmuted to and from byte /// slices. -pub trait AsAtomicBytes: AsBytes + FromBytes { +pub trait AsAtomicBytes: IntoBytes + FromBytes + Immutable + KnownLayout { /// Casts the type to a slice of atomic bytes. fn as_atomic_bytes(&mut self) -> &[AtomicU8] { - // SAFETY: AsBytes guarantees that Self can be cast to a byte slice. - // And since we have exclusive ownership of self, it should be safe to + // SAFETY: IntoBytes guarantees that Self can be cast to a byte slice. + // And since we have exclusive ownership of self + Immutable + KnownLayout, it should be safe to // cast to an atomic byte slice (which can then be used by multiple // threads safely). // FromBytes guarantees that any value then assigned to these bytes @@ -32,7 +34,7 @@ pub trait AsAtomicBytes: AsBytes + FromBytes { } } -impl AsAtomicBytes for T where T: AsBytes + FromBytes + ?Sized {} +impl AsAtomicBytes for T where T: IntoBytes + FromBytes + ?Sized + Immutable + KnownLayout {} /// Marker trait for atomic primitives. /// @@ -61,7 +63,7 @@ unsafe impl Atomic for atomic::AtomicI64 {} pub trait AtomicSliceOps { /// # Safety /// The caller must ensure that `dest..dest+len` is a - /// [valid](core::ptr#safety) target for writes. + /// [valid](core::ptr#safety + Immutable + KnownLayout) target for writes. unsafe fn atomic_read_ptr(&self, dest: *mut u8, len: usize); /// # Safety @@ -79,7 +81,7 @@ pub trait AtomicSliceOps { /// Reads an object from the slice. /// /// Panics if the slice is not the same size as `T`. - fn atomic_read_obj(&self) -> T { + fn atomic_read_obj(&self) -> T { let mut obj = mem::MaybeUninit::::uninit(); // SAFETY: `obj` is a valid target for writes, and will be initialized by // `atomic_read_ptr`. @@ -100,7 +102,7 @@ pub trait AtomicSliceOps { /// Writes an object to the slice. /// /// Panics if the slice is not the same size as `T`. - fn atomic_write_obj(&self, obj: &T) { + fn atomic_write_obj(&self, obj: &T) { self.atomic_write(obj.as_bytes()); } diff --git a/support/sev_guest_device/Cargo.toml b/support/sev_guest_device/Cargo.toml index 1796ec5c2d..b30cbb8bfe 100644 --- a/support/sev_guest_device/Cargo.toml +++ b/support/sev_guest_device/Cargo.toml @@ -10,7 +10,6 @@ rust-version.workspace = true bitfield-struct.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [target.'cfg(target_os = "linux")'.dependencies] nix = { workspace = true, features = ["ioctl"] } thiserror.workspace = true diff --git a/support/sev_guest_device/src/ioctl.rs b/support/sev_guest_device/src/ioctl.rs index 5366da057d..bcdb8328e6 100644 --- a/support/sev_guest_device/src/ioctl.rs +++ b/support/sev_guest_device/src/ioctl.rs @@ -10,8 +10,8 @@ use crate::protocol; use std::fs::File; use std::os::fd::AsRawFd; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[expect(missing_docs)] // self-explanatory fields #[derive(Debug, Error)] diff --git a/support/sev_guest_device/src/protocol.rs b/support/sev_guest_device/src/protocol.rs index dc526e790d..4434a9c3a2 100644 --- a/support/sev_guest_device/src/protocol.rs +++ b/support/sev_guest_device/src/protocol.rs @@ -4,9 +4,11 @@ //! The module includes the definitions of data structures according to SEV-SNP specification. use bitfield_struct::bitfield; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Ioctl type defined by Linux. pub const SNP_GUEST_REQ_IOC_TYPE: u8 = b'S'; @@ -30,7 +32,7 @@ pub struct SnpGuestRequestIoctl { /// VMM error code. #[repr(C)] -#[derive(FromZeroes)] +#[derive(FromZeros, Immutable, KnownLayout)] pub struct VmmErrorCode { /// Firmware error pub fw_error: u32, @@ -41,7 +43,7 @@ pub struct VmmErrorCode { /// Request structure for the `SNP_GET_REPORT` ioctl. /// See `MSG_REPORT_REQ` in Table 21, "SEV Secure Nested Paging Firmware ABI specification", Revision 1.55. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpReportReq { /// Guest-provided data to be included in the attestation report. pub user_data: [u8; 64], @@ -62,7 +64,7 @@ const LINUX_SNP_REPORT_RESP_DATA_SIZE: usize = 4000; /// Response structure for the `SNP_GET_REPORT` ioctl. /// See `MSG_REPORT_RSP` in Table 24, "SEV Secure Nested Paging Firmware ABI specification", Revision 1.55. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpReportResp { /// The status of key derivation operation. /// 0h: Success. @@ -90,7 +92,7 @@ pub const SNP_REPORT_DATA_SIZE: usize = 64; /// Report structure. /// See `ATTESTATION_REPORT` in Table 22, "SEV Secure Nested Paging Firmware ABI specification", Revision 1.55. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpReport { /// Version number of this attestation report. /// Set to 2h for this specification. @@ -179,7 +181,7 @@ static_assertions::const_assert_eq!(SNP_REPORT_SIZE, size_of::()); /// Request structure for the `SNP_GET_DERIVED_KEY` ioctl. /// See `MSG_KEY_REQ` in Table 18, "SEV Secure Nested Paging Firmware ABI specification", Revision 1.55. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpDerivedKeyReq { /// Selects the root key from which to derive the key. /// 0 indicates VCEK @@ -229,7 +231,7 @@ pub const SNP_DERIVED_KEY_SIZE: usize = 32; /// Response structure for the `SNP_GET_DERIVED_KEY` ioctl. /// See `MSG_KEY_RSP` in Table 20, "SEV Secure Nested Paging Firmware ABI specification", Revision 1.55. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpDerivedKeyResp { /// The status of key derivation operation. /// 0h: Success. diff --git a/support/sparse_mmap/src/lib.rs b/support/sparse_mmap/src/lib.rs index 1b5704e6ba..c701729069 100644 --- a/support/sparse_mmap/src/lib.rs +++ b/support/sparse_mmap/src/lib.rs @@ -27,8 +27,10 @@ use thiserror::Error; use unix as sys; #[cfg(windows)] use windows as sys; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Must be called before using try_copy on Unix platforms. pub fn initialize_try_copy() { @@ -269,7 +271,7 @@ pub unsafe fn try_write_bytes(dest: *mut T, val: u8, count: usize) -> Result< /// appropriate protection. For example, this routine is useful if `dest` is a /// sparse mapping where some pages are mapped with PAGE_NOACCESS/PROT_NONE, and /// some are mapped with PAGE_READWRITE/PROT_WRITE. -pub unsafe fn try_compare_exchange( +pub unsafe fn try_compare_exchange( dest: *mut T, mut current: T, new: T, @@ -338,7 +340,9 @@ pub unsafe fn try_compare_exchange( /// appropriate protection. For example, this routine is useful if `dest` is a /// sparse mapping where some pages are mapped with PAGE_NOACCESS/PROT_NONE, and /// some are mapped with PAGE_READWRITE/PROT_WRITE. -pub unsafe fn try_compare_exchange_ref( +pub unsafe fn try_compare_exchange_ref< + T: IntoBytes + FromBytes + Immutable + KnownLayout + ?Sized, +>( dest: *mut u8, current: &mut T, new: &T, @@ -349,25 +353,25 @@ pub unsafe fn try_compare_exchange_ref( match (size_of_val(current), size_of_val(new)) { (1, 1) => try_cmpxchg8( dest, - &mut *current.as_bytes_mut().as_mut_ptr(), + &mut *current.as_mut_bytes().as_mut_ptr(), new.as_bytes()[0], failure.as_mut_ptr(), ), (2, 2) => try_cmpxchg16( dest.cast(), - &mut *current.as_bytes_mut().as_mut_ptr().cast(), + &mut *current.as_mut_bytes().as_mut_ptr().cast(), u16::from_ne_bytes(new.as_bytes().try_into().unwrap()), failure.as_mut_ptr(), ), (4, 4) => try_cmpxchg32( dest.cast(), - &mut *current.as_bytes_mut().as_mut_ptr().cast(), + &mut *current.as_mut_bytes().as_mut_ptr().cast(), u32::from_ne_bytes(new.as_bytes().try_into().unwrap()), failure.as_mut_ptr(), ), (8, 8) => try_cmpxchg64( dest.cast(), - &mut *current.as_bytes_mut().as_mut_ptr().cast(), + &mut *current.as_mut_bytes().as_mut_ptr().cast(), u64::from_ne_bytes(new.as_bytes().try_into().unwrap()), failure.as_mut_ptr(), ), @@ -403,7 +407,9 @@ pub unsafe fn try_compare_exchange_ref( /// appropriate protection. For example, this routine is useful if `src` is a /// sparse mapping where some pages are mapped with PAGE_NOACCESS/PROT_NONE, and /// some are mapped with PAGE_READWRITE/PROT_WRITE. -pub unsafe fn try_read_volatile(src: *const T) -> Result { +pub unsafe fn try_read_volatile( + src: *const T, +) -> Result { let mut dest = MaybeUninit::::uninit(); let mut failure = MaybeUninit::uninit(); // SAFETY: guaranteed by caller @@ -448,7 +454,10 @@ pub unsafe fn try_read_volatile(src: *const T) -> Result(dest: *mut T, value: &T) -> Result<(), MemoryError> { +pub unsafe fn try_write_volatile( + dest: *mut T, + value: &T, +) -> Result<(), MemoryError> { let mut failure = MaybeUninit::uninit(); // SAFETY: guaranteed by caller let ret = unsafe { @@ -531,7 +540,10 @@ impl SparseMapping { } /// Tries to read a type `T` from `offset`. - pub fn read_plain(&self, offset: usize) -> Result { + pub fn read_plain( + &self, + offset: usize, + ) -> Result { let mut obj = MaybeUninit::::uninit(); // SAFETY: `obj` is a valid target for writes. unsafe { diff --git a/support/tdx_guest_device/Cargo.toml b/support/tdx_guest_device/Cargo.toml index 40ec2466f5..e2c2f870f1 100644 --- a/support/tdx_guest_device/Cargo.toml +++ b/support/tdx_guest_device/Cargo.toml @@ -9,7 +9,6 @@ rust-version.workspace = true [dependencies] static_assertions.workspace = true zerocopy.workspace = true - [target.'cfg(target_os = "linux")'.dependencies] nix = { workspace = true, features = ["ioctl"] } thiserror.workspace = true diff --git a/support/tdx_guest_device/src/ioctl.rs b/support/tdx_guest_device/src/ioctl.rs index ecb55be7b8..b0b5206f5b 100644 --- a/support/tdx_guest_device/src/ioctl.rs +++ b/support/tdx_guest_device/src/ioctl.rs @@ -10,7 +10,7 @@ use crate::protocol; use std::fs::File; use std::os::fd::AsRawFd; use thiserror::Error; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; #[expect(missing_docs)] // self-explanatory fields #[derive(Debug, Error)] diff --git a/support/tdx_guest_device/src/protocol.rs b/support/tdx_guest_device/src/protocol.rs index 5c042f8a31..b57ffe5d14 100644 --- a/support/tdx_guest_device/src/protocol.rs +++ b/support/tdx_guest_device/src/protocol.rs @@ -3,9 +3,10 @@ //! The module includes the definitions of data structures according to TDX specification. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Ioctl type defined by Linux. pub const TDX_CMD_GET_REPORT0_IOC_TYPE: u8 = b'T'; @@ -28,7 +29,7 @@ pub struct TdxReportReq { /// Report structure. /// See `TDREPORT_STRUCT` in Table 3.29, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdReport { /// An instance of [`ReportMac`] pub report_mac_struct: ReportMac, @@ -44,7 +45,7 @@ static_assertions::const_assert_eq!(TDX_REPORT_SIZE, size_of::()); /// See `REPORTMACSTRUCT` in Table 3.31, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReportMac { /// Type header structure pub report_type: ReportType, @@ -66,7 +67,7 @@ pub struct ReportMac { /// See `REPORTTYPE` in Table 3.32, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReportType { /// TEE type /// 0x00: SGX @@ -86,7 +87,7 @@ pub struct ReportType { /// See `TEE_TCB_INFO` in Table 3.29, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TeeTcbInfo { /// Indicates which fields are valid. /// Set to 0x301ff. @@ -109,7 +110,7 @@ pub struct TeeTcbInfo { /// See `TEE_TCB_SVN` in Section 3.9.4, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TeeTcbSvn { /// TDX module minor SVN pub tdx_module_svn_minor: u8, @@ -123,7 +124,7 @@ pub struct TeeTcbSvn { /// See `TDINFO_STRUCT` in Table 3.33, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdInfo { /// An instance of [`TdInfoBase`] pub td_info_base: TdInfoBase, @@ -136,7 +137,7 @@ pub type Rtmr = [u8; 48]; /// See `TDINFO_BASE` in Table 3.34, "Intel TDX Module v1.5 ABI specification", March 2024. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdInfoBase { /// TD's attributes pub attributes: [u8; 8], diff --git a/support/tee_call/Cargo.toml b/support/tee_call/Cargo.toml index cb36b0dd7d..28dc0015e5 100644 --- a/support/tee_call/Cargo.toml +++ b/support/tee_call/Cargo.toml @@ -13,6 +13,5 @@ tdx_guest_device.workspace = true static_assertions.workspace = true thiserror.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/support/tee_call/src/lib.rs b/support/tee_call/src/lib.rs index 0ca3e68193..e25d3663f5 100644 --- a/support/tee_call/src/lib.rs +++ b/support/tee_call/src/lib.rs @@ -9,7 +9,7 @@ #![warn(missing_docs)] use thiserror::Error; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[expect(missing_docs)] // self-explanatory fields #[derive(Debug, Error)] diff --git a/support/zerocopy_helpers/Cargo.toml b/support/zerocopy_helpers/Cargo.toml deleted file mode 100644 index 61d5eff893..0000000000 --- a/support/zerocopy_helpers/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -[package] -name = "zerocopy_helpers" -edition.workspace = true -rust-version.workspace = true - -[dependencies] -zerocopy.workspace = true - -[lints] -workspace = true diff --git a/support/zerocopy_helpers/src/lib.rs b/support/zerocopy_helpers/src/lib.rs deleted file mode 100644 index 3f9666eb96..0000000000 --- a/support/zerocopy_helpers/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -//! Additional functionality for `zerocopy` traits. - -#![no_std] - -use zerocopy::FromBytes; -use zerocopy::Ref; -use zerocopy::Unalign; - -pub trait FromBytesExt: FromBytes { - /// Reads a copy of Self from the prefix of bytes. Returns both the copy of Self and the remaining unused bytes. - fn read_from_prefix_split(bytes: &[u8]) -> Option<(Self, &[u8])> - where - Self: Sized, - { - Ref::<_, Unalign>::new_unaligned_from_prefix(bytes) - .map(|(r, s)| (r.read().into_inner(), s)) - } - - /// Reads a copy of Self from the suffix of bytes. Returns both the remaining unused bytes and the copy of Self. - fn read_from_suffix_split(bytes: &[u8]) -> Option<(&[u8], Self)> - where - Self: Sized, - { - Ref::<_, Unalign>::new_unaligned_from_suffix(bytes) - .map(|(s, r)| (s, r.read().into_inner())) - } -} - -impl FromBytesExt for T {} diff --git a/vm/aarch64/aarch64defs/Cargo.toml b/vm/aarch64/aarch64defs/Cargo.toml index d752265366..8ccb5f6a3d 100644 --- a/vm/aarch64/aarch64defs/Cargo.toml +++ b/vm/aarch64/aarch64defs/Cargo.toml @@ -11,6 +11,5 @@ open_enum.workspace = true bitfield-struct.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/aarch64/aarch64defs/src/lib.rs b/vm/aarch64/aarch64defs/src/lib.rs index a4c5b74986..9ab17e9b0f 100644 --- a/vm/aarch64/aarch64defs/src/lib.rs +++ b/vm/aarch64/aarch64defs/src/lib.rs @@ -10,9 +10,10 @@ pub mod psci; use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Aarch64 SPSR_EL2 register when in 64-bit mode. Usually called CPSR by /// hypervisors. @@ -54,7 +55,7 @@ pub struct Cpsr64 { /// ESR_EL2, exception syndrome register. #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EsrEl2 { #[bits(25)] pub iss: u32, @@ -792,7 +793,7 @@ pub struct TranslationBaseEl1 { } #[bitfield(u64)] -#[derive(PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Pte { pub valid: bool, pub not_large_page: bool, diff --git a/vm/acpi/Cargo.toml b/vm/acpi/Cargo.toml index 3a0cf102b2..affe830439 100644 --- a/vm/acpi/Cargo.toml +++ b/vm/acpi/Cargo.toml @@ -12,6 +12,5 @@ memory_range.workspace = true x86defs.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/acpi/src/builder.rs b/vm/acpi/src/builder.rs index 5ef30dbd1f..e0277e8e9b 100644 --- a/vm/acpi/src/builder.rs +++ b/vm/acpi/src/builder.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use std::num::Wrapping; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Copy, Clone)] pub struct OemInfo { diff --git a/vm/acpi/src/dsdt.rs b/vm/acpi/src/dsdt.rs index 25966cfe1c..8102a9baee 100644 --- a/vm/acpi/src/dsdt.rs +++ b/vm/acpi/src/dsdt.rs @@ -12,12 +12,13 @@ pub use objects::*; pub use ops::*; pub use resources::*; use x86defs::apic::APIC_BASE_ADDRESS; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DescriptionHeader { pub signature: u32, _length: u32, diff --git a/vm/acpi_spec/Cargo.toml b/vm/acpi_spec/Cargo.toml index 0e8af3c798..42663a0cf5 100644 --- a/vm/acpi_spec/Cargo.toml +++ b/vm/acpi_spec/Cargo.toml @@ -19,6 +19,5 @@ bitfield-struct.workspace = true static_assertions.workspace = true thiserror.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/acpi_spec/src/aspt.rs b/vm/acpi_spec/src/aspt.rs index 3b8eded084..4ddcdd2ef3 100644 --- a/vm/acpi_spec/src/aspt.rs +++ b/vm/acpi_spec/src/aspt.rs @@ -7,11 +7,13 @@ // device. use super::Table; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, Unaligned)] pub struct Aspt { pub num_structs: usize, // variable number of trailing structs @@ -22,7 +24,7 @@ impl Table for Aspt { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub struct AsptStructHeader { pub type_: structs::AsptStructType, // length of the struct, including this header @@ -41,12 +43,13 @@ impl AsptStructHeader { /// Each of these structs is prepended by a `AsptStructHeader` pub mod structs { use open_enum::open_enum; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum AsptStructType: u16 { ASP_GLOBAL_REGISTERS = 0, SEV_MAILBOX_REGISTERS = 1, @@ -54,12 +57,12 @@ pub mod structs { } } - pub trait AsptStruct: AsBytes { + pub trait AsptStruct: IntoBytes + Immutable + KnownLayout { const TYPE: AsptStructType; } #[repr(C, packed)] - #[derive(Copy, Clone, Debug, AsBytes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub struct AspGlobalRegisters { pub _reserved: u32, pub feature_register_address: u64, @@ -72,7 +75,7 @@ pub mod structs { } #[repr(C, packed)] - #[derive(Copy, Clone, Debug, AsBytes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub struct SevMailboxRegisters { pub mailbox_interrupt_id: u8, pub _reserved: [u8; 3], @@ -86,7 +89,7 @@ pub mod structs { } #[repr(C, packed)] - #[derive(Copy, Clone, Debug, AsBytes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub struct AcpiMailboxRegisters { pub _reserved1: u32, pub cmd_resp_register_address: u64, diff --git a/vm/acpi_spec/src/fadt.rs b/vm/acpi_spec/src/fadt.rs index a5eab5e2f6..7dc4a5a7b8 100644 --- a/vm/acpi_spec/src/fadt.rs +++ b/vm/acpi_spec/src/fadt.rs @@ -5,11 +5,13 @@ use super::Header; use super::Table; use core::mem::size_of; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, Default, AsBytes, Unaligned)] +#[derive(Copy, Clone, Debug, Default, IntoBytes, Immutable, KnownLayout, Unaligned)] pub struct Fadt { // 36 pub facs: u32, @@ -120,7 +122,7 @@ pub const FADT_HW_REDUCED_ACPI: u32 = 1 << 20; pub const FADT_LOW_POWER_S0_IDLE_CAPABLE: u32 = 1 << 21; #[repr(u8)] -#[derive(Copy, Clone, Debug, AsBytes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub enum AddressSpaceId { SystemMemory = 0, SystemIo = 1, @@ -138,7 +140,7 @@ impl Default for AddressSpaceId { } #[repr(u8)] -#[derive(Copy, Clone, Debug, AsBytes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout)] pub enum AddressWidth { Undefined = 0, Byte = 1, @@ -154,7 +156,7 @@ impl Default for AddressWidth { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, Default, AsBytes)] +#[derive(Copy, Clone, Debug, Default, IntoBytes, Immutable, KnownLayout)] pub struct GenericAddress { pub addr_space_id: AddressSpaceId, pub register_bit_width: u8, diff --git a/vm/acpi_spec/src/lib.rs b/vm/acpi_spec/src/lib.rs index 721e99ae8b..1d8b2361bb 100644 --- a/vm/acpi_spec/src/lib.rs +++ b/vm/acpi_spec/src/lib.rs @@ -24,13 +24,14 @@ mod packed_nums { use self::packed_nums::*; use core::mem::size_of; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct Rsdp { pub signature: [u8; 8], // "RSD PTR " pub checksum: u8, // first 20 bytes @@ -46,7 +47,7 @@ pub struct Rsdp { const_assert_eq!(size_of::(), 36); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct Header { pub signature: [u8; 4], pub length: u32_ne, @@ -62,6 +63,6 @@ pub struct Header { const_assert_eq!(size_of::
(), 36); /// Marker trait for ACPI Table structs that encodes the table's signature -pub trait Table: AsBytes + Unaligned { +pub trait Table: IntoBytes + Unaligned + Immutable + KnownLayout { const SIGNATURE: [u8; 4]; } diff --git a/vm/acpi_spec/src/madt.rs b/vm/acpi_spec/src/madt.rs index 2c13d2dc02..1f78ba5f73 100644 --- a/vm/acpi_spec/src/madt.rs +++ b/vm/acpi_spec/src/madt.rs @@ -8,9 +8,11 @@ use open_enum::open_enum; use size_of_val; use static_assertions::const_assert_eq; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; use zerocopy::LE; use zerocopy::U16; @@ -18,7 +20,7 @@ use zerocopy::U32; use zerocopy::U64; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct Madt { pub apic_addr: u32, pub flags: u32, @@ -31,7 +33,7 @@ impl Table for Madt { pub const MADT_PCAT_COMPAT: u32 = 1 << 0; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes, Unaligned)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub enum MadtType: u8 { APIC = 0x0, IO_APIC = 0x1, @@ -43,14 +45,14 @@ open_enum! { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtEntryHeader { pub typ: MadtType, pub length: u8, } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtApic { pub typ: MadtType, pub length: u8, @@ -77,7 +79,7 @@ pub const MADT_APIC_ENABLED: u32 = 1 << 0; pub const MADT_APIC_ONLINE_CAPABLE: u32 = 1 << 1; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtX2Apic { pub typ: MadtType, pub length: u8, @@ -103,7 +105,7 @@ impl MadtX2Apic { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtIoApic { pub typ: MadtType, pub length: u8, @@ -129,7 +131,7 @@ impl MadtIoApic { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtInterruptSourceOverride { pub typ: MadtType, pub length: u8, @@ -178,7 +180,7 @@ impl MadtInterruptSourceOverride { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MadtGicd { pub typ: MadtType, pub length: u8, @@ -210,7 +212,7 @@ impl MadtGicd { // TODO: use LE types everywhere, as here, to avoid #[repr(packed)] and to be // specific about endianness (which the ACPI spec dictates is always LE). #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct MadtGicc { pub typ: MadtType, pub length: u8, @@ -261,7 +263,9 @@ pub struct MadtParser<'a>(&'a [u8]); impl<'a> MadtParser<'a> { /// Partially an MADT table. pub fn new(table: &'a [u8]) -> Result { - let header = crate::Header::read_from_prefix(table).ok_or(ParserError)?; + let header = crate::Header::read_from_prefix(table) + .map_err(|_| ParserError)? + .0; // todo: zerocopy: map_err if (header.length.get() as usize) < size_of::() { return Err(ParserError); } @@ -351,7 +355,9 @@ pub struct MadtIter<'a> { impl MadtIter<'_> { fn parse(&mut self) -> Result, ParserError> { - while let Some(header) = MadtEntryHeader::read_from_prefix(self.entries) { + // todo: zerocopy: map_err + while let Ok((header, _)) = MadtEntryHeader::read_from_prefix(self.entries) { + // todo: zerocopy: ok if self.entries.len() < header.length as usize { return Err(ParserError); } @@ -359,10 +365,12 @@ impl MadtIter<'_> { self.entries = rest; let entry = match header.typ { MadtType::APIC => { - MadtEntry::Apic(FromBytes::read_from_prefix(buf).ok_or(ParserError)?) + MadtEntry::Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0) + // todo: zerocopy: map_err } MadtType::X2APIC => { - MadtEntry::X2Apic(FromBytes::read_from_prefix(buf).ok_or(ParserError)?) + MadtEntry::X2Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0) + // todo: zerocopy: map_err } _ => continue, }; diff --git a/vm/acpi_spec/src/pptt.rs b/vm/acpi_spec/src/pptt.rs index eee9692d7c..15da483682 100644 --- a/vm/acpi_spec/src/pptt.rs +++ b/vm/acpi_spec/src/pptt.rs @@ -6,14 +6,16 @@ use crate::packed_nums::u32_ne; use crate::Table; use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; /// PPTT table, used for describing the cache topology of a machine. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct Pptt {} impl Table for Pptt { @@ -21,7 +23,7 @@ impl Table for Pptt { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes, Unaligned)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub enum PpttType: u8 { PROCESSOR = 0, CACHE = 1, @@ -29,7 +31,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct PpttProcessor { pub typ: PpttType, pub len: u8, @@ -59,13 +61,13 @@ impl PpttProcessor { typ: PpttType::PROCESSOR, len: size_of::() as u8 + num_private_resources * 4, num_private_resources: (num_private_resources as u32).into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct PpttCache { pub typ: PpttType, pub len: u8, @@ -87,7 +89,7 @@ impl PpttCache { Self { typ: PpttType::CACHE, len: size_of::() as u8, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } @@ -107,7 +109,7 @@ pub struct PpttCacheFlags { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct PpttCacheAttributes { #[bits(2)] pub allocation_type: u8, diff --git a/vm/acpi_spec/src/srat.rs b/vm/acpi_spec/src/srat.rs index 1209c96a64..edac8686f2 100644 --- a/vm/acpi_spec/src/srat.rs +++ b/vm/acpi_spec/src/srat.rs @@ -8,14 +8,15 @@ use super::Table; use crate::packed_nums::*; use core::mem::size_of; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Ref; use zerocopy::Unaligned; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct SratHeader { pub rsvd1: u32_ne, pub rsvd2: u64_ne, @@ -37,7 +38,7 @@ impl Table for SratHeader { pub const SRAT_REVISION: u8 = 3; open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes, Unaligned)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub enum SratType: u8 { APIC = 0, MEMORY = 1, @@ -47,7 +48,7 @@ open_enum::open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct SratApic { pub typ: SratType, pub length: u8, @@ -84,7 +85,7 @@ impl SratApic { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct SratX2Apic { pub typ: SratType, pub length: u8, @@ -114,7 +115,7 @@ impl SratX2Apic { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct SratGicc { pub typ: SratType, pub length: u8, @@ -140,7 +141,7 @@ impl SratGicc { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)] pub struct SratMemory { pub typ: SratType, pub length: u8, @@ -157,8 +158,9 @@ pub struct SratMemory { impl core::fmt::Debug for SratMemory { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let address = u64::read_from([self.low_address, self.high_address].as_bytes()).unwrap(); - let length = u64::read_from([self.low_length, self.high_length].as_bytes()).unwrap(); + let address = + u64::read_from_bytes([self.low_address, self.high_address].as_bytes()).unwrap(); + let length = u64::read_from_bytes([self.low_length, self.high_length].as_bytes()).unwrap(); f.debug_struct("SratMemory") .field("typ", &self.typ) @@ -240,8 +242,8 @@ pub fn parse_srat<'a>( mut on_memory: impl FnMut(&'a SratMemory), ) -> Result<(&'a crate::Header, &'a SratHeader), ParseSratError> { let raw_srat_len = raw_srat.len(); - let (acpi_header, buf) = Ref::<_, crate::Header>::new_from_prefix(raw_srat) - .ok_or(ParseSratError::MissingAcpiHeader)?; + let (acpi_header, buf) = Ref::<_, crate::Header>::from_prefix(raw_srat) + .map_err(|_| ParseSratError::MissingAcpiHeader)?; // todo: zerocopy: map_err if acpi_header.signature != *b"SRAT" { return Err(ParseSratError::InvalidSignature(acpi_header.signature)); @@ -255,27 +257,27 @@ pub fn parse_srat<'a>( } let (srat_header, mut buf) = - Ref::<_, SratHeader>::new_from_prefix(buf).ok_or(ParseSratError::MissingFixedHeader)?; + Ref::<_, SratHeader>::from_prefix(buf).map_err(|_| ParseSratError::MissingFixedHeader)?; // todo: zerocopy: map_err while !buf.is_empty() { buf = match SratType(buf[0]) { SratType::APIC => { let (apic, rest) = - Ref::<_, SratApic>::new_from_prefix(buf).ok_or(ParseSratError::BadApic)?; - on_apic(apic.into_ref()); + Ref::<_, SratApic>::from_prefix(buf).map_err(|_| ParseSratError::BadApic)?; // todo: zerocopy: map_err + on_apic(Ref::into_ref(apic)); rest } SratType::MEMORY => { - let (mem, rest) = - Ref::<_, SratMemory>::new_from_prefix(buf).ok_or(ParseSratError::BadMemory)?; - on_memory(mem.into_ref()); + let (mem, rest) = Ref::<_, SratMemory>::from_prefix(buf) + .map_err(|_| ParseSratError::BadMemory)?; // todo: zerocopy: map_err + on_memory(Ref::into_ref(mem)); rest } _ => return Err(ParseSratError::UnknownType(buf[0])), } } - Ok((acpi_header.into_ref(), srat_header.into_ref())) + Ok((Ref::into_ref(acpi_header), Ref::into_ref(srat_header))) } #[cfg(feature = "alloc")] diff --git a/vm/chipset_device_fuzz/src/lib.rs b/vm/chipset_device_fuzz/src/lib.rs index 7509bd6880..559d733f64 100644 --- a/vm/chipset_device_fuzz/src/lib.rs +++ b/vm/chipset_device_fuzz/src/lib.rs @@ -155,7 +155,7 @@ impl FuzzChipset { let result = locked_dev .supports_pci() .expect("objects on the pci bus support pci") - .pci_cfg_read(offset, u32::mut_from(data).unwrap()); + .pci_cfg_read(offset, u32::mut_from_bytes(data).unwrap()); match result { IoResult::Ok => {} IoResult::Err(_) => { diff --git a/vm/devices/firmware/firmware_pcat/Cargo.toml b/vm/devices/firmware/firmware_pcat/Cargo.toml index 5ea8264526..191a3a922c 100644 --- a/vm/devices/firmware/firmware_pcat/Cargo.toml +++ b/vm/devices/firmware/firmware_pcat/Cargo.toml @@ -26,6 +26,5 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/firmware/firmware_pcat/src/lib.rs b/vm/devices/firmware/firmware_pcat/src/lib.rs index 61cd8fc485..b41fc75fab 100644 --- a/vm/devices/firmware/firmware_pcat/src/lib.rs +++ b/vm/devices/firmware/firmware_pcat/src/lib.rs @@ -46,7 +46,7 @@ use vm_topology::processor::VpIndex; use vmcore::device_state::ChangeDeviceState; use vmcore::vmtime::VmTimeAccess; use vmcore::vmtime::VmTimeSource; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Static config info which gets queried by the PCAT BIOS. pub mod config { diff --git a/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs b/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs index 0d3339b190..0f2d2d9d4a 100644 --- a/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs +++ b/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs @@ -18,9 +18,10 @@ use super::config::SmbiosProcessorInfoBundle; use core::mem::size_of; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// reSearch query: `RootCpuData::GetVpDmiInfo` pub(crate) fn get_vp_dmi_info( @@ -108,7 +109,7 @@ pub(crate) fn get_vp_dmi_info( // reSearch query: `SMBIOS_HEADER` #[repr(C, packed)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] struct SmbiosHeader { structure_type: u8, length: u8, @@ -122,7 +123,7 @@ struct SmbiosHeader { /// /// reSearch query: `SMBIOS_CPU_INFO_FORMATTED` #[repr(C, packed)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] struct SmbiosCpuInfoFormatted { header: SmbiosHeader, socket_designation: u8, @@ -173,14 +174,15 @@ const MAX_SMBIOS_STRING_TABLE_LENGTH: usize = /// reSearch query: `SMBIOS_CPU_INFO_STRINGS_LEGACY` #[repr(C, packed)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] -struct SmbiosCpuInfoStringsLegacy { +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] +// todo: zerocopy: remove `pub(crate)` once this issue is resolved: https://github.com/google/zerocopy/issues/2177 +pub(crate) struct SmbiosCpuInfoStringsLegacy { string_table: [u8; MAX_SMBIOS_STRING_TABLE_LEGACY_LENGTH], } /// reSearch query: `SMBIOS_CPU_INFO_STRINGS` #[repr(C, packed)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] struct SmbiosCpuInfoStrings { string_table: [u8; MAX_SMBIOS_STRING_TABLE_LENGTH], } @@ -191,7 +193,7 @@ static_assertions::const_assert!( /// reSearch query: `SMBIOS_CPU_INFORMATION_LEGACY` #[repr(C, packed)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] pub(crate) struct SmbiosCpuInfoLegacy { formatted: SmbiosCpuInfoFormatted, unformatted: SmbiosCpuInfoStringsLegacy, diff --git a/vm/devices/firmware/firmware_uefi/Cargo.toml b/vm/devices/firmware/firmware_uefi/Cargo.toml index cf6dd8442c..dca17b1d6d 100644 --- a/vm/devices/firmware/firmware_uefi/Cargo.toml +++ b/vm/devices/firmware/firmware_uefi/Cargo.toml @@ -51,7 +51,6 @@ tracelimit.workspace = true tracing.workspace = true wchar.workspace = true zerocopy.workspace = true - [dev-dependencies] test_with_tracing.workspace = true diff --git a/vm/devices/firmware/firmware_uefi/fuzz/Cargo.toml b/vm/devices/firmware/firmware_uefi/fuzz/Cargo.toml index fae77ea594..aae7cacc3f 100644 --- a/vm/devices/firmware/firmware_uefi/fuzz/Cargo.toml +++ b/vm/devices/firmware/firmware_uefi/fuzz/Cargo.toml @@ -14,7 +14,6 @@ xtask_fuzz.workspace = true guid.workspace = true ucs2.workspace = true zerocopy.workspace = true - arbitrary = { workspace = true, features = ["derive"] } [target.'cfg(all(target_os = "linux", target_env = "gnu"))'.dependencies] diff --git a/vm/devices/firmware/firmware_uefi/fuzz/fuzz_firmware_uefi.rs b/vm/devices/firmware/firmware_uefi/fuzz/fuzz_firmware_uefi.rs index 10d153c4b5..929e4817f1 100644 --- a/vm/devices/firmware/firmware_uefi/fuzz/fuzz_firmware_uefi.rs +++ b/vm/devices/firmware/firmware_uefi/fuzz/fuzz_firmware_uefi.rs @@ -101,9 +101,9 @@ fn do_fuzz(input: FuzzInput) { let var = ParsedAuthVar { name: &Ucs2LeVec::from(name), - vendor: Guid::read_from(&vendor).unwrap(), + vendor: Guid::read_from_bytes(&vendor).unwrap(), attr, - timestamp: EFI_TIME::read_from(×tamp).unwrap(), + timestamp: EFI_TIME::read_from_bytes(×tamp).unwrap(), pkcs7_data: &pkcs7_data, var_data: &var_data, }; diff --git a/vm/devices/firmware/firmware_uefi/src/service/event_log.rs b/vm/devices/firmware/firmware_uefi/src/service/event_log.rs index 8b40be3de7..6516634e97 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/event_log.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/event_log.rs @@ -83,7 +83,8 @@ impl EventLogServices { while !event_data.is_empty() { let desc = EfiEventDescriptor::read_from_prefix(event_data) - .ok_or(EventLogError::ConvertBytes)?; + .map_err(|_| EventLogError::ConvertBytes)? + .0; // todo: zerocopy: map_err let data = event_data .get(desc.header_size as usize..) @@ -97,7 +98,8 @@ impl EventLogServices { match desc.event_id { uefi_specs::hyperv::boot_bios_log::BOOT_DEVICE_EVENT_ID => { let boot_entry = BootEventDeviceEntry::read_from_prefix(data) - .ok_or(EventLogError::BootEventSize)?; + .map_err(|_| EventLogError::BootEventSize)? + .0; // todo: zerocopy: map_err tracing::debug!(?boot_entry, "boot log entry"); diff --git a/vm/devices/firmware/firmware_uefi/src/service/nvram/mod.rs b/vm/devices/firmware/firmware_uefi/src/service/nvram/mod.rs index 5cd4e0b15c..6b8d3aa87d 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/nvram/mod.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/nvram/mod.rs @@ -27,7 +27,7 @@ use thiserror::Error; use uefi_nvram_storage::InspectableNvramStorage; use uefi_specs::uefi::common::EfiStatus; use uefi_specs::uefi::nvram::EfiVariableAttributes; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[cfg(feature = "fuzzing")] pub mod spec_services; @@ -579,7 +579,7 @@ impl UefiDevice { let mut data = vec![0u16; command.len as usize / 2]; self.gm - .read_at(command.address.into(), data.as_bytes_mut())?; + .read_at(command.address.into(), data.as_mut_bytes())?; tracing::trace!( target: "uefi-nvram-guest-debug", diff --git a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/auth_var_crypto.rs b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/auth_var_crypto.rs index 1f63165a46..b389f90605 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/auth_var_crypto.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/auth_var_crypto.rs @@ -8,7 +8,7 @@ use super::ParsedAuthVar; use thiserror::Error; use uefi_nvram_specvars::signature_list; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Errors that occur due to various formatting issues in the crypto objects. #[derive(Debug, Error)] diff --git a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs index 1fe5165da6..00ab6aacd9 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs @@ -30,7 +30,7 @@ use uefi_specs::uefi::common::EfiStatus; use uefi_specs::uefi::nvram::EfiVariableAttributes; use uefi_specs::uefi::time::EFI_TIME; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; #[cfg(feature = "fuzzing")] pub mod auth_var_crypto; @@ -710,9 +710,10 @@ impl NvramSpecServices { }; // extract EFI_VARIABLE_AUTHENTICATION_2 header + // todo: zerocopy: err let auth_hdr = - match EFI_VARIABLE_AUTHENTICATION_2::read_from_prefix(data.as_slice()) { - Some(hdr) => hdr, + match EFI_VARIABLE_AUTHENTICATION_2::read_from_prefix(data.as_slice()).ok() { + Some((hdr, _)) => hdr, None => { return NvramResult( (), @@ -1507,7 +1508,8 @@ mod test { // represented in UCS-2). use pal_async::async_test; use wchar::wchz; - use zerocopy::AsBytes; + + use zerocopy::IntoBytes; /// Extension trait around `NvramServices` that makes it easier to use the /// API outside the context of the UEFI device diff --git a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/Cargo.toml b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/Cargo.toml index 573495862a..a1021c44a0 100644 --- a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/Cargo.toml +++ b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/Cargo.toml @@ -18,7 +18,6 @@ guid.workspace = true inspect = { workspace = true, optional = true } open_enum.workspace = true ucs2.workspace = true -zerocopy_helpers.workspace = true anyhow.workspace = true async-trait.workspace = true @@ -27,7 +26,6 @@ thiserror.workspace = true tracing.workspace = true wchar.workspace = true zerocopy.workspace = true - [dev-dependencies] pal_async.workspace = true diff --git a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs index 3cc595078a..859b8c0de0 100644 --- a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs +++ b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs @@ -27,10 +27,10 @@ use uefi_nvram_storage::NextVariable; use uefi_nvram_storage::NvramStorage; use uefi_nvram_storage::NvramStorageError; use uefi_nvram_storage::EFI_TIME; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const EFI_MAX_VARIABLE_NAME_SIZE: usize = 2 * 1024; const EFI_MAX_VARIABLE_DATA_SIZE: usize = 32 * 1024; @@ -46,14 +46,14 @@ mod format { use static_assertions::const_assert_eq; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum NvramHeaderType: u32 { VARIABLE = 0, } } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NvramHeader { pub header_type: NvramHeaderType, pub length: u32, // Total length of the variable, in bytes. Includes the header. @@ -62,7 +62,7 @@ mod format { const_assert_eq!(8, size_of::()); #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NvramVariable { pub header: NvramHeader, // Set to type NvramVariable pub attributes: u32, @@ -168,7 +168,9 @@ impl HclCompatNvram { self.in_memory.clear(); self.nvram_buf = nvram_buf; let mut buf = self.nvram_buf.as_slice(); - while let Some(header) = format::NvramHeader::read_from_prefix(buf) { + // todo: zerocopy: error propagation + // todo: zerocopy: review carefully! manual fixup + while let Ok((header, _)) = format::NvramHeader::read_from_prefix(buf) { if buf.len() < header.length as usize { return Err(NvramStorageError::Load( format!( @@ -199,14 +201,10 @@ impl HclCompatNvram { // corresponds to a VARIABLE entry let (var_header, var_name, var_data) = { - let (var_header, var_length_data) = { - match format::NvramVariable::read_from_prefix_split(entry_buf) { - Some(t) => t, - None => { - return Err(NvramStorageError::Load("variable entry too short".into())) - } - } - }; + let (var_header, var_length_data) = + // todo: zerocopy: error propagation + // todo: zerocopy: manual fix - review carefully! + format::NvramVariable::read_from_prefix(entry_buf).map_err(|_| NvramStorageError::Load("variable entry too short".into()))?; if var_length_data.len() != var_header.name_bytes as usize + var_header.data_bytes as usize diff --git a/vm/devices/firmware/hyperv_uefi_custom_vars_json/Cargo.toml b/vm/devices/firmware/hyperv_uefi_custom_vars_json/Cargo.toml index e9013b9477..8cf4058c27 100644 --- a/vm/devices/firmware/hyperv_uefi_custom_vars_json/Cargo.toml +++ b/vm/devices/firmware/hyperv_uefi_custom_vars_json/Cargo.toml @@ -17,6 +17,5 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true thiserror.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs b/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs index 6d00f32572..323bd2ac42 100644 --- a/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs +++ b/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs @@ -275,7 +275,7 @@ mod json { v.len() ))); } - Ok(Guid::read_from_prefix(v.as_slice()).unwrap()) + Ok(Guid::read_from_prefix(v.as_slice()).unwrap().0) // todo: zerocopy: use-rest-of-range } } } diff --git a/vm/devices/firmware/uefi_nvram_specvars/Cargo.toml b/vm/devices/firmware/uefi_nvram_specvars/Cargo.toml index 77d818d53a..6875437f25 100644 --- a/vm/devices/firmware/uefi_nvram_specvars/Cargo.toml +++ b/vm/devices/firmware/uefi_nvram_specvars/Cargo.toml @@ -13,11 +13,9 @@ default = [] guid.workspace = true ucs2.workspace = true uefi_specs.workspace = true -zerocopy_helpers.workspace = true thiserror.workspace = true zerocopy.workspace = true - [dev-dependencies] [lints] diff --git a/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs b/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs index 4dd6c3cdb9..1d32fa4583 100644 --- a/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs +++ b/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs @@ -9,7 +9,6 @@ use thiserror::Error; use ucs2::Ucs2LeSlice; use uefi_specs::uefi::boot; use zerocopy::FromBytes; -use zerocopy_helpers::FromBytesExt; #[derive(Debug, Error)] pub enum Error { @@ -99,8 +98,8 @@ pub enum EfiDevicePathProtocol<'a> { impl<'a> EfiDevicePathProtocol<'a> { pub fn parse(data: &'a [u8]) -> Result<(Self, &'a [u8]), Error> { - let (header, path_data) = boot::EfiDevicePathProtocol::read_from_prefix_split(data) - .ok_or(Error::InvalidLength)?; + let (header, path_data) = boot::EfiDevicePathProtocol::read_from_prefix(data) + .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err let length = u16::from_le_bytes(header.length) as usize; // TODO: Switch to split_at_checked below once stable and remove this check @@ -120,13 +119,13 @@ impl<'a> EfiDevicePathProtocol<'a> { match boot::EfiHardwareDeviceSubType(header.sub_type) { boot::EfiHardwareDeviceSubType::MEMORY_MAPPED => { HardwareDevice::MemoryMapped( - boot::EfiMemoryMappedDevice::read_from(path_data) - .ok_or(Error::InvalidLength)?, + boot::EfiMemoryMappedDevice::read_from_bytes(path_data) + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err ) } boot::EfiHardwareDeviceSubType::VENDOR => { - let (vendor_guid, path_data) = Guid::read_from_prefix_split(path_data) - .ok_or(Error::InvalidLength)?; + let (vendor_guid, path_data) = Guid::read_from_prefix(path_data) + .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err HardwareDevice::Vendor { vendor_guid, data: path_data, @@ -146,8 +145,7 @@ impl<'a> EfiDevicePathProtocol<'a> { return Err(Error::InvalidLength); } let (numeric, path_data) = - boot::EfiExpandedAcpiDevice::read_from_prefix_split(path_data) - .unwrap(); + boot::EfiExpandedAcpiDevice::read_from_prefix(path_data).unwrap(); // TODO: zerocopy: unwrap let hidstr = CStr::from_bytes_until_nul(path_data) .map_err(Error::NullTerminated)?; let path_data = &path_data[hidstr.to_bytes_with_nul().len()..]; @@ -175,8 +173,8 @@ impl<'a> EfiDevicePathProtocol<'a> { boot::EfiDeviceType::MESSAGING => EfiDevicePathProtocol::Messaging( match boot::EfiMessagingDeviceSubType(header.sub_type) { boot::EfiMessagingDeviceSubType::SCSI => MessagingDevice::Scsi( - boot::EfiScsiDevice::read_from(path_data) - .ok_or(Error::InvalidLength)?, + boot::EfiScsiDevice::read_from_bytes(path_data) + .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err ), device_subtype => MessagingDevice::Unknown { device_subtype, @@ -187,8 +185,8 @@ impl<'a> EfiDevicePathProtocol<'a> { boot::EfiDeviceType::MEDIA => EfiDevicePathProtocol::Media( match boot::EfiMediaDeviceSubType(header.sub_type) { boot::EfiMediaDeviceSubType::HARD_DRIVE => MediaDevice::HardDrive( - boot::EfiHardDriveDevice::read_from(path_data) - .ok_or(Error::InvalidLength)?, + boot::EfiHardDriveDevice::read_from_bytes(path_data) + .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err ), boot::EfiMediaDeviceSubType::FILE => { let file_name = Ucs2LeSlice::from_slice_with_nul(path_data) @@ -200,12 +198,14 @@ impl<'a> EfiDevicePathProtocol<'a> { } boot::EfiMediaDeviceSubType::PIWG_FIRMWARE_FILE => { MediaDevice::PiwgFirmwareFile( - Guid::read_from(path_data).ok_or(Error::InvalidLength)?, + Guid::read_from_bytes(path_data) + .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err ) } boot::EfiMediaDeviceSubType::PIWG_FIRMWARE_VOLUME => { MediaDevice::PiwgFirmwareVolume( - Guid::read_from(path_data).ok_or(Error::InvalidLength)?, + Guid::read_from_bytes(path_data) + .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err ) } device_subtype => MediaDevice::Unknown { @@ -246,7 +246,7 @@ pub struct EfiLoadOption<'a> { impl<'a> EfiLoadOption<'a> { pub fn parse(data: &'a [u8]) -> Result { let (header, data) = - boot::EfiLoadOption::read_from_prefix_split(data).ok_or(Error::InvalidLength)?; + boot::EfiLoadOption::read_from_prefix(data).map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err let description = Ucs2LeSlice::from_slice_with_nul(data).map_err(Error::InvalidUcs2)?; let mut data = &data[description.as_bytes().len()..]; diff --git a/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs b/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs index 3c0a1f8ae0..d5c8452835 100644 --- a/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs +++ b/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs @@ -14,8 +14,8 @@ use uefi_specs::uefi::nvram::signature_list::EFI_CERT_SHA256_GUID; use uefi_specs::uefi::nvram::signature_list::EFI_CERT_X509_GUID; use uefi_specs::uefi::nvram::signature_list::EFI_SIGNATURE_DATA; use uefi_specs::uefi::nvram::signature_list::EFI_SIGNATURE_LIST; -use zerocopy::AsBytes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromBytes; +use zerocopy::IntoBytes; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct X509Data<'a>(pub Cow<'a, [u8]>); @@ -249,8 +249,8 @@ impl<'a> ParseSignatureLists<'a> { signature_size, }, buf, - ) = EFI_SIGNATURE_LIST::read_from_prefix_split(self.buf) - .ok_or(ParseError::InvalidHeader)?; + ) = EFI_SIGNATURE_LIST::read_from_prefix(self.buf) + .map_err(|_| ParseError::InvalidHeader)?; // TODO: zerocopy: map_err let expected_data_len = signature_list_size as usize - size_of::(); if buf.len() < expected_data_len { @@ -313,8 +313,8 @@ impl<'a> ParseSignatureX509<'a> { return Ok(None); } - let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix_split(self.buf) - .ok_or(ParseError::X509InvalidHeader)?; + let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix(self.buf) + .map_err(|_| ParseError::X509InvalidHeader)?; // TODO: zerocopy: map_err let val: Cow<'a, [u8]> = buf.into(); let res = SignatureData::new_x509(header.signature_owner, val); @@ -359,8 +359,8 @@ impl<'a> ParseSignatureSha256<'a> { return Ok(None); } - let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix_split(self.buf) - .expect("buf size validated in `new`"); + let (header, buf) = + EFI_SIGNATURE_DATA::read_from_prefix(self.buf).expect("buf size validated in `new`"); // TODO: zerocopy: map_err let expected_data_len = 32; assert!(buf.len() >= expected_data_len, "validated in new()"); diff --git a/vm/devices/firmware/uefi_nvram_storage/Cargo.toml b/vm/devices/firmware/uefi_nvram_storage/Cargo.toml index e1152ffbd4..e894d3be77 100644 --- a/vm/devices/firmware/uefi_nvram_storage/Cargo.toml +++ b/vm/devices/firmware/uefi_nvram_storage/Cargo.toml @@ -21,7 +21,6 @@ async-trait.workspace = true thiserror.workspace = true wchar.workspace = true zerocopy.workspace = true - [dev-dependencies] pal_async.workspace = true diff --git a/vm/devices/firmware/uefi_nvram_storage/src/in_memory.rs b/vm/devices/firmware/uefi_nvram_storage/src/in_memory.rs index 449e707461..3000d7f42a 100644 --- a/vm/devices/firmware/uefi_nvram_storage/src/in_memory.rs +++ b/vm/devices/firmware/uefi_nvram_storage/src/in_memory.rs @@ -194,8 +194,8 @@ pub mod impl_agnostic_tests { use guid::Guid; use ucs2::Ucs2LeSlice; use wchar::wchz; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::IntoBytes; pub async fn test_single_variable(nvram: &mut dyn NvramStorage) { let vendor = Guid::new_random(); diff --git a/vm/devices/firmware/uefi_specs/Cargo.toml b/vm/devices/firmware/uefi_specs/Cargo.toml index 4c854f1f05..700f524cd6 100644 --- a/vm/devices/firmware/uefi_specs/Cargo.toml +++ b/vm/devices/firmware/uefi_specs/Cargo.toml @@ -21,7 +21,6 @@ bitfield-struct.workspace = true static_assertions.workspace = true wchar.workspace = true zerocopy.workspace = true - [dev-dependencies] [lints] diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/bios_event_log.rs b/vm/devices/firmware/uefi_specs/src/hyperv/bios_event_log.rs index 38966e20fb..0e92f2e5b7 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/bios_event_log.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/bios_event_log.rs @@ -5,9 +5,10 @@ use guid::Guid; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Represents an event channel plus data. /// @@ -16,7 +17,7 @@ use zerocopy::FromZeroes; /// /// reSearch query: `BIOS_EVENT_CHANNEL` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BiosEventChannel { pub channel: Guid, pub events_written: u32, @@ -27,7 +28,7 @@ pub struct BiosEventChannel { /// reSearch query: `EFI_EVENT_DESCRIPTOR` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EfiEventDescriptor { pub producer: Guid, // Optional GUID identifying the producer of the event pub correlation_id: Guid, // Optional Guid used to correlate an event entry with another event entry diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/boot_bios_log.rs b/vm/devices/firmware/uefi_specs/src/hyperv/boot_bios_log.rs index aa2a3d099f..837a563670 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/boot_bios_log.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/boot_bios_log.rs @@ -6,9 +6,10 @@ use crate::uefi::common::EfiStatus64; use open_enum::open_enum; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Event Id for Device Boot Attempts pub const BOOT_DEVICE_EVENT_ID: u32 = 1; @@ -29,7 +30,7 @@ open_enum! { /// in PlatformBdsString.uni must be updated /// /// reSearch query: `BOOT_DEVICE_STATUS` - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum BootDeviceStatus: u32 { BOOT_PENDING = 0, BOOT_DEVICE_NO_FILESYSTEM = DEVICE_STATUS_BOOT_GROUP, @@ -77,7 +78,7 @@ impl BootDeviceStatus { /// reSearch query: `BOOTEVENT_DEVICE_ENTRY` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BootEventDeviceEntry { pub status: BootDeviceStatus, pub pad: u32, diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/common.rs b/vm/devices/firmware/uefi_specs/src/hyperv/common.rs index edda15e39d..bd07d77b73 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/common.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/common.rs @@ -5,9 +5,10 @@ use crate::uefi::common::EfiStatus; use core::fmt::Debug; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::LittleEndian; use zerocopy::U64; @@ -23,7 +24,7 @@ use zerocopy::U64; /// Luckily, such warnings statuses are rare in practice and are unused by /// Hyper-V UEFI protocols. #[repr(transparent)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EfiStatus64NoErrorBit(pub U64); impl From for EfiStatus64NoErrorBit { diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/crypto.rs b/vm/devices/firmware/uefi_specs/src/hyperv/crypto.rs index 81bbe0efd1..5fe0dd9c0b 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/crypto.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/crypto.rs @@ -6,9 +6,10 @@ use self::packed_nums::*; use crate::hyperv::common::EfiStatus64NoErrorBit; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -22,7 +23,7 @@ open_enum! { /// Note that all commands other than GET_RANDOM_NUMBER have been deprecated. /// /// MsvmPkg: `CRYPTO_COMMAND` - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum CryptoCommand: u32 { COMPUTE_HASH = 0, VERIFY_RSA_PKCS_1 = 1, @@ -35,7 +36,7 @@ open_enum! { /// MsvmPkg: `CRYPTO_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CryptoCommandDescriptor { pub command: CryptoCommand, pub status: EfiStatus64NoErrorBit, @@ -43,7 +44,7 @@ pub struct CryptoCommandDescriptor { /// MsvmPkg: `CRYPTO_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CryptoGetRandomNumberParams { pub buffer_address: u64_ne, pub buffer_size: u32, diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/nvram.rs b/vm/devices/firmware/uefi_specs/src/hyperv/nvram.rs index 84ffcc3e87..d297795513 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/nvram.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/nvram.rs @@ -8,9 +8,10 @@ use crate::hyperv::common::EfiStatus64NoErrorBit; use bitfield_struct::bitfield; use guid::Guid; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -23,7 +24,7 @@ open_enum! { /// These correlate with the semantics of the UEFI runtime variable services. /// /// MsvmPkg: `NVRAM_COMMAND` - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum NvramCommand: u32 { GET_VARIABLE = 0, SET_VARIABLE = 1, @@ -37,7 +38,7 @@ open_enum! { /// MsvmPkg: `NVRAM_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct NvramCommandDescriptor { pub command: NvramCommand, pub status: EfiStatus64NoErrorBit, @@ -45,7 +46,7 @@ pub struct NvramCommandDescriptor { /// MsvmPkg: `NVRAM_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct NvramDebugStringCommand { pub padding: u32, pub address: u64_ne, @@ -54,7 +55,7 @@ pub struct NvramDebugStringCommand { /// MsvmPkg: `NVRAM_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct NvramVariableCommand { /// UEFI variable attributes associated with the variable: access rights /// (RT/BS). @@ -97,7 +98,7 @@ pub struct NvramVariableCommand { /// MsvmPkg: `NVRAM_COMMAND_DESCRIPTOR` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct NvramQueryInfo { /// Attribute mask, controls variable type for which the information is /// returned. @@ -113,7 +114,7 @@ pub struct NvramQueryInfo { /// MsvmPkg: `NVRAM_COMMAND_DESCRIPTOR` #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct SignalRuntimeCommandFlags { pub vsm_aware: bool, #[bits(63)] @@ -134,7 +135,7 @@ pub struct SignalRuntimeCommandFlags { /// } SignalRuntimeCommand; /// ``` #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct NvramSignalRuntimeCommand { pub flags: SignalRuntimeCommandFlags, } diff --git a/vm/devices/firmware/uefi_specs/src/hyperv/time.rs b/vm/devices/firmware/uefi_specs/src/hyperv/time.rs index c6e5a0a07d..78dc94af8e 100644 --- a/vm/devices/firmware/uefi_specs/src/hyperv/time.rs +++ b/vm/devices/firmware/uefi_specs/src/hyperv/time.rs @@ -5,13 +5,14 @@ use crate::uefi::common::EfiStatus64; use crate::uefi::time::EFI_TIME; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// MsvmPkg: `VM_EFI_TIME`` #[repr(C, packed)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmEfiTime { pub status: EfiStatus64, pub time: EFI_TIME, diff --git a/vm/devices/firmware/uefi_specs/src/lib.rs b/vm/devices/firmware/uefi_specs/src/lib.rs index 92a6059272..f7e18a62d9 100644 --- a/vm/devices/firmware/uefi_specs/src/lib.rs +++ b/vm/devices/firmware/uefi_specs/src/lib.rs @@ -18,7 +18,7 @@ macro_rules! defn_nvram_var { #[allow(non_snake_case)] pub fn $varname() -> (Guid, &'static ucs2::Ucs2LeSlice) { use ucs2::Ucs2LeSlice; - use zerocopy::AsBytes; + use zerocopy::IntoBytes; ( $guid, diff --git a/vm/devices/firmware/uefi_specs/src/uefi/boot.rs b/vm/devices/firmware/uefi_specs/src/uefi/boot.rs index bbcee9a0f1..9be0301113 100644 --- a/vm/devices/firmware/uefi_specs/src/uefi/boot.rs +++ b/vm/devices/firmware/uefi_specs/src/uefi/boot.rs @@ -4,13 +4,14 @@ //! Definitions related to UEFI boot entries use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; open_enum::open_enum! { /// From UEFI spec 7.2.1 - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiMemoryType: u32 { EFI_RESERVED_MEMORY_TYPE = 0, EFI_LOADER_CODE = 1, @@ -34,7 +35,7 @@ open_enum::open_enum! { /// From UEFI spec 10.2 #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EfiDevicePathProtocol { pub device_type: EfiDeviceType, pub sub_type: u8, @@ -43,14 +44,14 @@ pub struct EfiDevicePathProtocol { /// From UEFI spec 3.1.3 #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EfiLoadOption { pub attributes: u32, pub file_path_list_length: u16, } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiDeviceType: u8 { HARDWARE = 0x01, ACPI = 0x02, @@ -62,7 +63,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiEndDeviceSubType: u8 { INSTANCE = 0x01, ENTIRE = 0xFF, @@ -70,7 +71,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiHardwareDeviceSubType: u8 { PCI = 1, PCCARD = 2, @@ -82,7 +83,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiAcpiDeviceSubType: u8 { ACPI = 1, EXPANDED_ACPI = 2, @@ -92,7 +93,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiMessagingDeviceSubType: u8 { ATAPI = 1, SCSI = 2, @@ -130,7 +131,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiMediaDeviceSubType: u8 { HARD_DRIVE = 0x01, CD_ROM = 0x02, @@ -145,7 +146,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiPartitionFormat: u8 { MBR = 0x01, GUID = 0x02, @@ -153,7 +154,7 @@ open_enum::open_enum! { } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EfiSignatureType: u8 { NONE = 0x00, MBR = 0x01, @@ -162,7 +163,7 @@ open_enum::open_enum! { } #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug, PartialEq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Debug, PartialEq)] pub struct EfiHardDriveDevice { pub partition_number: u32, pub partition_start: u64, @@ -173,14 +174,14 @@ pub struct EfiHardDriveDevice { } #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug, PartialEq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Debug, PartialEq)] pub struct EfiScsiDevice { pub target_id: u16, pub logical_unit_num: u16, } #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug, PartialEq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Debug, PartialEq)] pub struct EfiMemoryMappedDevice { pub memory_type: EfiMemoryType, pub start_address: u64, @@ -188,7 +189,7 @@ pub struct EfiMemoryMappedDevice { } #[repr(C, packed)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug, PartialEq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Debug, PartialEq)] pub struct EfiExpandedAcpiDevice { pub hid: u32, pub cid: u32, diff --git a/vm/devices/firmware/uefi_specs/src/uefi/common.rs b/vm/devices/firmware/uefi_specs/src/uefi/common.rs index 1aa5f58427..f5d11512b9 100644 --- a/vm/devices/firmware/uefi_specs/src/uefi/common.rs +++ b/vm/devices/firmware/uefi_specs/src/uefi/common.rs @@ -5,9 +5,10 @@ use core::fmt::Debug; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::LittleEndian; use zerocopy::U64; @@ -20,7 +21,7 @@ open_enum! { /// high bits when taking a guest-provided 64-bit value. /// /// However, this type is not intended for direct sharing with the guest, so - /// it does not derive `AsBytes`, etc. To be clear about intent when using + /// it does not derive `IntoBytes`, etc. To be clear about intent when using /// this value for communication with the guest via shared memory, use /// [`EfiStatus64`] instead. If you are implementing a legacy protocol that /// does not preserve the error bit, use @@ -77,7 +78,7 @@ impl EfiStatus { /// A 64-bit, unaligned, little-endian encoding of [`EfiStatus`], appropriate /// for sharing with the guest. #[repr(transparent)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EfiStatus64(pub U64); impl Debug for EfiStatus64 { diff --git a/vm/devices/firmware/uefi_specs/src/uefi/nvram.rs b/vm/devices/firmware/uefi_specs/src/uefi/nvram.rs index 4571d25edb..2e020bf2ae 100644 --- a/vm/devices/firmware/uefi_specs/src/uefi/nvram.rs +++ b/vm/devices/firmware/uefi_specs/src/uefi/nvram.rs @@ -7,9 +7,10 @@ use crate::uefi::signing::WIN_CERTIFICATE_UEFI_GUID; use crate::uefi::time::EFI_TIME; use bitfield_struct::bitfield; use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// UEFI spec 8.2 - Variable Services #[bitfield(u32)] @@ -57,7 +58,7 @@ impl EfiVariableAttributes { } /// UEFI spec 8.2 -#[derive(FromBytes, FromZeroes, AsBytes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C)] pub struct EFI_VARIABLE_AUTHENTICATION_2 { /// Components Pad1, Nanosecond, TimeZone, Daylight and Pad2 shall be set to @@ -98,11 +99,12 @@ impl EFI_VARIABLE_AUTHENTICATION_2 { /// UEFI spec 32.4.1 pub mod signature_list { use guid::Guid; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; - #[derive(Debug, PartialEq, Eq, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C)] pub struct EFI_SIGNATURE_LIST { /// Type of the signature. GUID signature types are defined in "Related @@ -132,7 +134,17 @@ pub mod signature_list { } #[derive( - Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, FromZeroes, AsBytes, + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + IntoBytes, + FromBytes, + Immutable, + KnownLayout, )] #[repr(C)] pub struct EFI_SIGNATURE_DATA { diff --git a/vm/devices/firmware/uefi_specs/src/uefi/signing.rs b/vm/devices/firmware/uefi_specs/src/uefi/signing.rs index 87cf945d09..6fffa370be 100644 --- a/vm/devices/firmware/uefi_specs/src/uefi/signing.rs +++ b/vm/devices/firmware/uefi_specs/src/uefi/signing.rs @@ -2,15 +2,16 @@ // Licensed under the MIT License. use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// UEFI spec 32.2.4 /// /// This structure is the certificate header. /// There may be zero or more certificates. -#[derive(Debug, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C)] pub struct WIN_CERTIFICATE { /// The length of the entire certificate, including the length of the header, @@ -30,7 +31,7 @@ pub struct WIN_CERTIFICATE { } /// UEFI spec 32.2.4 - WIN_CERTIFICATE_UEFI_GUID -#[derive(Debug, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C)] pub struct WIN_CERTIFICATE_UEFI_GUID { /// certificate_type is set to WIN_CERT_TYPE_EFI_GUID. diff --git a/vm/devices/firmware/uefi_specs/src/uefi/time.rs b/vm/devices/firmware/uefi_specs/src/uefi/time.rs index faed304c77..d66183655a 100644 --- a/vm/devices/firmware/uefi_specs/src/uefi/time.rs +++ b/vm/devices/firmware/uefi_specs/src/uefi/time.rs @@ -6,9 +6,11 @@ use bitfield_struct::bitfield; use core::fmt::Display; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// UEFI Time Structure /// @@ -25,7 +27,7 @@ use zerocopy::FromZeroes; /// TimeZone: -1440 to 1440 or 2047 /// ``` #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] #[cfg_attr(feature = "inspect", derive(inspect::Inspect), inspect(display))] pub struct EFI_TIME { pub year: u16, @@ -97,7 +99,7 @@ pub const EFI_UNSPECIFIED_TIMEZONE: EfiTimezone = EfiTimezone(0x07FF); /// Timezone in minutes from UTC /// /// Valid values include -1440 to 1440 or 2047 (EFI_UNSPECIFIED_TIMEZONE) -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] #[repr(transparent)] #[cfg_attr(feature = "inspect", derive(inspect::Inspect), inspect(transparent))] pub struct EfiTimezone(pub i16); @@ -111,7 +113,7 @@ impl EfiTimezone { /// Bit Definitions for EFI_TIME.EfiDaylight /// from UEFI spec 8.3 - Time Services #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] #[cfg_attr(feature = "inspect", derive(inspect::Inspect), inspect(transparent))] pub struct EfiDaylight { /// EFI_TIME_ADJUST_DAYLIGHT diff --git a/vm/devices/get/get_helpers/Cargo.toml b/vm/devices/get/get_helpers/Cargo.toml index 87a4e8a613..09ee7b60fc 100644 --- a/vm/devices/get/get_helpers/Cargo.toml +++ b/vm/devices/get/get_helpers/Cargo.toml @@ -10,6 +10,5 @@ rust-version.workspace = true get_protocol.workspace = true guid.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/get/get_helpers/src/lib.rs b/vm/devices/get/get_helpers/src/lib.rs index e29d70c689..f4e24abd59 100644 --- a/vm/devices/get/get_helpers/src/lib.rs +++ b/vm/devices/get/get_helpers/src/lib.rs @@ -16,7 +16,7 @@ use get_protocol::TRACE_LOGGING_MESSAGE_MAX_SIZE; use get_protocol::TRACE_LOGGING_NAME_MAX_SIZE; use get_protocol::TRACE_LOGGING_TARGET_MAX_SIZE; use guid::Guid; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Truncates the specified slice by the specified length. fn truncate_slice(input: &[u8], len: usize) -> &[u8] { diff --git a/vm/devices/get/get_protocol/Cargo.toml b/vm/devices/get/get_protocol/Cargo.toml index 58269f1c87..98b55264a8 100644 --- a/vm/devices/get/get_protocol/Cargo.toml +++ b/vm/devices/get/get_protocol/Cargo.toml @@ -16,6 +16,5 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/get/get_protocol/src/crash.rs b/vm/devices/get/get_protocol/src/crash.rs index d637f04dec..4b26a2c1f2 100644 --- a/vm/devices/get/get_protocol/src/crash.rs +++ b/vm/devices/get/get_protocol/src/crash.rs @@ -5,16 +5,17 @@ use bitfield_struct::bitfield; use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unaligned; pub const CRASHDUMP_GUID: Guid = Guid::from_static_str("427b03e7-4ceb-4286-b5fc-486f4a1dd439"); /// Capabilities supported by the host crash dump services #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] pub struct Capabilities { pub windows_config_v1: bool, pub linux_config_v1: bool, @@ -24,7 +25,7 @@ pub struct Capabilities { open_enum::open_enum! { /// Dump types - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum DumpType: u32 { NONE = 0x00000000, ELF = 0x00000001, @@ -33,7 +34,7 @@ open_enum::open_enum! { } /// Crash dump configuration. -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct ConfigV1 { pub max_dump_size: u64, @@ -41,7 +42,7 @@ pub struct ConfigV1 { } /// Dump completion information -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct CompletionInfoV1 { pub major_version: u32, @@ -57,7 +58,7 @@ pub struct CompletionInfoV1 { open_enum::open_enum! { /// Message types - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum MessageType : u64 { INVALID = 0, // The default invalid type @@ -86,7 +87,7 @@ open_enum::open_enum! { } /// Common message header for all requests and responses. -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct Header { /// Correlates messages across guest/host @@ -95,14 +96,14 @@ pub struct Header { } /// Complete message payload for ResponseGetCapabilities_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpCapabilitiesRequestV1 { pub header: Header, } /// Complete message payload for ResponseGetCapabilities_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpCapabilitiesResponseV1 { pub header: Header, @@ -110,14 +111,14 @@ pub struct DumpCapabilitiesResponseV1 { } /// Complete message payload for RequestGetNixDumpConfig_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpConfigRequestV1 { pub header: Header, } /// Complete message payload for ResponseGetNixDumpConfig_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpConfigResponseV1 { pub header: Header, @@ -125,14 +126,14 @@ pub struct DumpConfigResponseV1 { } /// Complete message payload for RequestGetNixDumpConfig_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpStartRequestV1 { pub header: Header, } /// Complete message payload for ResponseGetNixDumpConfig_v1 -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpStartResponseV1 { pub header: Header, @@ -142,7 +143,9 @@ pub struct DumpStartResponseV1 { /// Complete message payload for RequestNixDumpWrite_v1 /// Data follows in a separate message with no headers. -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes, Unaligned)] +#[derive( + Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, +)] #[repr(C, packed)] pub struct DumpWriteRequestV1 { pub header: Header, @@ -152,7 +155,7 @@ pub struct DumpWriteRequestV1 { /// Response to a RequestNixDumpWrite_v1 /// A response is only sent if an error has occurred. -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpWriteResponseV1 { pub header: Header, @@ -161,7 +164,7 @@ pub struct DumpWriteResponseV1 { } /// Completes a Nix crash dump -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] #[repr(C, packed)] pub struct DumpCompleteRequestV1 { pub header: Header, diff --git a/vm/devices/get/get_protocol/src/lib.rs b/vm/devices/get/get_protocol/src/lib.rs index ac3f889021..40603db538 100644 --- a/vm/devices/get/get_protocol/src/lib.rs +++ b/vm/devices/get/get_protocol/src/lib.rs @@ -10,9 +10,10 @@ use open_enum::open_enum; use static_assertions::const_assert; use static_assertions::const_assert_eq; use std::fmt::Debug; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub mod crash; pub mod dps_json; // TODO: split into separate crate, so get_protocol can be no_std @@ -46,7 +47,7 @@ const fn make_version(major: u16, minor: u16) -> u32 { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum ProtocolVersion: u32 { INVALID = 0, RS5 = make_version(1, 0), @@ -56,7 +57,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum MessageVersions: u8 { INVALID = 0, HEADER_VERSION_1 = 1, @@ -64,7 +65,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum MessageTypes: u8 { INVALID = 0, HOST_NOTIFICATION = 1, @@ -79,7 +80,7 @@ open_enum! { /// /// These are intended to be "fire-and-forget" messages sent from the Host /// to the Guest, without requiring a response. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum GuestNotifications: u16 { INVALID = 0, UPDATE_GENERATION_ID = 1, @@ -99,7 +100,7 @@ open_enum! { /// /// These are intended to be "fire-and-forget" messages sent from the Guest /// to the Host, without requiring a response. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum HostNotifications: u16 { INVALID = 0, POWER_OFF = 1, @@ -117,7 +118,7 @@ open_enum! { open_enum! { /// Header ids (Each request has a response of the same ID). - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum HostRequests: u16 { INVALID = 0, VERSION = 1, @@ -167,9 +168,10 @@ pub mod header { use super::MessageTypes; use super::MessageVersions; use static_assertions::const_assert_eq; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; use super::GuestNotifications; use super::HostNotifications; @@ -177,7 +179,7 @@ pub mod header { /// The raw header pulled off the wire. #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] + #[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] pub struct HeaderRaw { pub message_version: MessageVersions, pub message_type: MessageTypes, @@ -189,7 +191,7 @@ pub mod header { // the `MessageId` associated type. pub trait HeaderMeta: private::Sealed { const MESSAGE_TYPE: MessageTypes; - type MessageId: Copy + AsBytes + FromBytes + Sized; + type MessageId: Copy + IntoBytes + FromBytes + Immutable + KnownLayout + Sized; } macro_rules! defn_header_meta { @@ -247,7 +249,7 @@ pub mod header { } #[repr(C)] - #[derive(Copy, Clone, Debug, FromBytes, FromZeroes, PartialEq)] + #[derive(Copy, Clone, Debug, FromBytes, Immutable, KnownLayout, PartialEq)] pub struct HeaderGeneric { pub message_version: MessageVersions, pub message_type: MessageTypes, @@ -255,14 +257,14 @@ pub mod header { } // SAFETY: - // - `HeaderMeta::MessageId` includes a bound on `AsBytes` - // - All other HeaderGeneric fields implement AsBytes - // - HeaderGeneric is repr(C) + // - `HeaderMeta::MessageId` includes a bound on `IntoBytes` + // - All other HeaderGeneric fields implement IntoBytes + // - HeaderGeneric is repr(C + Immutable + KnownLayout) // - the `defn_header_meta!` macro includes calls to `static_assert!` which // ensure that the `MessageId` type is the correct size + alignment // - a sealed trait bound on `HeaderMeta` ensures that external consumers // cannot construct instances of HeaderGeneric that have not been validated - unsafe impl AsBytes for HeaderGeneric { + unsafe impl IntoBytes for HeaderGeneric { fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized, @@ -282,7 +284,7 @@ pub mod header { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum LargePayloadState : u32 { END = 0, MORE = 1, @@ -290,7 +292,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct PowerOffNotification { pub message_header: HeaderHostNotification, pub hibernate: ProtocolBool, @@ -311,7 +313,7 @@ impl PowerOffNotification { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ResetNotification { pub message_header: HeaderHostNotification, } @@ -327,7 +329,7 @@ impl ResetNotification { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EventLogId: u32 { INVALID_ID = 0, BOOT_SUCCESS = 1, @@ -348,7 +350,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EventLogNotification { pub message_header: HeaderHostNotification, pub event_log_id: EventLogId, @@ -367,7 +369,7 @@ impl EventLogNotification { pub const TRACE_MSG_MAX_SIZE: usize = 256; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum LogLevel: u32 { INVALID = 0, CRITICAL = 1, @@ -395,7 +397,7 @@ impl From for u8 { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum GuestVtl2SaveRestoreStatus : u16 { SUCCESS = 0, FAILURE = 1, @@ -405,7 +407,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct LogTraceNotification { pub message_header: HeaderHostNotification, pub level: LogLevel, @@ -418,7 +420,7 @@ pub const VTL_CRASH_PARAMETERS: usize = 5; /// The transport level VTL crash data to send to the host. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VtlCrashNotification { pub message_header: HeaderHostNotification, pub vp_index: u32, @@ -453,14 +455,14 @@ impl VtlCrashNotification { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum TripleFaultType: u32 { UNRECOVERABLE_EXCEPTION = 1, } } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RegisterState { pub name: u32, pub value: [u8; 16], @@ -469,7 +471,7 @@ const_assert_eq!(20, size_of::()); /// Triple fault notification to send to the host. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TripleFaultNotification { pub message_header: HeaderHostNotification, pub vp_index: u32, @@ -490,7 +492,7 @@ impl TripleFaultNotification { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VersionRequest { pub message_header: HeaderHostRequest, pub version: ProtocolVersion, @@ -509,7 +511,7 @@ impl VersionRequest { const_assert_eq!(8, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VersionResponse { pub message_header: HeaderHostResponse, pub version_accepted: ProtocolBool, @@ -529,7 +531,7 @@ impl VersionResponse { const_assert_eq!(6, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TimeRequest { pub message_header: HeaderHostRequest, } @@ -545,7 +547,7 @@ impl TimeRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TimeResponse { pub message_header: HeaderHostResponse, pub _pad: u32, @@ -590,7 +592,7 @@ pub const IGVM_ATTEST_VMWP_GENERIC_ERROR_CODE: usize = 0xFFFFFFFF; /// previously shared pages to use for response. /// Use GET response packet to serialize and convey response length. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct IgvmAttestRequest { pub message_header: HeaderHostRequest, /// Number of GPA @@ -631,7 +633,7 @@ impl IgvmAttestRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct IgvmAttestResponse { pub message_header: HeaderHostResponse, pub length: u32, @@ -641,7 +643,7 @@ const_assert_eq!(8, size_of::()); /// This can only be used in PROTOCOL_VERSION_RS5 #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BiosBootFinalizeRequest { pub message_header: HeaderHostRequest, pub value: u8, @@ -651,7 +653,7 @@ pub struct BiosBootFinalizeRequest { const_assert_eq!(6, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BiosBootFinalizeResponse { pub message_header: HeaderHostResponse, } @@ -667,7 +669,7 @@ impl BiosBootFinalizeResponse { const_assert_eq!(4, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsGetDeviceInfoRequest { pub message_header: HeaderHostRequest, } @@ -683,7 +685,7 @@ impl VmgsGetDeviceInfoRequest { const_assert_eq!(4, size_of::()); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VmgsIoStatus: u32 { SUCCESS = 0, INVALID_COMMAND = 1, @@ -693,7 +695,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VmgsWriteFlags: u32 { NONE = 0, WRITE_THROUGH = 0x00000001, @@ -701,14 +703,14 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VmgsReadFlags: u32 { NONE = 0, } } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsGetDeviceInfoResponse { pub message_header: HeaderHostResponse, pub status: VmgsIoStatus, @@ -741,7 +743,7 @@ impl VmgsGetDeviceInfoResponse { const_assert_eq!(24, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsWriteRequest { pub message_header: HeaderHostRequest, pub flags: VmgsWriteFlags, @@ -766,7 +768,7 @@ impl VmgsWriteRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsWriteResponse { pub message_header: HeaderHostResponse, pub status: VmgsIoStatus, @@ -784,7 +786,7 @@ impl VmgsWriteResponse { const_assert_eq!(8, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsReadRequest { pub message_header: HeaderHostRequest, pub flags: VmgsReadFlags, @@ -808,7 +810,7 @@ impl VmgsReadRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsReadResponse { pub message_header: HeaderHostResponse, pub status: VmgsIoStatus, @@ -827,7 +829,7 @@ impl VmgsReadResponse { const_assert_eq!(8, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsFlushRequest { pub message_header: HeaderHostRequest, } @@ -843,7 +845,7 @@ impl VmgsFlushRequest { const_assert_eq!(4, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VmgsFlushResponse { pub message_header: HeaderHostResponse, pub status: VmgsIoStatus, @@ -869,7 +871,7 @@ const_assert!(VMGS_MAX_IO_MSG_HEADER_SIZE <= MAX_HEADER_SIZE); pub const MAX_TRANSFER_SIZE: usize = u32::MAX as usize - VMGS_MAX_IO_MSG_HEADER_SIZE; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum ActivityClassId: u32 { INVALID = 0, VMGS_INITIALIZE_DEVICE = 1, @@ -884,7 +886,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum ActivityOpCode: u32 { INFO = 0, START = 1, @@ -893,7 +895,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum EventId: u32 { INVALID = 0, VMGS_INFO = 1, @@ -904,7 +906,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct LogTraceRequest { pub message_header: HeaderHostRequest, pub level: LogLevel, @@ -914,7 +916,7 @@ pub struct LogTraceRequest { const_assert_eq!(520, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct LogTraceResponse { pub message_header: HeaderHostResponse, } @@ -922,7 +924,7 @@ pub struct LogTraceResponse { const_assert_eq!(4, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ActivityTraceStartRequest { pub message_header: HeaderHostRequest, pub activity_class: ActivityClassId, @@ -934,7 +936,7 @@ pub struct ActivityTraceStartRequest { const_assert_eq!(28, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ActivityTraceStartResponse { pub message_header: HeaderHostResponse, pub activity_id: Guid, @@ -943,7 +945,7 @@ pub struct ActivityTraceStartResponse { const_assert_eq!(20, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ActivityTraceOpRequest { pub message_header: HeaderHostRequest, pub activity_class: ActivityClassId, @@ -957,7 +959,7 @@ pub struct ActivityTraceOpRequest { const_assert_eq!(48, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ActivityTraceOpResponse { pub message_header: HeaderHostResponse, } @@ -965,7 +967,7 @@ pub struct ActivityTraceOpResponse { const_assert_eq!(4, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EventTraceRequest { pub message_header: HeaderHostRequest, pub event: EventId, @@ -976,7 +978,7 @@ pub struct EventTraceRequest { const_assert_eq!(12, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct EventTraceResponse { pub message_header: HeaderHostResponse, } @@ -984,7 +986,7 @@ pub struct EventTraceResponse { const_assert_eq!(4, size_of::()); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum SecureBootTemplateType: u32 { SECURE_BOOT_DISABLED = 0, MICROSOFT_WINDOWS = 1, @@ -994,7 +996,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum UefiConsoleMode: u8 { DEFAULT = 0, COM1 = 1, @@ -1006,7 +1008,7 @@ open_enum! { pub const HCL_DEVICE_PLATFORM_MAX_SMBIOS_LENGTH: usize = 64; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct DevicePlatformSettingsRequestV2 { pub message_header: HeaderHostRequest, } @@ -1024,7 +1026,7 @@ const_assert_eq!(4, size_of::()); /// This represents a boolean value sent over the protocol as a u8. The only /// valid values are 0 or 1. #[repr(transparent)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ProtocolBool(pub u8); impl From for ProtocolBool { @@ -1034,7 +1036,7 @@ impl From for ProtocolBool { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct DevicePlatformSettingsResponseV2 { pub message_header: HeaderHostResponse, @@ -1043,7 +1045,7 @@ pub struct DevicePlatformSettingsResponseV2 { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct DevicePlatformSettingsResponseV2Rev1 { pub message_header: HeaderHostResponse, @@ -1058,7 +1060,7 @@ pub const GSP_CIPHERTEXT_MAX: u32 = 512; pub const NUMBER_GSP: u32 = 2; #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] pub struct GspExtendedStatusFlags { pub state_refresh_request: bool, pub no_registry_file: bool, @@ -1071,7 +1073,7 @@ pub struct GspExtendedStatusFlags { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GspCleartextContent { pub length: u32, pub buffer: [u8; GSP_CLEARTEXT_MAX as usize * 2], @@ -1080,7 +1082,7 @@ pub struct GspCleartextContent { const_assert_eq!(68, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GspCiphertextContent { pub length: u32, pub buffer: [u8; GSP_CIPHERTEXT_MAX as usize], @@ -1090,7 +1092,7 @@ const_assert_eq!(516, size_of::()); /// This can only be used in PROTOCOL_VERSION_RS5 #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GuestStateProtectionByIdRequest { pub message_header: HeaderHostRequest, } @@ -1106,7 +1108,7 @@ impl GuestStateProtectionByIdRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GuestStateProtectionByIdResponse { pub message_header: HeaderHostResponse, pub seed: GspCleartextContent, @@ -1116,7 +1118,7 @@ pub struct GuestStateProtectionByIdResponse { const_assert_eq!(76, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GuestStateProtectionRequest { pub message_header: HeaderHostRequest, pub new_gsp: GspCleartextContent, @@ -1145,7 +1147,7 @@ impl GuestStateProtectionRequest { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GuestStateProtectionResponse { pub message_header: HeaderHostResponse, pub encrypted_gsp: GspCiphertextContent, @@ -1156,7 +1158,7 @@ pub struct GuestStateProtectionResponse { const_assert_eq!(660, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct UpdateGenerationId { pub message_header: HeaderGuestNotification, pub _pad: u32, @@ -1177,7 +1179,7 @@ impl UpdateGenerationId { /// Bitfield describing SaveGuestVtl2StateNotification::capabilities_flags #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct SaveGuestVtl2StateFlags { /// Explicitly allow nvme_keepalive feature when servicing. #[bits(1)] @@ -1188,7 +1190,7 @@ pub struct SaveGuestVtl2StateFlags { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct SaveGuestVtl2StateNotification { pub message_header: HeaderGuestNotification, pub correlation_id: Guid, @@ -1199,7 +1201,7 @@ pub struct SaveGuestVtl2StateNotification { const_assert_eq!(30, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct SaveGuestVtl2StateRequest { pub message_header: HeaderHostRequest, pub save_status: GuestVtl2SaveRestoreStatus, @@ -1218,7 +1220,7 @@ impl SaveGuestVtl2StateRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct SaveGuestVtl2StateResponse { pub message_header: HeaderHostResponse, pub save_status: GuestVtl2SaveRestoreStatus, @@ -1236,7 +1238,7 @@ impl SaveGuestVtl2StateResponse { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RestoreGuestVtl2StateHostNotification { pub message_header: HeaderHostNotification, pub status: GuestVtl2SaveRestoreStatus, @@ -1256,7 +1258,7 @@ impl RestoreGuestVtl2StateHostNotification { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RestoreGuestVtl2StateRequest { pub message_header: HeaderHostRequest, pub restore_status: GuestVtl2SaveRestoreStatus, @@ -1274,7 +1276,7 @@ impl RestoreGuestVtl2StateRequest { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RestoreGuestVtl2StateResponse { pub message_header: HeaderHostResponse, pub data_length: u32, @@ -1295,7 +1297,7 @@ impl RestoreGuestVtl2StateResponse { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VpciDeviceControlCode: u32 { UNDEFINED = 0, OFFER = 1, @@ -1305,7 +1307,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VpciDeviceControlStatus: u32 { SUCCESS = 0, INVALID_REQUEST = 1, @@ -1316,7 +1318,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VpciDeviceControlRequest { pub message_header: HeaderHostRequest, pub code: VpciDeviceControlCode, @@ -1336,7 +1338,7 @@ impl VpciDeviceControlRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VpciDeviceControlResponse { pub message_header: HeaderHostResponse, pub status: VpciDeviceControlStatus, @@ -1354,7 +1356,7 @@ impl VpciDeviceControlResponse { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum VpciDeviceNotificationCode : u32 { UNDEFINED = 0, ENUMERATED = 1, @@ -1363,7 +1365,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VpciDeviceNotification { pub message_header: HeaderGuestNotification, pub bus_instance_id: Guid, @@ -1373,7 +1375,7 @@ pub struct VpciDeviceNotification { const_assert_eq!(24, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VpciDeviceBindingChangeRequest { pub message_header: HeaderHostRequest, pub bus_instance_id: [u8; 16], // Guid @@ -1395,7 +1397,7 @@ impl VpciDeviceBindingChangeRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VpciDeviceBindingChangeResponse { pub message_header: HeaderHostResponse, pub bus_instance_id: Guid, @@ -1415,7 +1417,7 @@ impl VpciDeviceBindingChangeResponse { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VgaProxyPciReadRequest { pub message_header: HeaderHostRequest, pub offset: u16, @@ -1433,7 +1435,7 @@ impl VgaProxyPciReadRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VgaProxyPciReadResponse { pub message_header: HeaderHostResponse, pub value: u32, @@ -1451,7 +1453,7 @@ impl VgaProxyPciReadResponse { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VgaProxyPciWriteRequest { pub message_header: HeaderHostRequest, pub value: u32, @@ -1471,7 +1473,7 @@ impl VgaProxyPciWriteRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VgaProxyPciWriteResponse { pub message_header: HeaderHostResponse, } @@ -1487,7 +1489,7 @@ impl VgaProxyPciWriteResponse { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum ModifyVtl2SettingsStatus : u32 { SUCCESS = 0, FAILURE = 1, @@ -1495,7 +1497,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyVtl2SettingsNotification { pub message_header: HeaderGuestNotification, @@ -1506,7 +1508,7 @@ pub struct ModifyVtl2SettingsNotification { const_assert_eq!(8, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyVtl2SettingsRev1Notification { pub message_header: HeaderGuestNotification, @@ -1519,7 +1521,7 @@ pub struct ModifyVtl2SettingsRev1Notification { const_assert_eq!(12, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyVtl2SettingsCompleteNotification { pub message_header: HeaderHostNotification, pub modify_status: ModifyVtl2SettingsStatus, @@ -1542,7 +1544,7 @@ pub const GET_LOG_INTERFACE_GUID: Guid = Guid::from_static_str("AA5DE534-D149-487A-9053-05972BA20A7C"); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum LogType: u8 { EVENT = 0, SPAN_ENTER = 1, @@ -1551,7 +1553,7 @@ open_enum! { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct LogFlags { pub kmsg: bool, #[bits(15)] @@ -1569,7 +1571,7 @@ pub const TRACE_LOGGING_NOTIFICATION_MAX_SIZE: usize = TRACE_LOGGING_NAME_MAX_SI + size_of::(); #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TraceLoggingBufferOffset { pub size: u16, pub offset: u16, @@ -1581,7 +1583,7 @@ pub struct TraceLoggingBufferOffset { // | Header | Buffer [ name | target | fields | message ] | // --------------------------------------------------------- #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TraceLoggingNotificationHeader { pub log_type: LogType, pub level: u8, @@ -1600,7 +1602,7 @@ const_assert_eq!(80, size_of::()); /// MAP_FRAMEBUFFER_REQUEST #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct MapFramebufferRequest { pub message_header: HeaderHostRequest, pub gpa: u64, @@ -1618,7 +1620,7 @@ impl MapFramebufferRequest { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum MapFramebufferStatus : u32 { SUCCESS = 0, FAILURE = 1, @@ -1627,7 +1629,7 @@ open_enum! { /// MAP_FRAMEBUFFER_RESPONSE #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct MapFramebufferResponse { pub message_header: HeaderHostResponse, pub status: MapFramebufferStatus, @@ -1646,7 +1648,7 @@ impl MapFramebufferResponse { /// UNMAP_FRAMEBUFFER #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct UnmapFramebufferRequest { pub message_header: HeaderHostRequest, } @@ -1662,7 +1664,7 @@ impl UnmapFramebufferRequest { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum UnmapFramebufferStatus : u32 { SUCCESS = 0, FAILURE = 1, @@ -1671,7 +1673,7 @@ open_enum! { /// UNMAP_FRAMEBUFFER_RESPONSE #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct UnmapFramebufferResponse { pub message_header: HeaderHostResponse, pub status: UnmapFramebufferStatus, @@ -1689,7 +1691,7 @@ impl UnmapFramebufferResponse { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum StartVtl0Status : u32 { SUCCESS = 0, FAILURE = 1, @@ -1697,7 +1699,7 @@ open_enum! { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct StartVtl0CompleteNotification { pub message_header: HeaderHostNotification, pub status: StartVtl0Status, @@ -1719,7 +1721,7 @@ impl StartVtl0CompleteNotification { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BatteryStatusNotification { pub message_header: HeaderGuestNotification, pub flags: BatteryStatusFlags, @@ -1729,7 +1731,7 @@ pub struct BatteryStatusNotification { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct BatteryStatusFlags { pub ac_online: bool, pub battery_present: bool, @@ -1757,7 +1759,7 @@ impl BatteryStatusNotification { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CreateRamGpaRangeFlags { /// writes are discarded pub rom_mb: bool, @@ -1767,7 +1769,7 @@ pub struct CreateRamGpaRangeFlags { } #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CreateRamGpaRangeRequest { pub message_header: HeaderHostRequest, pub slot: u32, @@ -1799,7 +1801,7 @@ impl CreateRamGpaRangeRequest { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum CreateRamGpaRangeStatus : u32 { SUCCESS = 0, /// slot index out of bounds @@ -1816,7 +1818,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CreateRamGpaRangeResponse { pub message_header: HeaderHostResponse, pub status: CreateRamGpaRangeStatus, @@ -1834,7 +1836,7 @@ impl CreateRamGpaRangeResponse { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ResetRamGpaRangeRequest { pub message_header: HeaderHostRequest, pub slot: u32, @@ -1852,7 +1854,7 @@ impl ResetRamGpaRangeRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ResetRamGpaRangeResponse { pub message_header: HeaderHostResponse, } diff --git a/vm/devices/get/guest_crash_device/Cargo.toml b/vm/devices/get/guest_crash_device/Cargo.toml index 8c9fcce7af..27218e3a99 100644 --- a/vm/devices/get/guest_crash_device/Cargo.toml +++ b/vm/devices/get/guest_crash_device/Cargo.toml @@ -23,6 +23,5 @@ anyhow.workspace = true async-trait.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/get/guest_crash_device/src/lib.rs b/vm/devices/get/guest_crash_device/src/lib.rs index 4709617604..7d557e6133 100644 --- a/vm/devices/get/guest_crash_device/src/lib.rs +++ b/vm/devices/get/guest_crash_device/src/lib.rs @@ -9,7 +9,7 @@ pub mod resolver; -use anyhow::Context; +use anyhow::anyhow; use async_trait::async_trait; use get_protocol::crash; use get_protocol::crash::CRASHDUMP_GUID; @@ -33,8 +33,10 @@ use vmbus_channel::gpadl_ring::GpadlRingMem; use vmbus_channel::simple::SaveRestoreSimpleVmbusDevice; use vmbus_channel::simple::SimpleVmbusDevice; use vmcore::save_restore::SavedStateNotSupported; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// The crash device. #[derive(InspectMut)] @@ -59,7 +61,7 @@ struct GuestCrashPipe { } impl GuestCrashPipe { - fn send(&mut self, data: &T) -> std::io::Result<()> { + fn send(&mut self, data: &T) -> std::io::Result<()> { self.pipe.try_send(data.as_bytes()) } @@ -73,7 +75,9 @@ impl GuestCrashPipe { data: &'a mut [u8], ) -> anyhow::Result<(crash::Header, &'a [u8])> { let message = self.recv(data).await?; - let header = crash::Header::read_from_prefix(message).context("truncated message")?; + let header = crash::Header::read_from_prefix(message) + .map_err(|_| anyhow!("truncated message"))? + .0; Ok((header, message)) } } @@ -319,7 +323,8 @@ impl GuestCrashDevice { match header.message_type { crash::MessageType::REQUEST_NIX_DUMP_WRITE_V1 => { let request = crash::DumpWriteRequestV1::read_from_prefix(message) - .context("truncated message")?; + .map_err(|_| anyhow!("truncated message"))? // todo: zerocopy: anyhow! + .0; *payload = Some((request.offset, request.size)); } crash::MessageType::REQUEST_NIX_DUMP_COMPLETE_V1 => { diff --git a/vm/devices/get/guest_emulation_device/Cargo.toml b/vm/devices/get/guest_emulation_device/Cargo.toml index dab03aaeca..ada7a8d327 100644 --- a/vm/devices/get/guest_emulation_device/Cargo.toml +++ b/vm/devices/get/guest_emulation_device/Cargo.toml @@ -40,8 +40,6 @@ thiserror.workspace = true time = { workspace = true, features = ["local-offset", "macros"] } tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - guid.workspace = true [lints] diff --git a/vm/devices/get/guest_emulation_device/src/lib.rs b/vm/devices/get/guest_emulation_device/src/lib.rs index c0389c8863..7f5bc09c96 100644 --- a/vm/devices/get/guest_emulation_device/src/lib.rs +++ b/vm/devices/get/guest_emulation_device/src/lib.rs @@ -67,10 +67,9 @@ use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; use vmbus_ring::RingMem; use vmcore::save_restore::SavedStateNotSupported; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Host GET errors #[derive(Debug, Error)] @@ -358,7 +357,7 @@ impl GedChannel { GedState::Init => { // Negotiate the version let mut version_request = get_protocol::VersionRequest::new_zeroed(); - stop.until_stopped(self.channel.recv_exact(version_request.as_bytes_mut())) + stop.until_stopped(self.channel.recv_exact(version_request.as_mut_bytes())) .await? .map_err(Error::Vmbus)?; @@ -452,8 +451,9 @@ impl GedChannel { message_buf: &[u8], state: &mut GuestEmulationDevice, ) -> Result<(), Error> { - let header = - get_protocol::HeaderRaw::read_from_prefix(message_buf).ok_or(Error::MessageTooSmall)?; + let header = get_protocol::HeaderRaw::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err if header.message_version != get_protocol::MessageVersions::HEADER_VERSION_1 { return Err(Error::HeaderVersion(header.message_version)); @@ -602,7 +602,8 @@ impl GedChannel { fn handle_bios_boot_finalize(&mut self, message_buf: &[u8]) -> Result<(), Error> { let msg = get_protocol::BiosBootFinalizeRequest::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err tracing::trace!(?msg, "Bios Boot Finalize request"); @@ -662,7 +663,8 @@ impl GedChannel { message_buf: &[u8], ) -> Result<(), Error> { let message = get_protocol::VmgsReadRequest::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err let (status, payload) = if let Some(vmgs) = &mut state.vmgs { let len = message.sector_count as u64 * vmgs.disk.sector_size() as u64; @@ -712,8 +714,8 @@ impl GedChannel { state: &mut GuestEmulationDevice, message_buf: &[u8], ) -> Result<(), Error> { - let (message, rest) = get_protocol::VmgsWriteRequest::read_from_prefix_split(message_buf) - .ok_or(Error::MessageTooSmall)?; + let (message, rest) = get_protocol::VmgsWriteRequest::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err let status = if let Some(vmgs) = &mut state.vmgs { let len = message.sector_count as u64 * vmgs.disk.sector_size() as u64; @@ -787,7 +789,8 @@ impl GedChannel { let _message = get_protocol::GuestStateProtectionRequest::read_from_prefix( &message_buf.as_bytes()[..size_of::()], ) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: err let mut response = get_protocol::GuestStateProtectionResponse::new_zeroed(); response.message_header = HeaderGeneric::new(HostRequests::GUEST_STATE_PROTECTION); @@ -812,8 +815,9 @@ impl GedChannel { /// Stub implementation that simulates the behavior of GED and the host agent. /// Used only for test scenarios such as VMM tests. fn handle_igvm_attest(&mut self, message_buf: &[u8]) -> Result<(), Error> { - let request = - IgvmAttestRequest::read_from_prefix(message_buf).ok_or(Error::MessageTooSmall)?; + let request = IgvmAttestRequest::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err // Request sanitization (match GED behavior) if request.agent_data_length as usize > request.agent_data.len() @@ -824,7 +828,8 @@ impl GedChannel { } let request_payload = IgvmAttestRequestHeader::read_from_prefix(&request.report) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err let response = match request_payload.request_type { IgvmAttestRequestType::AK_CERT_REQUEST => { @@ -866,8 +871,8 @@ impl GedChannel { let save = self.save.as_mut().ok_or(Error::InvalidSequence)?; let (request_header, remaining) = - get_protocol::SaveGuestVtl2StateRequest::read_from_prefix_split(message_buf) - .ok_or(Error::MessageTooSmall)?; + get_protocol::SaveGuestVtl2StateRequest::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err let r = match request_header.save_status { get_protocol::GuestVtl2SaveRestoreStatus::MORE_DATA => { save.buffer.extend_from_slice(remaining); @@ -919,7 +924,8 @@ impl GedChannel { let response = get_protocol::MapFramebufferResponse::new( if let Some(framebuffer_control) = state.framebuffer_control.as_mut() { let message = get_protocol::MapFramebufferRequest::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err let gpa = message.gpa; tracing::debug!("Received map framebuffer request from guest {:#x}", gpa); framebuffer_control.map(gpa).await; @@ -957,7 +963,8 @@ impl GedChannel { fn handle_create_ram_gpa_range(&mut self, message_buf: &[u8]) -> Result<(), Error> { let request = get_protocol::CreateRamGpaRangeRequest::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err tracing::info!(?request, "create ram gpa range request"); @@ -972,7 +979,8 @@ impl GedChannel { fn handle_reset_ram_gpa_range(&mut self, message_buf: &[u8]) -> Result<(), Error> { let _request = get_protocol::ResetRamGpaRangeRequest::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err let response = get_protocol::ResetRamGpaRangeResponse::new(); self.channel .try_send(response.as_bytes()) @@ -1032,7 +1040,8 @@ impl GedChannel { message_buf: &[u8], ) -> Result<(), Error> { let msg = get_protocol::EventLogNotification::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err tracing::trace!("[Event Log] {:?}", msg); let event = match msg.event_log_id { get_protocol::EventLogId::BOOT_SUCCESS => GuestEvent::BootSuccess, @@ -1081,7 +1090,8 @@ impl GedChannel { ) -> Result<(), Error> { let message = get_protocol::RestoreGuestVtl2StateHostNotification::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err let success = match message.status { get_protocol::GuestVtl2SaveRestoreStatus::SUCCESS => true, get_protocol::GuestVtl2SaveRestoreStatus::FAILURE => false, @@ -1097,8 +1107,8 @@ impl GedChannel { message_buf: &[u8], ) -> Result<(), Error> { let (message, remaining) = - get_protocol::StartVtl0CompleteNotification::read_from_prefix_split(message_buf) - .ok_or(Error::MessageTooSmall)?; + get_protocol::StartVtl0CompleteNotification::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err let expected_len = message.result_document_size as usize; if remaining.len() != expected_len { return Err(Error::InvalidFieldValue); @@ -1128,7 +1138,8 @@ impl GedChannel { fn handle_vtl_crash(&mut self, message_buf: &[u8]) -> Result<(), Error> { let msg = get_protocol::VtlCrashNotification::read_from_prefix(message_buf) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err tracing::info!("Guest has reported a system crash {msg:x?}"); Ok(()) } @@ -1138,14 +1149,13 @@ impl GedChannel { state: &mut GuestEmulationDevice, message_buf: &[u8], ) -> Result<(), Error> { - let (msg, remaining) = - get_protocol::TripleFaultNotification::read_from_prefix_split(message_buf) - .ok_or(Error::MessageTooSmall)?; + let (msg, remaining) = get_protocol::TripleFaultNotification::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err let expected_len = msg.register_count as usize * size_of::(); if remaining.len() != expected_len { return Err(Error::InvalidFieldValue); } - let registers = RegisterState::slice_from(remaining).unwrap(); + let registers = <[RegisterState]>::ref_from_bytes(remaining).unwrap(); tracing::info!("Guest has reported a triple fault {msg:x?} {registers:?}"); // TODO report and translate registers state @@ -1156,10 +1166,8 @@ impl GedChannel { fn handle_modify_vtl2_settings_completed(&mut self, message_buf: &[u8]) -> Result<(), Error> { let (msg, remaining) = - get_protocol::ModifyVtl2SettingsCompleteNotification::read_from_prefix_split( - message_buf, - ) - .ok_or(Error::MessageTooSmall)?; + get_protocol::ModifyVtl2SettingsCompleteNotification::read_from_prefix(message_buf) + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err let modify = self.modify.take().ok_or(Error::InvalidSequence)?; let r = match msg.modify_status { diff --git a/vm/devices/get/guest_emulation_device/src/test_utilities.rs b/vm/devices/get/guest_emulation_device/src/test_utilities.rs index 1594a004d9..fbd8dfb20a 100644 --- a/vm/devices/get/guest_emulation_device/src/test_utilities.rs +++ b/vm/devices/get/guest_emulation_device/src/test_utilities.rs @@ -28,9 +28,9 @@ use vmbus_async::pipe::MessagePipe; use vmbus_channel::gpadl_ring::GpadlRingMem; use vmbus_ring::FlatRingMem; use vmbus_ring::RingMem; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Debug, Clone)] pub enum Event { @@ -94,7 +94,7 @@ impl TestGedChannel { while !version_accepted { let mut version_request = get_protocol::VersionRequest::new_zeroed(); self.channel - .recv_exact(version_request.as_bytes_mut()) + .recv_exact(version_request.as_mut_bytes()) .await .map_err(Error::Vmbus)?; @@ -125,7 +125,8 @@ impl TestGedChannel { } let header = get_protocol::HeaderRaw::read_from_prefix(&message_buf[..4]) - .ok_or(Error::MessageTooSmall)?; + .map_err(|_| Error::MessageTooSmall)? + .0; // todo: zerocopy: map_err if header.message_version != get_protocol::MessageVersions::HEADER_VERSION_1 { return Err(Error::HeaderVersion(header.message_version)); @@ -139,8 +140,8 @@ impl TestGedChannel { let notification = get_protocol::EventLogNotification::read_from_prefix( &message_buf[..size_of::()], ) - .unwrap(); - + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range self.vmgs[0] = notification.event_log_id.0 as u8; } HostNotifications::POWER_OFF => { @@ -158,10 +159,11 @@ impl TestGedChannel { Event::Response(response) => { use get_protocol::test_utilities::TEST_VMGS_SECTOR_SIZE; let response_header = - get_protocol::HeaderRaw::read_from_prefix(&response[..4]).unwrap(); - - // Check if response needs special handling. Otherwise, send - // response directly back to the guest. + get_protocol::HeaderRaw::read_from_prefix(&response[..4]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range + // Check if response needs special handling. Otherwise, send + // response directly back to the guest. match response_header.message_type { get_protocol::MessageTypes::HOST_RESPONSE => { let header: get_protocol::HeaderHostRequest = @@ -174,8 +176,9 @@ impl TestGedChannel { get_protocol::VmgsReadRequest::read_from_prefix( &message_buf[..request_size], ) - .unwrap(); - let offset = request.sector_offset as usize + .unwrap() + .0; + let offset = request.sector_offset as usize // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range * TEST_VMGS_SECTOR_SIZE as usize; let length = request.sector_count as usize * TEST_VMGS_SECTOR_SIZE as usize; @@ -188,8 +191,9 @@ impl TestGedChannel { get_protocol::VmgsWriteRequest::read_from_prefix( &message_buf[..request_size], ) - .unwrap(); - let buf = &message_buf[request_size..]; + .unwrap() + .0; + let buf = &message_buf[request_size..]; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range let offset = request.sector_offset as usize * TEST_VMGS_SECTOR_SIZE as usize; let length = request.sector_count as usize diff --git a/vm/devices/get/guest_emulation_log/Cargo.toml b/vm/devices/get/guest_emulation_log/Cargo.toml index 2d2f1f39c2..423a0c4f53 100644 --- a/vm/devices/get/guest_emulation_log/Cargo.toml +++ b/vm/devices/get/guest_emulation_log/Cargo.toml @@ -24,7 +24,5 @@ serde_json.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [lints] workspace = true diff --git a/vm/devices/get/guest_emulation_log/src/lib.rs b/vm/devices/get/guest_emulation_log/src/lib.rs index fee15e2257..e10adb4826 100644 --- a/vm/devices/get/guest_emulation_log/src/lib.rs +++ b/vm/devices/get/guest_emulation_log/src/lib.rs @@ -28,8 +28,8 @@ use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; use vmbus_ring::RingMem; use vmcore::save_restore::NoSavedState; -use zerocopy::AsBytes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] enum Error { @@ -172,7 +172,7 @@ impl GelChannel { loop { let n = self .channel - .recv(buffer.as_bytes_mut()) + .recv(buffer.as_mut_bytes()) .await .map_err(Error::PipeFailure)?; @@ -183,8 +183,8 @@ impl GelChannel { let buffer = &buffer[..n]; let (header, buffer) = - get_protocol::TraceLoggingNotificationHeader::read_from_prefix_split(buffer) - .ok_or(Error::InvalidPayloadSize(n))?; + get_protocol::TraceLoggingNotificationHeader::read_from_prefix(buffer) + .map_err(|_| Error::InvalidPayloadSize(n))?; // TODO: zerocopy: map_err let message = buffer .get( diff --git a/vm/devices/get/guest_emulation_transport/Cargo.toml b/vm/devices/get/guest_emulation_transport/Cargo.toml index 609ae2dd47..b97777ed74 100644 --- a/vm/devices/get/guest_emulation_transport/Cargo.toml +++ b/vm/devices/get/guest_emulation_transport/Cargo.toml @@ -40,8 +40,6 @@ thiserror.workspace = true tracing.workspace = true unicycle.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - vmbus_user_channel.workspace = true [dev-dependencies] diff --git a/vm/devices/get/guest_emulation_transport/src/api.rs b/vm/devices/get/guest_emulation_transport/src/api.rs index 8652409677..e7b73b6389 100644 --- a/vm/devices/get/guest_emulation_transport/src/api.rs +++ b/vm/devices/get/guest_emulation_transport/src/api.rs @@ -17,6 +17,7 @@ pub use get_protocol::GSP_CIPHERTEXT_MAX; pub use get_protocol::IGVM_ATTEST_MSG_REQ_AGENT_DATA_MAX_SIZE; pub use get_protocol::MAX_TRANSFER_SIZE; pub use get_protocol::NUMBER_GSP; +use zerocopy::FromZeros; use guid::Guid; @@ -175,8 +176,6 @@ pub struct GuestStateProtectionById { impl GuestStateProtectionById { /// Construct a blank instance of `GuestStateProtectionById` pub fn new_zeroed() -> GuestStateProtectionById { - use zerocopy::FromZeroes; - GuestStateProtectionById { seed: GspCleartextContent::new_zeroed(), extended_status_flags: GspExtendedStatusFlags::new_zeroed(), diff --git a/vm/devices/get/guest_emulation_transport/src/client.rs b/vm/devices/get/guest_emulation_transport/src/client.rs index be4401542a..d75de8ef80 100644 --- a/vm/devices/get/guest_emulation_transport/src/client.rs +++ b/vm/devices/get/guest_emulation_transport/src/client.rs @@ -15,7 +15,7 @@ use mesh::rpc::RpcSend; use std::sync::Arc; use user_driver::vfio::VfioDmaBuffer; use vpci::bus_control::VpciBusEvent; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Guest-side client for the GET. /// diff --git a/vm/devices/get/guest_emulation_transport/src/lib.rs b/vm/devices/get/guest_emulation_transport/src/lib.rs index 684ca15a68..ee7d0b21ea 100644 --- a/vm/devices/get/guest_emulation_transport/src/lib.rs +++ b/vm/devices/get/guest_emulation_transport/src/lib.rs @@ -128,8 +128,8 @@ mod tests { use test_with_tracing::test; use vmbus_async::async_dgram::AsyncRecvExt; use vmbus_async::async_dgram::AsyncSendExt; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::IntoBytes; #[async_test] async fn test_version_negotiation_failed(driver: DefaultDriver) { @@ -143,7 +143,7 @@ mod tests { assert_eq!( len, host_vmbus - .recv(version_request.as_bytes_mut()) + .recv(version_request.as_mut_bytes()) .await .unwrap() ); diff --git a/vm/devices/get/guest_emulation_transport/src/process_loop.rs b/vm/devices/get/guest_emulation_transport/src/process_loop.rs index fbfb6b0f2d..578803522f 100644 --- a/vm/devices/get/guest_emulation_transport/src/process_loop.rs +++ b/vm/devices/get/guest_emulation_transport/src/process_loop.rs @@ -41,10 +41,11 @@ use vmbus_async::async_dgram::AsyncSendExt; use vmbus_async::pipe::MessagePipe; use vmbus_ring::RingMem; use vpci::bus_control::VpciBusEvent; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Error type for GET errors #[derive(Debug, Error)] @@ -118,10 +119,12 @@ fn validate_response(header: get_protocol::HeaderHostResponse) -> Result<(), Fat } /// Parse the HostResponse message sent from the host in `buf`. -fn read_host_response_validated(buf: &[u8]) -> Result { - let response = T::read_from(buf).ok_or_else(|| FatalError::MessageSizeHostResponse { +fn read_host_response_validated( + buf: &[u8], +) -> Result { + let response = T::read_from_bytes(buf).map_err(|_| FatalError::MessageSizeHostResponse { len: buf.len(), - response: get_protocol::HeaderHostResponse::read_from(buf) + response: get_protocol::HeaderHostResponse::read_from_bytes(buf) .unwrap() .message_id, })?; @@ -130,11 +133,11 @@ fn read_host_response_validated(buf: &[u8]) -> Result( +fn read_guest_notification( notification: get_protocol::GuestNotifications, buf: &[u8], ) -> Result { - T::read_from(buf).ok_or(FatalError::MessageSizeGuestNotification { + T::read_from_bytes(buf).map_err(|_| FatalError::MessageSizeGuestNotification { len: buf.len(), notification, }) @@ -602,13 +605,14 @@ impl HostRequestPipeAccess { /// Waits for a known, fixed-size response message from the host. /// /// The caller is responsible for validating the message ID. - async fn recv_response_fixed_size( + async fn recv_response_fixed_size( &mut self, id: HostRequests, ) -> Result { let response = self.recv_response().await; - let header = - get_protocol::HeaderHostRequest::read_from_prefix(response.as_bytes()).unwrap(); + let header = get_protocol::HeaderHostRequest::read_from_prefix(response.as_bytes()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range if id != header.message_id { return Err(FatalError::ResponseHeaderMismatchId(header.message_id, id)); } @@ -619,13 +623,17 @@ impl HostRequestPipeAccess { /// /// Fails if the response's message ID does not match the request's message /// ID. - async fn send_request_fixed_size( + async fn send_request_fixed_size< + T: IntoBytes + ?Sized + Immutable + KnownLayout, + U: IntoBytes + FromBytes + Immutable + KnownLayout, + >( &mut self, data: &T, ) -> Result { self.send_message(data.as_bytes().to_vec()); - let req_header = - get_protocol::HeaderHostRequest::read_from_prefix(data.as_bytes()).unwrap(); + let req_header = get_protocol::HeaderHostRequest::read_from_prefix(data.as_bytes()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range self.recv_response_fixed_size(req_header.message_id).await } @@ -637,7 +645,7 @@ impl HostRequestPipeAccess { /// /// In the future, GED notifications for failures need to be added. /// This will require updates to both the host and openHCL. - async fn send_failed_save_state( + async fn send_failed_save_state( &mut self, data: &T, ) -> Result<(), FatalError> { @@ -711,7 +719,7 @@ impl ProcessLoop { // The next message must be the version response. let mut response = get_protocol::VersionResponse::new_zeroed(); - let len = self.read_pipe(response.as_bytes_mut()).await?; + let len = self.read_pipe(response.as_mut_bytes()).await?; validate_response(response.message_header)?; @@ -779,8 +787,9 @@ impl ProcessLoop { // way to get these kinds of per-message stats is to // quickly re-parse the header before sending the // message down the wire. - if let Some(header) = + if let Ok((header, _)) = get_protocol::HeaderRaw::read_from_prefix(outgoing.as_ref()) + // todo: zerocopy: use-rest-of-range, zerocopy: err { match header.message_type { get_protocol::MessageTypes::HOST_REQUEST => { @@ -906,7 +915,8 @@ impl ProcessLoop { let len = len?; let buf = &buf[..len]; let header = get_protocol::HeaderRaw::read_from_prefix(buf) - .ok_or(FatalError::MessageSizeHeader(len))?; + .map_err(|_| FatalError::MessageSizeHeader(len))? + .0; // todo: zerocopy: map_err match header.message_type { get_protocol::MessageTypes::HOST_RESPONSE => { @@ -984,9 +994,9 @@ impl ProcessLoop { req: Rpc, f: impl 'static + Send + FnOnce(I) -> Req, ) where - Req: AsBytes + 'static + Send + Sync, + Req: IntoBytes + 'static + Send + Sync + Immutable + KnownLayout, I: 'static + Send, - Resp: 'static + AsBytes + FromBytes + Send, + Resp: 'static + IntoBytes + FromBytes + Send + Immutable + KnownLayout, { self.push_host_request_handler(|mut access| { req.handle_must_succeed(move |input| async move { @@ -1334,12 +1344,12 @@ impl ProcessLoop { fn handle_modify_vtl2_settings_notification(&mut self, buf: &[u8]) -> Result<(), FatalError> { let (request, remaining) = - get_protocol::ModifyVtl2SettingsNotification::read_from_prefix_split(buf).ok_or( + get_protocol::ModifyVtl2SettingsNotification::read_from_prefix(buf).map_err(|_| { FatalError::MessageSizeGuestNotification { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS, - }, - )?; + } + })?; // todo: zerocopy: map_ let expected_len = request.size as usize; if remaining.len() != expected_len { @@ -1360,12 +1370,12 @@ impl ProcessLoop { buf: &[u8], ) -> Result<(), FatalError> { let (request, remaining) = - get_protocol::ModifyVtl2SettingsRev1Notification::read_from_prefix_split(buf).ok_or( - FatalError::MessageSizeGuestNotification { + get_protocol::ModifyVtl2SettingsRev1Notification::read_from_prefix(buf).map_err( + |_| FatalError::MessageSizeGuestNotification { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS_REV1, }, - )?; + )?; // TODO: zerocopy: map_err let expected_len = request.size as usize; if remaining.len() != expected_len { @@ -1549,7 +1559,9 @@ async fn request_device_platform_settings_v2( let mut result = Vec::new(); loop { let buf = access.recv_response().await; - let header = get_protocol::HeaderHostResponse::read_from_prefix(buf.as_slice()).unwrap(); + let header = get_protocol::HeaderHostResponse::read_from_prefix(buf.as_slice()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range // Protocol wart: request is sent as a // `HostRequests::DEVICE_PLATFORM_SETTINGS_V2`, but the host will send @@ -1566,13 +1578,13 @@ async fn request_device_platform_settings_v2( match header.message_id { HostRequests::DEVICE_PLATFORM_SETTINGS_V2 => { let (response, remaining) = - get_protocol::DevicePlatformSettingsResponseV2::read_from_prefix_split( + get_protocol::DevicePlatformSettingsResponseV2::read_from_prefix( buf.as_slice(), ) - .ok_or(FatalError::MessageSizeHostResponse { + .map_err(|_| FatalError::MessageSizeHostResponse { len: buf.len(), response: HostRequests::DEVICE_PLATFORM_SETTINGS_V2, - })?; + })?; // todo: zerocopy: map_err if response.size as usize != remaining.len() { return Err(FatalError::DevicePlatformSettingsV2Payload { @@ -1586,13 +1598,13 @@ async fn request_device_platform_settings_v2( } HostRequests::DEVICE_PLATFORM_SETTINGS_V2_REV1 => { let (response, remaining) = - get_protocol::DevicePlatformSettingsResponseV2Rev1::read_from_prefix_split( + get_protocol::DevicePlatformSettingsResponseV2Rev1::read_from_prefix( buf.as_slice(), ) - .ok_or(FatalError::MessageSizeGuestNotification { + .map_err(|_| FatalError::MessageSizeGuestNotification { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS_REV1, - })?; + })?; // todo: zerocopy: map_err if remaining.len() != (response.size as usize) { return Err(FatalError::DevicePlatformSettingsV2Payload { @@ -1639,13 +1651,11 @@ async fn request_vmgs_read( let buf = access.recv_response().await; let vmgs_buf_len = (sector_count * sector_size) as usize; - let (response, remaining) = get_protocol::VmgsReadResponse::read_from_prefix_split( - buf.as_slice(), - ) - .ok_or(FatalError::MessageSizeHostResponse { - len: buf.len(), - response: HostRequests::VMGS_READ, - })?; + let (response, remaining) = get_protocol::VmgsReadResponse::read_from_prefix(buf.as_slice()) + .map_err(|_| FatalError::MessageSizeHostResponse { + len: buf.len(), + response: HostRequests::VMGS_READ, + })?; // todo: zerocopy: map_err if response.message_header.message_id != HostRequests::VMGS_READ { return Err(FatalError::ResponseHeaderMismatchId( @@ -1771,13 +1781,11 @@ async fn request_saved_state( let message_buf = access.recv_response().await; let (response_header, remaining) = - get_protocol::RestoreGuestVtl2StateResponse::read_from_prefix_split( - message_buf.as_slice(), - ) - .ok_or(FatalError::MessageSizeHostResponse { + get_protocol::RestoreGuestVtl2StateResponse::read_from_prefix(message_buf.as_slice()) + .map_err(|_| FatalError::MessageSizeHostResponse { len: message_buf.len(), response: HostRequests::RESTORE_GUEST_VTL2_STATE, - })?; + })?; // todo: zerocopy: map_err let message_id = response_header.message_header.message_id; if message_id != HostRequests::RESTORE_GUEST_VTL2_STATE { @@ -1853,7 +1861,8 @@ async fn request_igvm_attest( let response = access.recv_response().await; // Validate the response and returns the validated data. - let Some(response) = get_protocol::IgvmAttestResponse::read_from_prefix(&response) else { + // todo: zerocopy: use error here, use rest of range + let Ok((response, _)) = get_protocol::IgvmAttestResponse::read_from_prefix(&response) else { Err(FatalError::DeserializeIgvmAttestResponse)? }; diff --git a/vm/devices/hyperv_ic/Cargo.toml b/vm/devices/hyperv_ic/Cargo.toml index c9db83c3bb..bc11988e88 100644 --- a/vm/devices/hyperv_ic/Cargo.toml +++ b/vm/devices/hyperv_ic/Cargo.toml @@ -24,8 +24,6 @@ futures-concurrency.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [dev-dependencies] [lints] diff --git a/vm/devices/hyperv_ic/src/shutdown.rs b/vm/devices/hyperv_ic/src/shutdown.rs index 43b91f2bfe..9abb04aa62 100644 --- a/vm/devices/hyperv_ic/src/shutdown.rs +++ b/vm/devices/hyperv_ic/src/shutdown.rs @@ -32,10 +32,9 @@ use vmbus_channel::gpadl_ring::GpadlRingMem; use vmbus_channel::simple::SaveRestoreSimpleVmbusDevice; use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// A shutdown IC device. #[derive(InspectMut)] @@ -178,7 +177,7 @@ impl ShutdownChannel { let message = hyperv_ic_protocol::NegotiateMessage { framework_version_count: FRAMEWORK_VERSIONS.len() as u16, message_version_count: message_versions.len() as u16, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let header = hyperv_ic_protocol::Header { @@ -191,7 +190,7 @@ impl ShutdownChannel { flags: hyperv_ic_protocol::HeaderFlags::new() .with_transaction(true) .with_request(true), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.pipe @@ -209,14 +208,15 @@ impl ShutdownChannel { ChannelState::WaitVersion => { let (_result, buf) = read_response(&mut self.pipe).await?; let (message, rest) = - hyperv_ic_protocol::NegotiateMessage::read_from_prefix_split(buf.as_slice()) - .ok_or(Error::TruncatedMessage)?; + hyperv_ic_protocol::NegotiateMessage::read_from_prefix(buf.as_slice()) + .map_err(|_| Error::TruncatedMessage)?; // todo: zerocopy: map_err if message.framework_version_count != 1 || message.message_version_count != 1 { return Err(Error::NoSupportedVersions); } let [framework_version, message_version] = <[hyperv_ic_protocol::Version; 2]>::read_from_prefix(rest) - .ok_or(Error::TruncatedMessage)?; + .map_err(|_| Error::TruncatedMessage)? + .0; // todo: zerocopy: map_err self.state = ChannelState::Ready { framework_version, @@ -258,7 +258,7 @@ impl ShutdownChannel { flags: hyperv_ic_protocol::HeaderFlags::new() .with_transaction(true) .with_request(true), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.pipe @@ -294,7 +294,7 @@ async fn read_response(pipe: &mut MessagePipe) -> Result<(u32, Vec let n = pipe.recv(&mut buf).await.map_err(Error::Ring)?; let buf = &buf[..n]; let (header, rest) = - hyperv_ic_protocol::Header::read_from_prefix_split(buf).ok_or(Error::TruncatedMessage)?; + hyperv_ic_protocol::Header::read_from_prefix(buf).map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err if header.transaction_id != 0 || !header.flags.transaction() || !header.flags.response() { return Err(Error::InvalidVersionResponse); diff --git a/vm/devices/hyperv_ic_guest/Cargo.toml b/vm/devices/hyperv_ic_guest/Cargo.toml index 9d78fb1430..728a252c7f 100644 --- a/vm/devices/hyperv_ic_guest/Cargo.toml +++ b/vm/devices/hyperv_ic_guest/Cargo.toml @@ -24,8 +24,6 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [dev-dependencies] [lints] diff --git a/vm/devices/hyperv_ic_guest/src/shutdown.rs b/vm/devices/hyperv_ic_guest/src/shutdown.rs index 049c54f298..cc69cbd9b8 100644 --- a/vm/devices/hyperv_ic_guest/src/shutdown.rs +++ b/vm/devices/hyperv_ic_guest/src/shutdown.rs @@ -31,10 +31,9 @@ use vmbus_relay_intercept_device::SimpleVmbusClientDevice; use vmbus_relay_intercept_device::SimpleVmbusClientDeviceAsync; use vmbus_ring::RingMem; use vmcore::save_restore::NoSavedState; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const E_FAIL: u32 = 0x80004005; @@ -120,8 +119,9 @@ impl ShutdownGuestChannel { } async fn handle_host_message(&mut self, buf: &[u8], ic: &ShutdownGuestIc) { - let (header, rest) = match hyperv_ic_protocol::Header::read_from_prefix_split(buf) { - Some(result) => result, + // todo: zerocopy: err + let (header, rest) = match hyperv_ic_protocol::Header::read_from_prefix(buf).ok() { + Some((h, r)) => (h, r), None => { tracelimit::error_ratelimited!("invalid shutdown packet from host",); return; @@ -163,8 +163,9 @@ impl ShutdownGuestChannel { let mut next_version; let mut latest_version = None; for _ in 0..count { - (next_version, rest) = match hyperv_ic_protocol::Version::read_from_prefix_split(rest) { - Some(result) => result, + // todo: zerocopy: err + (next_version, rest) = match hyperv_ic_protocol::Version::read_from_prefix(rest).ok() { + Some((n, r)) => (n, r), None => { tracelimit::error_ratelimited!("truncated message version list"); return (latest_version, rest); @@ -194,8 +195,8 @@ impl ShutdownGuestChannel { header: &hyperv_ic_protocol::Header, msg: &[u8], ) -> Result<(), Error> { - let (prefix, rest) = hyperv_ic_protocol::NegotiateMessage::read_from_prefix_split(msg) - .ok_or(Error::TruncatedMessage)?; + let (prefix, rest) = hyperv_ic_protocol::NegotiateMessage::read_from_prefix(msg) + .map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err let (latest_framework_version, rest) = Self::find_latest_supported_version( rest, prefix.framework_version_count as usize, @@ -224,7 +225,7 @@ impl ShutdownGuestChannel { let message = hyperv_ic_protocol::NegotiateMessage { framework_version_count: 1, message_version_count: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let response = hyperv_ic_protocol::Header { message_type: hyperv_ic_protocol::MessageType::VERSION_NEGOTIATION, @@ -236,7 +237,7 @@ impl ShutdownGuestChannel { flags: hyperv_ic_protocol::HeaderFlags::new() .with_transaction(header.flags.transaction()) .with_response(true), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.pipe .send_vectored(&[ @@ -271,7 +272,8 @@ impl ShutdownGuestChannel { }; let message = hyperv_ic_protocol::shutdown::ShutdownMessage::read_from_prefix(buf) - .ok_or(Error::TruncatedMessage)?; + .map_err(|_| Error::TruncatedMessage)? + .0; // todo: zerocopy: map_err let shutdown_type = if message.flags.restart() { ShutdownType::Reboot } else if message.flags.hibernate() { @@ -298,7 +300,7 @@ impl ShutdownGuestChannel { flags: hyperv_ic_protocol::HeaderFlags::new() .with_transaction(header.flags.transaction()) .with_response(true), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.pipe .send(response.as_bytes()) diff --git a/vm/devices/hyperv_ic_protocol/Cargo.toml b/vm/devices/hyperv_ic_protocol/Cargo.toml index 545ef20024..e7c52428c3 100644 --- a/vm/devices/hyperv_ic_protocol/Cargo.toml +++ b/vm/devices/hyperv_ic_protocol/Cargo.toml @@ -12,6 +12,5 @@ guid.workspace = true bitfield-struct.workspace = true open_enum.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/hyperv_ic_protocol/src/lib.rs b/vm/devices/hyperv_ic_protocol/src/lib.rs index e570b1d789..98ca5639d7 100644 --- a/vm/devices/hyperv_ic_protocol/src/lib.rs +++ b/vm/devices/hyperv_ic_protocol/src/lib.rs @@ -8,16 +8,17 @@ use bitfield_struct::bitfield; use open_enum::open_enum; use std::fmt::Display; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Maximum message size between guest and host for IC devices. pub const MAX_MESSAGE_SIZE: usize = 13312; /// Protocol version. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Version { /// Major version. pub major: u16, @@ -40,7 +41,7 @@ impl Display for Version { open_enum! { /// Type of message - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum MessageType: u16 { /// Initial version negotiation between host and guest. VERSION_NEGOTIATION = 0, @@ -65,7 +66,7 @@ open_enum! { /// Common message header for IC messages. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] pub struct Header { /// Version of the IC framework. pub framework_version: Version, @@ -87,7 +88,7 @@ pub struct Header { /// Flags for IC messages. #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HeaderFlags { /// Message expects a response. pub transaction: bool, @@ -102,7 +103,7 @@ pub struct HeaderFlags { /// Version negotiation message. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NegotiateMessage { /// The number of supported framework versions, located directly after /// this structure. @@ -117,13 +118,14 @@ pub struct NegotiateMessage { /// Heartbeat component protocol. pub mod heartbeat { use open_enum::open_enum; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; /// Heartbeat message from guest to host. #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HeartbeatMessage { /// Incrementing sequence counter. pub sequence_number: u64, @@ -134,7 +136,7 @@ pub mod heartbeat { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] /// Current state of guest. pub enum ApplicationState: u32 { /// Guest is in an unknown state. @@ -154,9 +156,10 @@ pub mod shutdown { use crate::Version; use bitfield_struct::bitfield; use guid::Guid; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; /// The unique vmbus interface ID of the shutdown IC. pub const INTERFACE_ID: Guid = Guid::from_static_str("0e0b6031-5213-4934-818b-38d90ced39db"); @@ -176,7 +179,7 @@ pub mod shutdown { /// The message for shutdown initiated from the host. #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ShutdownMessage { /// The shutdown reason. pub reason_code: u32, @@ -191,7 +194,7 @@ pub mod shutdown { /// Flags for shutdown. #[bitfield(u32)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ShutdownFlags { /// Whether the shutdown operation is being forced. pub force: bool, diff --git a/vm/devices/net/gdma/Cargo.toml b/vm/devices/net/gdma/Cargo.toml index e7be4eedbc..077f75623e 100644 --- a/vm/devices/net/gdma/Cargo.toml +++ b/vm/devices/net/gdma/Cargo.toml @@ -32,6 +32,5 @@ slab.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/net/gdma/src/bnic.rs b/vm/devices/net/gdma/src/bnic.rs index 7e0cdca0a9..e13778fc4b 100644 --- a/vm/devices/net/gdma/src/bnic.rs +++ b/vm/devices/net/gdma/src/bnic.rs @@ -24,6 +24,7 @@ use crate::bnic::bnic_defs::CQE_RX_OKAY; use crate::hwc::HwState; use crate::queues::Queues; use crate::VportConfig; +use anyhow::anyhow; use anyhow::Context; use gdma_defs::access::WqeAccess; use gdma_defs::bnic as bnic_defs; @@ -61,9 +62,9 @@ use task_control::AsyncRun; use task_control::InspectTaskMut; use task_control::StopTask; use task_control::TaskControl; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; pub struct GuestBuffers { gm: GuestMemory, @@ -146,7 +147,7 @@ impl BufferAccess for GuestBuffers { .with_client_type(MANA_CQE_COMPLETION), rx_wqe_offset: packet.wqe_offset, flags, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; packet.oob.ppi[0].pkt_len = metadata.len as u16; } @@ -517,11 +518,14 @@ impl TxRxTask { tracing::trace!("tx wqe"); let oob = sqe.oob(); let oob = if oob.len() >= size_of::() { - ManaTxOob::read_from_prefix(oob).unwrap() + ManaTxOob::read_from_prefix(oob).unwrap().0 } else { ManaTxOob { - s_oob: ManaTxShortOob::read_from_prefix(oob).context("oob too small")?, - ..FromZeroes::new_zeroed() + // todo: zerocopy: use details from SizeError in the returned context + s_oob: ManaTxShortOob::read_from_prefix(oob) + .map_err(|_| anyhow!("oob too small"))? + .0, + ..FromZeros::new_zeroed() } }; @@ -607,7 +611,7 @@ impl TxRxTask { segments, len, wqe_offset, - oob: FromZeroes::new_zeroed(), + oob: FromZeros::new_zeroed(), }; let id = RxId(self.rx_packets.lock().insert(packet) as u32); self.epqueue.rx_avail(&[id]); diff --git a/vm/devices/net/gdma/src/hwc.rs b/vm/devices/net/gdma/src/hwc.rs index f43de3a996..43f045b797 100644 --- a/vm/devices/net/gdma/src/hwc.rs +++ b/vm/devices/net/gdma/src/hwc.rs @@ -54,9 +54,9 @@ use std::sync::Arc; use task_control::AsyncRun; use task_control::InspectTaskMut; use task_control::StopTask; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const BNIC_DEV_ID: GdmaDevId = GdmaDevId { ty: GdmaDevType::GDMA_DEVICE_MANA, @@ -200,7 +200,9 @@ impl HwControl { let (rqe_offset, rqe) = poll_fn(|cx| self.state.queues.poll_rq(self.rq_id, cx)).await; let queues = self.state.queues.clone(); - let tx_oob = HwcTxOob::read_from_prefix(sqe.oob()).context("reading tx oob")?; + let tx_oob = HwcTxOob::read_from_prefix(sqe.oob()) + .map_err(|_| anyhow!("reading tx oob"))? + .0; // todo: zerocopy: map_err, use-rest-of-range, use error details in the returned `anyhow!` if tx_oob.flags3.vscq_id() != self.cq_id { anyhow::bail!( "mismatched cq id: {} != {}", @@ -273,7 +275,7 @@ impl HwControl { let rx_oob = HwcRxOob { wqe_addr_low_or_offset: rqe_offset, tx_oob_data_size: (size_of_val(&resp) + response_len) as u32, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.state @@ -339,7 +341,7 @@ impl HwControl { GdmaRequestType::GDMA_LIST_DEVICES => { let mut resp = GdmaListDevicesResp { num_of_devs: 2, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; resp.devs[0] = HWC_DEV_ID; resp.devs[1] = BNIC_DEV_ID; diff --git a/vm/devices/net/gdma/src/lib.rs b/vm/devices/net/gdma/src/lib.rs index ed2bd31d28..246beff94a 100644 --- a/vm/devices/net/gdma/src/lib.rs +++ b/vm/devices/net/gdma/src/lib.rs @@ -56,8 +56,8 @@ use vmcore::save_restore::SaveError; use vmcore::save_restore::SaveRestore; use vmcore::save_restore::SavedStateNotSupported; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const REGMAP: Range = 0..40; const SHMEM: Range = 40..72; @@ -173,7 +173,7 @@ impl GdmaDevice { Self { config, msix, - shmem: Shmem(FromZeroes::new_zeroed()), + shmem: Shmem(FromZeros::new_zeroed()), regmap, queues, destroying_hwc: false, @@ -201,7 +201,7 @@ impl GdmaDevice { } fn write_shmem(&mut self, offset: usize, data: &[u8]) { - self.shmem.0.as_bytes_mut()[offset..offset + data.len()].copy_from_slice(data); + self.shmem.0.as_mut_bytes()[offset..offset + data.len()].copy_from_slice(data); if (SHMEM_LEN - 4..SHMEM_LEN).overlaps_range(&(offset..offset + data.len())) { let status = match self.handle_smc() { Ok(true) => 0, diff --git a/vm/devices/net/gdma/src/queues.rs b/vm/devices/net/gdma/src/queues.rs index f47a3538da..2d0d98a1d4 100644 --- a/vm/devices/net/gdma/src/queues.rs +++ b/vm/devices/net/gdma/src/queues.rs @@ -31,8 +31,10 @@ use std::task::Waker; use thiserror::Error; use vmcore::interrupt::Interrupt; use vmcore::vm_task::VmTaskDriver; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Offset the queue IDs seen by the guest. const ID_OFFSET: usize = 24; @@ -65,7 +67,7 @@ pub enum QueueAllocError { NoMoreQueues, } -impl CqEq { +impl CqEq { fn new(region: DmaRegion) -> Result { if !region.is_aligned_to(size_of::()) { return Err(QueueAllocError::InvalidAlignment); @@ -229,7 +231,7 @@ impl Wq { let mut wqe = Wqe { header, - data: FromZeroes::new_zeroed(), + data: FromZeros::new_zeroed(), }; if let Err(err) = reader.read(&mut wqe.data[..wqe.header.data_len()]) { @@ -453,7 +455,7 @@ impl Queues { pub fn post_cq(&self, cq_id: u32, data: &[u8], wq_id: u32, is_send: bool) { let post_to_eq = self.cq(cq_id).and_then(|mut cq| { let mut cqe = Cqe { - data: FromZeroes::new_zeroed(), + data: FromZeros::new_zeroed(), params: CqeParams::new() .with_is_send_wq(is_send) .with_wq_number(wq_id) @@ -472,7 +474,7 @@ impl Queues { pub fn post_eq(&self, eq_id: u32, ty: u8, data: &[u8]) { let post_msi = self.eq(eq_id).and_then(|mut eq| { let mut eqe = Eqe { - data: FromZeroes::new_zeroed(), + data: FromZeros::new_zeroed(), params: EqeParams::new() .with_event_type(ty) .with_owner_count(eq.q.owner_count()), diff --git a/vm/devices/net/gdma_defs/Cargo.toml b/vm/devices/net/gdma_defs/Cargo.toml index 45cf5493e2..13cf173f3c 100644 --- a/vm/devices/net/gdma_defs/Cargo.toml +++ b/vm/devices/net/gdma_defs/Cargo.toml @@ -14,6 +14,5 @@ open_enum.workspace = true bitfield-struct.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/net/gdma_defs/src/bnic.rs b/vm/devices/net/gdma_defs/src/bnic.rs index 37fa40c7b1..d865f44de5 100644 --- a/vm/devices/net/gdma_defs/src/bnic.rs +++ b/vm/devices/net/gdma_defs/src/bnic.rs @@ -8,9 +8,10 @@ use super::GdmaQueueType; use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; open_enum! { pub enum ManaCommandCode: u32 { @@ -36,7 +37,7 @@ pub const MANA_VTL2_QUERY_FILTER_STATE_REQUEST_V1: u16 = 1; pub const MANA_VTL2_QUERY_FILTER_STATE_RESPONSE_V1: u16 = 1; #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BasicNicDriverFlags { #[bits(1)] pub query_link_status: u8, @@ -49,7 +50,7 @@ pub struct BasicNicDriverFlags { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryDeviceCfgReq { pub mn_drv_cap_flags1: u64, pub mn_drv_cap_flags2: u64, @@ -64,7 +65,7 @@ pub struct ManaQueryDeviceCfgReq { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryDeviceCfgResp { pub pf_cap_flags1: BasicNicDriverFlags, pub pf_cap_flags2: u64, @@ -104,13 +105,13 @@ impl ManaQueryDeviceCfgResp { /* Query vPort Configuration */ #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryVportCfgReq { pub vport_index: u32, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryVportCfgResp { pub max_num_sq: u32, pub max_num_rq: u32, @@ -123,7 +124,7 @@ pub struct ManaQueryVportCfgResp { /* Move Filter invoked from VTL2 to move filter from VTL2 to VTL0 and back*/ #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaMoveFilterVTL2PrivilegedReq { pub vport: u64, pub direction_to_vtl0: u8, @@ -133,7 +134,7 @@ pub struct ManaMoveFilterVTL2PrivilegedReq { /* Set vport serial number. */ #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaSetVportSerialNo { pub vport: u64, pub serial_no: u32, @@ -142,20 +143,20 @@ pub struct ManaSetVportSerialNo { /* Get vport Filter State. */ #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryFilterStateReq { pub vport: u64, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryFilterStateResponse { pub direction_to_vtl0: u8, pub reserved: [u8; 7], } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaConfigVportReq { pub vport: u64, pub pdid: u32, @@ -163,7 +164,7 @@ pub struct ManaConfigVportReq { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaConfigVportResp { pub tx_vport_offset: u16, pub short_form_allowed: u8, @@ -171,7 +172,7 @@ pub struct ManaConfigVportResp { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaCreateWqobjReq { pub vport: u64, pub wq_type: GdmaQueueType, @@ -185,7 +186,7 @@ pub struct ManaCreateWqobjReq { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaCreateWqobjResp { pub wq_id: u32, pub cq_id: u32, @@ -193,7 +194,7 @@ pub struct ManaCreateWqobjResp { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaDestroyWqobjReq { pub wq_type: GdmaQueueType, pub reserved: u32, @@ -201,13 +202,13 @@ pub struct ManaDestroyWqobjReq { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaFenceRqReq { pub wq_obj_handle: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaCfgRxSteerReq { pub vport: u64, pub num_indir_entries: u16, @@ -223,7 +224,7 @@ pub struct ManaCfgRxSteerReq { } #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct Tristate(pub u32); impl Tristate { @@ -243,7 +244,7 @@ impl From> for Tristate { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaCqeHeader { #[bits(6)] pub cqe_type: u8, @@ -273,7 +274,7 @@ pub const CQE_TX_VLAN_TAGGING_VIOLATION: u8 = 41; pub const MANA_CQE_COMPLETION: u8 = 1; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaTxCompOob { pub cqe_hdr: ManaCqeHeader, pub tx_data_offset: u32, @@ -282,7 +283,7 @@ pub struct ManaTxCompOob { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaTxCompOobOffsets { #[bits(5)] pub tx_sgl_offset: u32, @@ -291,7 +292,7 @@ pub struct ManaTxCompOobOffsets { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaRxcompPerpktInfo { pub pkt_len: u16, pub reserved1: u16, @@ -300,7 +301,7 @@ pub struct ManaRxcompPerpktInfo { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaRxcompOob { pub cqe_hdr: ManaCqeHeader, pub flags: ManaRxcompOobFlags, @@ -309,7 +310,7 @@ pub struct ManaRxcompOob { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaRxcompOobFlags { #[bits(12)] pub rx_vlan_id: u32, @@ -329,7 +330,7 @@ pub struct ManaRxcompOobFlags { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaTxShortOob { #[bits(2)] pub pkt_fmt: u8, @@ -353,7 +354,7 @@ pub const MANA_SHORT_PKT_FMT: u8 = 0; pub const MANA_LONG_PKT_FMT: u8 = 1; #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaTxLongOob { pub is_encap: bool, pub inner_is_ipv6: bool, @@ -378,7 +379,7 @@ pub struct ManaTxLongOob { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaTxOob { pub s_oob: ManaTxShortOob, pub l_oob: ManaTxLongOob, @@ -441,13 +442,13 @@ pub const STATISTICS_FLAGS_ALL: u64 = STATISTICS_FLAGS_IN_DISCARDS_NO_WQE | STATISTICS_FLAGS_HC_OUT_BCAST_OCTETS; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryStatisticsRequest { pub requested_statistics: u64, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ManaQueryStatisticsResponse { pub reported_statistics: u64, // In discards/errors diff --git a/vm/devices/net/gdma_defs/src/lib.rs b/vm/devices/net/gdma_defs/src/lib.rs index d6300cd407..12b6320474 100644 --- a/vm/devices/net/gdma_defs/src/lib.rs +++ b/vm/devices/net/gdma_defs/src/lib.rs @@ -11,9 +11,10 @@ use bitfield_struct::bitfield; use inspect::Inspect; use open_enum::open_enum; use std::fmt::Debug; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const VENDOR_ID: u16 = 0x1414; pub const DEVICE_ID: u16 = 0x00BA; @@ -22,7 +23,7 @@ pub const PAGE_SIZE32: u32 = 4096; pub const PAGE_SIZE64: u64 = 4096; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Inspect)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] pub struct RegMap { #[inspect(hex)] pub micro_version_number: u16, @@ -76,7 +77,7 @@ pub struct WqDoorbellValue { // Shmem #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SmcProtoHdr { #[bits(3)] pub msg_type: u8, @@ -105,7 +106,7 @@ pub const SMC_MSG_TYPE_DESTROY_HWC_VERSION: u8 = 0; pub const SMC_MSG_TYPE_REPORT_HWC_TIMEOUT_VERSION: u8 = 1; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EstablishHwc { pub eq: [u8; 6], pub cq: [u8; 6], @@ -118,7 +119,7 @@ pub struct EstablishHwc { // Wq #[repr(C, align(8))] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Wqe { pub header: WqeHeader, pub data: [u8; 512 - 8], @@ -132,7 +133,7 @@ impl Wqe { } pub fn sgl(&self) -> &[Sge] { - Sge::slice_from_prefix( + <[Sge]>::ref_from_prefix_with_elems( &self.data[self.header.sgl_offset()..], self.header.params.num_sgl_entries() as usize, ) @@ -142,7 +143,7 @@ impl Wqe { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct WqeHeader { pub reserved: [u8; 3], pub last_vbytes: u8, @@ -183,7 +184,7 @@ impl WqeHeader { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct WqeParams { pub num_sgl_entries: u8, #[bits(3)] @@ -202,7 +203,7 @@ pub const CLIENT_OOB_24: u8 = 6; pub const CLIENT_OOB_32: u8 = 7; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Sge { pub address: u64, pub mem_key: u32, @@ -210,14 +211,14 @@ pub struct Sge { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cqe { pub data: [u8; 60], pub params: CqeParams, } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CqeParams { #[bits(24)] pub wq_number: u32, @@ -233,14 +234,14 @@ pub const OWNER_BITS: u32 = 3; pub const OWNER_MASK: u32 = (1 << OWNER_BITS) - 1; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Eqe { pub data: [u8; 12], pub params: EqeParams, } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EqeParams { pub event_type: u8, pub reserved: u8, @@ -258,14 +259,14 @@ pub const GDMA_EQE_HWC_INIT_DONE: u8 = 131; pub const GDMA_EQE_HWC_RECONFIG_DATA: u8 = 133; #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcInitEqIdDb { pub eq_id: u16, pub doorbell: u16, } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcInitTypeData { #[bits(24)] pub value: u32, @@ -276,7 +277,7 @@ pub const HWC_DATA_CONFIG_HWC_TIMEOUT: u8 = 1; pub const HWC_DATA_TYPE_HW_VPORT_LINK_CONNECT: u8 = 2; pub const HWC_DATA_TYPE_HW_VPORT_LINK_DISCONNECT: u8 = 3; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EqeDataReconfig { pub data: [u8; 3], pub data_type: u8, @@ -294,7 +295,7 @@ pub const HWC_INIT_DATA_PDID: u8 = 8; pub const HWC_INIT_DATA_GPA_MKEY: u8 = 9; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum GdmaRequestType : u32 { GDMA_VERIFY_VF_DRIVER_VERSION = 1, GDMA_QUERY_MAX_RESOURCES = 2, @@ -312,7 +313,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaMsgHdr { pub hdr_type: u32, pub msg_type: u32, @@ -326,14 +327,14 @@ pub const GDMA_STANDARD_HEADER_TYPE: u32 = 0; pub const GDMA_MESSAGE_V1: u16 = 1; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct GdmaDevId { pub ty: GdmaDevType, pub instance: u16, } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum GdmaDevType: u16 { GDMA_DEVICE_NONE = 0, GDMA_DEVICE_HWC = 1, @@ -347,7 +348,7 @@ pub const HWC_DEV_ID: GdmaDevId = GdmaDevId { }; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaReqHdr { pub req: GdmaMsgHdr, pub resp: GdmaMsgHdr, @@ -356,7 +357,7 @@ pub struct GdmaReqHdr { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaRespHdr { pub response: GdmaMsgHdr, pub dev_id: GdmaDevId, @@ -366,13 +367,13 @@ pub struct GdmaRespHdr { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaGenerateTestEventReq { pub queue_index: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcTxOob { pub reserved: u64, pub flags1: HwcTxOobFlags1, @@ -382,7 +383,7 @@ pub struct HwcTxOob { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcTxOobFlags1 { #[bits(24)] pub vrq_id: u32, @@ -390,7 +391,7 @@ pub struct HwcTxOobFlags1 { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcTxOobFlags2 { #[bits(24)] pub vrcq_id: u32, @@ -398,7 +399,7 @@ pub struct HwcTxOobFlags2 { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcTxOobFlags3 { #[bits(24)] pub vscq_id: u32, @@ -410,7 +411,7 @@ pub struct HwcTxOobFlags3 { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcTxOobFlags4 { #[bits(24)] pub vsq_id: u32, @@ -418,7 +419,7 @@ pub struct HwcTxOobFlags4 { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcRxOob { pub flags: HwcRxOobFlags, pub reserved2: u32, @@ -430,7 +431,7 @@ pub struct HwcRxOob { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HwcRxOobFlags { #[bits(6)] pub ty: u8, @@ -449,7 +450,7 @@ pub const DRIVER_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT: u64 = 0x20; pub const DRIVER_CAP_FLAG_1_HW_VPORT_LINK_AWARE: u64 = 0x40; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaVerifyVerReq { pub protocol_ver_min: u64, pub protocol_ver_max: u64, @@ -472,7 +473,7 @@ pub struct GdmaVerifyVerReq { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaVerifyVerResp { pub gdma_protocol_ver: u64, pub pf_cap_flags1: u64, @@ -482,7 +483,7 @@ pub struct GdmaVerifyVerResp { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaQueryMaxResourcesResp { pub status: u32, pub max_sq: u32, @@ -497,7 +498,7 @@ pub struct GdmaQueryMaxResourcesResp { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaListDevicesResp { pub num_of_devs: u32, pub reserved: u32, @@ -505,7 +506,7 @@ pub struct GdmaListDevicesResp { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaRegisterDeviceResp { pub pdid: u32, pub gpa_mkey: u32, @@ -513,7 +514,7 @@ pub struct GdmaRegisterDeviceResp { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaCreateDmaRegionReq { pub length: u64, pub offset_in_page: u32, @@ -526,19 +527,19 @@ pub struct GdmaCreateDmaRegionReq { pub const GDMA_PAGE_TYPE_4K: u32 = 0; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaCreateDmaRegionResp { pub gdma_region: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaDestroyDmaRegionReq { pub gdma_region: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaCreateQueueReq { pub queue_type: GdmaQueueType, pub reserved1: u32, @@ -559,7 +560,7 @@ pub struct GdmaCreateQueueReq { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum GdmaQueueType: u32 { GDMA_SQ = 1, GDMA_RQ = 2, @@ -569,13 +570,13 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaCreateQueueResp { pub queue_index: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaDisableQueueReq { pub queue_type: GdmaQueueType, pub queue_index: u32, @@ -583,7 +584,7 @@ pub struct GdmaDisableQueueReq { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdmaChangeMsixVectorIndexForEq { pub queue_index: u32, pub msix: u32, diff --git a/vm/devices/net/mana_driver/Cargo.toml b/vm/devices/net/mana_driver/Cargo.toml index 233fe4e737..27a19c9fbc 100644 --- a/vm/devices/net/mana_driver/Cargo.toml +++ b/vm/devices/net/mana_driver/Cargo.toml @@ -25,7 +25,6 @@ getrandom.workspace = true parking_lot.workspace = true tracing.workspace = true zerocopy.workspace = true - safe_intrinsics.workspace = true [dev-dependencies] diff --git a/vm/devices/net/mana_driver/src/bnic_driver.rs b/vm/devices/net/mana_driver/src/bnic_driver.rs index 07d0fff29e..fd9de36fc6 100644 --- a/vm/devices/net/mana_driver/src/bnic_driver.rs +++ b/vm/devices/net/mana_driver/src/bnic_driver.rs @@ -31,9 +31,11 @@ use gdma_defs::GdmaDevId; use gdma_defs::GdmaQueueType; use gdma_defs::GdmaReqHdr; use user_driver::DeviceBacking; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub struct BnicDriver<'a, T: DeviceBacking> { gdma: &'a mut GdmaDriver, @@ -154,7 +156,7 @@ impl<'a, T: DeviceBacking> BnicDriver<'a, T> { config: &RxConfig<'_>, ) -> anyhow::Result<()> { #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct Req { req: ManaCfgRxSteerReq, table: [u64; 128], @@ -174,7 +176,7 @@ impl<'a, T: DeviceBacking> BnicDriver<'a, T> { default_rxobj: config.default_rxobj.unwrap_or(0), hashkey: *config.hash_key.unwrap_or(&[0; 40]), }, - table: FromZeroes::new_zeroed(), + table: FromZeros::new_zeroed(), }; if let Some(table) = config.indirection_table { req.table[..table.len()].copy_from_slice(table); diff --git a/vm/devices/net/mana_driver/src/gdma_driver.rs b/vm/devices/net/mana_driver/src/gdma_driver.rs index 14b81fda6c..5a19250026 100644 --- a/vm/devices/net/mana_driver/src/gdma_driver.rs +++ b/vm/devices/net/mana_driver/src/gdma_driver.rs @@ -80,9 +80,11 @@ use user_driver::memory::PAGE_SIZE64; use user_driver::DeviceBacking; use user_driver::DeviceRegisterIo; use user_driver::HostDmaAllocator; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const HWC_WARNING_TIME_IN_MS: u32 = 3000; const HWC_TIMEOUT_DEFAULT_IN_MS: u32 = 10000; @@ -234,7 +236,7 @@ impl GdmaDriver { if i == 0 && v == !0 { anyhow::bail!("bar0 read returned -1, device is not present"); } - map.as_bytes_mut()[i * 4..(i + 1) * 4].copy_from_slice(&v.to_ne_bytes()); + map.as_mut_bytes()[i * 4..(i + 1) * 4].copy_from_slice(&v.to_ne_bytes()); } tracing::debug!(?map, "register map"); @@ -295,7 +297,7 @@ impl GdmaDriver { .with_msg_version(SMC_MSG_TYPE_ESTABLISH_HWC_VERSION), }; - let shmem = u32::slice_from(establish.as_bytes()).unwrap(); + let shmem = <[u32]>::ref_from_bytes(establish.as_bytes()).unwrap(); assert!(shmem.len() == 8); for (i, &n) in shmem.iter().enumerate() { bar0_mapping.write_u32(map.vf_gdma_sriov_shared_reg_start as usize + i * 4, n); @@ -369,13 +371,13 @@ impl GdmaDriver { tracing::debug!(event_type = eqe.params.event_type(), "got init eqe"); match eqe.params.event_type() { GDMA_EQE_HWC_INIT_EQ_ID_DB => { - let data = HwcInitEqIdDb::read_from_prefix(&eqe.data[..]).unwrap(); + let data = HwcInitEqIdDb::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range eq.set_id(data.eq_id().into()); eq.set_doorbell(DoorbellPage::new(bar0.clone(), data.doorbell().into())?); db_id = Some(data.doorbell()); } GDMA_EQE_HWC_INIT_DATA => { - let data = HwcInitTypeData::read_from_prefix(&eqe.data[..]).unwrap(); + let data = HwcInitTypeData::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range match data.ty() { HWC_INIT_DATA_CQID => cq_id = Some(data.value()), HWC_INIT_DATA_RQID => rq_id = Some(data.value()), @@ -618,7 +620,10 @@ impl GdmaDriver { self.rq.commit(); } - pub async fn request_version( + pub async fn request_version< + Req: IntoBytes + Immutable + KnownLayout, + Resp: IntoBytes + FromBytes + Immutable + KnownLayout, + >( &mut self, req_msg_type: u32, req_msg_version: u16, @@ -663,7 +668,7 @@ impl GdmaDriver { let oob = HwcTxOob { flags3: HwcTxOobFlags3::new().with_vscq_id(self.cq.id()), flags4: HwcTxOobFlags4::new().with_vsq_id(self.sq.id()), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let hw_access = async { @@ -743,7 +748,10 @@ impl GdmaDriver { Ok((resp, self.hwc_activity_id)) } - pub async fn request( + pub async fn request< + Req: IntoBytes + Immutable + KnownLayout, + Resp: IntoBytes + FromBytes + Immutable + KnownLayout, + >( &mut self, msg_type: u32, dev_id: GdmaDevId, @@ -782,7 +790,7 @@ impl GdmaDriver { GDMA_EQE_COMPLETION => self.cq_armed = false, GDMA_EQE_TEST_EVENT => self.test_events += 1, GDMA_EQE_HWC_RECONFIG_DATA => { - let data = EqeDataReconfig::read_from_prefix(&eqe.data[..]).unwrap(); + let data = EqeDataReconfig::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range let mut value: [u8; 4] = [0; 4]; value[0..3].copy_from_slice(&data.data); let value: u32 = u32::from_le_bytes(value); @@ -943,7 +951,7 @@ impl GdmaDriver { gd_drv_cap_flags1: DRIVER_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | DRIVER_CAP_FLAG_1_HW_VPORT_LINK_AWARE | DRIVER_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, ) .await?; @@ -1069,7 +1077,7 @@ impl GdmaDriver { gdma_region, queue_size, eq_pci_msix_index: msix, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, ) .await?; @@ -1109,7 +1117,7 @@ impl GdmaDriver { mem: MemoryBlock, ) -> anyhow::Result { #[repr(C)] - #[derive(AsBytes)] + #[derive(IntoBytes, Immutable, KnownLayout)] struct Req { req: GdmaCreateDmaRegionReq, pages: [u64; 16], diff --git a/vm/devices/net/mana_driver/src/queues.rs b/vm/devices/net/mana_driver/src/queues.rs index 349838a5e6..f23479dab5 100644 --- a/vm/devices/net/mana_driver/src/queues.rs +++ b/vm/devices/net/mana_driver/src/queues.rs @@ -26,8 +26,10 @@ use std::marker::PhantomData; use std::sync::atomic::Ordering::Acquire; use std::sync::Arc; use user_driver::memory::MemoryBlock; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// An interface to write a doorbell value to signal the device. pub trait Doorbell: Send + Sync { @@ -121,7 +123,7 @@ impl CqEq { } } -impl CqEq { +impl CqEq { /// Creates a new queue. fn new( queue_type: GdmaQueueType, @@ -160,7 +162,7 @@ impl CqEq { self.id } - fn read_next(&self, offset: u32) -> U { + fn read_next(&self, offset: u32) -> U { assert!((offset as usize & (size_of::() - 1)) + size_of::() <= size_of::()); self.mem .read_obj((self.next.wrapping_add(offset) & (self.size - 1)) as usize) @@ -319,7 +321,7 @@ impl Wq { /// external data via a scatter-gather list. pub fn push>( &mut self, - oob: &impl AsBytes, + oob: &(impl IntoBytes + Immutable + KnownLayout), sgl: I, client_oob_in_sgl: Option, gd_client_unit_data: u16, diff --git a/vm/devices/net/net_mana/Cargo.toml b/vm/devices/net/net_mana/Cargo.toml index 49e95f522f..7e0613a510 100644 --- a/vm/devices/net/net_mana/Cargo.toml +++ b/vm/devices/net/net_mana/Cargo.toml @@ -27,7 +27,6 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] chipset_device.workspace = true gdma.workspace = true diff --git a/vm/devices/net/net_mana/src/lib.rs b/vm/devices/net/net_mana/src/lib.rs index cd558e5151..b3dc469ced 100644 --- a/vm/devices/net/net_mana/src/lib.rs +++ b/vm/devices/net/net_mana/src/lib.rs @@ -64,7 +64,7 @@ use user_driver::DeviceBacking; use user_driver::HostDmaAllocator; use vmcore::slim_event::SlimEvent; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; /// Per queue limit, in number of pages. /// Used to handle bounce buffering non-contiguous network packet headers. @@ -797,7 +797,7 @@ impl Queue for ManaQueue { while i < packets.len() { if let Some(cqe) = self.rx_cq.pop() { let rx = self.posted_rx.pop_front().unwrap(); - let rx_oob = ManaRxcompOob::read_from_prefix(&cqe.data[..]).unwrap(); + let rx_oob = ManaRxcompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range match rx_oob.cqe_hdr.cqe_type() { CQE_RX_OKAY => { let ip_checksum = if rx_oob.flags.rx_iphdr_csum_succeed() { @@ -902,7 +902,7 @@ impl Queue for ManaQueue { let mut i = 0; while i < done.len() { let id = if let Some(cqe) = self.tx_cq.pop() { - let tx_oob = ManaTxCompOob::read_from_prefix(&cqe.data[..]).unwrap(); + let tx_oob = ManaTxCompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range match tx_oob.cqe_hdr.cqe_type() { CQE_TX_OKAY => { self.stats.tx_packets += 1; diff --git a/vm/devices/net/netvsp/src/buffers.rs b/vm/devices/net/netvsp/src/buffers.rs index 0ce4b23290..6812ec6860 100644 --- a/vm/devices/net/netvsp/src/buffers.rs +++ b/vm/devices/net/netvsp/src/buffers.rs @@ -20,8 +20,10 @@ use safeatomic::AtomicSliceOps; use std::ops::Range; use std::sync::Arc; use vmbus_channel::gpadl::GpadlView; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const PAGE_SIZE: usize = 4096; const PAGE_SIZE32: u32 = 4096; @@ -159,7 +161,7 @@ impl BufferAccess for BufferPool { fn write_header(&mut self, id: RxId, metadata: &RxMetadata) { #[repr(C)] - #[derive(zerocopy::AsBytes, Debug)] + #[derive(zerocopy::IntoBytes, Immutable, KnownLayout, Debug)] struct Header { header: rndisprot::MessageHeader, packet: rndisprot::Packet, @@ -167,7 +169,7 @@ impl BufferAccess for BufferPool { } #[repr(C)] - #[derive(zerocopy::AsBytes, Debug)] + #[derive(zerocopy::IntoBytes, Immutable, KnownLayout, Debug)] struct PerPacketInfo { header: rndisprot::PerPacketInfo, checksum: rndisprot::RxTcpIpChecksumInfo, diff --git a/vm/devices/net/netvsp/src/lib.rs b/vm/devices/net/netvsp/src/lib.rs index 90a2e2952e..3802e4b94e 100644 --- a/vm/devices/net/netvsp/src/lib.rs +++ b/vm/devices/net/netvsp/src/lib.rs @@ -104,9 +104,11 @@ use vmcore::save_restore::SaveError; use vmcore::save_restore::SavedStateBlob; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // The minimum ring space required to handle a control message. Most control messages only need to send a completion // packet, but also need room for an additional SEND_VF_ASSOCIATION message. @@ -732,7 +734,7 @@ impl OffloadConfig { }, checksum, lso_v2, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } @@ -1928,7 +1930,7 @@ impl Packet<'_> { } } -fn read_packet_data( +fn read_packet_data( reader: &mut impl MemoryRead, ) -> Result { reader.read_plain().map_err(PacketError::Access) @@ -2033,14 +2035,18 @@ struct NvspMessage { padding: &'static [u8], } -impl NvspMessage { +impl NvspMessage { fn payload(&self) -> [&[u8]; 3] { [self.header.as_bytes(), self.data.as_bytes(), self.padding] } } impl NetChannel { - fn message(&self, message_type: u32, data: P) -> NvspMessage

{ + fn message( + &self, + message_type: u32, + data: P, + ) -> NvspMessage

{ let padding = self.padding(&data); NvspMessage { header: protocol::MessageHeader { message_type }, @@ -2051,7 +2057,7 @@ impl NetChannel { /// Returns zero padding bytes to round the payload up to the packet size. /// Only needed for Windows guests, which are picky about packet sizes. - fn padding(&self, data: &P) -> &'static [u8] { + fn padding(&self, data: &P) -> &'static [u8] { static PADDING: &[u8] = &[0; protocol::PACKET_SIZE_V61]; let padding_len = self.packet_size - cmp::min( @@ -2455,7 +2461,7 @@ impl NetChannel { } #[repr(C)] - #[derive(AsBytes)] + #[derive(IntoBytes, Immutable, KnownLayout)] struct SendIndirectionMsg { pub message: protocol::Message5SendIndirectionTable, pub send_indirection_table: @@ -2936,7 +2942,7 @@ impl NetChannel { } /// Writes an RNDIS message to `writer`. -fn write_rndis_message( +fn write_rndis_message( writer: &mut impl MemoryWrite, message_type: u32, extra: usize, @@ -3294,7 +3300,7 @@ impl Adapter { // Vmswitch doesn't validate the NDIS header on this object, so read it manually. let mut params = rndisprot::NdisReceiveScaleParameters::new_zeroed(); let len = reader.len().min(size_of_val(¶ms)); - reader.clone().read(&mut params.as_bytes_mut()[..len])?; + reader.clone().read(&mut params.as_mut_bytes()[..len])?; if ((params.flags & NDIS_RSS_PARAM_FLAG_DISABLE_RSS) != 0) || ((params.hash_information & NDIS_HASH_FUNCTION_MASK) == 0) @@ -3319,7 +3325,7 @@ impl Adapter { .read(&mut key)?; reader .skip(params.indirection_table_offset as usize)? - .read(indirection_table[..indirection_table_size].as_bytes_mut())?; + .read(indirection_table[..indirection_table_size].as_mut_bytes())?; if indirection_table .iter() .any(|&x| x >= self.max_queues as u32) @@ -3502,7 +3508,7 @@ impl Adapter { } } -fn read_ndis_object( +fn read_ndis_object( mut reader: impl MemoryRead, object_type: rndisprot::NdisObjectType, min_revision: u8, @@ -3511,9 +3517,11 @@ fn read_ndis_object( let mut buffer = T::new_zeroed(); let sent_size = reader.len(); let len = sent_size.min(size_of_val(&buffer)); - reader.read(&mut buffer.as_bytes_mut()[..len])?; + reader.read(&mut buffer.as_mut_bytes()[..len])?; validate_ndis_object_header( - &rndisprot::NdisObjectHeader::read_from_prefix(buffer.as_bytes()).unwrap(), + &rndisprot::NdisObjectHeader::read_from_prefix(buffer.as_bytes()) + .unwrap() + .0, // todo: zerocopy: use-rest-of-range sent_size, object_type, min_revision, diff --git a/vm/devices/net/netvsp/src/protocol.rs b/vm/devices/net/netvsp/src/protocol.rs index 1ebe4be1a5..789437019b 100644 --- a/vm/devices/net/netvsp/src/protocol.rs +++ b/vm/devices/net/netvsp/src/protocol.rs @@ -7,9 +7,10 @@ use crate::rndisprot; use bitfield_struct::bitfield; use inspect::Inspect; use vmbus_channel::gpadl::GpadlId; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const fn make_version(major: u16, minor: u16) -> u32 { ((major as u32) << 16) | minor as u32 @@ -204,7 +205,7 @@ pub const MESSAGE6_MAX: u32 = MESSAGE6_TYPE_PD_POST_BATCH; */ open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum Status: u32 { NONE = 0, SUCCESS = 1, @@ -216,7 +217,7 @@ open_enum::open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub message_type: u32, } @@ -236,7 +237,7 @@ pub struct MessageHeader { // number. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageInit { pub protocol_version: u32, // was MinProtocolVersion pub protocol_version2: u32, // was MaxProtocolVersion @@ -248,7 +249,7 @@ pub struct MessageInit { // then versioning (i.e. this message will be the same for ever). // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageInitComplete { pub deprecated: u32, // was NegotiatedProtocolVersion (2) in Win6 pub maximum_mdl_chain_length: u32, @@ -267,7 +268,7 @@ pub const INVALID_PROTOCOL_VERSION: u32 = 0xffffffff; // OIDs sent by the VSC. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendNdisVersion { pub ndis_major_version: u32, pub ndis_minor_version: u32, @@ -279,7 +280,7 @@ pub struct Message1SendNdisVersion { // send data to the VSC. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendReceiveBuffer { pub gpadl_handle: GpadlId, pub id: u16, @@ -287,7 +288,7 @@ pub struct Message1SendReceiveBuffer { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReceiveBufferSection { pub offset: u32, pub sub_allocation_size: u32, @@ -301,7 +302,7 @@ pub struct ReceiveBufferSection { // VSP before the VSP uses the receive buffer. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendReceiveBufferComplete { pub status: Status, pub num_sections: u32, @@ -314,7 +315,7 @@ pub struct Message1SendReceiveBufferComplete { // use the receive buffer again. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1RevokeReceiveBuffer { pub id: u16, } @@ -325,7 +326,7 @@ pub struct Message1RevokeReceiveBuffer { // send data to the VSP. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendSendBuffer { pub gpadl_handle: GpadlId, pub id: u16, @@ -338,7 +339,7 @@ pub struct Message1SendSendBuffer { // VSP before the VSP uses the sent buffer. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendSendBufferComplete { pub status: Status, @@ -357,7 +358,7 @@ pub struct Message1SendSendBufferComplete { // use the send buffer again. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1RevokeSendBuffer { pub id: u16, } @@ -366,7 +367,7 @@ pub struct Message1RevokeSendBuffer { // a RNDIS message to the opposite channel endpoint. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendRndisPacket { // // This field is specified by RNIDS. They assume there's @@ -395,7 +396,7 @@ pub struct Message1SendRndisPacket { // associated with the original RNDIS packet. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message1SendRndisPacketComplete { pub status: Status, } @@ -406,7 +407,7 @@ pub struct Message1SendRndisPacketComplete { // OIDs sent by the VSC. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message2SendNdisConfig { pub mtu: u32, pub reserved: u32, @@ -415,7 +416,7 @@ pub struct Message2SendNdisConfig { #[derive(Inspect)] #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisConfigCapabilities { #[inspect(safe)] pub vmq: bool, @@ -441,7 +442,7 @@ pub struct NdisConfigCapabilities { // NvspMessage4TypeSendVFAssociation // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message4SendVfAssociation { /// Specifies whether VF is allocated for this channel /// If 1, SerialNumber of the VF is specified. @@ -457,7 +458,7 @@ pub struct Message4SendVfAssociation { // in NVSP_4_MESSAGE_SWITCH_DATA_PATH structure // open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum DataPath: u32 { SYNTHETIC = 0, VF = 1, @@ -468,7 +469,7 @@ open_enum::open_enum! { // NvspMessage4TypeSwitchDataPath // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message4SwitchDataPath { /// Specifies the current data path that is active in the VM pub active_data_path: u32, @@ -478,7 +479,7 @@ pub struct Message4SwitchDataPath { // NvspMessage5TypeOidQueryEx // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message5OidQueryEx { /// Header information for the Query OID header: rndisprot::NdisObjectHeader, @@ -490,7 +491,7 @@ pub struct Message5OidQueryEx { // NvspMessage5TypeOidQueryExComplete // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message5OidQueryExComplete { pub status: u32, pub bytes: u32, @@ -503,7 +504,7 @@ pub struct Message5OidQueryExComplete { // primary channel's channel close callback. // open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SubchannelOperation: u32 { NONE = 0, ALLOCATE = 1, @@ -514,7 +515,7 @@ open_enum::open_enum! { // NvspMessage5TypeSubChannel // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message5SubchannelRequest { /// The subchannel operation pub operation: SubchannelOperation, @@ -525,7 +526,7 @@ pub struct Message5SubchannelRequest { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message5SubchannelComplete { /// The status of the subchannel operation. pub status: Status, @@ -538,7 +539,7 @@ pub struct Message5SubchannelComplete { // NvspMessage5TypeSendIndirectionTable // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Message5SendIndirectionTable { // // The number of entries in the send indirection table. diff --git a/vm/devices/net/netvsp/src/rndisprot.rs b/vm/devices/net/netvsp/src/rndisprot.rs index 12ec94d204..8fba61ff90 100644 --- a/vm/devices/net/netvsp/src/rndisprot.rs +++ b/vm/devices/net/netvsp/src/rndisprot.rs @@ -6,9 +6,10 @@ use bitfield_struct::bitfield; use open_enum::open_enum; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // // Basic types @@ -106,7 +107,7 @@ pub const STATUS_TOKEN_RING_OPEN_ERROR: Status = 0xC0011000; // open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum Oid: u32 { OID_GEN_SUPPORTED_LIST = 0x00010101, OID_GEN_HARDWARE_STATUS = 0x00010102, @@ -207,7 +208,7 @@ open_enum! { /// Response to OID_GEN_FRIENDLY_NAME. #[repr(C)] -#[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct FriendlyName { pub name: [u16; 255], pub null: u16, @@ -290,7 +291,7 @@ pub const MAC_OPTION_RECEIVE_AT_DPC: u32 = 0x00000100; pub const MAC_OPTION_8021Q_VLAN: u32 = 0x00000200; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LinkState { pub header: NdisObjectHeader, pub media_connect_state: u32, @@ -303,7 +304,7 @@ pub struct LinkState { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LinkSpeed { pub xmit: u64, pub rcv: u64, @@ -313,7 +314,7 @@ pub struct LinkSpeed { // NdisInitialize message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InitializeRequest { pub request_id: RequestId, pub major_version: u32, @@ -325,7 +326,7 @@ pub struct InitializeRequest { // Response to NdisInitialize // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InitializeComplete { pub request_id: RequestId, pub status: Status, @@ -345,7 +346,7 @@ pub struct InitializeComplete { // supported by the device is appended to the response to NdisInitialize. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CoAddressFamily { pub address_family: AddressFamily, pub major_version: u32, @@ -356,7 +357,7 @@ pub struct CoAddressFamily { // NdisHalt message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HaltRequest { pub request_id: RequestId, } @@ -365,7 +366,7 @@ pub struct HaltRequest { // NdisQueryRequest message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryRequest { pub request_id: RequestId, pub oid: Oid, @@ -378,7 +379,7 @@ pub struct QueryRequest { // Response to NdisQueryRequest // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryComplete { pub request_id: RequestId, pub status: Status, @@ -390,7 +391,7 @@ pub struct QueryComplete { // NdisSetRequest message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetRequest { pub request_id: RequestId, pub oid: Oid, @@ -403,7 +404,7 @@ pub struct SetRequest { // Response to NdisSetRequest // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetComplete { pub request_id: RequestId, pub status: Status, @@ -413,7 +414,7 @@ pub struct SetComplete { // NdisSetExRequest message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetExRequest { pub request_id: RequestId, pub oid: Oid, @@ -426,7 +427,7 @@ pub struct SetExRequest { // Response to NdisSetExRequest // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetExComplete { pub request_id: RequestId, pub status: Status, @@ -438,7 +439,7 @@ pub struct SetExComplete { // NdisReset message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ResetRequest { pub reserved: u32, } @@ -447,7 +448,7 @@ pub struct ResetRequest { // Response to NdisReset // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ResetComplete { pub status: Status, pub addressing_reset: u32, @@ -457,7 +458,7 @@ pub struct ResetComplete { // NdisMIndicateStatus message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IndicateStatus { pub status: Status, pub status_buffer_length: u32, @@ -469,7 +470,7 @@ pub struct IndicateStatus { // RNDIS_INDICATE_STATUS messages signifying error conditions. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DiagnosticInfo { pub diag_status: Status, pub error_offset: u32, @@ -479,7 +480,7 @@ pub struct DiagnosticInfo { // NdisKeepAlive message // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct KeepaliveRequest { pub request_id: RequestId, } @@ -488,7 +489,7 @@ pub struct KeepaliveRequest { // Response to NdisKeepAlive // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct KeepaliveComplete { pub request_id: RequestId, pub status: Status, @@ -501,7 +502,7 @@ pub struct KeepaliveComplete { // contains the VC handle. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Packet { pub data_offset: u32, pub data_length: u32, @@ -518,7 +519,7 @@ pub struct Packet { // Optional Out of Band data associated with a Data message. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Oobd { pub size: u32, pub typ: ClassId, @@ -532,7 +533,7 @@ pub const PACKET_INFO_FLAGS_MULTI_SUBALLOC_LAST_FRAGMENT: u8 = 1 << 2; pub const PACKET_INFO_ID_VERSION_V1: u8 = 1; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PacketIdInfo { pub version: u8, pub flags: u8, @@ -545,7 +546,7 @@ const PACKET_INFO_ID: u16 = 1; // Packet extension field contents associated with a Data message. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PerPacketInfo { pub size: u32, pub typ: u32, // high bit means internal @@ -553,7 +554,7 @@ pub struct PerPacketInfo { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TxTcpIpChecksumInfo(pub u32); impl TxTcpIpChecksumInfo { @@ -608,7 +609,7 @@ impl TxTcpIpChecksumInfo { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RxTcpIpChecksumInfo(pub u32); impl RxTcpIpChecksumInfo { @@ -687,7 +688,7 @@ impl RxTcpIpChecksumInfo { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TcpLsoInfo(pub u32); impl TcpLsoInfo { @@ -716,7 +717,7 @@ pub const PPI_LSO: u32 = 2; // OID_GEN_RNDIS_CONFIG_PARAMETER. // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ConfigParameterInfo { pub parameter_name_offset: u32, pub parameter_name_length: u32, @@ -735,7 +736,7 @@ pub const CONFIG_PARAM_TYPE_STRING: u32 = 2; // Remote NDIS message format // #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub message_type: u32, @@ -745,7 +746,7 @@ pub struct MessageHeader { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum NdisObjectType: u8 { DEFAULT = 0x80, RSS_CAPABILITIES = 0x88, @@ -756,7 +757,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisObjectHeader { pub object_type: NdisObjectType, pub revision: u8, @@ -764,7 +765,7 @@ pub struct NdisObjectHeader { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisReceiveScaleCapabilities { pub header: NdisObjectHeader, pub capabilities_flags: u32, @@ -777,7 +778,7 @@ pub struct NdisReceiveScaleCapabilities { pub const NDIS_SIZEOF_RECEIVE_SCALE_CAPABILITIES_REVISION_2: usize = 18; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisReceiveScaleParameters { pub header: NdisObjectHeader, @@ -861,7 +862,7 @@ pub const NDIS_RSS_CAPS_SUPPORTS_MSI_X: u32 = 0x20000000; pub const NDIS_RSS_CAPS_SUPPORTS_INDEPENDENT_ENTRY_MOVE: u32 = 0x40000000; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisOffload { pub header: NdisObjectHeader, @@ -907,7 +908,7 @@ pub const NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_3: usize = const_assert_eq!(NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_3, 156); #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TcpIpChecksumOffload { pub ipv4_tx_encapsulation: u32, pub ipv4_tx_flags: Ipv4ChecksumOffload, @@ -920,7 +921,7 @@ pub struct TcpIpChecksumOffload { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Ipv4ChecksumOffload { #[bits(2)] pub ip_options_supported: u32, @@ -937,7 +938,7 @@ pub struct Ipv4ChecksumOffload { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Ipv6ChecksumOffload { #[bits(2)] pub ip_extension_headers_supported: u32, @@ -954,7 +955,7 @@ pub struct Ipv6ChecksumOffload { pub const NDIS_ENCAPSULATION_IEEE_802_3: u32 = 2; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TcpLargeSendOffloadV2 { pub ipv4_encapsulation: u32, pub ipv4_max_offload_size: u32, @@ -966,7 +967,7 @@ pub struct TcpLargeSendOffloadV2 { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Ipv6LsoFlags { #[bits(2)] pub ip_extension_headers_supported: u32, @@ -977,7 +978,7 @@ pub struct Ipv6LsoFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisOffloadEncapsulation { pub header: NdisObjectHeader, pub ipv4_enabled: u32, @@ -998,7 +999,7 @@ pub const NDIS_OFFLOAD_SET_ON: u32 = 1; pub const NDIS_OFFLOAD_SET_OFF: u32 = 2; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NdisOffloadParameters { pub header: NdisObjectHeader, pub ipv4_checksum: OffloadParametersChecksum, @@ -1019,7 +1020,7 @@ pub struct NdisOffloadParameters { pub const NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1: usize = 20; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum OffloadParametersChecksum: u8 { NO_CHANGE = 0, TX_RX_DISABLED = 1, @@ -1042,7 +1043,7 @@ impl OffloadParametersChecksum { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum OffloadParametersSimple: u8 { NO_CHANGE = 0, DISABLED = 1, @@ -1062,7 +1063,7 @@ impl OffloadParametersSimple { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RndisConfigParameterInfo { pub name_offset: u32, pub name_length: u32, @@ -1072,7 +1073,7 @@ pub struct RndisConfigParameterInfo { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum NdisParameterType: u32 { INTEGER = 0, HEX_INTEGER = 1, diff --git a/vm/devices/net/netvsp/src/test.rs b/vm/devices/net/netvsp/src/test.rs index 6d6dae911e..d53f8940f5 100644 --- a/vm/devices/net/netvsp/src/test.rs +++ b/vm/devices/net/netvsp/src/test.rs @@ -68,9 +68,11 @@ use vmcore::save_restore::SavedStateBlob; use vmcore::slim_event::SlimEvent; use vmcore::vm_task::SingleDriverBackend; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const VMNIC_CHANNEL_TYPE_GUID: Guid = Guid::from_static_str("f8615163-df3e-46c5-913f-f2d2f965ed0e"); @@ -625,7 +627,7 @@ impl<'a> TestNicChannel<'a> { timeout: Duration, ) -> Option where - T: AsBytes + FromBytes, + T: IntoBytes + FromBytes + Immutable + KnownLayout, { let mem = self.nic.mock_vmbus.memory.clone(); let gpadl_map_view = self.gpadl_map.clone().view(); @@ -700,7 +702,7 @@ impl<'a> TestNicChannel<'a> { pub async fn read_rndis_control_message(&mut self, message_type: u32) -> Option where - T: AsBytes + FromBytes, + T: IntoBytes + FromBytes + Immutable + KnownLayout, { self.read_rndis_control_message_with_timeout(message_type, Duration::from_millis(333)) .await @@ -896,7 +898,9 @@ impl<'a> TestNicChannel<'a> { self.send_send_buffer_message().await; } - pub async fn send_rndis_control_message_no_completion( + pub async fn send_rndis_control_message_no_completion< + T: IntoBytes + Immutable + KnownLayout, + >( &mut self, message_type: u32, message: T, @@ -944,7 +948,7 @@ impl<'a> TestNicChannel<'a> { self.transaction_id += 1; } - pub async fn send_rndis_control_message( + pub async fn send_rndis_control_message( &mut self, message_type: u32, message: T, diff --git a/vm/devices/net/vmswitch/Cargo.toml b/vm/devices/net/vmswitch/Cargo.toml index 637d7d6a7a..d17cef78c3 100644 --- a/vm/devices/net/vmswitch/Cargo.toml +++ b/vm/devices/net/vmswitch/Cargo.toml @@ -18,8 +18,6 @@ thiserror.workspace = true tracing.workspace = true widestring.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [target.'cfg(windows)'.dependencies.winapi] features = [ "consoleapi", diff --git a/vm/devices/net/vmswitch/src/dio.rs b/vm/devices/net/vmswitch/src/dio.rs index d2b590fc02..7e95688b3e 100644 --- a/vm/devices/net/vmswitch/src/dio.rs +++ b/vm/devices/net/vmswitch/src/dio.rs @@ -32,10 +32,11 @@ use winapi::um::fileapi::WriteFile; use winapi::um::ioapiset::CancelIo; use winapi::um::synchapi::WaitForSingleObject; use winapi::um::winbase::INFINITE; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const MINIMUM_FRAME_SIZE: usize = 60; pub const FRAME_SIZE: usize = 1514; @@ -65,7 +66,7 @@ struct QueueState { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct DioNicPacketHeader { len: u32, next: u32, @@ -227,7 +228,7 @@ impl DioQueue { let (buf_index, offset) = self.state.in_next_full; let buf = &self.state.in_buf[buf_index][offset..]; - let (header, data) = DioNicPacketHeader::read_from_prefix_split(buf).unwrap(); + let (header, data) = DioNicPacketHeader::read_from_prefix(buf).unwrap(); // TODO: zerocopy: unwrap let len = header.len as usize; let r = f(&data[..len]); if header.next != 0 { diff --git a/vm/devices/pci/pci_bus/Cargo.toml b/vm/devices/pci/pci_bus/Cargo.toml index 5e6a93feb1..b4aa12701e 100644 --- a/vm/devices/pci/pci_bus/Cargo.toml +++ b/vm/devices/pci/pci_bus/Cargo.toml @@ -18,6 +18,5 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/pci/pci_bus/src/lib.rs b/vm/devices/pci/pci_bus/src/lib.rs index 86e1adc250..ad49ffd7b8 100644 --- a/vm/devices/pci/pci_bus/src/lib.rs +++ b/vm/devices/pci/pci_bus/src/lib.rs @@ -36,8 +36,8 @@ use std::sync::Arc; use std::task::Context; use std::task::Poll; use vmcore::device_state::ChangeDeviceState; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Standard x86 IO ports associated with PCI #[expect(missing_docs)] // self explanatory constants @@ -443,7 +443,7 @@ impl PortIoIntercept for GenericPciBus { let new_value = { let mut temp: u32 = 0; - temp.as_bytes_mut()[..data.len()].copy_from_slice(data); + temp.as_mut_bytes()[..data.len()].copy_from_slice(data); temp }; @@ -545,7 +545,7 @@ impl PollDevice for GenericPciBus { address, } => { let mut buf = 0; - if let Poll::Ready(res) = deferred_device_read.poll_read(cx, buf.as_bytes_mut()) + if let Poll::Ready(res) = deferred_device_read.poll_read(cx, buf.as_mut_bytes()) { let value = match res { Ok(()) => buf, @@ -575,7 +575,7 @@ impl PollDevice for GenericPciBus { address, } => { let mut buf = 0; - if let Poll::Ready(res) = deferred_device_read.poll_read(cx, buf.as_bytes_mut()) + if let Poll::Ready(res) = deferred_device_read.poll_read(cx, buf.as_mut_bytes()) { let old_value = match res { Ok(()) => buf, diff --git a/vm/devices/pci/pci_core/Cargo.toml b/vm/devices/pci/pci_core/Cargo.toml index 99380fbc2d..196b004f95 100644 --- a/vm/devices/pci/pci_core/Cargo.toml +++ b/vm/devices/pci/pci_core/Cargo.toml @@ -20,6 +20,5 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/pci/pci_core/src/capabilities/read_only.rs b/vm/devices/pci/pci_core/src/capabilities/read_only.rs index 43b798dcc6..6ec731e379 100644 --- a/vm/devices/pci/pci_core/src/capabilities/read_only.rs +++ b/vm/devices/pci/pci_core/src/capabilities/read_only.rs @@ -6,16 +6,18 @@ use super::PciCapability; use inspect::Inspect; use std::fmt::Debug; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; -/// Helper to define a read-only [`PciCapability`] from an [`AsBytes`] type. +/// Helper to define a read-only [`PciCapability`] from an [`IntoBytes`] type. #[derive(Debug)] pub struct ReadOnlyCapability { label: String, data: T, } -impl ReadOnlyCapability { +impl ReadOnlyCapability { /// Create a new [`ReadOnlyCapability`] pub fn new(label: impl Into, data: T) -> Self { Self { @@ -35,7 +37,7 @@ impl Inspect for ReadOnlyCapability { impl PciCapability for ReadOnlyCapability where - T: AsBytes + Send + Sync + Debug, + T: IntoBytes + Send + Sync + Debug + Immutable + KnownLayout, { fn label(&self) -> &str { &self.label diff --git a/vm/devices/pci/pci_core/src/spec.rs b/vm/devices/pci/pci_core/src/spec.rs index f46eb0c19f..c1082aacbc 100644 --- a/vm/devices/pci/pci_core/src/spec.rs +++ b/vm/devices/pci/pci_core/src/spec.rs @@ -188,9 +188,10 @@ pub mod hwid { pub mod cfg_space { use bitfield_struct::bitfield; use inspect::Inspect; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; open_enum::open_enum! { /// Offsets into the type 00h configuration space header. @@ -261,7 +262,7 @@ pub mod cfg_space { /// Command Register #[derive(Inspect)] #[bitfield(u16)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Command { pub pio_enabled: bool, pub mmio_enabled: bool, @@ -282,7 +283,7 @@ pub mod cfg_space { /// Status Register #[bitfield(u16)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Status { #[bits(3)] _reserved: u16, diff --git a/vm/devices/pci/vpci/Cargo.toml b/vm/devices/pci/vpci/Cargo.toml index 36fc48646f..25eaf43cae 100644 --- a/vm/devices/pci/vpci/Cargo.toml +++ b/vm/devices/pci/vpci/Cargo.toml @@ -37,6 +37,5 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/pci/vpci/src/device.rs b/vm/devices/pci/vpci/src/device.rs index 34a8d56d3f..de63739b77 100644 --- a/vm/devices/pci/vpci/src/device.rs +++ b/vm/devices/pci/vpci/src/device.rs @@ -43,9 +43,11 @@ use vmcore::vpci_msi::MsiAddressData; use vmcore::vpci_msi::RegisterInterruptError; use vmcore::vpci_msi::VpciInterruptMapper; use vmcore::vpci_msi::VpciInterruptParameters; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Ref; const PCI_MAX_MSI_VECTOR_COUNT: u16 = 32; @@ -85,7 +87,7 @@ impl MmioResource { let len = self.len; let mut flags = protocol::ResourceFlags::new(); let (resource_type, shift) = if len == 0 { - return FromZeroes::new_zeroed(); + return FromZeros::new_zeroed(); } else if len < 1 << 32 { (protocol::ResourceType::MEMORY, 0) } else if len < 1 << 40 { @@ -260,19 +262,20 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { - let (msg, rest) = Ref::<_, protocol::DeviceTranslate>::new_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("translate"))?; + let (msg, rest) = Ref::<_, protocol::DeviceTranslate>::from_prefix(buf) + .map_err(|_| PacketError::PacketTooSmall("translate"))?; // todo: zerocopy: map_err if msg.msi_resource_count > protocol::MAX_SUPPORTED_INTERRUPT_MESSAGES { return Err(PacketError::TooManyMsis(msg.msi_resource_count)); @@ -287,20 +290,23 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result ( AssignedResourcesReplyType::V1, - protocol::MsiResource::slice_from_prefix(rest, msg.msi_resource_count as usize) - .ok_or(PacketError::PacketTooSmall("msi"))? - .0 - .iter() - .map(|rsrc| InterruptResourceRequest::from_protocol(rsrc.descriptor())) - .collect::, _>>()?, + <[protocol::MsiResource]>::ref_from_prefix_with_elems( + rest, + msg.msi_resource_count as usize, + ) + .map_err(|_| PacketError::PacketTooSmall("msi"))? // todo: zerocopy: map_err + .0 + .iter() + .map(|rsrc| InterruptResourceRequest::from_protocol(rsrc.descriptor())) + .collect::, _>>()?, ), protocol::MessageType::ASSIGNED_RESOURCES2 => ( AssignedResourcesReplyType::V2, - protocol::MsiResource2::slice_from_prefix( + <[protocol::MsiResource2]>::ref_from_prefix_with_elems( rest, msg.msi_resource_count as usize, ) - .ok_or(PacketError::PacketTooSmall("msi2"))? + .map_err(|_| PacketError::PacketTooSmall("msi2"))? // todo: zerocopy: map_err .0 .iter() .map(|rsrc| InterruptResourceRequest::from_protocol2(rsrc.descriptor())) @@ -322,7 +328,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::PdoMessage::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("release"))?; + .map_err(|_| PacketError::PacketTooSmall("release"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, @@ -331,7 +338,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::CreateInterrupt::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("interrupt"))?; + .map_err(|_| PacketError::PacketTooSmall("interrupt"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::CreateInterrupt { @@ -341,7 +349,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::CreateInterrupt2::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("interrupt2"))?; + .map_err(|_| PacketError::PacketTooSmall("interrupt2"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::CreateInterrupt { @@ -351,7 +360,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::DeleteInterrupt::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("delete_interrupt"))?; + .map_err(|_| PacketError::PacketTooSmall("delete_interrupt"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::DeleteInterrupt { @@ -361,7 +371,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::QueryResourceRequirements::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("query_req"))?; + .map_err(|_| PacketError::PacketTooSmall("query_req"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::QueryResources, @@ -369,7 +380,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::GetResources::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("get_resources"))?; + .map_err(|_| PacketError::PacketTooSmall("get_resources"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::GetResources, @@ -377,7 +389,8 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::FdoD0Entry::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("power_on"))?; + .map_err(|_| PacketError::PacketTooSmall("power_on"))? + .0; // todo: zerocopy: map_err PacketData::FdoD0Entry { mmio_start: msg.mmio_start, } @@ -386,14 +399,16 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result PacketData::QueryRelations, protocol::MessageType::QUERY_PROTOCOL_VERSION => { let msg = protocol::QueryProtocolVersion::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("query_version"))?; + .map_err(|_| PacketError::PacketTooSmall("query_version"))? + .0; // todo: zerocopy: map_err PacketData::QueryProtocolVersion { version: msg.protocol_version, } } protocol::MessageType::DEVICE_POWER_STATE_CHANGE => { let msg = protocol::DevicePowerChange::read_from_prefix(buf) - .ok_or(PacketError::PacketTooSmall("device_power_state"))?; + .map_err(|_| PacketError::PacketTooSmall("device_power_state"))? + .0; // todo: zerocopy: map_err PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::DevicePowerChange { @@ -421,7 +436,10 @@ enum WorkerError { } impl Connection { - async fn send_packet(&mut self, payload: &P) -> Result<(), WorkerError> { + async fn send_packet( + &mut self, + payload: &P, + ) -> Result<(), WorkerError> { tracing::trace!(?payload, "send packet"); self.queue .split() @@ -442,7 +460,7 @@ impl Connection { write.wait_ready(len).await.map_err(WorkerError::Queue) } - fn send_completion( + fn send_completion( &mut self, transaction_id: Option, payload: &P, @@ -719,7 +737,7 @@ impl ReadyState { conn.send_completion(transaction_id, &protocol::Status::SUCCESS, &[])?; } DeviceRequest::CreateInterrupt { interrupt } => { - let mut resource = FromZeroes::new_zeroed(); + let mut resource = FromZeros::new_zeroed(); dev.map_interrupts(&[interrupt], &mut |r| resource = r)?; conn.send_completion( transaction_id, @@ -1197,9 +1215,12 @@ mod tests { use vmbus_async::queue::Queue; use vmbus_ring as ring; use vmcore::vpci_msi::VpciInterruptMapper; - use zerocopy::AsBytes; use zerocopy::FromBytes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; + enum ReadPacketInfo { None, NewTransaction, @@ -1268,7 +1289,7 @@ mod tests { } } - async fn read_packet( + async fn read_packet( &mut self, pkt_info: &mut ReadPacketInfo, ) -> Result { @@ -1291,7 +1312,7 @@ mod tests { } } - async fn write_packet( + async fn write_packet( &mut self, transaction_id: Option, payload: &T, diff --git a/vm/devices/pci/vpci/src/protocol.rs b/vm/devices/pci/vpci/src/protocol.rs index 9de9b48f12..c82ae418c9 100644 --- a/vm/devices/pci/vpci/src/protocol.rs +++ b/vm/devices/pci/vpci/src/protocol.rs @@ -6,9 +6,11 @@ use bitfield_struct::bitfield; use guid::Guid; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::NativeEndian; use zerocopy::U64; @@ -21,7 +23,7 @@ pub const MMIO_PAGE_CONFIG_SPACE: u64 = 0x1000; pub const MMIO_PAGE_MASK: u64 = !0xfff; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum MessageType: u32 { BUS_RELATIONS = 0x42490000, QUERY_BUS_RELATIONS = 0x42490001, @@ -53,7 +55,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum ResourceType: u8 { NULL = 0, PORT = 1, @@ -70,7 +72,7 @@ pub const GUID_VPCI_VSP_CHANNEL_TYPE: Guid = Guid::from_static_str("44C4F61D-4444-4400-9D52-802E27EDE19F"); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum ProtocolVersion: u32 { WIN8 = 0x00010000, WIN10 = 0x00010001, @@ -83,14 +85,14 @@ pub const MAXIMUM_PACKET_SIZE: usize = size_of::() + size_of::() * MAX_SUPPORTED_INTERRUPT_MESSAGES as usize; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryProtocolVersion { pub message_type: MessageType, pub protocol_version: ProtocolVersion, } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum Status: u32 { SUCCESS = 0, REVISION_MISMATCH = 0xC0000059, @@ -99,14 +101,14 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryProtocolVersionReply { pub status: Status, pub protocol_version: ProtocolVersion, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PnpId { pub vendor_id: u16, pub device_id: u16, @@ -119,7 +121,7 @@ pub struct PnpId { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeviceDescription { pub pnp_id: PnpId, pub slot: SlotNumber, @@ -127,7 +129,7 @@ pub struct DeviceDescription { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryBusRelations { pub message_type: MessageType, pub device_count: u32, @@ -135,7 +137,7 @@ pub struct QueryBusRelations { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeviceDescription2 { pub pnp_id: PnpId, pub slot: SlotNumber, @@ -146,7 +148,7 @@ pub struct DeviceDescription2 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryBusRelations2 { pub message_type: MessageType, pub device_count: u32, @@ -154,7 +156,7 @@ pub struct QueryBusRelations2 { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SlotNumber { #[bits(5)] pub device: u8, @@ -165,21 +167,21 @@ pub struct SlotNumber { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryResourceRequirements { pub message_type: MessageType, pub slot: SlotNumber, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueryResourceRequirementsReply { pub status: Status, pub bars: [u32; 6], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetResources { pub message_type: MessageType, pub slot: SlotNumber, @@ -187,7 +189,7 @@ pub struct GetResources { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PartialResourceList { pub version: u16, pub revision: u16, @@ -196,7 +198,7 @@ pub struct PartialResourceList { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ResourceFlags { #[bits(9)] pub reserved: u16, @@ -208,7 +210,7 @@ pub struct ResourceFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FdoD0Entry { pub message_type: MessageType, pub padding: u32, @@ -216,7 +218,7 @@ pub struct FdoD0Entry { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PartialResourceDescriptor { pub resource_type: ResourceType, pub share_disposition: u8, @@ -228,14 +230,14 @@ pub struct PartialResourceDescriptor { // < VPCI_PROTOCOL_VERSION_RS1 #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResource { // union of Descriptor (request) and remap (response) pub resource_data: [u64; 2], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResourceRemapped { pub reserved: u16, pub message_count: u16, @@ -244,7 +246,7 @@ pub struct MsiResourceRemapped { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResourceDescriptor { pub vector: u8, pub delivery_mode: u8, @@ -254,7 +256,7 @@ pub struct MsiResourceDescriptor { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResourceDescriptor2 { pub vector: u8, pub delivery_mode: u8, @@ -265,7 +267,7 @@ pub struct MsiResourceDescriptor2 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResourceDescriptor3 { pub vector: u32, pub delivery_mode: u8, @@ -294,25 +296,33 @@ impl From for MsiResource { impl MsiResource { pub fn remapped(&self) -> &MsiResourceRemapped { - MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { - MsiResourceRemapped::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range pub fn descriptor(&self) -> &MsiResourceDescriptor { - MsiResourceDescriptor::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceDescriptor::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor { - MsiResourceDescriptor::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceDescriptor::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range } // >= VPCI_PROTOCOL_VERSION_RS1 #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResource2 { // union of Descriptor (request) and remap (response) pub resource_data: [u64; 9], @@ -336,24 +346,32 @@ impl From for MsiResource2 { impl MsiResource2 { pub fn remapped(&self) -> &MsiResourceRemapped { - MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { - MsiResourceRemapped::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range pub fn descriptor(&self) -> &MsiResourceDescriptor2 { - MsiResourceDescriptor2::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceDescriptor2::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor2 { - MsiResourceDescriptor2::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceDescriptor2::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsiResource3 { // union of Descriptor (request) and remap (response) pub resource_data: [u64; 10], @@ -377,26 +395,34 @@ impl From for MsiResource3 { impl MsiResource3 { pub fn remapped(&self) -> &MsiResourceRemapped { - MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { - MsiResourceRemapped::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range pub fn descriptor(&self) -> &MsiResourceDescriptor3 { - MsiResourceDescriptor3::ref_from_prefix(self.resource_data.as_bytes()).unwrap() + MsiResourceDescriptor3::ref_from_prefix(self.resource_data.as_bytes()) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor3 { - MsiResourceDescriptor3::mut_from_prefix(self.resource_data.as_bytes_mut()).unwrap() - } + MsiResourceDescriptor3::mut_from_prefix(self.resource_data.as_mut_bytes()) + .unwrap() + .0 + } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range } pub const MAX_SUPPORTED_INTERRUPT_MESSAGES: u32 = 494; // 500 resources minus 6 for the BARs. #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeviceTranslate { pub message_type: MessageType, pub slot: SlotNumber, @@ -407,7 +433,7 @@ pub struct DeviceTranslate { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeviceTranslateReply { pub status: Status, pub slot: SlotNumber, @@ -418,7 +444,7 @@ pub struct DeviceTranslateReply { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CreateInterrupt { pub message_type: MessageType, pub slot: SlotNumber, @@ -426,7 +452,7 @@ pub struct CreateInterrupt { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CreateInterruptReply { pub status: Status, pub rsvd: u32, @@ -434,7 +460,7 @@ pub struct CreateInterruptReply { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CreateInterrupt2 { pub message_type: MessageType, pub slot: SlotNumber, @@ -442,7 +468,7 @@ pub struct CreateInterrupt2 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeleteInterrupt { pub message_type: MessageType, pub slot: SlotNumber, @@ -450,7 +476,7 @@ pub struct DeleteInterrupt { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DevicePowerChange { pub message_type: MessageType, pub slot: SlotNumber, @@ -458,7 +484,7 @@ pub struct DevicePowerChange { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum DevicePowerState: u32 { D0 = 1, D3 = 4, @@ -466,7 +492,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PdoMessage { pub message_type: MessageType, pub slot: SlotNumber, diff --git a/vm/devices/serial/vmbus_serial_guest/Cargo.toml b/vm/devices/serial/vmbus_serial_guest/Cargo.toml index d573279731..c69a7b6a6b 100644 --- a/vm/devices/serial/vmbus_serial_guest/Cargo.toml +++ b/vm/devices/serial/vmbus_serial_guest/Cargo.toml @@ -21,7 +21,6 @@ futures.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(unix)'.dependencies] anyhow.workspace = true async-trait.workspace = true diff --git a/vm/devices/serial/vmbus_serial_guest/src/lib.rs b/vm/devices/serial/vmbus_serial_guest/src/lib.rs index 44e68cf527..f03ee553d5 100644 --- a/vm/devices/serial/vmbus_serial_guest/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_guest/src/lib.rs @@ -44,8 +44,8 @@ use vmbus_async::async_dgram::AsyncRecvExt; use vmbus_async::async_dgram::AsyncSend; use vmbus_async::async_dgram::AsyncSendExt; use vmbus_serial_protocol as protocol; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// Configuration for an open vmbus serial port resource. #[derive(MeshPayload)] @@ -226,7 +226,8 @@ impl VmbusSerialDriver { let mut buf = [0; MAX_MESSAGE_SIZE]; let n = self.pipe.as_mut().recv(&mut buf).await?; let response = protocol::VersionRequestResponse::read_from_prefix(&buf[..n]) - .ok_or(ErrorInner::TruncatedMessage)?; + .map_err(|_| ErrorInner::TruncatedMessage)? + .0; // todo: zerocopy: map_err let host_response = response .header @@ -302,7 +303,9 @@ impl VmbusSerialDriver { } fn handle_message(&mut self, buf: &[u8]) -> Result<(), ErrorInner> { - let header = protocol::Header::read_from_prefix(buf).ok_or(ErrorInner::TruncatedMessage)?; + let header = protocol::Header::read_from_prefix(buf) + .map_err(|_| ErrorInner::TruncatedMessage)? + .0; // todo: zerocopy: map_err if header.message_version != MessageVersions::HEADER_VERSION_1 { return Err(ErrorInner::InvalidMessageVersion(header.message_version)); } @@ -310,7 +313,8 @@ impl VmbusSerialDriver { match req { HostRequests::GET_RX_DATA => { let response = protocol::RxDataResponse::read_from_prefix(buf) - .ok_or(ErrorInner::TruncatedMessage)?; + .map_err(|_| ErrorInner::TruncatedMessage)? + .0; // todo: zerocopy: map_err let b = response .buffer @@ -334,7 +338,8 @@ impl VmbusSerialDriver { GuestNotifications::RX_DATA_AVAILABLE => self.rx_avail = true, GuestNotifications::SET_MODEM_STATUS => { let status = protocol::SetModumStatusMessage::read_from_prefix(buf) - .ok_or(ErrorInner::TruncatedMessage)?; + .map_err(|_| ErrorInner::TruncatedMessage)? + .0; // todo: zerocopy: map_err self.connected = status.is_connected != 0; } @@ -454,7 +459,7 @@ mod tests { use vmbus_serial_host::Serial; use vmbus_serial_host::SerialChannel; use vmbus_serial_protocol::*; - use zerocopy::AsBytes; + use zerocopy::IntoBytes; #[async_test] async fn test_version_negotiation_failed(driver: DefaultDriver) { @@ -463,7 +468,7 @@ mod tests { let host_task = driver.spawn("test", async move { let mut version_request = VersionRequestMessage::default(); let len = host_vmbus - .recv(version_request.as_bytes_mut()) + .recv(version_request.as_mut_bytes()) .await .unwrap(); diff --git a/vm/devices/serial/vmbus_serial_host/Cargo.toml b/vm/devices/serial/vmbus_serial_host/Cargo.toml index 403d46c002..2acb68fc0e 100644 --- a/vm/devices/serial/vmbus_serial_host/Cargo.toml +++ b/vm/devices/serial/vmbus_serial_host/Cargo.toml @@ -26,6 +26,5 @@ async-trait.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/serial/vmbus_serial_host/src/lib.rs b/vm/devices/serial/vmbus_serial_host/src/lib.rs index 6b84929b7c..45d65b95b1 100644 --- a/vm/devices/serial/vmbus_serial_host/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_host/src/lib.rs @@ -37,8 +37,10 @@ use vmbus_channel::RawAsyncChannel; use vmbus_ring::RingMem; use vmbus_serial_protocol as protocol; use vmcore::save_restore::SavedStateNotSupported; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// The error type returned by the serial device. #[derive(Debug, Error)] @@ -241,7 +243,7 @@ impl SerialChannel { async fn process_init(&mut self) -> Result<(), Error> { // Negotiate transport version with the client. let mut version_request = protocol::VersionRequestMessage::default(); - self.read_pipe(version_request.as_bytes_mut()).await?; + self.read_pipe(version_request.as_mut_bytes()).await?; tracing::trace!(?version_request); if version_request.header != protocol::Header::new_host_request(HostRequests::VERSION) { @@ -349,7 +351,10 @@ impl SerialChannel { } /// Writes to the pipe. The caller must guarantee that there is enough space. - fn write_pipe(&mut self, message: impl AsBytes) -> Result<(), Error> { + fn write_pipe( + &mut self, + message: impl IntoBytes + Immutable + KnownLayout, + ) -> Result<(), Error> { self.channel .try_send(message.as_bytes()) .map_err(Error::Io)?; @@ -365,8 +370,9 @@ impl SerialChannel { tracing::trace!(len = buf.len(), "read message len"); // Extract header from read buf. - let header = - protocol::Header::read_from_prefix(buf).ok_or(Error::MessageSizeHeader(buf.len()))?; + let header = protocol::Header::read_from_prefix(buf) + .map_err(|_| Error::MessageSizeHeader(buf.len()))? + .0; // todo: zerocopy: map_err tracing::trace!("read header {:?}", &header); @@ -407,12 +413,15 @@ impl SerialChannel { todo!("clear rx buffer unimplemented") } HostNotifications::TX_DATA_AVAILABLE => { - let message = protocol::TxDataAvailableMessage::read_from_prefix(buf).ok_or( - Error::MessageSizeHostNotification { - len: buf.len(), - notification, - }, - )?; + let message = protocol::TxDataAvailableMessage::read_from_prefix(buf) + .map_err(|_| { + // todo: zerocopy: map_err + Error::MessageSizeHostNotification { + len: buf.len(), + notification, + } + })? + .0; if self.state.tx_pending { return Err(Error::TxInFlight); diff --git a/vm/devices/serial/vmbus_serial_protocol/Cargo.toml b/vm/devices/serial/vmbus_serial_protocol/Cargo.toml index 4b2806e892..3f65e56afe 100644 --- a/vm/devices/serial/vmbus_serial_protocol/Cargo.toml +++ b/vm/devices/serial/vmbus_serial_protocol/Cargo.toml @@ -12,6 +12,5 @@ open_enum.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/serial/vmbus_serial_protocol/src/lib.rs b/vm/devices/serial/vmbus_serial_protocol/src/lib.rs index 8ee1cb28d3..91bbe94f3b 100644 --- a/vm/devices/serial/vmbus_serial_protocol/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_protocol/src/lib.rs @@ -9,9 +9,11 @@ use core::fmt::Debug; use guid::Guid; use open_enum::open_enum; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Maximum message size for all messages. pub const MAX_MESSAGE_SIZE: usize = 512; @@ -46,7 +48,7 @@ const fn make_version(major: u16, minor: u16) -> u32 { open_enum! { /// Protocol versions. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum ProtocolVersions: u32 { /// Represents the MANGANESE protocol version. MANGANESE = make_version(1, 0), @@ -55,7 +57,7 @@ open_enum! { open_enum! { /// Header message versions. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum MessageVersions: u8 { /// Invalid version. INVALID = 0, @@ -66,7 +68,7 @@ open_enum! { open_enum! { /// Enum for the different message types. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum MessageTypes: u8 { /// Invalid message type. INVALID = 0, @@ -84,7 +86,7 @@ open_enum! { open_enum! { /// Enum for the different host notification messages. /// These are aysynchronous messages sent by the HCL to the Host. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HostNotifications: u8 { /// Invalid message. INVALID = 0, @@ -98,7 +100,7 @@ open_enum! { open_enum! { /// Enum for the different guest notification messages. /// These are asynchronous messages sent by the Host to the HCL. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum GuestNotifications: u8 { /// Invalid message. INVALID = 0, @@ -117,7 +119,7 @@ open_enum! { /// These are synchronous messages sent by the HCL to the host. /// Note that the host response shares the same enum. /// (Each request has a response of the same ID) - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HostRequests: u16 { /// Invalid message. INVALID = 0, @@ -147,7 +149,7 @@ open_enum! { /// currently unused for anything, just have a wrapper struct with accessor methods for /// individual field types. #[repr(transparent)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct MessageId(pub u16); impl Debug for MessageId { @@ -189,7 +191,7 @@ impl MessageId { /// A protocol message header. #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct Header { /// The message version. pub message_version: MessageVersions, @@ -320,7 +322,7 @@ pub const UART_MSG_MAX_PAYLOAD: usize = 64; /// Host notification message that TX data is available. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TxDataAvailableMessage { /// The message header. pub header: Header, @@ -349,7 +351,7 @@ const_assert_eq!(70, size_of::()); /// Guest notification that the connection state of the serial port has changed. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetModumStatusMessage { /// The message header. pub header: Header, @@ -365,7 +367,7 @@ const_assert_eq!(6, size_of::()); /// A version negotiation request sent from the guest to host. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionRequestMessage { /// The message header. pub header: Header, @@ -386,7 +388,7 @@ const_assert_eq!(8, size_of::()); /// A version negotiation response sent from host to guest. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionRequestResponse { /// The message header. pub header: Header, @@ -400,7 +402,7 @@ const_assert_eq!(6, size_of::()); /// A response to an RX Data host request message that contains RX data. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RxDataResponse { /// The message header. pub header: Header, diff --git a/vm/devices/storage/disk_blob/Cargo.toml b/vm/devices/storage/disk_blob/Cargo.toml index 1f17017841..5eb5ca794a 100644 --- a/vm/devices/storage/disk_blob/Cargo.toml +++ b/vm/devices/storage/disk_blob/Cargo.toml @@ -28,7 +28,6 @@ hyper-util = { workspace = true, features = ["client", "client-legacy", "http1", once_cell.workspace = true thiserror.workspace = true zerocopy.workspace = true - # tokio use is allowed in this crate only. # FUTURE: replace this with our own executor tokio = { version = "1", features = ["rt-multi-thread"] } diff --git a/vm/devices/storage/disk_blob/src/lib.rs b/vm/devices/storage/disk_blob/src/lib.rs index 9152a52a6e..ed825517f4 100644 --- a/vm/devices/storage/disk_blob/src/lib.rs +++ b/vm/devices/storage/disk_blob/src/lib.rs @@ -20,8 +20,8 @@ use scsi_buffers::RequestBuffers; use std::sync::Arc; use thiserror::Error; use vhd1_defs::VhdFooter; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const DEFAULT_SECTOR_SIZE: u32 = 512; @@ -75,7 +75,7 @@ impl BlobDisk { .ok_or(ErrorInner::BlobTooSmall)?; let mut footer = VhdFooter::new_zeroed(); - blob.read(footer.as_bytes_mut(), footer_offset) + blob.read(footer.as_mut_bytes(), footer_offset) .await .map_err(ErrorInner::VhdFooter)?; diff --git a/vm/devices/storage/disk_blockdevice/src/ioctl.rs b/vm/devices/storage/disk_blockdevice/src/ioctl.rs index 4b8ba2ea78..57a9219cf4 100644 --- a/vm/devices/storage/disk_blockdevice/src/ioctl.rs +++ b/vm/devices/storage/disk_blockdevice/src/ioctl.rs @@ -14,9 +14,10 @@ use nix::request_code_none; use open_enum::open_enum; use std::fs; use std::os::unix::prelude::*; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Linux block device IOCTLs. const BLK_IOC_MAGIC: u8 = 0x12; @@ -46,7 +47,7 @@ ioctl_none_bad!(blk_eject_ioctl, 0x5309); ioctl_write_int_bad!(blk_lockdoor_ioctl, 0x5329); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] enum BlkStatus: u8 { BLK_STS_OK = 0, BLK_STS_NOTSUPP = 1, diff --git a/vm/devices/storage/disk_blockdevice/src/nvme.rs b/vm/devices/storage/disk_blockdevice/src/nvme.rs index 4260c65866..e841740516 100644 --- a/vm/devices/storage/disk_blockdevice/src/nvme.rs +++ b/vm/devices/storage/disk_blockdevice/src/nvme.rs @@ -13,9 +13,10 @@ use nvme_spec::nvm; use std::fs; use std::io; use std::os::unix::io::AsRawFd; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; mod ioctl { use nix::ioctl_readwrite; @@ -76,7 +77,7 @@ enum Opcode { fn nvme_command( file: &fs::File, opcode: Opcode, - data: &mut (impl AsBytes + FromBytes + ?Sized), + data: &mut (impl IntoBytes + FromBytes + ?Sized + Immutable + KnownLayout), command: &NvmeCommand, ) -> io::Result { let mut cmd = ioctl::NvmeCmd { @@ -89,9 +90,9 @@ fn nvme_command( cdw2: command.cdw2, cdw3: command.cdw3, metadata: 0, - addr: data.as_bytes_mut().as_mut_ptr() as u64, + addr: data.as_mut_bytes().as_mut_ptr() as u64, metadata_len: 0, - data_len: data.as_bytes_mut().len() as u32, + data_len: data.as_mut_bytes().len() as u32, cdw10: command.cdw10, cdw11: command.cdw11, cdw12: command.cdw12, @@ -119,7 +120,7 @@ fn nvme_command( const PAGE_SIZE: usize = 4096; #[repr(C, align(4096))] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] struct Page([u8; PAGE_SIZE]); const ZERO_PAGE: Page = Page([0; PAGE_SIZE]); @@ -178,7 +179,7 @@ fn nvme_reservation_report( // One page should be good enough for most cases. Just in case let caller set bigger buffer size. let size = std::cmp::max(size, PAGE_SIZE); let mut buffer = vec![ZERO_PAGE; size.div_ceil(PAGE_SIZE)]; - let buffer = &mut buffer.as_bytes_mut()[..size]; + let buffer = &mut buffer.as_mut_bytes()[..size]; let cmd = NvmeCommand { ns_id, cdw10: nvm::Cdw10ReservationReport::new() @@ -194,7 +195,9 @@ fn nvme_reservation_report( &cmd, )?; - let report_header = nvm::ReservationReportExtended::read_from_prefix(&*buffer).unwrap(); + let report_header = nvm::ReservationReportExtended::read_from_prefix(&*buffer) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let mut controllers = Vec::new(); // Return all controllers or none so caller can set correct buffer size and call again @@ -207,7 +210,9 @@ fn nvme_reservation_report( if source + controller_count * source_step <= size { for _i in 0..controller_count { let controller = - nvm::RegisteredControllerExtended::read_from_prefix(&buffer[source..]).unwrap(); + nvm::RegisteredControllerExtended::read_from_prefix(&buffer[source..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range tracing::debug!(controller = ?controller, "nvme_reservation_report"); controllers.push(controller); source += source_step; @@ -247,7 +252,7 @@ pub fn nvme_identify_namespace_data( ) -> io::Result { let size = size_of::(); let mut buffer = vec![ZERO_PAGE; size.div_ceil(PAGE_SIZE)]; - let buffer = &mut buffer.as_bytes_mut()[..size]; + let buffer = &mut buffer.as_mut_bytes()[..size]; let cmd = NvmeCommand { ns_id, cdw10: nvme_spec::Cdw10Identify::new() @@ -263,7 +268,7 @@ pub fn nvme_identify_namespace_data( &cmd, )?; - let data = nvm::IdentifyNamespace::read_from_prefix(buffer).unwrap(); + let data = nvm::IdentifyNamespace::read_from_prefix(buffer).unwrap().0; // todo: zerocopy: use-rest-of-range tracing::trace!(?data, "nvme_identify_namespace_data"); Ok(data) } @@ -271,7 +276,7 @@ pub fn nvme_identify_namespace_data( pub fn nvme_identify_controller_data(file: &fs::File) -> io::Result { let size = size_of::(); let mut buffer = vec![ZERO_PAGE; size.div_ceil(PAGE_SIZE)]; - let buffer = &mut buffer.as_bytes_mut()[..size]; + let buffer = &mut buffer.as_mut_bytes()[..size]; let cmd = NvmeCommand { cdw10: nvme_spec::Cdw10Identify::new() .with_cns(nvme_spec::Cns::CONTROLLER.0) @@ -286,7 +291,9 @@ pub fn nvme_identify_controller_data(file: &fs::File) -> io::Result NvmeDriver { .into(), ..admin_cmd(spec::AdminOpcode::IDENTIFY) }, - Arc::get_mut(identify).unwrap().as_bytes_mut(), + Arc::get_mut(identify).unwrap().as_mut_bytes(), ) .await .context("failed to identify controller")?; @@ -522,7 +522,7 @@ impl NvmeDriver { // s.namespaces.push(ns.save()?); // } Ok(NvmeDriverSavedState { - identify_ctrl: spec::IdentifyController::read_from( + identify_ctrl: spec::IdentifyController::read_from_bytes( self.identify.as_ref().unwrap().as_bytes(), ) .unwrap(), @@ -575,8 +575,8 @@ impl NvmeDriver { })), admin: None, // Updated below. identify: Some(Arc::new( - spec::IdentifyController::read_from(saved_state.identify_ctrl.as_bytes()) - .ok_or(RestoreError::InvalidData)?, + spec::IdentifyController::read_from_bytes(saved_state.identify_ctrl.as_bytes()) + .map_err(|_| RestoreError::InvalidData)?, // todo: zerocopy: map_err )), driver: driver.clone(), io_issuers, @@ -711,7 +711,7 @@ async fn handle_asynchronous_events( .into(), ..admin_cmd(spec::AdminOpcode::GET_LOG_PAGE) }, - list.as_bytes_mut(), + list.as_mut_bytes(), ) .await .context("failed to query changed namespace list")?; diff --git a/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs b/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs index 150c734919..1724cfceb9 100644 --- a/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs +++ b/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs @@ -23,9 +23,9 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use thiserror::Error; use vmcore::vm_task::VmTaskDriver; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// An error getting a namespace. #[derive(Debug, Error)] @@ -404,7 +404,9 @@ impl Namespace { ) .await?; - let header = nvm::ReservationReportExtended::read_from_prefix(&data[..]).unwrap(); + let header = nvm::ReservationReportExtended::read_from_prefix(&data[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let len = size_of_val(&header) + header.report.regctl.get() as usize * size_of::(); @@ -420,7 +422,7 @@ impl Namespace { ]; controllers - .as_bytes_mut() + .as_mut_bytes() .copy_from_slice(&data[size_of_val(&header)..len]); break Ok((header, controllers)); @@ -623,7 +625,7 @@ async fn identify_namespace( .into(), ..admin_cmd(spec::AdminOpcode::IDENTIFY) }, - identify.as_bytes_mut(), + identify.as_mut_bytes(), ) .await?; Ok(identify) @@ -633,6 +635,6 @@ fn nvm_cmd(opcode: nvm::NvmOpcode, nsid: u32) -> spec::Command { spec::Command { cdw0: spec::Cdw0::new().with_opcode(opcode.0), nsid, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } diff --git a/vm/devices/storage/disk_nvme/nvme_driver/src/queue_pair.rs b/vm/devices/storage/disk_nvme/nvme_driver/src/queue_pair.rs index ed383c62a9..7a23f9b483 100644 --- a/vm/devices/storage/disk_nvme/nvme_driver/src/queue_pair.rs +++ b/vm/devices/storage/disk_nvme/nvme_driver/src/queue_pair.rs @@ -41,7 +41,7 @@ use user_driver::memory::PAGE_SIZE; use user_driver::memory::PAGE_SIZE64; use user_driver::DeviceBacking; use user_driver::HostDmaAllocator; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; /// Value for unused PRP entries, to catch/mitigate buffer size mismatches. const INVALID_PAGE_ADDR: u64 = !(PAGE_SIZE as u64 - 1); @@ -720,6 +720,6 @@ impl QueueHandler { pub(crate) fn admin_cmd(opcode: spec::AdminOpcode) -> spec::Command { spec::Command { cdw0: spec::Cdw0::new().with_opcode(opcode.0), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } diff --git a/vm/devices/storage/disk_nvme/nvme_driver/src/tests.rs b/vm/devices/storage/disk_nvme/nvme_driver/src/tests.rs index b7c0d78257..47dfc8b148 100644 --- a/vm/devices/storage/disk_nvme/nvme_driver/src/tests.rs +++ b/vm/devices/storage/disk_nvme/nvme_driver/src/tests.rs @@ -27,7 +27,7 @@ use user_driver::DeviceBacking; use user_driver::DeviceRegisterIo; use vmcore::vm_task::SingleDriverBackend; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[async_test] async fn test_nvme_driver_direct_dma(driver: DefaultDriver) { @@ -292,7 +292,7 @@ async fn test_nvme_save_restore_inner(driver: DefaultDriver) { // Enable the controller for keep-alive test. let mut dword = 0u32; // Read Register::CC. - new_nvme_ctrl.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + new_nvme_ctrl.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); // Set CC.EN. dword |= 1; new_nvme_ctrl.write_bar0(0x14, dword.as_bytes()).unwrap(); diff --git a/vm/devices/storage/disk_vhd1/Cargo.toml b/vm/devices/storage/disk_vhd1/Cargo.toml index d4069e6387..c58670b724 100644 --- a/vm/devices/storage/disk_vhd1/Cargo.toml +++ b/vm/devices/storage/disk_vhd1/Cargo.toml @@ -20,7 +20,6 @@ inspect.workspace = true pal_async.workspace = true thiserror.workspace = true zerocopy.workspace = true - [dev-dependencies] tempfile.workspace = true diff --git a/vm/devices/storage/disk_vhd1/src/lib.rs b/vm/devices/storage/disk_vhd1/src/lib.rs index b6d4f4128c..6cd7ed3204 100644 --- a/vm/devices/storage/disk_vhd1/src/lib.rs +++ b/vm/devices/storage/disk_vhd1/src/lib.rs @@ -24,8 +24,8 @@ use vhd1_defs::VhdFooter; use vm_resource::declare_static_resolver; use vm_resource::kind::DiskHandleKind; use vm_resource::ResolveResource; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; pub struct Vhd1Resolver; declare_static_resolver!(Vhd1Resolver, (DiskHandleKind, FixedVhd1DiskHandle)); @@ -145,8 +145,8 @@ impl Vhd1Disk { return Err(OpenError::InvalidFileSize(len)); } file.seek(io::SeekFrom::End(-512))?; - let mut footer: VhdFooter = FromZeroes::new_zeroed(); - file.read_exact(footer.as_bytes_mut())?; + let mut footer: VhdFooter = FromZeros::new_zeroed(); + file.read_exact(footer.as_mut_bytes())?; let metadata = Metadata::from_footer(footer, len)?; // Just wrap FileDisk for handling actual IO. @@ -244,7 +244,7 @@ mod tests { use pal_async::async_test; use scsi_buffers::OwnedRequestBuffers; use std::io::Write; - use zerocopy::AsBytes; + use zerocopy::IntoBytes; #[async_test] async fn open_fixed() { @@ -263,7 +263,7 @@ mod tests { ) .await .unwrap(); - mem.read_at(0, buf.as_bytes_mut()).unwrap(); + mem.read_at(0, buf.as_mut_bytes()).unwrap(); assert!(buf.iter().copied().eq(1000_u32 * 128..1001 * 128)); } } diff --git a/vm/devices/storage/disklayer_ram/Cargo.toml b/vm/devices/storage/disklayer_ram/Cargo.toml index 4a8e869a48..f4402a6394 100644 --- a/vm/devices/storage/disklayer_ram/Cargo.toml +++ b/vm/devices/storage/disklayer_ram/Cargo.toml @@ -24,7 +24,6 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] inspect = { workspace = true, features = ["initiate"] } test_with_tracing.workspace = true diff --git a/vm/devices/storage/disklayer_ram/src/lib.rs b/vm/devices/storage/disklayer_ram/src/lib.rs index b1ac647ec9..706cf17dc4 100644 --- a/vm/devices/storage/disklayer_ram/src/lib.rs +++ b/vm/devices/storage/disklayer_ram/src/lib.rs @@ -398,14 +398,14 @@ mod tests { use pal_async::async_test; use scsi_buffers::OwnedRequestBuffers; use test_with_tracing::test; - use zerocopy::AsBytes; + use zerocopy::IntoBytes; const SECTOR_U64: u64 = SECTOR_SIZE as u64; const SECTOR_USIZE: usize = SECTOR_SIZE as usize; fn check(mem: &GuestMemory, sector: u64, start: usize, count: usize, high: u8) { let mut buf = vec![0u32; count * SECTOR_USIZE / 4]; - mem.read_at(start as u64 * SECTOR_U64, buf.as_bytes_mut()) + mem.read_at(start as u64 * SECTOR_U64, buf.as_mut_bytes()) .unwrap(); for (i, &b) in buf.iter().enumerate() { let offset = sector * SECTOR_U64 + i as u64 * 4; diff --git a/vm/devices/storage/ide/Cargo.toml b/vm/devices/storage/ide/Cargo.toml index 1ffb18a252..ba80204183 100644 --- a/vm/devices/storage/ide/Cargo.toml +++ b/vm/devices/storage/ide/Cargo.toml @@ -31,7 +31,6 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] disk_file.workspace = true diff --git a/vm/devices/storage/ide/src/drive/atapi_drive.rs b/vm/devices/storage/ide/src/drive/atapi_drive.rs index 12379a9099..9af8fcaa9b 100644 --- a/vm/devices/storage/ide/src/drive/atapi_drive.rs +++ b/vm/devices/storage/ide/src/drive/atapi_drive.rs @@ -29,8 +29,8 @@ use std::sync::Arc; use std::task::Context; use std::task::Poll; use std::task::Waker; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; // This disk supports 12-byte CDBs. const COMMAND_PACKET_SIZE: usize = 12; @@ -49,8 +49,8 @@ struct Sense { impl Default for Sense { fn default() -> Self { Self { - sense_key: FromZeroes::new_zeroed(), - additional_sense_code: FromZeroes::new_zeroed(), + sense_key: FromZeros::new_zeroed(), + additional_sense_code: FromZeros::new_zeroed(), additional_sense_code_qualifier: Default::default(), } } @@ -690,7 +690,7 @@ impl AtapiDrive { recommended_multi_dma_time: 0x0078, min_pio_cycle_time_no_flow: 0x01FC, // Taken from a real CD device min_pio_cycle_time_flow: 0x00B4, // Taken from a real CD device - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.command_buffer.buffer[..protocol::IDENTIFY_DEVICE_BYTES].atomic_write_obj(&features); diff --git a/vm/devices/storage/ide/src/drive/hard_drive.rs b/vm/devices/storage/ide/src/drive/hard_drive.rs index 572730de03..78e3d296d4 100644 --- a/vm/devices/storage/ide/src/drive/hard_drive.rs +++ b/vm/devices/storage/ide/src/drive/hard_drive.rs @@ -30,8 +30,8 @@ use std::task::Poll; use std::task::Waker; use thiserror::Error; use tracing_helpers::ErrorValueExt; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const MAX_CMD_BUFFER_BYTES: usize = 64 * 1024; @@ -1084,7 +1084,7 @@ impl HardDrive { total_sectors_48_bit: self.geometry.total_sectors.into(), default_sector_size_config: 0x4000, // describes the sector size related info. Reflect the underlying device sector size and logical:physical ratio logical_block_alignment: 0x4000, // describes alignment of logical blocks within physical block - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.command_buffer.buffer[..protocol::IDENTIFY_DEVICE_BYTES].atomic_write_obj(&features); diff --git a/vm/devices/storage/ide/src/lib.rs b/vm/devices/storage/ide/src/lib.rs index 90905f43e8..5f558cb055 100644 --- a/vm/devices/storage/ide/src/lib.rs +++ b/vm/devices/storage/ide/src/lib.rs @@ -47,7 +47,7 @@ use std::task::Context; use thiserror::Error; use vmcore::device_state::ChangeDeviceState; use vmcore::line_interrupt::LineInterrupt; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; open_enum! { pub enum IdeIoPort: u16 { @@ -1749,9 +1749,9 @@ mod tests { use std::task::Poll; use tempfile::NamedTempFile; use test_with_tracing::test; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::IntoBytes; #[derive(Debug, Inspect)] struct MediaGeometry { @@ -2292,7 +2292,9 @@ mod tests { // PIO - reads data from track cache buffer let data = &mut [0_u8; protocol::IDENTIFY_DEVICE_BYTES]; ide_device.io_read(IdeIoPort::PRI_DATA.0, data).unwrap(); - let features = protocol::IdeFeatures::read_from_prefix(&data[..]).unwrap(); + let features = protocol::IdeFeatures::read_from_prefix(&data[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let ex_features = protocol::IdeFeatures { config_bits: 0x85C0, serial_no: *b" ", @@ -2313,7 +2315,7 @@ mod tests { recommended_multi_dma_time: 0x0078, min_pio_cycle_time_no_flow: 0x01FC, // Taken from a real CD device min_pio_cycle_time_flow: 0x00B4, // Taken from a real CD device - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; assert_eq!(features.as_bytes(), ex_features.as_bytes()); } @@ -2336,7 +2338,9 @@ mod tests { // PIO - reads data from track cache buffer let data = &mut [0_u8; protocol::IDENTIFY_DEVICE_BYTES]; ide_device.io_read(IdeIoPort::PRI_DATA.0, data).unwrap(); - let features = protocol::IdeFeatures::read_from_prefix(&data[..]).unwrap(); + let features = protocol::IdeFeatures::read_from_prefix(&data[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let total_chs_sectors: u32 = geometry.sectors_per_track * geometry.cylinder_count * geometry.head_count; @@ -2413,7 +2417,7 @@ mod tests { total_sectors_48_bit: geometry.total_sectors.into(), default_sector_size_config: 0x4000, // describes the sector size related info. Reflect the underlying device sector size and logical:physical ratio logical_block_alignment: 0x4000, // describes alignment of logical blocks within physical block - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; assert_eq!(features.as_bytes(), ex_features.as_bytes()); } diff --git a/vm/devices/storage/ide/src/protocol.rs b/vm/devices/storage/ide/src/protocol.rs index 98f5d537d2..e94ba0a681 100644 --- a/vm/devices/storage/ide/src/protocol.rs +++ b/vm/devices/storage/ide/src/protocol.rs @@ -4,9 +4,10 @@ use bitfield_struct::bitfield; use inspect::Inspect; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -38,7 +39,7 @@ pub struct Status { // ide commands open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes, Inspect)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] #[inspect(debug)] pub enum IdeCommand: u8 { DEVICE_RESET = 0x08, @@ -92,7 +93,7 @@ open_enum! { // errors #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct ErrorReg { /// no address mark or illegal length indication, register default values pub amnf_ili_default: bool, @@ -121,7 +122,7 @@ pub const DEVICE_ACTIVE_OR_IDLE: u8 = 0xFF; #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DeviceHeadReg { #[bits(4)] pub head: u8, @@ -146,7 +147,7 @@ pub const ATAPI_DATA_FOR_HOST: u8 = 0x02; pub const ATAPI_COMMAND_COMPLETE: u8 = 0x03; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IdeFeatures { pub config_bits: u16, // word 0 pub cylinders: u16, // word 1 @@ -290,7 +291,7 @@ impl DeviceControlReg { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BusMasterDmaDesc { pub mem_physical_base: u32, pub byte_count: u16, @@ -299,7 +300,7 @@ pub struct BusMasterDmaDesc { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EnlightenedInt13Command { pub command: IdeCommand, pub device_head: DeviceHeadReg, diff --git a/vm/devices/storage/nvme/src/namespace.rs b/vm/devices/storage/nvme/src/namespace.rs index 5a396b119e..28b578f40a 100644 --- a/vm/devices/storage/nvme/src/namespace.rs +++ b/vm/devices/storage/nvme/src/namespace.rs @@ -14,9 +14,9 @@ use disk_backend::Disk; use guestmem::GuestMemory; use inspect::Inspect; use scsi_buffers::RequestBuffers; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// An NVMe namespace built on top of a [`Disk`]. #[derive(Inspect)] @@ -40,7 +40,7 @@ impl Namespace { } pub fn identify(&self, buf: &mut [u8]) { - let id = nvm::IdentifyNamespace::mut_from_prefix(buf).unwrap(); + let id = nvm::IdentifyNamespace::mut_from_prefix(buf).unwrap().0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range let size = self.disk.sector_count(); let rescap = if let Some(pr) = self.disk.pr() { @@ -63,13 +63,15 @@ impl Namespace { nlbaf: 0, flbas: nvm::Flbas::new().with_low_index(0), rescap, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; id.lbaf[0] = nvm::Lbaf::new().with_lbads(self.block_shift as u8); } pub fn namespace_id_descriptor(&self, buf: &mut [u8]) { - let id = nvm::NamespaceIdentificationDescriptor::mut_from_prefix(buf).unwrap(); + let id = nvm::NamespaceIdentificationDescriptor::mut_from_prefix(buf) + .unwrap() + .0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range let mut nid = [0u8; 0x10]; if let Some(guid) = self.disk.disk_id() { nid = guid; @@ -180,10 +182,13 @@ impl Namespace { nvm::NvmOpcode::DSM => { let cdw10 = nvm::Cdw10Dsm::from(command.cdw10); let cdw11 = nvm::Cdw11Dsm::from(command.cdw11); - let mut dsm_ranges = nvm::DsmRange::new_box_slice_zeroed(cdw10.nr_z() as usize + 1); + // todo: zerocopy: manual: review carefully! + let mut dsm_ranges = + <[nvm::DsmRange]>::new_box_zeroed_with_elems(cdw10.nr_z() as usize + 1) + .unwrap(); let prp = PrpRange::parse(&self.mem, size_of_val(dsm_ranges.as_ref()), command.dptr)?; - prp.read(&self.mem, dsm_ranges.as_bytes_mut())?; + prp.read(&self.mem, dsm_ranges.as_mut_bytes())?; tracing::debug!(nsid = self.nsid, ?cdw11, ?dsm_ranges, "dsm"); if cdw11.ad() { for range in dsm_ranges.as_ref() { diff --git a/vm/devices/storage/nvme/src/namespace/reservations.rs b/vm/devices/storage/nvme/src/namespace/reservations.rs index 5ab96fc761..6665e42ee0 100644 --- a/vm/devices/storage/nvme/src/namespace/reservations.rs +++ b/vm/devices/storage/nvme/src/namespace/reservations.rs @@ -11,8 +11,8 @@ use crate::spec; use crate::spec::nvm; use disk_backend::pr::PersistentReservation; use nvme_common::to_nvme_reservation_type; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; impl Namespace { pub(super) async fn reservation_register( @@ -23,7 +23,7 @@ impl Namespace { let cdw10 = nvm::Cdw10ReservationRegister::from(command.cdw10); let mut data = nvm::ReservationRegister::new_zeroed(); let range = PrpRange::parse(&self.mem, size_of_val(&data), command.dptr)?; - range.read(&self.mem, data.as_bytes_mut())?; + range.read(&self.mem, data.as_mut_bytes())?; let current_key = (!cdw10.iekey()).then_some(data.crkey); let ptpl = if pr.capabilities().persist_through_power_loss { @@ -82,9 +82,9 @@ impl Namespace { .map_or(nvm::ReservationType(0), to_nvme_reservation_type), regctl: (report.controllers.len() as u16).into(), ptpls: 0, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let controllers = report.controllers.iter().map(|controller| { @@ -97,7 +97,7 @@ impl Namespace { .with_holds_reservation(controller.holds_reservation), hostid, rkey: controller.key, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } }); @@ -116,7 +116,7 @@ impl Namespace { rcsts: controller.rcsts, hostid: controller.hostid[..8].try_into().unwrap(), rkey: controller.rkey, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } .as_bytes(), ); @@ -135,7 +135,7 @@ impl Namespace { let cdw10 = nvm::Cdw10ReservationAcquire::from(command.cdw10); let mut data = nvm::ReservationAcquire::new_zeroed(); let range = PrpRange::parse(&self.mem, size_of_val(&data), command.dptr)?; - range.read(&self.mem, data.as_bytes_mut())?; + range.read(&self.mem, data.as_mut_bytes())?; // According to the spec, this is never to be set. if cdw10.iekey() { @@ -176,7 +176,7 @@ impl Namespace { let cdw10 = nvm::Cdw10ReservationRelease::from(command.cdw10); let mut data = nvm::ReservationRelease::new_zeroed(); let range = PrpRange::parse(&self.mem, size_of_val(&data), command.dptr)?; - range.read(&self.mem, data.as_bytes_mut())?; + range.read(&self.mem, data.as_mut_bytes())?; // According to the spec, this is never to be set. if cdw10.iekey() { diff --git a/vm/devices/storage/nvme/src/prp.rs b/vm/devices/storage/nvme/src/prp.rs index 46fa6556b5..6c96d776a0 100644 --- a/vm/devices/storage/nvme/src/prp.rs +++ b/vm/devices/storage/nvme/src/prp.rs @@ -12,7 +12,7 @@ use crate::PAGE_SIZE; use crate::PAGE_SIZE64; use guestmem::ranges::PagedRange; use guestmem::GuestMemory; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; const PRP_PER_PAGE: usize = PAGE_SIZE / 8; @@ -42,7 +42,7 @@ impl PrpRange { let mut next_prp_list = prp[1]; loop { let n = pfns.len().min(PRP_PER_PAGE); - mem.read_at(next_prp_list, pfns[..n].as_bytes_mut()) + mem.read_at(next_prp_list, pfns[..n].as_mut_bytes()) .map_err(|err| NvmeError::new(spec::Status::DATA_TRANSFER_ERROR, err))?; if n == pfns.len() { break; diff --git a/vm/devices/storage/nvme/src/tests/controller_tests.rs b/vm/devices/storage/nvme/src/tests/controller_tests.rs index 2eb2383a31..cb972ce85c 100644 --- a/vm/devices/storage/nvme/src/tests/controller_tests.rs +++ b/vm/devices/storage/nvme/src/tests/controller_tests.rs @@ -22,8 +22,8 @@ use pci_core::test_helpers::TestPciInterruptController; use user_driver::backoff::Backoff; use vmcore::vm_task::SingleDriverBackend; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; fn instantiate_controller( driver: DefaultDriver, @@ -170,17 +170,17 @@ pub async fn instantiate_and_build_admin_queue( // Enable the controller. let mut dword = 0u32; - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); dword |= 1; nvmec.write_bar0(0x14, dword.as_bytes()).unwrap(); backoff.back_off().await; - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); assert!(dword & 1 != 0); // Read CSTS let mut ready = false; for _i in 0..5 { - nvmec.read_bar0(0x1c, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x1c, dword.as_mut_bytes()).unwrap(); let csts = spec::Csts::from(dword); assert_eq!(csts.cfs(), false); if csts.rdy() { @@ -200,20 +200,20 @@ async fn test_basic_registers(driver: DefaultDriver) { let mut dword = 0u32; // Read controller caps, version. - nvmec.read_bar0(0, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0, dword.as_mut_bytes()).unwrap(); assert_eq!(dword, 0xFF0100FF); let mut qword = 0u64; - nvmec.read_bar0(0, qword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0, qword.as_mut_bytes()).unwrap(); assert_eq!(qword, 0x20FF0100FF); - nvmec.read_bar0(8, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(8, dword.as_mut_bytes()).unwrap(); assert_eq!(dword, 0x20000); // Read ACQ and write it back, see that it sticks. - nvmec.read_bar0(0x30, qword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x30, qword.as_mut_bytes()).unwrap(); assert_eq!(qword, 0); qword = 0x1000; nvmec.write_bar0(0x30, qword.as_bytes()).unwrap(); - nvmec.read_bar0(0x30, qword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x30, qword.as_mut_bytes()).unwrap(); assert_eq!(qword, 0x1000); } @@ -222,12 +222,12 @@ async fn test_invalid_configuration(driver: DefaultDriver) { let gm = test_memory(); let mut nvmec = instantiate_controller(driver, &gm, None); let mut dword = 0u32; - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); // Set MPS to some disallowed value dword |= 0x380; nvmec.write_bar0(0x14, dword.as_bytes()).unwrap(); // Read CSTS, expect fatal error - nvmec.read_bar0(0x1c, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x1c, dword.as_mut_bytes()).unwrap(); assert!(dword & 2 != 0); } @@ -247,14 +247,14 @@ async fn test_enable_controller(driver: DefaultDriver) { nvmec.write_bar0(0x24, dword.as_bytes()).unwrap(); // Enable the controller. - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); dword |= 1; nvmec.write_bar0(0x14, dword.as_bytes()).unwrap(); - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); assert!(dword & 1 != 0); // Read CSTS - nvmec.read_bar0(0x1c, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x1c, dword.as_mut_bytes()).unwrap(); assert!(dword & 2 == 0); } @@ -274,14 +274,14 @@ async fn test_multi_page_admin_queues(driver: DefaultDriver) { nvmec.write_bar0(0x24, dword.as_bytes()).unwrap(); // Enable the controller. - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); dword |= 1; nvmec.write_bar0(0x14, dword.as_bytes()).unwrap(); - nvmec.read_bar0(0x14, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x14, dword.as_mut_bytes()).unwrap(); assert!(dword & 1 != 0); // Read CSTS - nvmec.read_bar0(0x1c, dword.as_bytes_mut()).unwrap(); + nvmec.read_bar0(0x1c, dword.as_mut_bytes()).unwrap(); assert!(dword & 2 == 0); } diff --git a/vm/devices/storage/nvme/src/tests/shadow_doorbell_tests.rs b/vm/devices/storage/nvme/src/tests/shadow_doorbell_tests.rs index fd0950592f..3885a2adf0 100644 --- a/vm/devices/storage/nvme/src/tests/shadow_doorbell_tests.rs +++ b/vm/devices/storage/nvme/src/tests/shadow_doorbell_tests.rs @@ -16,8 +16,8 @@ use pal_async::async_test; use pal_async::DefaultDriver; use pci_core::test_helpers::TestPciInterruptController; use user_driver::backoff::Backoff; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const CQ_BASE: u64 = 0x0; const SQ_BASE: u64 = 0x1000; diff --git a/vm/devices/storage/nvme/src/workers/admin.rs b/vm/devices/storage/nvme/src/workers/admin.rs index 22a9bf1b3e..edf59c0bec 100644 --- a/vm/devices/storage/nvme/src/workers/admin.rs +++ b/vm/devices/storage/nvme/src/workers/admin.rs @@ -49,9 +49,9 @@ use thiserror::Error; use vmcore::interrupt::Interrupt; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const IOSQES: u8 = 6; const IOCQES: u8 = 4; @@ -559,10 +559,10 @@ impl AdminHandler { let cdw10: spec::Cdw10Identify = command.cdw10.into(); // All identify results are 4096 bytes. let mut buf = [0u64; 512]; - let buf = buf.as_bytes_mut(); + let buf = buf.as_mut_bytes(); match spec::Cns(cdw10.cns()) { spec::Cns::CONTROLLER => { - let id = spec::IdentifyController::mut_from_prefix(buf).unwrap(); + let id = spec::IdentifyController::mut_from_prefix(buf).unwrap().0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range *id = self.identify_controller(); write!( @@ -576,7 +576,7 @@ impl AdminHandler { if command.nsid >= 0xfffffffe { return Err(spec::Status::INVALID_NAMESPACE_OR_FORMAT.into()); } - let nsids = u32::mut_slice_from(buf).unwrap(); + let nsids = <[u32]>::mut_from_bytes(buf).unwrap(); for (ns, nsid) in self .namespaces .keys() @@ -642,7 +642,7 @@ impl AdminHandler { .with_broadcast_flush_behavior(spec::BroadcastFlushBehavior::NOT_SUPPORTED.0), cntrltype: spec::ControllerType::IO_CONTROLLER, oacs, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } diff --git a/vm/devices/storage/nvme_spec/Cargo.toml b/vm/devices/storage/nvme_spec/Cargo.toml index 8b93c30139..a8f6e5102a 100644 --- a/vm/devices/storage/nvme_spec/Cargo.toml +++ b/vm/devices/storage/nvme_spec/Cargo.toml @@ -14,6 +14,5 @@ inspect.workspace = true bitfield-struct.workspace = true open_enum.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/storage/nvme_spec/src/lib.rs b/vm/devices/storage/nvme_spec/src/lib.rs index 0060fd82b8..812a950225 100644 --- a/vm/devices/storage/nvme_spec/src/lib.rs +++ b/vm/devices/storage/nvme_spec/src/lib.rs @@ -14,9 +14,10 @@ use bitfield_struct::bitfield; use inspect::Inspect; use open_enum::open_enum; use storage_string::AsciiString; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; type U128LE = zerocopy::U128; @@ -126,7 +127,7 @@ pub struct Aqa { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, Inspect)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] pub struct Command { pub cdw0: Cdw0, pub nsid: u32, @@ -145,7 +146,7 @@ pub struct Command { #[derive(Inspect)] #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdw0 { pub opcode: u8, #[bits(2)] @@ -206,7 +207,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Completion { pub dw0: u32, pub dw1: u32, @@ -217,7 +218,7 @@ pub struct Completion { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CompletionStatus { pub phase: bool, /// 8 bits of status code followed by 3 bits of the status code type. @@ -396,7 +397,7 @@ open_enum! { #[derive(Inspect)] #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct OptionalAdminCommandSupport { pub security_send_security_receive: bool, pub format_nvm: bool, @@ -414,7 +415,7 @@ pub struct OptionalAdminCommandSupport { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Inspect, Clone)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect, Clone)] pub struct IdentifyController { pub vid: u16, pub ssvid: u16, @@ -534,7 +535,7 @@ const _: () = assert!(size_of::() == 4096); #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QueueEntrySize { #[bits(4)] pub min: u8, @@ -544,7 +545,7 @@ pub struct QueueEntrySize { #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FirmwareUpdates { pub ffsro: bool, #[bits(3)] @@ -558,7 +559,7 @@ pub struct FirmwareUpdates { /// Optional asynchronous events supported #[derive(Inspect)] #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Oaes { _rsvd: u8, pub namespace_attribute: bool, @@ -575,7 +576,7 @@ pub struct Oaes { /// Optional NVM command support #[derive(Inspect)] #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Oncs { pub compare: bool, pub write_uncorrectable: bool, @@ -591,7 +592,7 @@ pub struct Oncs { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes, Inspect)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] #[inspect(debug)] pub enum ControllerType: u8 { RESERVED = 0, @@ -603,7 +604,7 @@ open_enum! { #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VolatileWriteCache { pub present: bool, #[bits(2)] diff --git a/vm/devices/storage/nvme_spec/src/nvm.rs b/vm/devices/storage/nvme_spec/src/nvm.rs index d1d99df6c8..2017331195 100644 --- a/vm/devices/storage/nvme_spec/src/nvm.rs +++ b/vm/devices/storage/nvme_spec/src/nvm.rs @@ -9,14 +9,15 @@ use crate::U128LE; use bitfield_struct::bitfield; use inspect::Inspect; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::LE; use zerocopy::U16; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Inspect, Clone)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect, Clone)] pub struct IdentifyNamespace { pub nsze: u64, pub ncap: u64, @@ -78,7 +79,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Inspect)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] pub struct NamespaceIdentificationDescriptor { pub nidt: u8, // NamespaceIdentifierType pub nidl: u8, @@ -88,7 +89,7 @@ pub struct NamespaceIdentificationDescriptor { #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Nsfeat { /// Thin provisioning pub thinp: bool, @@ -106,7 +107,7 @@ pub struct Nsfeat { /// LBA format #[derive(Inspect)] #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Lbaf { /// Metadata size pub ms: u16, @@ -122,7 +123,7 @@ pub struct Lbaf { /// Formatted LBA size #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Flbas { #[bits(4)] pub low_index: u8, @@ -136,7 +137,7 @@ pub struct Flbas { #[derive(Inspect)] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationCapabilities { pub persist_through_power_loss: bool, pub write_exclusive: bool, @@ -217,7 +218,7 @@ pub struct Cdw11Dsm { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DsmRange { pub context_attributes: u32, pub lba_count: u32, @@ -255,7 +256,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationRegister { /// Current reservation key pub crkey: u64, @@ -285,7 +286,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum ReservationType: u8 { WRITE_EXCLUSIVE = 1, EXCLUSIVE_ACCESS = 2, @@ -297,7 +298,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationAcquire { /// Current reservation key pub crkey: u64, @@ -326,7 +327,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationRelease { /// Current reservation key pub crkey: u64, @@ -346,7 +347,7 @@ pub struct Cdw11ReservationReport { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationReport { /// Generation pub generation: u32, @@ -362,7 +363,7 @@ pub struct ReservationReport { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationReportExtended { pub report: ReservationReport, pub reserved: [u8; 40], @@ -370,7 +371,7 @@ pub struct ReservationReportExtended { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RegisteredController { /// Controller ID pub cntlid: u16, @@ -384,7 +385,7 @@ pub struct RegisteredController { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RegisteredControllerExtended { /// Controller ID pub cntlid: u16, @@ -399,7 +400,7 @@ pub struct RegisteredControllerExtended { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReservationStatus { pub holds_reservation: bool, #[bits(7)] diff --git a/vm/devices/storage/scsi_buffers/src/lib.rs b/vm/devices/storage/scsi_buffers/src/lib.rs index 7b60d470da..1ae3227220 100644 --- a/vm/devices/storage/scsi_buffers/src/lib.rs +++ b/vm/devices/storage/scsi_buffers/src/lib.rs @@ -22,9 +22,10 @@ use std::ops::Deref; use std::sync::atomic::AtomicU8; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A pointer/length pair that is ABI compatible with the iovec type on Linux. #[derive(Debug, Copy, Clone)] @@ -135,7 +136,7 @@ impl Deref for IoBuffer<'_> { const PAGE_SIZE: usize = 4096; #[repr(C, align(4096))] -#[derive(Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] struct Page([u8; PAGE_SIZE]); const ZERO_PAGE: Page = Page([0; PAGE_SIZE]); @@ -150,7 +151,7 @@ impl BounceBuffer { /// Allocates a new bounce buffer of `size` bytes. pub fn new(size: usize) -> Self { let mut pages = vec![ZERO_PAGE; size.div_ceil(PAGE_SIZE)]; - let io_vec = pages.as_bytes_mut()[..size].as_atomic_bytes().into(); + let io_vec = pages.as_mut_bytes()[..size].as_atomic_bytes().into(); BounceBuffer { pages, io_vec } } diff --git a/vm/devices/storage/scsi_defs/src/lib.rs b/vm/devices/storage/scsi_defs/src/lib.rs index 0aa0678340..c638144fe7 100644 --- a/vm/devices/storage/scsi_defs/src/lib.rs +++ b/vm/devices/storage/scsi_defs/src/lib.rs @@ -8,16 +8,17 @@ pub mod srb; use bitfield_struct::bitfield; use core::fmt::Debug; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; type U16BE = zerocopy::byteorder::U16; type U32BE = zerocopy::byteorder::U32; type U64BE = zerocopy::byteorder::U64; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum ScsiOp: u8 { TEST_UNIT_READY = 0x00, REZERO_UNIT = 0x01, @@ -231,7 +232,7 @@ pub const MEDIUM_NOT_PRESENT_TRAY_CLOSED: u8 = 0x01; pub const MEDIUM_NOT_PRESENT_TRAY_OPEN: u8 = 0x02; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbInquiry { pub operation_code: u8, // 0x12 - SCSIOP_INQUIRY pub flags: InquiryFlags, @@ -241,7 +242,7 @@ pub struct CdbInquiry { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InquiryFlags { #[bits(1)] pub vpd: bool, @@ -332,7 +333,7 @@ struct InquiryData { */ #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InquiryDataHeader { /* UCHAR DeviceType : 5; @@ -346,7 +347,7 @@ pub struct InquiryDataHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InquiryDataFlag2 { #[bits(7)] pub device_type_modifier: u8, @@ -355,7 +356,7 @@ pub struct InquiryDataFlag2 { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InquiryDataFlag3 { #[bits(4)] pub response_data_format: u8, @@ -370,7 +371,7 @@ pub struct InquiryDataFlag3 { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InquiryData { pub header: InquiryDataHeader, pub reserved: [u8; 2], @@ -395,7 +396,7 @@ pub struct InquiryData { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdPageHeader { /* UCHAR DeviceType : 5; @@ -408,7 +409,7 @@ pub struct VpdPageHeader { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdT10Id { pub header: VpdIdentificationDescriptor, pub vendor_id: [u8; 8], @@ -419,7 +420,7 @@ pub struct VpdT10Id { /// => NAA = 6. /// #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdNaaId { pub header: VpdIdentificationDescriptor, /* @@ -437,7 +438,7 @@ pub struct VpdNaaId { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdIdentificationDescriptor { pub code_set: u8, pub identifiertype: u8, @@ -446,7 +447,7 @@ pub struct VpdIdentificationDescriptor { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdBlockLimitsDescriptor { pub reserved0: u8, pub max_compare_and_write_length: u8, @@ -467,14 +468,14 @@ pub struct VpdBlockLimitsDescriptor { /// VPD Page 0xB1, Block Device Characteristics #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdBlockDeviceCharacteristicsPage { pub medium_rotation_rate: U16BE, pub data: [u8; 58], // Needn't know the details } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdMsftVirtualDevicePropertiesPage { pub version: u8, /* @@ -489,7 +490,7 @@ pub struct VpdMsftVirtualDevicePropertiesPage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdMsftPagingExtentPropertiesPage { pub version: u8, /* @@ -507,7 +508,7 @@ pub const PROVISIONING_TYPE_RESOURCE: u8 = 0x1; pub const PROVISIONING_TYPE_THIN: u8 = 0x2; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpdLogicalBlockProvisioningPage { pub threshold_exponent: u8, /* @@ -529,7 +530,7 @@ pub struct VpdLogicalBlockProvisioningPage { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SenseDataHeader { /* UCHAR ErrorCode:7; @@ -556,7 +557,7 @@ pub struct SenseDataHeader { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SenseData { pub header: SenseDataHeader, pub command_specific_information: [u8; 4], @@ -594,7 +595,7 @@ impl SenseData { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SenseKey: u8 { NO_SENSE = 0x00, RECOVERED_ERROR = 0x01, @@ -616,7 +617,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SenseDataErrorCode: u8 { FIXED_CURRENT = 0x70, FIXED_DEFERRED = 0x71, @@ -626,7 +627,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum AdditionalSenseCode: u8 { NO_SENSE = 0x00, NO_SEEK_COMPLETE = 0x02, @@ -712,7 +713,7 @@ pub const SCSI_SENSEQ_INCOMPATIBLE_FORMAT: u8 = 0x02; pub const SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED: u8 = 0x02; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum ScsiStatus: u8 { GOOD = 0x00, @@ -729,14 +730,14 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadCapacityData { pub logical_block_address: U32BE, pub bytes_per_block: U32BE, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSense { pub operation_code: ScsiOp, pub flags1: u8, @@ -747,7 +748,7 @@ pub struct ModeSense { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSense10 { pub operation_code: ScsiOp, pub flags1: u8, @@ -759,7 +760,7 @@ pub struct ModeSense10 { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSenseFlags { #[bits(6)] pub page_code: u8, @@ -768,7 +769,7 @@ pub struct ModeSenseFlags { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeReadWriteRecoveryPage { /* UCHAR PageCode : 6; @@ -795,7 +796,7 @@ pub struct ModeReadWriteRecoveryPage { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSenseModePageTimeoutProtect { /* UCHAR PageCode : 6; @@ -820,7 +821,7 @@ pub struct ModeSenseModePageTimeoutProtect { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PowerConditionPage { /* UCHAR PageCode : 6; @@ -847,7 +848,7 @@ pub const LIST_OF_MODE_PAGES: [u8; 3] = [ ]; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSelect { pub operation_code: ScsiOp, pub flags: ModeSelectFlags, @@ -857,7 +858,7 @@ pub struct ModeSelect { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSelect10 { pub operation_code: ScsiOp, pub flags: ModeSelectFlags, @@ -867,7 +868,7 @@ pub struct ModeSelect10 { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeSelectFlags { #[bits(1)] pub spbit: bool, @@ -918,7 +919,7 @@ pub const MODE_SENSE_SAVED_VALUES: u8 = 0xc0; pub const MODE_SENSE_RETURN_ALL: u8 = 0x3f; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeParameterHeader { pub mode_data_length: u8, pub medium_type: u8, @@ -927,7 +928,7 @@ pub struct ModeParameterHeader { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeParameterHeader10 { pub mode_data_length: U16BE, pub medium_type: u8, @@ -937,7 +938,7 @@ pub struct ModeParameterHeader10 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModeCachingPage { /* UCHAR PageCode : 6; @@ -971,18 +972,18 @@ pub const MODE_DSP_FUA_SUPPORTED: u8 = 0x10; pub const MODE_DSP_WRITE_PROTECT: u8 = 0x80; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LunList { pub length: U32BE, pub reserved: [u8; 4], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LunListEntry(pub [u8; 8]); #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdb10 { pub operation_code: ScsiOp, pub flags: CdbFlags, @@ -993,7 +994,7 @@ pub struct Cdb10 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdb6ReadWrite { pub operation_code: u8, // 0x08, 0x0A - SCSIOP_READ, SCSIOP_WRITE pub logical_block: [u8; 3], @@ -1002,7 +1003,7 @@ pub struct Cdb6ReadWrite { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdb12 { pub operation_code: ScsiOp, pub flags: CdbFlags, @@ -1013,7 +1014,7 @@ pub struct Cdb12 { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdb16 { pub operation_code: ScsiOp, pub flags: Cdb16Flags, @@ -1024,7 +1025,7 @@ pub struct Cdb16 { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbFlags { pub relative_address: bool, #[bits(2)] @@ -1036,7 +1037,7 @@ pub struct CdbFlags { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Cdb16Flags { #[bits(3)] pub reserved1: u8, @@ -1047,7 +1048,7 @@ pub struct Cdb16Flags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ServiceActionIn16 { pub operation_code: ScsiOp, pub service_action: u8, @@ -1063,14 +1064,14 @@ pub const SERVICE_ACTION_GET_PHYSICAL_ELEMENT_STATUS: u8 = 0x17; pub const SERVICE_ACTION_REMOVE_ELEMENT_AND_TRUNCATE: u8 = 0x18; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadCapacityDataEx { pub logical_block_address: U64BE, pub bytes_per_block: U32BE, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadCapacity16Data { pub ex: ReadCapacityDataEx, /* @@ -1113,7 +1114,7 @@ pub const SRB_FLAGS_CONSOLIDATEABLE_BLOCKS_ONLY: u32 = SRB_FLAGS_MS_SPECIAL_BEHA pub const SRB_FLAGS_BLOCK_LEVEL_ONLY: u32 = SRB_FLAGS_MS_SPECIAL_BEHAVIOR; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetLbaStatus { pub operation_code: ScsiOp, /* @@ -1128,7 +1129,7 @@ pub struct GetLbaStatus { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LbaStatusDescriptor { pub start_lba: U64BE, pub logical_block_count: U32BE, @@ -1141,7 +1142,7 @@ pub struct LbaStatusDescriptor { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LbaStatusListHeader { pub parameter_length: U32BE, pub reserved: u32, @@ -1152,7 +1153,7 @@ pub const LBA_STATUS_DEALLOCATED: u8 = 0x1; pub const LBA_STATUS_ANCHORED: u8 = 0x2; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Unmap { pub operation_code: ScsiOp, /* @@ -1171,7 +1172,7 @@ pub struct Unmap { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct UnmapBlockDescriptor { pub start_lba: U64BE, pub lba_count: U32BE, @@ -1179,14 +1180,14 @@ pub struct UnmapBlockDescriptor { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct UnmapListHeader { pub data_length: U16BE, pub block_descriptor_data_length: U16BE, pub reserved: [u8; 4], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartStop { pub operation_code: ScsiOp, /* @@ -1201,7 +1202,7 @@ pub struct StartStop { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartStopFlags { #[bits(1)] pub start: bool, @@ -1215,7 +1216,7 @@ pub const IMMEDIATE_BIT: u8 = 1; pub const START_BIT: u8 = 1; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PersistentReserveIn { pub operation_code: ScsiOp, pub service_action: PersistentReserveServiceActionIn, @@ -1225,7 +1226,7 @@ pub struct PersistentReserveIn { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PersistentReserveOut { pub operation_code: ScsiOp, pub service_action: PersistentReserveServiceActionOut, @@ -1236,7 +1237,7 @@ pub struct PersistentReserveOut { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PersistentReserveTypeScope { #[bits(4)] reserve_type_bits: u8, @@ -1262,7 +1263,7 @@ pub const RESERVATION_SCOPE_LU: u8 = 0x00; pub const RESERVATION_SCOPE_ELEMENT: u8 = 0x02; #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PersistentReserveServiceActionIn { #[bits(5)] service_action_bits: u8, @@ -1285,7 +1286,7 @@ impl PersistentReserveServiceActionIn { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PersistentReserveServiceActionOut { #[bits(5)] service_action_bits: u8, @@ -1345,7 +1346,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ProParameterList { pub reservation_key: U64BE, pub service_action_reservation_key: U64BE, @@ -1356,7 +1357,7 @@ pub struct ProParameterList { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ProParameterListFlags { pub aptpl: bool, pub reserved1: bool, @@ -1367,7 +1368,7 @@ pub struct ProParameterListFlags { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SendDiagnosticFlags { pub unit_offline: bool, pub device_offline: bool, @@ -1379,7 +1380,7 @@ pub struct SendDiagnosticFlags { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SendDiagnostic { pub op_code: u8, // 0x1D - SCSIOP_SEND_DIAGNOSTIC pub flags: SendDiagnosticFlags, @@ -1389,7 +1390,7 @@ pub struct SendDiagnostic { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriReportCapabilities { pub length: U16BE, pub flags: PriReportCapabilitiesFlags, @@ -1398,7 +1399,7 @@ pub struct PriReportCapabilities { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriReportCapabilitiesFlags { pub persist_through_power_loss_capable: bool, _reserved: bool, @@ -1417,7 +1418,7 @@ pub struct PriReportCapabilitiesFlags { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriReportCapabilitiesTypeMask { _reserved: bool, pub write_exclusive: bool, @@ -1433,28 +1434,28 @@ pub struct PriReportCapabilitiesTypeMask { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriRegistrationListHeader { pub generation: U32BE, pub additional_length: U32BE, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriFullStatusListHeader { pub generation: U32BE, pub additional_length: U32BE, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriReservationListHeader { pub generation: U32BE, pub additional_length: U32BE, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriReservationDescriptor { pub reservation_key: U64BE, pub obsolete: [u8; 4], @@ -1464,7 +1465,7 @@ pub struct PriReservationDescriptor { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriFullStatusDescriptorHeader { pub reservation_key: U64BE, pub reserved: [u8; 4], @@ -1476,7 +1477,7 @@ pub struct PriFullStatusDescriptorHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PriFullStatusDescriptorHeaderFlags { pub reservation_holder: bool, pub all_target_ports: bool, @@ -1485,7 +1486,7 @@ pub struct PriFullStatusDescriptorHeaderFlags { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IsoVpdIdentifiers { pub id_page: VpdIdentificationDescriptor, pub vendor_id: [u8; 8], @@ -1493,7 +1494,7 @@ pub struct IsoVpdIdentifiers { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbGetEventStatusNotification { pub operation_code: ScsiOp, pub flags: GetEventStatusFlags, @@ -1505,7 +1506,7 @@ pub struct CdbGetEventStatusNotification { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetEventStatusFlags { #[bits(1)] pub immediate: bool, @@ -1553,7 +1554,7 @@ pub const NOTIFICATION_BUSY_EVENT_NO_EVENT: u8 = 0x0; pub const NOTIFICATION_BUSY_STATUS_NO_EVENT: u8 = 0x0; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationMediaStatus { /* UCHAR MediaEvent : 4; @@ -1566,7 +1567,7 @@ pub struct NotificationMediaStatus { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MediaFlags { #[bits(1)] pub door_tray_open: bool, @@ -1577,7 +1578,7 @@ pub struct MediaFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationEventStatusHeader { pub event_data_length: U16BE, pub flags: EventStatusFlags, @@ -1585,7 +1586,7 @@ pub struct NotificationEventStatusHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EventStatusFlags { #[bits(3)] pub notification_class: u8, @@ -1596,7 +1597,7 @@ pub struct EventStatusFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationOperationalStatus { /* UCHAR OperationalEvent : 4; @@ -1608,7 +1609,7 @@ pub struct NotificationOperationalStatus { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct OperationalStatusFlags { #[bits(4)] pub operational_status: u8, @@ -1619,7 +1620,7 @@ pub struct OperationalStatusFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationPowerStatus { /* UCHAR PowerEvent : 4; @@ -1631,7 +1632,7 @@ pub struct NotificationPowerStatus { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationExternalStatus { /* UCHAR ExternalEvent : 4; @@ -1643,7 +1644,7 @@ pub struct NotificationExternalStatus { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ExternalStatusFlags { #[bits(4)] pub external_status: u8, @@ -1654,7 +1655,7 @@ pub struct ExternalStatusFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationMultiHostStatus { /* UCHAR MultiHostEvent : 4; @@ -1666,7 +1667,7 @@ pub struct NotificationMultiHostStatus { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MultiHostStatusFlags { #[bits(4)] pub multi_host_status: u8, @@ -1677,7 +1678,7 @@ pub struct MultiHostStatusFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationBusyStatus { /* UCHAR DeviceBusyEvent : 4; @@ -1786,7 +1787,7 @@ impl TryFrom for FeatureNumber { } } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetConfigurationHeader { pub data_length: U32BE, pub reserved: [u8; 2], @@ -1794,7 +1795,7 @@ pub struct GetConfigurationHeader { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbGetConfiguration { pub operation_code: ScsiOp, pub flags: GetConfigurationFlags, @@ -1805,7 +1806,7 @@ pub struct CdbGetConfiguration { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetConfigurationFlags { #[bits(2)] request_type_bits: u8, @@ -1828,14 +1829,14 @@ impl GetConfigurationFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetConfigurationFeatureDataProfileList { pub header: FeatureHeader, pub profile: [FeatureDataProfileList; 2], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataProfileList { pub profile_number: U16BE, /* @@ -1847,7 +1848,7 @@ pub struct FeatureDataProfileList { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureHeader { pub feature_code: U16BE, pub flags: FeatureHeaderFlags, @@ -1855,7 +1856,7 @@ pub struct FeatureHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureHeaderFlags { #[bits(1)] pub current: bool, @@ -1868,7 +1869,7 @@ pub struct FeatureHeaderFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataRandomReadable { pub header: FeatureHeader, pub logical_block_size: U32BE, @@ -1882,7 +1883,7 @@ pub struct FeatureDataRandomReadable { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataDvdRead { pub header: FeatureHeader, /* @@ -1900,7 +1901,7 @@ pub struct FeatureDataDvdRead { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RealTimeStreamingFlags { #[bits(1)] pub stream_recording: bool, @@ -1917,7 +1918,7 @@ pub struct RealTimeStreamingFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataRealTimeStreaming { pub header: FeatureHeader, pub flags: RealTimeStreamingFlags, @@ -1925,7 +1926,7 @@ pub struct FeatureDataRealTimeStreaming { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataCore { pub header: FeatureHeader, pub physical_interface: U32BE, @@ -1939,7 +1940,7 @@ pub struct FeatureDataCore { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureMorphingFlags { #[bits(1)] pub asynchronous: bool, @@ -1950,7 +1951,7 @@ pub struct FeatureMorphingFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataMorphing { pub header: FeatureHeader, pub flags: FeatureMorphingFlags, @@ -1958,7 +1959,7 @@ pub struct FeatureDataMorphing { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RemovableMediumFlags { #[bits(1)] pub lockable: bool, @@ -1975,7 +1976,7 @@ pub struct RemovableMediumFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataRemovableMedium { pub header: FeatureHeader, pub flags: RemovableMediumFlags, @@ -1983,7 +1984,7 @@ pub struct FeatureDataRemovableMedium { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CDReadFlags { #[bits(1)] pub cd_text: bool, @@ -1996,7 +1997,7 @@ pub struct CDReadFlags { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataCdRead { pub header: FeatureHeader, pub flags: CDReadFlags, @@ -2004,13 +2005,13 @@ pub struct FeatureDataCdRead { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataPowerManagement { pub header: FeatureHeader, } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureDataTimeout { pub header: FeatureHeader, /* @@ -2029,7 +2030,7 @@ pub const CDROM_READ_TOC_EX_FORMAT_PMA: u8 = 0x03; pub const CDROM_READ_TOC_EX_FORMAT_ATIP: u8 = 0x04; pub const CDROM_READ_TOC_EX_FORMAT_CDTEXT: u8 = 0x05; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbReadToc { pub operation_code: ScsiOp, /* @@ -2054,7 +2055,7 @@ pub struct CdbReadToc { pub reserved1: u8, } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadTocFlag { #[bits(1)] pub reserved0: bool, @@ -2066,7 +2067,7 @@ pub struct ReadTocFlag { pub location_unit_number: u8, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadTocFormattedToc { pub length: U16BE, pub first_complete_session: u8, @@ -2075,7 +2076,7 @@ pub struct ReadTocFormattedToc { pub trackaa: TrackData, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TrackData { pub reserved: u8, pub flag: TrackDataFlag, @@ -2084,7 +2085,7 @@ pub struct TrackData { pub address: [u8; 4], } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TrackDataFlag { #[bits(4)] pub control: u8, @@ -2092,7 +2093,7 @@ pub struct TrackDataFlag { pub adr: u8, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdromTocSessionData { // Header pub length: U16BE, // add two bytes for this field @@ -2104,7 +2105,7 @@ pub struct CdromTocSessionData { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbRequestSense { pub operation_code: ScsiOp, pub desc: u8, @@ -2114,7 +2115,7 @@ pub struct CdbRequestSense { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbMediaRemoval { pub operation_code: ScsiOp, /* @@ -2127,7 +2128,7 @@ pub struct CdbMediaRemoval { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MediaRemovalFlags { #[bits(1)] pub prevent: bool, @@ -2138,7 +2139,7 @@ pub struct MediaRemovalFlags { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadTrackInfoFlag { #[bits(2)] pub number_type: u8, @@ -2149,7 +2150,7 @@ pub struct ReadTrackInfoFlag { } #[repr(C)] -#[derive(Copy, Clone, FromBytes, FromZeroes)] +#[derive(Copy, Clone, FromBytes)] pub struct CdbReadTrackInformation { pub operation_code: ScsiOp, /* @@ -2165,7 +2166,7 @@ pub struct CdbReadTrackInformation { } #[repr(C)] -#[derive(Copy, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TrackInformation3 { pub length: U16BE, pub track_number_lsb: u8, @@ -2212,7 +2213,7 @@ pub const DVD_FORMAT_BCA: u8 = 0x03; pub const DVD_FORMAT_MANUFACTURING: u8 = 0x04; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbReadDVDStructure { pub op: u8, /* @@ -2234,7 +2235,7 @@ pub struct CdbReadDVDStructure { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadDVDStructurePhysicalFormatInformation { pub length: U16BE, pub reserved: [u8; 2], @@ -2274,7 +2275,7 @@ pub struct ReadDVDStructurePhysicalFormatInformation { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadDVDStructureCopyrightInformation { pub data_length: U16BE, pub reserved: u8, @@ -2284,7 +2285,7 @@ pub struct ReadDVDStructureCopyrightInformation { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadDVDStructureManufacturingStructure { pub data_length: U16BE, pub reserved: [u8; 2], @@ -2302,7 +2303,7 @@ pub const PERFORMANCE_EXCEPT_PERFORMANCE_EXCEPTIONS_ONLY: u8 = 0x2; pub const PERFORMANCE_1000_BYTES_PER_SECOND: u32 = 1350 * 24; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbGetPerformance { pub op: u8, pub flags: GetPerformanceFlags, @@ -2314,7 +2315,7 @@ pub struct CdbGetPerformance { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetPerformanceFlags { #[bits(2)] pub except: u8, @@ -2327,7 +2328,7 @@ pub struct GetPerformanceFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetPerformanceNominalPerformanceDescriptor { pub start_lba: U32BE, pub start_performance: U32BE, @@ -2336,7 +2337,7 @@ pub struct GetPerformanceNominalPerformanceDescriptor { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetPerformanceHeader { pub total_data_length: U32BE, /* @@ -2349,7 +2350,7 @@ pub struct GetPerformanceHeader { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbMechStatus { pub op: u8, /* @@ -2364,7 +2365,7 @@ pub struct CdbMechStatus { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MechanismStatusHeader { /* UCHAR CurrentSlotLow5 : 5; @@ -2379,7 +2380,7 @@ pub struct MechanismStatusHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MechanismStatusHeaderFlags { #[bits(3)] pub current_slot_high3: u8, @@ -2392,7 +2393,7 @@ pub struct MechanismStatusHeaderFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbReadBufferCapacity { pub op: u8, pub flags: ReadBufferCapacityFlags, @@ -2402,7 +2403,7 @@ pub struct CdbReadBufferCapacity { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadBufferCapacityFlags { #[bits(1)] pub block_info: bool, @@ -2411,7 +2412,7 @@ pub struct ReadBufferCapacityFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadBufferCapacityData { pub data_length: U16BE, pub reserved1: u8, @@ -2425,7 +2426,7 @@ pub struct ReadBufferCapacityData { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbReadDiscInformation { pub operation_code: ScsiOp, pub flags: ReadDiscFlags, @@ -2435,7 +2436,7 @@ pub struct CdbReadDiscInformation { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadDiscFlags { #[bits(3)] pub data_type: u8, @@ -2444,7 +2445,7 @@ pub struct ReadDiscFlags { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DiscInformation { pub length: U16BE, pub flags1: DiscInfoFlags1, @@ -2473,7 +2474,7 @@ pub struct DiscInformation { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DiscInfoFlags1 { #[bits(2)] pub disc_status: u8, @@ -2486,7 +2487,7 @@ pub struct DiscInfoFlags1 { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DiscInfoFlags2 { #[bits(2)] pub mrw_status: u8, @@ -2503,7 +2504,7 @@ pub struct DiscInfoFlags2 { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CdbSetStreaming { pub operation_code: ScsiOp, pub reserved: [u8; 8], @@ -2512,7 +2513,7 @@ pub struct CdbSetStreaming { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetStreamingPerformanceDescriptor { pub flags: SetStreamingFlags, pub reserved2: [u8; 3], @@ -2525,7 +2526,7 @@ pub struct SetStreamingPerformanceDescriptor { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetStreamingFlags { #[bits(1)] pub mrw: bool, @@ -2542,7 +2543,7 @@ pub struct SetStreamingFlags { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReportLuns { pub operation_code: ScsiOp, pub reserved1: [u8; 5], diff --git a/vm/devices/storage/scsi_defs/src/srb.rs b/vm/devices/storage/scsi_defs/src/srb.rs index 4330100745..ab849a70c3 100644 --- a/vm/devices/storage/scsi_defs/src/srb.rs +++ b/vm/devices/storage/scsi_defs/src/srb.rs @@ -3,12 +3,13 @@ use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct SrbStatusAndFlags { #[bits(6)] @@ -32,7 +33,7 @@ impl SrbStatusAndFlags { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SrbStatus: u8 { PENDING = 0x00, SUCCESS = 0x01, diff --git a/vm/devices/storage/scsidisk/src/atapi_scsi.rs b/vm/devices/storage/scsidisk/src/atapi_scsi.rs index 297e30fd7c..470dd7f704 100644 --- a/vm/devices/storage/scsidisk/src/atapi_scsi.rs +++ b/vm/devices/storage/scsidisk/src/atapi_scsi.rs @@ -28,8 +28,8 @@ use stackfuture::StackFuture; use std::sync::Arc; use vmcore::save_restore::RestoreError; use vmcore::save_restore::SaveError; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// A wrapper to filter and redirect ATAPI SCSI commands from an IDE ISO to inner [`AsyncScsiDisk`]. #[derive(Inspect)] @@ -138,7 +138,9 @@ impl AtapiScsiDisk { external_data: &RequestBuffers<'_>, request: &Request, ) -> ScsiResult { - let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; let min = size_of::(); @@ -191,7 +193,9 @@ impl AtapiScsiDisk { external_data: &RequestBuffers<'_>, request: &Request, ) -> ScsiResult { - let cdb = scsi::ReportLuns::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ReportLuns::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; if allocation_length == 0 { return ScsiResult { @@ -225,8 +229,8 @@ impl AtapiScsiDisk { length: 8.into(), reserved: [0; 4], }; - data.as_bytes_mut()[..HEADER_SIZE].copy_from_slice(header.as_bytes()); - data[1].as_bytes_mut()[..2].copy_from_slice(&0_u16.to_be_bytes()); + data.as_mut_bytes()[..HEADER_SIZE].copy_from_slice(header.as_bytes()); + data[1].as_mut_bytes()[..2].copy_from_slice(&0_u16.to_be_bytes()); let result = external_data.writer().write(&data.as_bytes()[..tx]); diff --git a/vm/devices/storage/scsidisk/src/getlbastatus.rs b/vm/devices/storage/scsidisk/src/getlbastatus.rs index 4cd3cfccda..06b028246e 100644 --- a/vm/devices/storage/scsidisk/src/getlbastatus.rs +++ b/vm/devices/storage/scsidisk/src/getlbastatus.rs @@ -14,9 +14,9 @@ use scsi::AdditionalSenseCode; use scsi_buffers::RequestBuffers; use scsi_core::Request; use scsi_defs as scsi; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Result of a get LBA status request. #[derive(Debug, Default, Copy, Clone)] @@ -91,7 +91,9 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::GetLbaStatus::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::GetLbaStatus::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range // Validate the request parameters. let start_lba = cdb.start_lba.get(); diff --git a/vm/devices/storage/scsidisk/src/inquiry.rs b/vm/devices/storage/scsidisk/src/inquiry.rs index e8a48b5351..e4d9e6a1c8 100644 --- a/vm/devices/storage/scsidisk/src/inquiry.rs +++ b/vm/devices/storage/scsidisk/src/inquiry.rs @@ -11,23 +11,25 @@ use guid::Guid; use scsi::AdditionalSenseCode; use scsi_buffers::RequestBuffers; use scsi_core::Request; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; type U16BE = zerocopy::byteorder::U16; type U32BE = zerocopy::byteorder::U32; type U64BE = zerocopy::byteorder::U64; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] struct VhdmpVpdWindowsBlockDeviceRodLimitsEcopDescriptorHeader { pub ecop_descriptor_type: U16BE, pub ecop_descriptor_length: U16BE, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] struct VhdmpVpdWindowsBlockDeviceRodLimitsEcopDescriptor { pub header: VhdmpVpdWindowsBlockDeviceRodLimitsEcopDescriptorHeader, pub microsoft_signature: u8, // 0x4D --> 'M' @@ -81,7 +83,7 @@ pub const INQUIRY_DATA_TEMPLATE: scsi::InquiryData = scsi::InquiryData { /// /// Assumes that allocation_length is already validated to be at least /// `size_of::()`. -fn write_vpd_page( +fn write_vpd_page( external_data: &RequestBuffers<'_>, allocation_length: usize, page_code: u8, @@ -169,7 +171,7 @@ impl SimpleScsiDisk { allocation_length: usize, ) -> Result { #[repr(C)] - #[derive(AsBytes)] + #[derive(IntoBytes, Immutable, KnownLayout)] struct Ids { t10_id: scsi::VpdT10Id, // NAA ID page - need this for compliance @@ -252,7 +254,7 @@ impl SimpleScsiDisk { optimal_unmap_granularity: optimal_unmap_granularity.into(), unmap_granularity_alignment: [0x80, 0x00, 0x00, 0x00], // UGAValid = 1 max_write_same_length: max_write_same_length.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; tracing::debug!( @@ -277,7 +279,7 @@ impl SimpleScsiDisk { ) -> Result { let page = scsi::VpdBlockDeviceCharacteristicsPage { medium_rotation_rate: self.scsi_parameters.medium_rotation_rate.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; write_vpd_page( @@ -467,7 +469,9 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; if external_data.len() < allocation_length { diff --git a/vm/devices/storage/scsidisk/src/lib.rs b/vm/devices/storage/scsidisk/src/lib.rs index 07d1525259..6ac2ca0c30 100644 --- a/vm/devices/storage/scsidisk/src/lib.rs +++ b/vm/devices/storage/scsidisk/src/lib.rs @@ -53,9 +53,9 @@ use tracing_helpers::ErrorValueExt; use unmap::validate_lba_range; use vmcore::save_restore::RestoreError; use vmcore::save_restore::SaveError; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const UNMAP_RANGE_DESCRIPTOR_COUNT_MAX: u16 = 4096; const VHDMP_MAX_WRITE_SAME_LENGTH_BYTES: u64 = 8 * 1024 * 1024; // bytes @@ -276,7 +276,9 @@ impl SimpleScsiDisk { request: &Request, unit_attention: bool, ) -> Result { - let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; let min = size_of::(); @@ -321,12 +323,16 @@ impl SimpleScsiDisk { let header_size; let is_spbit_set; if is_mode_select_10 { - let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range request_length = cdb.parameter_list_length.get() as usize; header_size = MODE_PARAMETER_HEADER10_SIZE; is_spbit_set = cdb.flags.spbit(); } else { - let cdb = scsi::ModeSelect::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSelect::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range request_length = cdb.parameter_list_length as usize; header_size = MODE_PARAMETER_HEADER_SIZE; is_spbit_set = cdb.flags.spbit(); @@ -366,12 +372,14 @@ impl SimpleScsiDisk { let temp10 = scsi::ModeParameterHeader10::read_from_prefix( &buffer[..MODE_PARAMETER_HEADER10_SIZE], ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range usize::from(temp10.block_descriptor_length) } else { let temp = scsi::ModeParameterHeader::read_from_prefix(&buffer[..MODE_PARAMETER_HEADER_SIZE]) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range temp.block_descriptor_length as usize }; @@ -389,8 +397,8 @@ impl SimpleScsiDisk { let page = scsi::ModeCachingPage::read_from_prefix( &buffer[skipped..skipped + MODE_CACHING_PAGE_SIZE], ) - .unwrap(); - + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err if page.page_code != scsi::MODE_PAGE_CACHING || (page.page_length as usize) < MODE_CACHING_PAGE_SIZE || ((page.flags & scsi::MODE_CACHING_WRITE_CACHE_ENABLE == 0) @@ -440,13 +448,17 @@ impl SimpleScsiDisk { let allocation_length; let header_size; if is_mode_sense_10 { - let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range allocation_length = cdb.allocation_length.get() as usize; page_code = cdb.flags2.page_code(); page_control = cdb.flags2.pc() << 6; header_size = MODE_PARAMETER_HEADER10_SIZE; } else { - let cdb = scsi::ModeSense::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSense::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range allocation_length = cdb.allocation_length as usize; page_code = cdb.flags2.page_code(); page_control = cdb.flags2.pc() << 6; @@ -491,14 +503,14 @@ impl SimpleScsiDisk { temp10 = scsi::ModeParameterHeader10 { mode_data_length: MODE_DATA_LENGTH10.into(), device_specific_parameter: dsp, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; temp10.as_bytes() } else { temp = scsi::ModeParameterHeader { mode_data_length: MODE_DATA_LENGTH, device_specific_parameter: dsp, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; temp.as_bytes() }; @@ -506,7 +518,7 @@ impl SimpleScsiDisk { let mut page = scsi::ModeCachingPage { page_code: scsi::MODE_PAGE_CACHING, page_length: (MODE_CACHING_PAGE_SIZE - 2) as u8, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if (page_control == scsi::MODE_CONTROL_CURRENT_VALUES @@ -537,7 +549,9 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::ServiceActionIn16::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ServiceActionIn16::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range match cdb.service_action & 0x1f { scsi::SERVICE_ACTION_READ_CAPACITY16 => { let min = size_of::(); @@ -554,7 +568,7 @@ impl SimpleScsiDisk { bytes_per_block: (1u32 << self.sector_shift).into(), }, exponents: self.physical_extra_shift, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if self.scsi_parameters.support_unmap { @@ -624,7 +638,7 @@ impl SimpleScsiDisk { tracing::debug!("handle_verify_validation"); let (start_lba, lba_count) = match op { ScsiOp::VERIFY | ScsiOp::WRITE_VERIFY => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -635,7 +649,7 @@ impl SimpleScsiDisk { ) } ScsiOp::VERIFY12 | ScsiOp::WRITE_VERIFY12 => { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -646,7 +660,7 @@ impl SimpleScsiDisk { ) } ScsiOp::VERIFY16 | ScsiOp::WRITE_VERIFY16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range (cdb.logical_block.get(), cdb.transfer_blocks.get() as u64) } _ => unreachable!(), @@ -664,7 +678,9 @@ impl SimpleScsiDisk { fn handle_send_diagnostic_validation(&self, request: &Request) -> Result { tracing::debug!("handle_send_diagnostic_validation"); - let cdb = scsi::SendDiagnostic::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::SendDiagnostic::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range if cdb.flags.self_test_code() == 0 && !cdb.flags.page_format() && cdb.parameter_list_length.get() == 0 @@ -723,7 +739,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -757,7 +773,9 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb6ReadWrite::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb6ReadWrite::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let len = cdb.transfer_blocks as u64; let offset = u32::from_be_bytes([ 0, @@ -795,7 +813,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -828,7 +846,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range let len = cdb.transfer_blocks.get() as u64; let offset = cdb.logical_block.get(); let sector_shift = self.sector_shift; @@ -861,7 +879,7 @@ impl SimpleScsiDisk { let op = request.scsiop(); let mut p = match op { ScsiOp::WRITE_SAME => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -875,7 +893,7 @@ impl SimpleScsiDisk { } } ScsiOp::WRITE_SAME16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range WriteSameParameters { start_lba: cdb.logical_block.get(), lba_count: cdb.transfer_blocks.get() as usize, @@ -1198,7 +1216,9 @@ impl SimpleScsiDisk { } async fn handle_start_stop(&self, request: &Request) -> Result { - let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range if cdb.immediate & scsi::IMMEDIATE_BIT != 0 { tracing::debug!("immediate bit is not supported"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); diff --git a/vm/devices/storage/scsidisk/src/reservation.rs b/vm/devices/storage/scsidisk/src/reservation.rs index 64ac913ea5..b0e083ee90 100644 --- a/vm/devices/storage/scsidisk/src/reservation.rs +++ b/vm/devices/storage/scsidisk/src/reservation.rs @@ -18,9 +18,11 @@ use guestmem::MemoryWrite; use scsi::AdditionalSenseCode; use scsi::ScsiOp; use scsi_core::Request; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; fn from_scsi_reservation_type( scsi_type: scsi::ReservationType, @@ -163,7 +165,7 @@ impl SimpleScsiDisk { allocation_length: usize, ) -> Result { #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct Output { header: PriReservationListHeader, descriptor: PriReservationDescriptor, @@ -198,7 +200,7 @@ impl SimpleScsiDisk { .find_map(|d| d.holds_reservation.then_some(d.key)) .unwrap_or(0) .into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, }; has_reservation.as_bytes() @@ -254,7 +256,7 @@ impl SimpleScsiDisk { ), relative_target_port_identifier: controller.controller_id.into(), additional_descriptor_length: (controller.host_id.len() as u32).into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; data.extend(header.as_bytes()); @@ -266,7 +268,7 @@ impl SimpleScsiDisk { additional_length: ((data.len() - size_of::()) as u32).into(), }; - header.write_to_prefix(data.as_mut_slice()); + header.write_to_prefix(data.as_mut_slice()).unwrap(); // PANIC: Infallable since data extended to fit header above. // Copy as much as we can let tx = std::cmp::min(allocation_length, data.len()); @@ -283,7 +285,9 @@ impl SimpleScsiDisk { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::PersistentReserveIn::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::PersistentReserveIn::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; if allocation_length > external_data.len() { tracelimit::error_ratelimited!( @@ -337,7 +341,9 @@ impl SimpleScsiDisk { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::PersistentReserveOut::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::PersistentReserveOut::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let service_action = cdb.service_action.service_action(); const EXPECT_PARAMETER_LIST_LENGTH: usize = size_of::(); diff --git a/vm/devices/storage/scsidisk/src/scsidvd/mod.rs b/vm/devices/storage/scsidisk/src/scsidvd/mod.rs index 91acb784a1..06d5a21c9b 100644 --- a/vm/devices/storage/scsidisk/src/scsidvd/mod.rs +++ b/vm/devices/storage/scsidisk/src/scsidvd/mod.rs @@ -33,9 +33,11 @@ use thiserror::Error; use tracing::Instrument; use vmcore::save_restore::RestoreError; use vmcore::save_restore::SaveError; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; enum Media { Unloaded, @@ -292,7 +294,7 @@ impl ScsiSaveRestore for SimpleScsiDvd { /// /// Assumes that allocation_length is already validated to be at least /// `size_of::()`. -fn write_vpd_page( +fn write_vpd_page( external_data: &RequestBuffers<'_>, allocation_length: usize, page_code: u8, @@ -328,7 +330,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; @@ -415,7 +419,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbGetEventStatusNotification::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbGetEventStatusNotification::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.event_list_length.get() as usize; let mut pending_medium_event = IsoMediumEvent::None; @@ -695,7 +701,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbGetConfiguration::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbGetConfiguration::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let request_type = cdb.flags.request_type(); let starting_feature = cdb.starting_feature.get() as usize; let allocation_length = cdb.allocation_length.get() as usize; @@ -806,7 +814,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbReadToc::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbReadToc::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; let format = cdb.format2 & 0x0f; let msf = cdb.flag1.msf(); @@ -899,7 +909,9 @@ impl SimpleScsiDvd { } async fn handle_start_stop_unit(&self, request: &Request) -> Result { - let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let start = cdb.flag.start(); let load_eject = cdb.flag.load_eject(); @@ -965,7 +977,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbRequestSense::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbRequestSense::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length as usize; let new_sense_data = SenseData::new(SenseKey::NO_SENSE, AdditionalSenseCode::NO_SENSE, 0x00); @@ -989,7 +1003,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let page_code = cdb.flags2.page_code(); let allocation_length = cdb.allocation_length.get() as usize; let pc = cdb.flags2.pc() << 6; @@ -1060,7 +1076,9 @@ impl SimpleScsiDvd { } fn handle_medium_removal_iso(&self, request: &Request) -> Result { - let cdb = scsi::CdbMediaRemoval::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbMediaRemoval::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range // prevent/allow media removal based on the Persistent/Prevent bits let mut media_state = self.media_state.lock(); @@ -1074,7 +1092,9 @@ impl SimpleScsiDvd { request: &Request, external_data: &RequestBuffers<'_>, ) -> Result { - let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let sp_bit = cdb.flags.spbit(); let request_length = cdb.parameter_list_length.get() as usize; @@ -1131,8 +1151,8 @@ impl SimpleScsiDvd { ..super::MODE_PARAMETER_HEADER10_SIZE + size_of::()], ) - .unwrap(); - + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err match mode_page_error_recovery.page_code { scsi::MODE_PAGE_ERROR_RECOVERY => { // ModePageErrorRecovery = (PMODE_READ_WRITE_RECOVERY_PAGE) (Buffer + sizeof (MODE_PARAMETER_HEADER10)); @@ -1161,7 +1181,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbReadTrackInformation::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbReadTrackInformation::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let number_type = cdb.flag.number_type(); let open = cdb.flag.open(); let logical_track_number = cdb.logical_track_number.get() as usize; @@ -1239,7 +1261,7 @@ impl SimpleScsiDvd { */ data_mode: 0b00100001, track_size: last_lba.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = std::cmp::min(allocation_length, size_of::()); external_data @@ -1254,7 +1276,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbReadDVDStructure::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbReadDVDStructure::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let media_type = cdb.media_type; let layer = cdb.layer; let allocation_length = cdb.allocation_length.get() as usize; @@ -1361,7 +1385,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbGetPerformance::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbGetPerformance::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let data_type = cdb.data_type; let write = cdb.flags.write(); let tolerance = cdb.flags.tolerance(); @@ -1453,7 +1479,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbMechStatus::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbMechStatus::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let allocation_length = cdb.allocation_length.get() as usize; if allocation_length > external_data.len() { @@ -1465,7 +1493,7 @@ impl SimpleScsiDvd { let mechanism_status_header: scsi::MechanismStatusHeader = scsi::MechanismStatusHeader { flags: scsi::MechanismStatusHeaderFlags::new() .with_door_open(self.media_state.lock().drive_state.tray_open()), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = std::cmp::min(allocation_length, size_of::()); external_data @@ -1481,7 +1509,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbReadBufferCapacity::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbReadBufferCapacity::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let block_info = cdb.flags.block_info(); let allocation_length = cdb.allocation_length.get() as usize; @@ -1494,7 +1524,7 @@ impl SimpleScsiDvd { let data = scsi::ReadBufferCapacityData { data_length: (size_of::() as u16 - 2).into(), block_data_returned: block_info as u8, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; external_data @@ -1510,7 +1540,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbReadDiscInformation::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbReadDiscInformation::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let data_type = cdb.flags.data_type(); let allocation_length = cdb.allocation_length.get() as usize; @@ -1546,7 +1578,7 @@ impl SimpleScsiDvd { .with_uru(true) .with_dbc_v(false) .with_did_v(false), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; external_data .writer() @@ -1561,7 +1593,9 @@ impl SimpleScsiDvd { external_data: &RequestBuffers<'_>, request: &Request, ) -> Result { - let cdb = scsi::CdbSetStreaming::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::CdbSetStreaming::read_from_prefix(&request.cdb[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let parameter_list_length = usize::from(cdb.parameter_list_length); let mut buffer = vec![0; parameter_list_length]; @@ -1592,7 +1626,9 @@ impl SimpleScsiDvd { .read(&mut buffer) .map_err(ScsiDvdError::MemoryAccess)?; let performance_descriptor = - scsi::SetStreamingPerformanceDescriptor::read_from_prefix(&buffer[..]).unwrap(); + scsi::SetStreamingPerformanceDescriptor::read_from_prefix(&buffer[..]) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range // If RDD bit is set to one, it shall indicate that the drive is to return to its // default performance settings and the remaining fields in this descriptor shall be ignored. @@ -1753,7 +1789,7 @@ impl SimpleScsiDvd { .with_reserved(0), additional_length: 0x08, }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if bytes_used > 0 { external_data @@ -1954,7 +1990,7 @@ impl SimpleScsiDvd { let header = scsi::GetConfigurationHeader { data_length: (data_length as u32).into(), current_profile: current_profile.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = external_data.len(); @@ -1986,7 +2022,7 @@ impl SimpleScsiDvd { vendor_id: *b"Msft ", product_id: *b"Virtual DVD-ROM ", product_revision_level: *b"1.0 ", - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = std::cmp::min(allocation_length, size_of::()); @@ -2053,21 +2089,21 @@ impl SimpleScsiDvd { ) -> Result { let (len, offset) = match op { ScsiOp::READ => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range ( cdb.transfer_blocks.get() as u64, cdb.logical_block.get() as u64, ) } ScsiOp::READ12 => { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range ( cdb.transfer_blocks.get() as u64, cdb.logical_block.get() as u64, ) } ScsiOp::READ16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range (cdb.transfer_blocks.get() as u64, cdb.logical_block.get()) } _ => unreachable!(), @@ -2141,7 +2177,7 @@ impl SimpleScsiDvd { let data = scsi::PowerConditionPage { page_code: 0x1a, page_length: 0x0a, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; external_data .writer() @@ -2185,7 +2221,7 @@ impl SimpleScsiDvd { let data = scsi::ModeParameterHeader10 { mode_data_length: (data_length - (size_of::() as u16)).into(), block_descriptor_length: 0.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = std::cmp::min(super::MODE_PARAMETER_HEADER10_SIZE, buffer_size); external_data @@ -2222,7 +2258,7 @@ impl SimpleScsiDvd { let header = scsi::GetPerformanceHeader { total_data_length: (data_length as u32).into(), except: except & 0x01, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let tx = @@ -2358,7 +2394,8 @@ mod tests { use scsi_core::save_restore::ScsiDvdSavedState; use scsi_core::AsyncScsiDisk; use scsi_core::Request; - use zerocopy::AsBytes; + + use zerocopy::IntoBytes; #[derive(Debug)] struct TestDisk { diff --git a/vm/devices/storage/scsidisk/src/tests/basic_tests.rs b/vm/devices/storage/scsidisk/src/tests/basic_tests.rs index 45b68b118d..76ed1da5cb 100644 --- a/vm/devices/storage/scsidisk/src/tests/basic_tests.rs +++ b/vm/devices/storage/scsidisk/src/tests/basic_tests.rs @@ -29,7 +29,7 @@ use scsi_core::Request; use scsi_core::ScsiSaveRestore; use std::sync::atomic::Ordering; use std::sync::Arc; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; fn save_scsi_disk(scsi_disk: &SimpleScsiDisk) -> ScsiDiskSavedState { let saved_state = if let Some(ScsiSavedState::ScsiDisk(saved_state)) = scsi_disk.save().unwrap() diff --git a/vm/devices/storage/scsidisk/src/tests/pr_tests.rs b/vm/devices/storage/scsidisk/src/tests/pr_tests.rs index b43e679d2c..3b4d19f909 100644 --- a/vm/devices/storage/scsidisk/src/tests/pr_tests.rs +++ b/vm/devices/storage/scsidisk/src/tests/pr_tests.rs @@ -22,8 +22,8 @@ use scsi::SenseKey; use scsi_buffers::OwnedRequestBuffers; use scsi_core::Request; use scsi_core::ScsiResult; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const EXPECT_PARAMETER_LIST_LENGTH: usize = size_of::(); @@ -239,7 +239,7 @@ fn make_read_reservations_response( des = scsi::PriReservationDescriptor { type_scope: scsi::PersistentReserveTypeScope::new().with_reserve_type(ty), reservation_key: key.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; temp_data.extend(des.as_bytes()); } @@ -288,7 +288,7 @@ fn make_read_full_status_response( }, relative_target_port_identifier: 0_u16.into(), additional_descriptor_length: 8_u32.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; temp_data.extend(header.as_bytes()); temp_data.extend(0_u64.as_bytes()); diff --git a/vm/devices/storage/scsidisk/src/tests/test_helpers.rs b/vm/devices/storage/scsidisk/src/tests/test_helpers.rs index d798929657..ac04b533a6 100644 --- a/vm/devices/storage/scsidisk/src/tests/test_helpers.rs +++ b/vm/devices/storage/scsidisk/src/tests/test_helpers.rs @@ -24,7 +24,7 @@ use scsi_core::AsyncScsiDisk; use scsi_core::Request; use scsi_core::ScsiResult; use std::sync::Arc; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug)] pub struct TestDiskStorageState { diff --git a/vm/devices/storage/scsidisk/src/unmap.rs b/vm/devices/storage/scsidisk/src/unmap.rs index 2a1055c13e..ba61d7e5f1 100644 --- a/vm/devices/storage/scsidisk/src/unmap.rs +++ b/vm/devices/storage/scsidisk/src/unmap.rs @@ -30,8 +30,9 @@ fn validate_unmap_list_header( // We will find out how many block descriptors the unmap request has let unmap_list_header = scsi::UnmapListHeader::read_from_prefix(&buffer[0..size_of::()]) - .unwrap(); - let unmap_list_header_length = unmap_list_header.data_length.get() as usize; + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + let unmap_list_header_length = unmap_list_header.data_length.get() as usize; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range let expected = allocation_length - size_of_val(&unmap_list_header.data_length); if unmap_list_header_length != expected { tracelimit::error_ratelimited!(unmap_list_header_length, expected, "validate_unmap_error"); @@ -107,8 +108,8 @@ impl SimpleScsiDisk { let block_descriptor = scsi::UnmapBlockDescriptor::read_from_prefix( &buffer[unmap_info.offset..unmap_info.offset + size_of::()], ) - .unwrap(); - + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, err let start_lba = block_descriptor.start_lba.get(); let lba_count = block_descriptor.lba_count.get() as u64; @@ -135,7 +136,7 @@ impl SimpleScsiDisk { return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); } - let cdb = scsi::Unmap::read_from_prefix(&request.cdb[..]).unwrap(); + let cdb = scsi::Unmap::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range // make sure the data buffer is large enough for UNMAP_LIST_HEADER let allocation_length = cdb.allocation_length.get() as usize; diff --git a/vm/devices/storage/storage_string/Cargo.toml b/vm/devices/storage/storage_string/Cargo.toml index 90cd9114be..4b2d4ee09f 100644 --- a/vm/devices/storage/storage_string/Cargo.toml +++ b/vm/devices/storage/storage_string/Cargo.toml @@ -12,6 +12,5 @@ mesh_protobuf.workspace = true thiserror.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/storage/storage_string/src/lib.rs b/vm/devices/storage/storage_string/src/lib.rs index 454c63753b..ca74d3ad65 100644 --- a/vm/devices/storage/storage_string/src/lib.rs +++ b/vm/devices/storage/storage_string/src/lib.rs @@ -11,12 +11,13 @@ use inspect::Inspect; use mesh_protobuf::Protobuf; use std::str::FromStr; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// A fixed-size string that is padded out with ASCII spaces. -#[derive(Copy, Clone, Protobuf, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Protobuf, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(transparent)] #[mesh(transparent)] pub struct AsciiString([u8; N]); diff --git a/vm/devices/storage/storvsp/Cargo.toml b/vm/devices/storage/storvsp/Cargo.toml index 935dc9d456..75d582b757 100644 --- a/vm/devices/storage/storvsp/Cargo.toml +++ b/vm/devices/storage/storvsp/Cargo.toml @@ -56,7 +56,6 @@ tracelimit.workspace = true tracing.workspace = true unicycle.workspace = true zerocopy.workspace = true - [dev-dependencies] criterion = { workspace = true, features = ["async"] } disklayer_ram.workspace = true diff --git a/vm/devices/storage/storvsp/fuzz/Cargo.toml b/vm/devices/storage/storvsp/fuzz/Cargo.toml index 01cd47d733..ecf77f68eb 100644 --- a/vm/devices/storage/storvsp/fuzz/Cargo.toml +++ b/vm/devices/storage/storvsp/fuzz/Cargo.toml @@ -23,7 +23,6 @@ vmbus_channel.workspace = true vmbus_ring.workspace = true xtask_fuzz.workspace = true zerocopy.workspace = true - [target.'cfg(all(target_os = "linux", target_env = "gnu"))'.dependencies] libfuzzer-sys.workspace = true diff --git a/vm/devices/storage/storvsp/fuzz/fuzz_storvsp.rs b/vm/devices/storage/storvsp/fuzz/fuzz_storvsp.rs index 38ee547904..b27c40cd01 100644 --- a/vm/devices/storage/storvsp/fuzz/fuzz_storvsp.rs +++ b/vm/devices/storage/storvsp/fuzz/fuzz_storvsp.rs @@ -26,8 +26,8 @@ use vmbus_channel::connected_async_channels; use vmbus_ring::OutgoingPacketType; use vmbus_ring::PAGE_SIZE; use xtask_fuzz::fuzz_target; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Arbitrary)] enum StorvspFuzzAction { @@ -110,7 +110,7 @@ async fn send_arbitrary_readwrite_packet( operation_code: *(u.choose(&scsiop_choices)?), logical_block: block.into(), transfer_blocks: ((byte_len / 512) as u16).into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut scsi_req = protocol::ScsiRequest { @@ -121,7 +121,7 @@ async fn send_arbitrary_readwrite_packet( cdb_length: size_of::() as u8, data_transfer_length: byte_len.try_into()?, data_in: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; scsi_req.payload[0..10].copy_from_slice(cdb.as_bytes()); diff --git a/vm/devices/storage/storvsp/src/ioperf.rs b/vm/devices/storage/storvsp/src/ioperf.rs index c1a763c57d..013d5d6249 100644 --- a/vm/devices/storage/storvsp/src/ioperf.rs +++ b/vm/devices/storage/storvsp/src/ioperf.rs @@ -18,7 +18,10 @@ use scsidisk::SimpleScsiDisk; use std::sync::Arc; use vmbus_async::queue::Queue; use vmbus_channel::connected_async_channels; -use zerocopy::AsBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub struct PerfTester { _worker: TestWorker, diff --git a/vm/devices/storage/storvsp/src/lib.rs b/vm/devices/storage/storvsp/src/lib.rs index e8e82e7e2f..2358933cd6 100644 --- a/vm/devices/storage/storvsp/src/lib.rs +++ b/vm/devices/storage/storvsp/src/lib.rs @@ -96,9 +96,11 @@ use vmcore::save_restore::SaveError; use vmcore::save_restore::SavedStateBlob; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub struct StorageDevice { instance_id: Guid, @@ -381,7 +383,7 @@ fn parse_packet( protocol::Operation::QUERY_PROTOCOL_VERSION => { let mut version = protocol::ProtocolVersion::new_zeroed(); reader - .read(version.as_bytes_mut()) + .read(version.as_mut_bytes()) .map_err(PacketError::Access)?; PacketData::QueryProtocolVersion(version.major_minor) } @@ -397,7 +399,7 @@ fn parse_packet( { let full_request = Arc::get_mut(&mut full_request).unwrap(); - let request_buf = &mut full_request.request.as_bytes_mut()[..request_size]; + let request_buf = &mut full_request.request.as_mut_bytes()[..request_size]; reader.read(request_buf).map_err(PacketError::Access)?; let buf = packet.read_external_ranges().map_err(PacketError::Range)?; @@ -414,7 +416,7 @@ fn parse_packet( protocol::Operation::CREATE_SUB_CHANNELS => { let mut sub_channel_count: u16 = 0; reader - .read(sub_channel_count.as_bytes_mut()) + .read(sub_channel_count.as_mut_bytes()) .map_err(PacketError::Access)?; PacketData::CreateSubChannels(sub_channel_count) } @@ -480,7 +482,7 @@ impl WorkerInner { }) } - fn send_packet( + fn send_packet( &mut self, writer: &mut queue::WriteHalf<'_, M>, operation: protocol::Operation, @@ -498,7 +500,7 @@ impl WorkerInner { ) } - fn send_completion( + fn send_completion( &mut self, writer: &mut queue::WriteHalf<'_, M>, packet: &Packet, @@ -577,9 +579,9 @@ impl ScsiCommandQueue { length: (luns.len() as u32 * 8).into(), reserved: [0; 4], }; - data.as_bytes_mut()[..HEADER_SIZE].copy_from_slice(header.as_bytes()); + data.as_mut_bytes()[..HEADER_SIZE].copy_from_slice(header.as_bytes()); for (i, lun) in luns.iter().enumerate() { - data[i + 1].as_bytes_mut()[..2].copy_from_slice(&(*lun as u16).to_be_bytes()); + data[i + 1].as_mut_bytes()[..2].copy_from_slice(&(*lun as u16).to_be_bytes()); } if external_data.len() >= HEADER_SIZE { let tx = std::cmp::min(external_data.len(), data.as_bytes().len()); @@ -624,7 +626,9 @@ impl ScsiCommandQueue { .await } ScsiOp::INQUIRY => { - let cdb = scsi::CdbInquiry::ref_from_prefix(&request.payload).unwrap(); + let cdb = scsi::CdbInquiry::ref_from_prefix(&request.payload) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range if external_data.len() < cdb.allocation_length.get() as usize || request.data_in != protocol::SCSI_IOCTL_DATA_IN || (cdb.allocation_length.get() as usize) < size_of::() @@ -1623,7 +1627,7 @@ impl VmbusDevice for StorageDevice { path_id: path.path, target_id: path.target, flags: protocol::OFFER_PROPERTIES_FLAG_IDE_DEVICE, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut user_defined = UserDefinedData::new_zeroed(); offer_properties @@ -1866,7 +1870,8 @@ mod tests { major_minor: !0, reserved: 0, } - .write_to_prefix(&mut buf[..]); + .write_to_prefix(&mut buf[..]) + .unwrap(); // PANIC: Infallable since `ProtcolVersion` is less than 128 bytes for &(len, resp_len) in &[(48, 48), (50, 56), (56, 56), (64, 64), (72, 64)] { guest diff --git a/vm/devices/storage/storvsp/src/protocol.rs b/vm/devices/storage/storvsp/src/protocol.rs index 6e0c7d414f..a3aa1fb79b 100644 --- a/vm/devices/storage/storvsp/src/protocol.rs +++ b/vm/devices/storage/storvsp/src/protocol.rs @@ -8,9 +8,10 @@ use open_enum::open_enum; use scsi_defs::srb::SrbStatusAndFlags; use scsi_defs::ScsiStatus; use std::fmt::Debug; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const SCSI_INTERFACE_ID: Guid = Guid::from_static_str("ba6163d9-04a1-4d29-b605-72e2ffb1dc7f"); @@ -21,7 +22,7 @@ pub const IDE_ACCELERATOR_INTERFACE_ID: Guid = /// this to determine the IDE device the channel is for. Newer drivers and Linux /// just look at instance ID. #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct OfferProperties { pub reserved: u16, pub path_id: u8, @@ -44,7 +45,7 @@ pub const VERSION_BLUE: u16 = version(6, 0); pub const VERSION_THRESHOLD: u16 = version(6, 2); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum NtStatus: u32 { SUCCESS = 0x0000_0000, @@ -66,7 +67,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct Packet { // Requested operation type @@ -78,7 +79,7 @@ pub struct Packet { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum Operation: u32 { COMPLETE_IO = 1, @@ -103,7 +104,7 @@ pub const MAX_DATA_BUFFER_LENGTH_WITH_PADDING: usize = 0x14; pub const VMSCSI_SENSE_BUFFER_SIZE: usize = 0x14; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct ScsiRequest { pub length: u16, @@ -140,7 +141,7 @@ pub const SCSI_REQUEST_LEN_MAX: usize = SCSI_REQUEST_LEN_V2; const _: () = assert!(SCSI_REQUEST_LEN_MAX == size_of::()); #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ChannelProperties { pub reserved: u32, pub maximum_sub_channel_count: u16, @@ -154,7 +155,7 @@ pub struct ChannelProperties { pub const STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL: u32 = 0x1; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ProtocolVersion { // Major (MSB) and minor (LSB) version numbers. pub major_minor: u16, @@ -162,13 +163,13 @@ pub struct ProtocolVersion { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClientProperties { flags: u32, // AsyncNotifyCapable } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NotificationPacket { pub lun: u8, pub target: u8, diff --git a/vm/devices/storage/storvsp/src/save_restore.rs b/vm/devices/storage/storvsp/src/save_restore.rs index ac0e8e8f58..8ff57a171d 100644 --- a/vm/devices/storage/storvsp/src/save_restore.rs +++ b/vm/devices/storage/storvsp/src/save_restore.rs @@ -23,8 +23,8 @@ use vmbus_ring::gparange::GpnList; use vmbus_ring::gparange::MultiPagedRangeBuf; use vmcore::save_restore::RestoreError; use vmcore::save_restore::SaveError; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; mod state { use mesh::payload::Protobuf; @@ -219,7 +219,7 @@ impl state::ScsiRequestSavedState { let mut protocol_request = protocol::ScsiRequest::new_zeroed(); protocol_request - .as_bytes_mut() + .as_mut_bytes() .get_mut(..request.len()) .ok_or(StorvspRestoreError::RequestTooLarge)? .copy_from_slice(request); diff --git a/vm/devices/storage/storvsp/src/test_helpers.rs b/vm/devices/storage/storvsp/src/test_helpers.rs index cc2db90435..f784166ba9 100644 --- a/vm/devices/storage/storvsp/src/test_helpers.rs +++ b/vm/devices/storage/storvsp/src/test_helpers.rs @@ -35,8 +35,8 @@ use vmbus_ring as ring; use vmbus_ring::FlatRingMem; use vmbus_ring::OutgoingPacketType; use vmbus_ring::PAGE_SIZE; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; pub struct TestWorker { task: Task>, @@ -236,7 +236,7 @@ impl TestGuest { operation_code: ScsiOp::WRITE, logical_block: block.into(), transfer_blocks: ((byte_len / 512) as u16).into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut scsi_req = protocol::ScsiRequest { @@ -246,7 +246,7 @@ impl TestGuest { length: protocol::SCSI_REQUEST_LEN_V2 as u16, cdb_length: size_of::() as u8, data_transfer_length: byte_len as u32, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; scsi_req.payload[0..10].copy_from_slice(cdb.as_bytes()); @@ -278,7 +278,7 @@ impl TestGuest { operation_code: ScsiOp::READ, logical_block: block.into(), transfer_blocks: ((byte_len / 512) as u16).into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut scsi_req = protocol::ScsiRequest { @@ -289,7 +289,7 @@ impl TestGuest { cdb_length: size_of::() as u8, data_transfer_length: byte_len as u32, data_in: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; scsi_req.payload[0..10].copy_from_slice(cdb.as_bytes()); @@ -317,7 +317,7 @@ impl TestGuest { let cdb = scsi::Cdb10 { operation_code: ScsiOp::REPORT_LUNS, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut scsi_req = protocol::ScsiRequest { @@ -328,7 +328,7 @@ impl TestGuest { cdb_length: size_of::() as u8, data_transfer_length: data_buffer_len as u32, data_in: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; scsi_req.payload[0..10].copy_from_slice(cdb.as_bytes()); diff --git a/vm/devices/support/fs/fuse/Cargo.toml b/vm/devices/support/fs/fuse/Cargo.toml index e2251c1416..a85377c0a6 100644 --- a/vm/devices/support/fs/fuse/Cargo.toml +++ b/vm/devices/support/fs/fuse/Cargo.toml @@ -17,7 +17,6 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(unix)'.dependencies] libc.workspace = true diff --git a/vm/devices/support/fs/fuse/src/lib.rs b/vm/devices/support/fs/fuse/src/lib.rs index 46fb0142f7..7be846f54b 100644 --- a/vm/devices/support/fs/fuse/src/lib.rs +++ b/vm/devices/support/fs/fuse/src/lib.rs @@ -26,9 +26,10 @@ use lx::LxStr; use lx::LxString; use protocol::*; use std::time::Duration; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Reply data for the `create` operation. /// @@ -36,7 +37,7 @@ use zerocopy::FromZeroes; /// combination of these values as they're just passed as separate arguments to `fuse_reply_create` /// in libfuse. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CreateOut { pub entry: fuse_entry_out, pub open: fuse_open_out, diff --git a/vm/devices/support/fs/fuse/src/protocol.rs b/vm/devices/support/fs/fuse/src/protocol.rs index 8db86ebd35..52172324da 100644 --- a/vm/devices/support/fs/fuse/src/protocol.rs +++ b/vm/devices/support/fs/fuse/src/protocol.rs @@ -12,9 +12,10 @@ #![allow(dead_code)] #![allow(unused_parens)] -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /* * Version negotiation: @@ -49,7 +50,7 @@ pub const FUSE_ROOT_ID: u64 = 1; userspace works under 64bit kernels */ #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_attr { pub ino: u64, pub size: u64, @@ -70,7 +71,7 @@ pub struct fuse_attr { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_kstatfs { pub blocks: u64, pub bfree: u64, @@ -85,7 +86,7 @@ pub struct fuse_kstatfs { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_file_lock { pub start: u64, pub end: u64, @@ -331,7 +332,7 @@ pub const FUSE_MIN_READ_BUFFER: u32 = 8192; pub const FUSE_COMPAT_ENTRY_OUT_SIZE: u32 = 120; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_entry_out { pub nodeid: u64, /* Inode ID */ pub generation: u64, /* Inode generation: nodeid:gen must @@ -344,27 +345,27 @@ pub struct fuse_entry_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_forget_in { pub nlookup: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_forget_one { pub nodeid: u64, pub nlookup: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_batch_forget_in { pub count: u32, pub dummy: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_getattr_in { pub getattr_flags: u32, pub dummy: u32, @@ -374,7 +375,7 @@ pub struct fuse_getattr_in { pub const FUSE_COMPAT_ATTR_OUT_SIZE: u32 = 96; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_attr_out { pub attr_valid: u64, /* Cache timeout for the attributes */ pub attr_valid_nsec: u32, @@ -385,7 +386,7 @@ pub struct fuse_attr_out { pub const FUSE_COMPAT_MKNOD_IN_SIZE: u32 = 8; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_mknod_in { pub mode: u32, pub rdev: u32, @@ -394,20 +395,20 @@ pub struct fuse_mknod_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_mkdir_in { pub mode: u32, pub umask: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_rename_in { pub newdir: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_rename2_in { pub newdir: u64, pub flags: u32, @@ -415,13 +416,13 @@ pub struct fuse_rename2_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_link_in { pub oldnodeid: u64, } #[repr(C)] -#[derive(Clone, Copy, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_setattr_in { pub valid: u32, pub padding: u32, @@ -442,14 +443,14 @@ pub struct fuse_setattr_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_open_in { pub flags: u32, pub unused: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_create_in { pub flags: u32, pub mode: u32, @@ -458,7 +459,7 @@ pub struct fuse_create_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_open_out { pub fh: u64, pub open_flags: u32, @@ -466,7 +467,7 @@ pub struct fuse_open_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_release_in { pub fh: u64, pub flags: u32, @@ -475,7 +476,7 @@ pub struct fuse_release_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_flush_in { pub fh: u64, pub unused: u32, @@ -484,7 +485,7 @@ pub struct fuse_flush_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_read_in { pub fh: u64, pub offset: u64, @@ -498,7 +499,7 @@ pub struct fuse_read_in { pub const FUSE_COMPAT_WRITE_IN_SIZE: u32 = 24; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_write_in { pub fh: u64, pub offset: u64, @@ -510,7 +511,7 @@ pub struct fuse_write_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_write_out { pub size: u32, pub padding: u32, @@ -519,13 +520,13 @@ pub struct fuse_write_out { pub const FUSE_COMPAT_STATFS_SIZE: u32 = 48; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_statfs_out { pub st: fuse_kstatfs, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_fsync_in { pub fh: u64, pub fsync_flags: u32, @@ -533,28 +534,28 @@ pub struct fuse_fsync_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_setxattr_in { pub size: u32, pub flags: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_getxattr_in { pub size: u32, pub padding: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_getxattr_out { pub size: u32, pub padding: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_lk_in { pub fh: u64, pub owner: u64, @@ -564,20 +565,20 @@ pub struct fuse_lk_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_lk_out { pub lk: fuse_file_lock, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_access_in { pub mask: u32, pub padding: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_init_in { pub major: u32, pub minor: u32, @@ -589,7 +590,7 @@ pub const FUSE_COMPAT_INIT_OUT_SIZE: u32 = 8; pub const FUSE_COMPAT_22_INIT_OUT_SIZE: u32 = 24; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_init_out { pub major: u32, pub minor: u32, @@ -607,7 +608,7 @@ pub struct fuse_init_out { pub const CUSE_INIT_INFO_MAX: u32 = 4096; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct cuse_init_in { pub major: u32, pub minor: u32, @@ -616,7 +617,7 @@ pub struct cuse_init_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct cuse_init_out { pub major: u32, pub minor: u32, @@ -630,13 +631,13 @@ pub struct cuse_init_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_interrupt_in { pub unique: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_bmap_in { pub block: u64, pub blocksize: u32, @@ -644,13 +645,13 @@ pub struct fuse_bmap_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_bmap_out { pub block: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_ioctl_in { pub fh: u64, pub flags: u32, @@ -661,14 +662,14 @@ pub struct fuse_ioctl_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_ioctl_iovec { pub base: u64, pub len: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_ioctl_out { pub result: i32, pub flags: u32, @@ -677,7 +678,7 @@ pub struct fuse_ioctl_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_poll_in { pub fh: u64, pub kh: u64, @@ -686,20 +687,20 @@ pub struct fuse_poll_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_poll_out { pub revents: u32, pub padding: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_poll_wakeup_out { pub kh: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_fallocate_in { pub fh: u64, pub offset: u64, @@ -709,7 +710,7 @@ pub struct fuse_fallocate_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_in_header { pub len: u32, pub opcode: u32, @@ -722,7 +723,7 @@ pub struct fuse_in_header { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_out_header { pub len: u32, pub error: i32, @@ -730,7 +731,7 @@ pub struct fuse_out_header { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_dirent { pub ino: u64, pub off: u64, @@ -743,14 +744,14 @@ pub fn fuse_dirent_align(x: usize) -> usize { (((x) + size_of::() - 1) & !(size_of::() - 1)) } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_direntplus { pub entry_out: fuse_entry_out, pub dirent: fuse_dirent, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_inval_inode_out { pub ino: u64, pub off: i64, @@ -758,7 +759,7 @@ pub struct fuse_notify_inval_inode_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_inval_entry_out { pub parent: u64, pub namelen: u32, @@ -766,7 +767,7 @@ pub struct fuse_notify_inval_entry_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_delete_out { pub parent: u64, pub child: u64, @@ -775,7 +776,7 @@ pub struct fuse_notify_delete_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_store_out { pub nodeid: u64, pub offset: u64, @@ -784,7 +785,7 @@ pub struct fuse_notify_store_out { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_retrieve_out { pub notify_unique: u64, pub nodeid: u64, @@ -795,7 +796,7 @@ pub struct fuse_notify_retrieve_out { /* Matches the size of fuse_write_in */ #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_notify_retrieve_in { pub dummy1: u64, pub offset: u64, @@ -809,7 +810,7 @@ pub struct fuse_notify_retrieve_in { // const FUSE_DEV_IOC_CLONE: u32 = _IOR(229, 0, u32); #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_lseek_in { pub fh: u64, pub offset: u64, @@ -818,13 +819,13 @@ pub struct fuse_lseek_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_lseek_out { pub offset: u64, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_copy_file_range_in { pub fh_in: u64, pub off_in: u64, @@ -838,7 +839,7 @@ pub struct fuse_copy_file_range_in { pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = (1 << 0); #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_setupmapping_in { /* An already open handle */ pub fh: u64, @@ -853,14 +854,14 @@ pub struct fuse_setupmapping_in { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_removemapping_in { /* number of fuse_removemapping_one follows */ pub count: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_removemapping_one { /* Offset into the dax to start the unmapping */ pub moffset: u64, @@ -869,7 +870,7 @@ pub struct fuse_removemapping_one { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct fuse_syncfs_in { pub padding: u64, } diff --git a/vm/devices/support/fs/fuse/src/reply.rs b/vm/devices/support/fs/fuse/src/reply.rs index 78f4b96ed8..d765af0569 100644 --- a/vm/devices/support/fs/fuse/src/reply.rs +++ b/vm/devices/support/fs/fuse/src/reply.rs @@ -4,8 +4,10 @@ use super::protocol::*; use std::io; use std::io::Write; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Trait used by objects that send FUSE replies to the kernel. pub trait ReplySender { @@ -19,7 +21,11 @@ pub trait ReplySender { } /// Send a reply with a struct as an argument. - fn send_arg(&mut self, unique: u64, arg: T) -> io::Result<()> { + fn send_arg( + &mut self, + unique: u64, + arg: T, + ) -> io::Result<()> { tracing::trace!(unique, ?arg, "reply"); let header = make_header(unique, size_of_val(&arg), 0); let header = header.as_bytes(); @@ -47,7 +53,7 @@ pub trait ReplySender { } /// Send a reply with a struct argument and arbitrary data. - fn send_arg_data( + fn send_arg_data( &mut self, unique: u64, arg: T, diff --git a/vm/devices/support/fs/fuse/src/request.rs b/vm/devices/support/fs/fuse/src/request.rs index d5707c0137..f6dd13d3da 100644 --- a/vm/devices/support/fs/fuse/src/request.rs +++ b/vm/devices/support/fs/fuse/src/request.rs @@ -6,8 +6,10 @@ mod macros; use crate::protocol::*; use std::io; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Define an enum for all operations and their arguments. fuse_operations! { @@ -180,9 +182,9 @@ pub trait RequestReader: io::Read { } /// Read a struct of type `T`. - fn read_type(&mut self) -> lx::Result { + fn read_type(&mut self) -> lx::Result { let mut value: T = T::new_zeroed(); - self.read_exact(value.as_bytes_mut())?; + self.read_exact(value.as_mut_bytes())?; Ok(value) } diff --git a/vm/devices/support/fs/fuse/src/session.rs b/vm/devices/support/fs/fuse/src/session.rs index 47d84df546..1414958aba 100644 --- a/vm/devices/support/fs/fuse/src/session.rs +++ b/vm/devices/support/fs/fuse/src/session.rs @@ -16,7 +16,9 @@ use parking_lot::RwLock; use std::io; use std::sync::atomic; use thiserror::Error; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::KnownLayout; // These are the flags that libfuse enables by default when calling init. const DEFAULT_FLAGS: u32 = FUSE_ASYNC_READ @@ -488,7 +490,9 @@ impl Session { } /// Send a reply and call the release method if the reply was interrupted. - fn send_release_if_interrupted( + fn send_release_if_interrupted< + TArg: zerocopy::IntoBytes + std::fmt::Debug + Immutable + KnownLayout, + >( &self, request: &Request, sender: &mut impl ReplySender, diff --git a/vm/devices/support/fs/fuse/tests/fuse_hello.rs b/vm/devices/support/fs/fuse/tests/fuse_hello.rs index 0fa3b3c95c..3b0062accf 100644 --- a/vm/devices/support/fs/fuse/tests/fuse_hello.rs +++ b/vm/devices/support/fs/fuse/tests/fuse_hello.rs @@ -12,7 +12,7 @@ use fuse::*; use std::fs; use std::os::linux::fs::MetadataExt; use std::path::Path; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; // Implements a file system similar to libfuse's hello_ll sample. // This test is excluded from CI because it requires root. diff --git a/vm/devices/support/fs/lxutil/Cargo.toml b/vm/devices/support/fs/lxutil/Cargo.toml index 65fc5a1938..ea0ec86f95 100644 --- a/vm/devices/support/fs/lxutil/Cargo.toml +++ b/vm/devices/support/fs/lxutil/Cargo.toml @@ -25,7 +25,6 @@ ntapi.workspace = true parking_lot.workspace = true widestring.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies.winapi] workspace = true features = [ diff --git a/vm/devices/support/fs/lxutil/src/windows/mod.rs b/vm/devices/support/fs/lxutil/src/windows/mod.rs index 1a6f9a35ca..56d57fda90 100644 --- a/vm/devices/support/fs/lxutil/src/windows/mod.rs +++ b/vm/devices/support/fs/lxutil/src/windows/mod.rs @@ -31,9 +31,11 @@ use winapi::shared::basetsd; use winapi::shared::ntdef; use winapi::shared::ntstatus; use winapi::um::winnt; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const DOT_ENTRY_COUNT: lx::off_t = 2; @@ -1038,7 +1040,7 @@ impl LxVolume { /// See ntifs.h REPARSE_DATA_BUFFER. #[allow(non_snake_case)] #[repr(C)] - #[derive(Clone, Copy, AsBytes, FromBytes, FromZeroes)] + #[derive(Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] struct REPARSE_DATA_BUFFER { ReparseTag: u32, ReparseDataLength: u16, diff --git a/vm/devices/support/fs/lxutil/src/windows/util.rs b/vm/devices/support/fs/lxutil/src/windows/util.rs index 170aa013c2..487e8b7456 100644 --- a/vm/devices/support/fs/lxutil/src/windows/util.rs +++ b/vm/devices/support/fs/lxutil/src/windows/util.rs @@ -18,9 +18,11 @@ use winapi::shared::ntdef; use winapi::shared::ntstatus; use winapi::um::winioctl; use winapi::um::winnt; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Minimum permissions needed to access a file's metadata. pub const MINIMUM_PERMISSIONS: u32 = @@ -793,7 +795,7 @@ pub fn create_link( // at the end removed. u8 arrays are used for fields to remove the need for padding and repr(packed). #[allow(non_snake_case)] #[repr(C)] - #[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] struct FILE_LINK_INFORMATION { ReplaceIfExists: ntdef::BOOLEAN, pad: [u8; 7], @@ -804,7 +806,7 @@ pub fn create_link( } // Default + FromBytes: External APIs require Default (even though the - // all-zero repr is not a semantically valid default) + // all-zero repr is not a semantically valid default + Immutable + KnownLayout) impl Default for FILE_LINK_INFORMATION { fn default() -> Self { Self::new_zeroed() diff --git a/vm/devices/tpm/Cargo.toml b/vm/devices/tpm/Cargo.toml index 2320a29a67..e0c26a5770 100644 --- a/vm/devices/tpm/Cargo.toml +++ b/vm/devices/tpm/Cargo.toml @@ -34,6 +34,5 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/tpm/src/lib.rs b/vm/devices/tpm/src/lib.rs index c2e11ac44c..192fd2f78f 100644 --- a/vm/devices/tpm/src/lib.rs +++ b/vm/devices/tpm/src/lib.rs @@ -50,8 +50,8 @@ use tpm_resources::TpmRegisterLayout; use vmcore::device_state::ChangeDeviceState; use vmcore::non_volatile_store::NonVolatileStore; use vmcore::non_volatile_store::NonVolatileStoreError; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; pub const TPM_DEVICE_MMIO_REGION_BASE_ADDRESS: u64 = 0xfed40000; pub const TPM_DEVICE_MMIO_REGION_SIZE: u64 = 0x70; @@ -487,7 +487,7 @@ impl Tpm { // Create auth value for NV index password authorization. // The value needs to be preserved across live servicing. let mut auth_value = 0; - getrandom::getrandom(auth_value.as_bytes_mut()).expect("rng failure"); + getrandom::getrandom(auth_value.as_mut_bytes()).expect("rng failure"); self.auth_value = Some(auth_value); // Initialize `TpmKeys`. @@ -1127,7 +1127,7 @@ impl MmioIntercept for Tpm { }; let mut val: u32 = 0; - val.as_bytes_mut()[..data.len()].copy_from_slice(data); + val.as_mut_bytes()[..data.len()].copy_from_slice(data); match (address - TPM_DEVICE_MMIO_REGION_BASE_ADDRESS) as usize { ControlArea::OFFSET_OF_LOC_STATE => {} ControlArea::OFFSET_OF_LOC_CTRL => self.requested_locality = val & 0x2 != 0x2, @@ -1160,7 +1160,8 @@ impl MmioIntercept for Tpm { let cmd_header = tpm20proto::protocol::common::CmdHeader::ref_from_prefix( &self.command_buffer, ) - .and_then(|cmd_header| cmd_header.command_code.into_enum()); + .ok() // todo: zerocopy: err + .and_then(|(cmd_header, _)| cmd_header.command_code.into_enum()); tracing::debug!( cmd = ?cmd_header, @@ -1191,7 +1192,7 @@ impl MmioIntercept for Tpm { response_code = ?tpm20proto::protocol::common::ReplyHeader::ref_from_prefix( &self.tpm_engine_helper.reply_buffer, ) - .map(|reply| reply.response_code), + .map(|(reply, _)| reply.response_code), // todo: zerocopy: manual: review carefully! "response code from guest tpm cmd", ); @@ -1233,13 +1234,15 @@ impl MmioIntercept for Tpm { /// The IO port interface bespoke to the Hyper-V implementation of the vTPM. mod io_port_interface { use inspect::Inspect; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; open_enum::open_enum! { /// I/O port command definitions - #[derive(Inspect, AsBytes, FromBytes, FromZeroes)] + #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes, )] #[inspect(debug)] pub enum TpmIoCommand: u32 { /// It can be used for engine vs. guest version negotiation. Not used. @@ -1279,7 +1282,7 @@ mod io_port_interface { /// Table 2: Physical Presence Interface Operation Summary for TPM 2.0 /// /// Part of the Physical Presence Interface Specification - TCG PC Client Platform - #[derive(Inspect, AsBytes, FromBytes, FromZeroes)] + #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes, )] #[inspect(debug)] pub enum PpiOperation: u32 { NO_OP = 0, @@ -1308,11 +1311,13 @@ mod persist_restore { use super::*; mod state { - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; + + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(C)] pub struct PersistedPpiState { pub pending_ppi_operation: u32, @@ -1326,7 +1331,7 @@ mod persist_restore { } pub(crate) fn deserialize_ppi_state(buf: Vec) -> Option { - let saved = state::PersistedPpiState::read_from(buf.as_bytes())?; + let saved = state::PersistedPpiState::read_from_bytes(buf.as_bytes()).ok()?; // todo: zerocopy: map_err let state::PersistedPpiState { pending_ppi_operation, in_query_ppi_operation, diff --git a/vm/devices/tpm/src/tpm20proto.rs b/vm/devices/tpm/src/tpm20proto.rs index a6fb21999e..fb5bf877ff 100644 --- a/vm/devices/tpm/src/tpm20proto.rs +++ b/vm/devices/tpm/src/tpm20proto.rs @@ -9,10 +9,11 @@ use self::packed_nums::*; use bitfield_struct::bitfield; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::ByteOrder; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -78,7 +79,7 @@ pub enum ResponseValidationError { } #[repr(transparent)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct ReservedHandle(pub u32_be); impl PartialEq for u32 { @@ -114,7 +115,7 @@ pub const NV_INDEX_RANGE_BASE_TCG_ASSIGNED: u32 = (TPM20_HT_NV_INDEX as u32) << pub const MAX_DIGEST_BUFFER_SIZE: usize = 1024; #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SessionTag(pub u16_be); impl PartialEq for u16 { @@ -199,7 +200,7 @@ impl SessionTagEnum { } #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct CommandCode(pub u32_be); impl PartialEq for u32 { @@ -581,7 +582,7 @@ impl ResponseCode { } #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct AlgId(pub u16_be); impl PartialEq for u16 { @@ -635,7 +636,7 @@ impl AlgIdEnum { /// `TPMA_OBJECT` #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct TpmaObject(pub u32_be); impl TpmaObject { @@ -682,7 +683,7 @@ pub struct TpmaObjectBits { /// `TPMA_NV` #[repr(transparent)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct TpmaNv(pub u32_be); impl TpmaNv { @@ -767,7 +768,7 @@ pub mod protocol { use super::*; #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CmdHeader { pub session_tag: SessionTag, pub size: u32_be, @@ -789,7 +790,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReplyHeader { pub session_tag: u16_be, pub size: u32_be, @@ -850,7 +851,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CmdAuth { handle: ReservedHandle, nonce_2b: u16_be, @@ -870,7 +871,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReplyAuth { pub nonce_2b: u16_be, pub session: u8, @@ -882,7 +883,7 @@ pub mod protocol { use common::ReplyHeader; /// Marker trait for a struct that corresponds to a TPM Command - pub trait TpmCommand: AsBytes + FromBytes + Sized { + pub trait TpmCommand: IntoBytes + FromBytes + Sized + Immutable + KnownLayout { type Reply: TpmReply; fn base_validate_reply( @@ -898,7 +899,7 @@ pub mod protocol { } /// Marker trait for a struct that corresponds to a TPM Reply - pub trait TpmReply: AsBytes + FromBytes + Sized { + pub trait TpmReply: IntoBytes + FromBytes + Sized + Immutable + KnownLayout { type Command: TpmCommand; fn base_validation( @@ -906,8 +907,9 @@ pub mod protocol { session_tag: SessionTag, ) -> Result { // `Reply::deserialize` guarantees this should not fail - let header = - ReplyHeader::ref_from_prefix(self.as_bytes()).expect("unexpected response size"); + let header = ReplyHeader::ref_from_prefix(self.as_bytes()) + .expect("unexpected response size") + .0; // todo: zerocopy: error header.base_validation(session_tag, self.payload_size() as u32) } fn deserialize(bytes: &[u8]) -> Option; @@ -916,7 +918,7 @@ pub mod protocol { /// General type for TPM 2.0 sized buffers. #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct Tpm2bBuffer { pub size: u16_be, // Use value that is large enough as the buffer size so that we @@ -960,7 +962,7 @@ pub mod protocol { return None; } - let size = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let size: u16 = u16_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify if size as usize > MAX_DIGEST_BUFFER_SIZE { return None; } @@ -991,7 +993,7 @@ pub mod protocol { /// `TPML_PCR_SELECTION` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmlPcrSelection { pub count: u32_be, pub pcr_selections: [PcrSelection; 5], @@ -1032,7 +1034,7 @@ pub mod protocol { return None; } - let count = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let count: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify if count > 5 { return None; } @@ -1065,7 +1067,7 @@ pub mod protocol { /// `TPMS_SENSITIVE_CREATE` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmsSensitiveCreate { user_auth: Tpm2bBuffer, data: Tpm2bBuffer, @@ -1100,7 +1102,7 @@ pub mod protocol { /// `TPM2B_SENSITIVE_CREATE` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct Tpm2bSensitiveCreate { size: u16_be, sensitive: TpmsSensitiveCreate, @@ -1137,7 +1139,7 @@ pub mod protocol { /// `TPMT_RSA_SCHEME` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes, PartialEq)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout, PartialEq)] pub struct TpmtRsaScheme { scheme: AlgId, hash_alg: AlgId, @@ -1172,12 +1174,12 @@ pub mod protocol { return None; } - let scheme = AlgId::read_from_prefix(&bytes[start..end])?; + let scheme = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error let hash_alg = if scheme != AlgIdEnum::NULL.into() { start = end; end += size_of::(); - AlgId::read_from_prefix(&bytes[start..end])? + AlgId::read_from_prefix(&bytes[start..end]).ok()?.0 // todo: zerocopy: use-rest-of-range, option-to-error } else { AlgId::new(0) }; @@ -1200,7 +1202,7 @@ pub mod protocol { /// `TPMT_SYM_DEF_OBJECT` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes, PartialEq)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout, PartialEq)] pub struct TpmtSymDefObject { algorithm: AlgId, key_bits: u16_be, @@ -1241,18 +1243,18 @@ pub mod protocol { return None; } - let algorithm = AlgId::read_from_prefix(&bytes[start..end])?; + let algorithm = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error let (key_bits, mode) = if algorithm != AlgIdEnum::NULL.into() { start = end; end += size_of::(); - let key_bits = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let key_bits = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify start = end; end += size_of::(); - let mode = AlgId::read_from_prefix(&bytes[start..end])?; + let mode = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error - (key_bits.into(), mode) + (key_bits, mode) } else { (new_u16_be(0), AlgId::new(0)) }; @@ -1280,7 +1282,7 @@ pub mod protocol { /// `TPMS_RSA_PARMS` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes, PartialEq)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout, PartialEq)] pub struct TpmsRsaParams { symmetric: TpmtSymDefObject, scheme: TpmtRsaScheme, @@ -1325,25 +1327,29 @@ pub mod protocol { let scheme = TpmtRsaScheme::deserialize(&bytes[start..])?; end += scheme.payload_size(); + // todo: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid + // manual size checks. Leaving this code as-is to reduce risk of the 0.7 -> 0.8 move. start = end; end += size_of::(); if bytes.len() < end { return None; } - let key_bits = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let key_bits = u16_be::read_from_bytes(&bytes[start..end]).ok()?; + // todo: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid + // manual size checks. Leaving this code as-is to reduce risk of the 0.7 -> 0.8 move. start = end; end += size_of::(); if bytes.len() < end { return None; } - let exponent = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let exponent = u32_be::read_from_bytes(&bytes[start..end]).ok()?; Some(Self { symmetric, scheme, - key_bits: key_bits.into(), - exponent: exponent.into(), + key_bits, + exponent, }) } @@ -1361,9 +1367,9 @@ pub mod protocol { /// `TPMT_PUBLIC` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmtPublic { - r#type: AlgId, + my_type: AlgId, name_alg: AlgId, object_attributes: TpmaObject, auth_policy: Tpm2bBuffer, @@ -1375,7 +1381,7 @@ pub mod protocol { impl TpmtPublic { pub fn new( - r#type: AlgId, + my_type: AlgId, name_alg: AlgId, object_attributes: TpmaObjectBits, auth_policy: &[u8], @@ -1386,7 +1392,7 @@ pub mod protocol { Tpm2bBuffer::new(auth_policy).map_err(TpmProtoError::TpmtPublicAuthPolicy)?; let unique = Tpm2bBuffer::new(unique).map_err(TpmProtoError::TpmtPublicUnique)?; Ok(Self { - r#type, + my_type, name_alg, object_attributes: object_attributes.into(), auth_policy, @@ -1398,7 +1404,7 @@ pub mod protocol { pub fn serialize(self) -> Vec { let mut buffer = Vec::new(); - buffer.extend_from_slice(self.r#type.as_bytes()); + buffer.extend_from_slice(self.my_type.as_bytes()); buffer.extend_from_slice(self.name_alg.as_bytes()); buffer.extend_from_slice(self.object_attributes.as_bytes()); buffer.extend_from_slice(&self.auth_policy.serialize()); @@ -1414,21 +1420,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let r#type = AlgId::read_from_prefix(&bytes[start..end])?; + let r#type = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let name_alg = AlgId::read_from_prefix(&bytes[start..end])?; + let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let object_attributes = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let object_attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify start = end; let auth_policy = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1445,7 +1451,7 @@ pub mod protocol { let unique = Tpm2bBuffer::deserialize(&bytes[start..])?; Some(Self { - r#type, + my_type: r#type, name_alg, object_attributes: object_attributes.into(), auth_policy, @@ -1457,7 +1463,7 @@ pub mod protocol { pub fn payload_size(&self) -> usize { let mut payload_size = 0; - payload_size += size_of_val(&self.r#type); + payload_size += size_of_val(&self.my_type); payload_size += size_of_val(&self.name_alg); payload_size += size_of_val(&self.object_attributes); payload_size += self.auth_policy.payload_size(); @@ -1470,7 +1476,7 @@ pub mod protocol { /// `TPM2B_PUBLIC` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct Tpm2bPublic { pub size: u16_be, pub public_area: TpmtPublic, @@ -1502,15 +1508,12 @@ pub mod protocol { return None; } - let size = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify start = end; let public_area = TpmtPublic::deserialize(&bytes[start..])?; - Some(Self { - size: size.into(), - public_area, - }) + Some(Self { size, public_area }) } pub fn payload_size(&self) -> usize { @@ -1525,7 +1528,7 @@ pub mod protocol { /// `TPMS_CREATION_DATA` #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmsCreationData { pcr_select: TpmlPcrSelection, pcr_digest: Tpm2bBuffer, @@ -1560,7 +1563,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parent_name_alg = AlgId::read_from_prefix(&bytes[start..end])?; + let parent_name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; let parent_name = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1600,7 +1603,7 @@ pub mod protocol { } /// `TPM2B_CREATION_DATA` - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] #[repr(C)] pub struct Tpm2bCreationData { size: u16_be, @@ -1616,13 +1619,13 @@ pub mod protocol { return None; } - let size = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify start = end; let creation_data = TpmsCreationData::deserialize(&bytes[start..])?; Some(Self { - size: size.into(), + size, creation_data, }) } @@ -1639,7 +1642,7 @@ pub mod protocol { /// `TPMT_TK_CREATION` #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmtTkCreation { tag: SessionTag, hierarchy: ReservedHandle, @@ -1653,14 +1656,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let tag = SessionTag::read_from_prefix(&bytes[start..end])?; + let tag = SessionTag::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let hierarchy = ReservedHandle::read_from_prefix(&bytes[start..end])?; + let hierarchy = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; let digest = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1685,7 +1688,7 @@ pub mod protocol { /// `TPMS_NV_PUBLIC` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct TpmsNvPublic { nv_index: u32_be, name_alg: AlgId, @@ -1732,21 +1735,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let nv_index = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let nv_index: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify start = end; end += size_of::(); if bytes.len() < end { return None; } - let name_alg = AlgId::read_from_prefix(&bytes[start..end])?; + let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let attributes = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify start = end; let auth_policy = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1757,14 +1760,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let data_size = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let data_size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify Some(Self { nv_index: nv_index.into(), name_alg, attributes: attributes.into(), auth_policy, - data_size: data_size.into(), + data_size, }) } @@ -1783,7 +1786,7 @@ pub mod protocol { /// `TPM2B_NV_PUBLIC` #[repr(C)] - #[derive(Debug, Copy, Clone, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct Tpm2bNvPublic { size: u16_be, pub nv_public: TpmsNvPublic, @@ -1819,15 +1822,12 @@ pub mod protocol { return None; } - let size = zerocopy::BigEndian::read_u16(&bytes[start..end]); + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify start = end; let nv_public = TpmsNvPublic::deserialize(&bytes[start..])?; - Some(Self { - size: size.into(), - nv_public, - }) + Some(Self { size, nv_public }) } pub fn payload_size(&self) -> usize { @@ -1843,7 +1843,7 @@ pub mod protocol { // === ClearControl === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClearControlCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -1870,7 +1870,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClearControlReply { pub header: ReplyHeader, pub param_size: u32_be, @@ -1885,7 +1885,7 @@ pub mod protocol { type Command = ClearControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -1896,7 +1896,7 @@ pub mod protocol { // === Clear === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClearCmd { header: CmdHeader, @@ -1921,7 +1921,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClearReply { pub header: ReplyHeader, pub param_size: u32_be, @@ -1936,7 +1936,7 @@ pub mod protocol { type Command = ClearCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -1953,7 +1953,7 @@ pub mod protocol { } #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartupCmd { header: CmdHeader, startup_type: u16_be, @@ -1973,7 +1973,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartupReply { pub header: ReplyHeader, } @@ -1986,7 +1986,7 @@ pub mod protocol { type Command = StartupCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -1997,7 +1997,7 @@ pub mod protocol { // === Self Test === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SelfTestCmd { header: CmdHeader, full_test: u8, @@ -2013,7 +2013,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SelfTestReply { pub header: ReplyHeader, } @@ -2026,7 +2026,7 @@ pub mod protocol { type Command = SelfTestCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2037,7 +2037,7 @@ pub mod protocol { // === Hierarchy Control === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HierarchyControlCmd { header: CmdHeader, @@ -2069,7 +2069,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HierarchyControlReply { pub header: ReplyHeader, pub param_size: u32_be, @@ -2084,7 +2084,7 @@ pub mod protocol { type Command = HierarchyControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2095,7 +2095,7 @@ pub mod protocol { // === Pcr Allocate === // #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PcrSelection { pub hash: AlgId, pub size_of_select: u8, @@ -2119,7 +2119,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let hash = AlgId::read_from_prefix(&bytes[start..end])?; + let hash = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); @@ -2158,7 +2158,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PcrAllocateCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -2229,7 +2229,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PcrAllocateReply { pub header: ReplyHeader, pub auth_size: u32_be, @@ -2249,7 +2249,7 @@ pub mod protocol { type Command = PcrAllocateCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2260,7 +2260,7 @@ pub mod protocol { // === ChangeSeed === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ChangeSeedCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -2285,7 +2285,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ChangeSeedReply { pub header: ReplyHeader, pub param_size: u32_be, @@ -2301,7 +2301,7 @@ pub mod protocol { type Command = ChangeSeedCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: option-to-error } fn payload_size(&self) -> usize { @@ -2312,7 +2312,7 @@ pub mod protocol { // === CreatePrimary === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CreatePrimaryCmd { pub header: CmdHeader, primary_handle: ReservedHandle, @@ -2394,7 +2394,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct CreatePrimaryReply { pub header: ReplyHeader, pub object_handle: ReservedHandle, @@ -2420,7 +2420,7 @@ pub mod protocol { fn deserialize(bytes: &[u8]) -> Option { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -2431,11 +2431,11 @@ pub mod protocol { start = end; end += size_of::(); - let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end])?; + let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); - let param_size = zerocopy::BigEndian::read_u32(&bytes[start..end]); + let param_size = u32_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify start = end; let out_public = Tpm2bPublic::deserialize(&bytes[start..])?; @@ -2459,7 +2459,9 @@ pub mod protocol { start = end; end += size_of::(); - let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end])?; + let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if header.size.get() as usize != end { return None; @@ -2468,7 +2470,7 @@ pub mod protocol { Some(Self { header, object_handle, - param_size: param_size.into(), + param_size, out_public, creation_data, creation_hash, @@ -2498,7 +2500,7 @@ pub mod protocol { // === FlushContext === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FlushContextCmd { pub header: CmdHeader, // Parameter @@ -2518,7 +2520,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct FlushContextReply { pub header: ReplyHeader, } @@ -2531,7 +2533,7 @@ pub mod protocol { type Command = FlushContextCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2542,7 +2544,7 @@ pub mod protocol { // === EvictControl === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EvictControlCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -2574,7 +2576,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct EvictControlReply { pub header: ReplyHeader, } @@ -2587,7 +2589,7 @@ pub mod protocol { type Command = EvictControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: error-to-option } fn payload_size(&self) -> usize { @@ -2598,7 +2600,7 @@ pub mod protocol { // === ReadPublic === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadPublicCmd { header: CmdHeader, object_handle: ReservedHandle, @@ -2614,7 +2616,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct ReadPublicReply { pub header: ReplyHeader, pub out_public: Tpm2bPublic, @@ -2633,7 +2635,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -2684,7 +2686,7 @@ pub mod protocol { // === Nv DefineSpace === // #[repr(C)] - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvDefineSpaceCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -2752,7 +2754,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvDefineSpaceReply { pub header: ReplyHeader, } @@ -2765,7 +2767,7 @@ pub mod protocol { type Command = NvDefineSpaceCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2776,7 +2778,7 @@ pub mod protocol { // === Nv UndefineSpace === // #[repr(C)] - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvUndefineSpaceCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -2804,7 +2806,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvUndefineSpaceReply { pub header: ReplyHeader, } @@ -2817,7 +2819,7 @@ pub mod protocol { type Command = NvUndefineSpaceCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -2828,7 +2830,7 @@ pub mod protocol { // === Nv ReadPublic === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NvReadPublicCmd { header: CmdHeader, nv_index: u32_be, @@ -2844,7 +2846,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvReadPublicReply { pub header: ReplyHeader, // Parameters @@ -2863,7 +2865,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -2907,7 +2909,7 @@ pub mod protocol { // === Nv Write === // #[repr(C)] - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvWriteCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -3001,7 +3003,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvWriteReply { pub header: ReplyHeader, } @@ -3014,7 +3016,7 @@ pub mod protocol { type Command = NvWriteCmd; fn deserialize(bytes: &[u8]) -> Option { - Self::read_from_prefix(bytes) + Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? } fn payload_size(&self) -> usize { @@ -3025,7 +3027,7 @@ pub mod protocol { // === Nv Read === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NvReadCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -3069,7 +3071,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let header = CmdHeader::read_from_prefix(&bytes[start..end])?; + let header = CmdHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error if header.command_code != CommandCodeEnum::NV_Read.into() { return None; @@ -3080,21 +3082,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let auth_handle = ReservedHandle::read_from_prefix(&bytes[start..end])?; + let auth_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let nv_index = u32_be::read_from_prefix(&bytes[start..end])?; + let nv_index = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let auth_size = u32_be::read_from_prefix(&bytes[start..end])?; + let auth_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Skip authorization area end += auth_size.get() as usize; @@ -3104,14 +3106,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let size = u16_be::read_from_prefix(&bytes[start..end])?; + let size = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let offset = u16_be::read_from_prefix(&bytes[start..end])?; + let offset = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error Some(Self { header, @@ -3126,7 +3128,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct NvReadReply { pub header: ReplyHeader, pub parameter_size: u32_be, @@ -3147,7 +3149,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -3164,7 +3166,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end])?; + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; let data = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -3175,7 +3177,9 @@ pub mod protocol { if bytes.len() < end { return None; } - let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end])?; + let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if header.size.get() as usize != end { return None; @@ -3202,7 +3206,7 @@ pub mod protocol { // === Import === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ImportCmd { pub header: CmdHeader, pub auth_handle: ReservedHandle, @@ -3324,7 +3328,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct ImportReply { pub header: ReplyHeader, pub parameter_size: u32_be, @@ -3346,7 +3350,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -3363,7 +3367,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end])?; + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error let expected_auth_start = end + parameter_size.get() as usize; start = end; @@ -3378,7 +3382,9 @@ pub mod protocol { if bytes.len() < end { return None; } - let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end])?; + let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if header.size.get() as usize != end { return None; @@ -3405,7 +3411,7 @@ pub mod protocol { // === Load === // #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LoadCmd { header: CmdHeader, auth_handle: ReservedHandle, @@ -3469,7 +3475,7 @@ pub mod protocol { } #[repr(C)] - #[derive(Debug, FromBytes, FromZeroes, AsBytes)] + #[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)] pub struct LoadReply { pub header: ReplyHeader, pub object_handle: ReservedHandle, @@ -3492,7 +3498,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end])?; + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error // Handle the command failure. if header.size.get() as usize == end { @@ -3510,14 +3516,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end])?; + let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error start = end; end += size_of::(); if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end])?; + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error let expected_auth_start = end + parameter_size.get() as usize; start = end; @@ -3532,7 +3538,9 @@ pub mod protocol { if bytes.len() < end { return None; } - let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end])?; + let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if header.size.get() as usize != end { return None; diff --git a/vm/devices/tpm/src/tpm_helper.rs b/vm/devices/tpm/src/tpm_helper.rs index 9a59aabb72..8d91998637 100644 --- a/vm/devices/tpm/src/tpm_helper.rs +++ b/vm/devices/tpm/src/tpm_helper.rs @@ -43,8 +43,8 @@ use crate::TPM_RSA_SRK_HANDLE; use inspect::InspectMut; use ms_tpm_20_ref::MsTpm20RefPlatform; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; // The size of command and response buffers. // DEVNOTE: The specification only requires the size to be large @@ -821,7 +821,7 @@ impl TpmEngineHelper { let mut cmd = StartupCmd::new(session_tag.into(), startup_type); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match StartupCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -847,7 +847,7 @@ impl TpmEngineHelper { let mut cmd = SelfTestCmd::new(session_tag.into(), full_test); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match SelfTestCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -884,7 +884,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match HierarchyControlCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -918,7 +918,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match ClearControlCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -947,7 +947,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match ClearCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1038,7 +1038,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match ChangeSeedCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1067,7 +1067,7 @@ impl TpmEngineHelper { let mut cmd = ReadPublicCmd::new(session_tag.into(), object_handle); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match ReadPublicCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1090,7 +1090,7 @@ impl TpmEngineHelper { let mut cmd = FlushContextCmd::new(flush_handle); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match FlushContextCmd::base_validate_reply(&self.reply_buffer, cmd.header.session_tag) { @@ -1127,7 +1127,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match EvictControlCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1153,7 +1153,7 @@ impl TpmEngineHelper { let mut cmd = NvReadPublicCmd::new(session_tag.into(), nv_index); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match NvReadPublicCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1187,7 +1187,7 @@ impl TpmEngineHelper { ); self.tpm_engine - .execute_command(cmd.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(cmd.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; match NvUndefineSpaceCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1406,7 +1406,7 @@ impl TpmEngineHelper { nv_read.update_read_parameters(bytes_to_transfer, transferred_bytes); self.tpm_engine - .execute_command(nv_read.as_bytes_mut(), &mut self.reply_buffer) + .execute_command(nv_read.as_mut_bytes(), &mut self.reply_buffer) .map_err(TpmCommandError::TpmExecuteCommand)?; let res = match NvReadCmd::base_validate_reply(&self.reply_buffer, session_tag) { @@ -1615,7 +1615,6 @@ mod tests { use ms_tpm_20_ref::DynResult; use std::time::Instant; use tpm20proto::AlgId; - use zerocopy::FromZeroes; const TPM_AZURE_EK_HANDLE: ReservedHandle = ReservedHandle::new(TPM20_HT_PERSISTENT, 0x010001); const AUTH_VALUE: u64 = 0x7766554433221100; diff --git a/vm/devices/uidevices/Cargo.toml b/vm/devices/uidevices/Cargo.toml index cda19cdc24..54bc02fde1 100644 --- a/vm/devices/uidevices/Cargo.toml +++ b/vm/devices/uidevices/Cargo.toml @@ -31,8 +31,6 @@ thiserror.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [dev-dependencies] tracing_helpers.workspace = true diff --git a/vm/devices/uidevices/src/keyboard/mod.rs b/vm/devices/uidevices/src/keyboard/mod.rs index 0b8fb7ee10..d7b31af626 100644 --- a/vm/devices/uidevices/src/keyboard/mod.rs +++ b/vm/devices/uidevices/src/keyboard/mod.rs @@ -27,9 +27,10 @@ use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; use vmbus_ring::RingMem; use vmcore::save_restore::SavedStateRoot; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug)] enum Request { @@ -56,17 +57,19 @@ async fn recv_packet(reader: &mut impl AsyncRecv) -> Result { let n = reader.recv(&mut buf).await.map_err(Error::Io)?; let buf = &buf[..n]; let (header, buf) = - protocol::MessageHeader::read_from_prefix_split(buf).ok_or(Error::BadPacket)?; + protocol::MessageHeader::read_from_prefix(buf).map_err(|_| Error::BadPacket)?; // TODO: zerocopy: map_err let request = match header.message_type { protocol::MESSAGE_PROTOCOL_REQUEST => { - let message = - protocol::MessageProtocolRequest::read_from_prefix(buf).ok_or(Error::BadPacket)?; + let message = protocol::MessageProtocolRequest::read_from_prefix(buf) + .map_err(|_| Error::BadPacket)? + .0; // todo: zerocopy: map_err Request::ProtocolRequest(message.version) } protocol::MESSAGE_SET_LED_INDICATORS => { // We don't have any actual LEDs to set, so check the message for validity but ignore its contents. let _message = protocol::MessageLedIndicatorsState::read_from_prefix(buf) - .ok_or(Error::BadPacket)?; + .map_err(|_| Error::BadPacket)? + .0; // todo: zerocopy: map_err Request::SetLedIndicators } typ => return Err(Error::UnknownMessageType(typ)), @@ -74,7 +77,7 @@ async fn recv_packet(reader: &mut impl AsyncRecv) -> Result { Ok(request) } -async fn send_packet( +async fn send_packet( writer: &mut impl AsyncSend, typ: u32, packet: &T, @@ -328,12 +331,13 @@ mod tests { return None; } let packet = &packet[..n]; - let (header, rest) = protocol::MessageHeader::read_from_prefix_split(packet).unwrap(); + let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap Some(match header.message_type { protocol::MESSAGE_PROTOCOL_RESPONSE => { - Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap()) + Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap().0) + // todo: zerocopy: use-rest-of-range } - protocol::MESSAGE_EVENT => Packet::Event(FromBytes::read_from_prefix(rest).unwrap()), + protocol::MESSAGE_EVENT => Packet::Event(FromBytes::read_from_prefix(rest).unwrap().0), // todo: zerocopy: use-rest-of-range _ => panic!("unknown packet type {}", header.message_type), }) } diff --git a/vm/devices/uidevices/src/keyboard/protocol.rs b/vm/devices/uidevices/src/keyboard/protocol.rs index 6368cf3662..968bb9222a 100644 --- a/vm/devices/uidevices/src/keyboard/protocol.rs +++ b/vm/devices/uidevices/src/keyboard/protocol.rs @@ -4,9 +4,10 @@ #![allow(dead_code)] use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // f912ad6d-2b17-48ea-bd65-f927a61c7684 pub const INTERFACE_GUID: Guid = Guid::from_static_str("f912ad6d-2b17-48ea-bd65-f927a61c7684"); @@ -25,32 +26,32 @@ pub const MESSAGE_EVENT: u32 = 3; pub const MESSAGE_SET_LED_INDICATORS: u32 = 4; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub message_type: u32, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageProtocolRequest { pub version: u32, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageLedIndicatorsState { pub led_flags: u16, pub padding: u16, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageProtocolResponse { pub accepted: u32, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageKeystroke { pub make_code: u16, pub padding: u16, diff --git a/vm/devices/uidevices/src/mouse/mod.rs b/vm/devices/uidevices/src/mouse/mod.rs index afabb38bad..82b05b5dfa 100644 --- a/vm/devices/uidevices/src/mouse/mod.rs +++ b/vm/devices/uidevices/src/mouse/mod.rs @@ -27,10 +27,11 @@ use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; use vmbus_ring::RingMem; use vmcore::save_restore::SavedStateRoot; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug, Error)] enum Error { @@ -85,17 +86,19 @@ async fn recv_packet(reader: &mut (impl AsyncRecv + Unpin)) -> Result { - let message = - protocol::MessageProtocolRequest::read_from_prefix(buf).ok_or(Error::BadPacket)?; + let message = protocol::MessageProtocolRequest::read_from_prefix(buf) + .map_err(|_| Error::BadPacket)? + .0; // todo: zerocopy: map_err Request::ProtocolRequest(message.version) } protocol::SYNTHHID_INIT_DEVICE_INFO_ACK => { // We don't need the message contents, but we do still want to ensure it's valid. - let _message = - protocol::MessageDeviceInfoAck::read_from_prefix(buf).ok_or(Error::BadPacket)?; + let _message = protocol::MessageDeviceInfoAck::read_from_prefix(buf) + .map_err(|_| Error::BadPacket)? + .0; // todo: zerocopy: map_err Request::DeviceInfoAck } typ => return Err(Error::UnknownMessageType(typ)), @@ -103,7 +106,7 @@ async fn recv_packet(reader: &mut (impl AsyncRecv + Unpin)) -> Result( +async fn send_packet( writer: &mut (impl AsyncSend + Unpin), typ: u32, size: u32, @@ -359,7 +362,7 @@ async fn post_mouse_packet( channel: &mut (impl AsyncSend + Unpin), ) -> Result<(), Error> { let mut scrolled = protocol::ScrollType::NoChange; - let mut mouse_packet: protocol::MousePacket = FromZeroes::new_zeroed(); + let mut mouse_packet: protocol::MousePacket = FromZeros::new_zeroed(); mouse_packet.x = mouse_data.x; mouse_packet.y = mouse_data.y; @@ -424,13 +427,15 @@ mod tests { return None; } let packet = &packet[..n]; - let (header, rest) = protocol::MessageHeader::read_from_prefix_split(packet).unwrap(); + let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap Some(match header.message_type { protocol::SYNTHHID_PROTOCOL_RESPONSE => { - Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap()) + Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap().0) + // todo: zerocopy: use-rest-of-range } protocol::SYNTHHID_INIT_DEVICE_INFO => { - Packet::DeviceInfo(FromBytes::read_from_prefix(rest).unwrap()) + Packet::DeviceInfo(FromBytes::read_from_prefix(rest).unwrap().0) + // todo: zerocopy: use-rest-of-range } _ => panic!("unknown packet type {}", header.message_type), }) diff --git a/vm/devices/uidevices/src/mouse/protocol.rs b/vm/devices/uidevices/src/mouse/protocol.rs index 9822073812..2c7a4fbc4a 100644 --- a/vm/devices/uidevices/src/mouse/protocol.rs +++ b/vm/devices/uidevices/src/mouse/protocol.rs @@ -7,9 +7,10 @@ use guid::Guid; use static_assertions::const_assert_eq; use std::fmt; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; //cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a pub const INTERFACE_GUID: Guid = Guid::from_static_str("cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a"); @@ -41,7 +42,7 @@ pub const MAX_HID_REPORT_DESCRIPTOR: u16 = 256; //HID Protocol Structs #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HidAttributes { pub size: u32, pub vendor_id: u16, @@ -53,7 +54,7 @@ pub struct HidAttributes { const_assert_eq!(0x20, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HidDescriptor { pub length: u8, pub descriptor_type: u8, @@ -66,7 +67,7 @@ pub struct HidDescriptor { const_assert_eq!(0x9, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HidDescriptorList { pub report_type: u8, pub report_length: u16, @@ -75,7 +76,7 @@ pub struct HidDescriptorList { const_assert_eq!(0x3, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub message_type: u32, pub message_size: u32, @@ -84,7 +85,7 @@ pub struct MessageHeader { const_assert_eq!(0x8, size_of::()); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageProtocolRequest { pub version: u32, } @@ -92,7 +93,7 @@ pub struct MessageProtocolRequest { const_assert_eq!(0x4, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageProtocolResponse { pub version_requested: u32, pub accepted: u8, @@ -101,7 +102,7 @@ pub struct MessageProtocolResponse { const_assert_eq!(0x5, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageDeviceInfo { pub device_attributes: HidAttributes, pub descriptor_info: HidDescriptor, @@ -119,7 +120,7 @@ impl fmt::Debug for MessageDeviceInfo { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageDeviceInfoAck { pub acknowledged: u8, } @@ -127,7 +128,7 @@ pub struct MessageDeviceInfoAck { const_assert_eq!(1, size_of::()); #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageInputReport { pub input_report: MousePacket, } @@ -222,7 +223,7 @@ pub const fn event_single_change(button: MouseButton) -> u32 { pub const MOUSE_EVENT_FLAG_FORCE_REPORT_EVENT: u32 = 1 << 8; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MousePacket { pub button_data: u8, diff --git a/vm/devices/uidevices/src/video/mod.rs b/vm/devices/uidevices/src/video/mod.rs index 0e1b96bc56..a9844ab8e8 100644 --- a/vm/devices/uidevices/src/video/mod.rs +++ b/vm/devices/uidevices/src/video/mod.rs @@ -27,8 +27,10 @@ use vmbus_channel::simple::SaveRestoreSimpleVmbusDevice; use vmbus_channel::simple::SimpleVmbusDevice; use vmbus_channel::RawAsyncChannel; use vmcore::save_restore::SavedStateRoot; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Ref; #[derive(Debug, Error)] @@ -74,16 +76,18 @@ enum Request { fn parse_packet(buf: &[u8]) -> Result { let (header, buf) = - Ref::<_, protocol::MessageHeader>::new_from_prefix(buf).ok_or(Error::InvalidPacket)?; + Ref::<_, protocol::MessageHeader>::from_prefix(buf).map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err let request = match header.typ.to_ne() { protocol::MESSAGE_VERSION_REQUEST => { let message = protocol::VersionRequestMessage::ref_from_prefix(buf) - .ok_or(Error::InvalidPacket)?; + .map_err(|_| Error::InvalidPacket)? + .0; // todo: zerocopy: map_err Request::Version(message.version) } protocol::MESSAGE_VRAM_LOCATION => { - let message = - protocol::VramLocationMessage::ref_from_prefix(buf).ok_or(Error::InvalidPacket)?; + let message = protocol::VramLocationMessage::ref_from_prefix(buf) + .map_err(|_| Error::InvalidPacket)? + .0; // todo: zerocopy: map_err let address = if message.is_vram_gpa_address_specified != 0 { Some(message.vram_gpa_address.into()) } else { @@ -96,7 +100,8 @@ fn parse_packet(buf: &[u8]) -> Result { } protocol::MESSAGE_SITUATION_UPDATE => { let message = protocol::SituationUpdateMessage::ref_from_prefix(buf) - .ok_or(Error::InvalidPacket)?; + .map_err(|_| Error::InvalidPacket)? + .0; // todo: zerocopy: map_err Request::SituationUpdate { user_context: message.user_context.into(), situation: message.video_output, @@ -104,7 +109,8 @@ fn parse_packet(buf: &[u8]) -> Result { } protocol::MESSAGE_POINTER_POSITION => { let message = protocol::PointerPositionMessage::ref_from_prefix(buf) - .ok_or(Error::InvalidPacket)?; + .map_err(|_| Error::InvalidPacket)? + .0; // todo: zerocopy: map_err Request::PointerPosition { is_visible: message.is_visible != 0, x: message.image_x.into(), @@ -112,23 +118,27 @@ fn parse_packet(buf: &[u8]) -> Result { } } protocol::MESSAGE_POINTER_SHAPE => { - //let message = protocol::PointerShapeMessage::from_bytes(buf).ok_or(Error::InvalidPacket)?; + //let message = protocol::PointerShapeMessage::from_bytes(buf).map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err Request::PointerShape } protocol::MESSAGE_DIRT => { - let (message, buf) = Ref::<_, protocol::DirtMessage>::new_from_prefix(buf) - .ok_or(Error::InvalidPacket)?; + let (message, buf) = Ref::<_, protocol::DirtMessage>::from_prefix(buf) + .map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err Request::Dirt( - protocol::Rectangle::slice_from_prefix(buf, message.dirt_count as usize) - .ok_or(Error::InvalidPacket)? - .0 - .into(), + <[protocol::Rectangle]>::ref_from_prefix_with_elems( + buf, + message.dirt_count as usize, + ) + .map_err(|_| Error::InvalidPacket)? // todo: zerocopy: map_err + .0 + .into(), ) } protocol::MESSAGE_BIOS_INFO_REQUEST => Request::BiosInfo, protocol::MESSAGE_SUPPORTED_RESOLUTIONS_REQUEST => { let message = protocol::SupportedResolutionsRequestMessage::ref_from_prefix(buf) - .ok_or(Error::InvalidPacket)?; + .map_err(|_| Error::InvalidPacket)? + .0; // todo: zerocopy: map_err Request::SupportedResolutions { maximum_count: message.maximum_resolution_count, } @@ -373,7 +383,7 @@ impl VideoChannel { } } - async fn send_packet( + async fn send_packet( writer: &mut (impl AsyncSend + Unpin), typ: u32, packet: &T, diff --git a/vm/devices/uidevices/src/video/protocol.rs b/vm/devices/uidevices/src/video/protocol.rs index ce1127dd47..b33510dea5 100644 --- a/vm/devices/uidevices/src/video/protocol.rs +++ b/vm/devices/uidevices/src/video/protocol.rs @@ -3,9 +3,10 @@ #![allow(dead_code)] -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const MAX_VMBUS_PACKET_SIZE: usize = 0x4000; @@ -43,7 +44,7 @@ macro_rules! packed { ($wrap:ident, $prim:ident, $count:literal) => { #[allow(non_camel_case_types)] #[repr(transparent)] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct $wrap([u8; $count]); impl $wrap { @@ -81,7 +82,7 @@ packed!(u16p, u16, 2); packed!(i32p, i32, 4); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ScreenInfo { pub width: u16p, pub height: u16p, @@ -102,7 +103,7 @@ pub const MAX_VSP_TO_VSC_MESSAGE_SIZE: usize = size_of:: u32 { pub const EDID_BLOCK_SIZE: usize = 128; #[repr(transparent)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EdidBlock(pub [u8; EDID_BLOCK_SIZE]); impl std::fmt::Debug for EdidBlock { @@ -196,7 +197,7 @@ pub const MESSAGE_CAPABILITY_RESPONSE: u32 = 16; // Basic message structures. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub typ: u32p, // Type of the enclosed message pub size: u32p, // Size of the enclosed message (size of the data payload) @@ -207,7 +208,7 @@ pub struct MessageHeader { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionRequestMessage { pub version: Version, } @@ -215,7 +216,7 @@ pub struct VersionRequestMessage { // VSP to VSC #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionResponseMessage { pub version: Version, pub is_accepted: u8, @@ -224,14 +225,14 @@ pub struct VersionResponseMessage { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SupportedResolutionsRequestMessage { pub maximum_resolution_count: u8, } // VSP to VSC #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SupportedResolutionsResponseMessage { pub edid_block: EdidBlock, pub resolution_count: u8, @@ -242,13 +243,13 @@ pub struct SupportedResolutionsResponseMessage { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CapabilityRequestMessage {} // VSP to VSC #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CapabilityResponseMessage { pub lock_on_disconnect: u32p, pub reserved: [u32p; 15], @@ -256,7 +257,7 @@ pub struct CapabilityResponseMessage { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VramLocationMessage { pub user_context: u64p, pub is_vram_gpa_address_specified: u8, @@ -269,7 +270,7 @@ pub struct VramLocationMessage { // that the guest can safely write to knowing that the writes will actually // be reflected in the VRAM memory block. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VramLocationAckMessage { pub user_context: u64p, } @@ -277,7 +278,7 @@ pub struct VramLocationAckMessage { // These messages are used to communicate "situation updates" or changes // in the layout of the primary surface. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VideoOutputSituation { pub active: u8, // Determine if the device is active or not. pub primary_surface_vram_offset: u32p, // Removed in Threshold -- must be zero. @@ -291,7 +292,7 @@ pub struct VideoOutputSituation { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SituationUpdateMessage { pub user_context: u64p, pub video_output_count: u8, // 1 in Viridian 1.0 @@ -300,7 +301,7 @@ pub struct SituationUpdateMessage { // VSP to VSC #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SituationUpdateAckMessage { pub user_context: u64p, } @@ -308,7 +309,7 @@ pub struct SituationUpdateAckMessage { // These messages are used to communicate the BIOS Information of the VM. // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BiosInfoRequestMessage {} // VSP to VSC @@ -317,7 +318,7 @@ pub struct BiosInfoRequestMessage {} // map to the least significant bit and generation 2 (value 1) maps // functionally to the StopDeviceSupported flag below. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BiosInfoResponseMessage { pub stop_device_supported: u32p, pub reserved: [u8; 12], @@ -329,7 +330,7 @@ pub struct BiosInfoResponseMessage { // VSC to VSP // This message is ignored unless we're in relative mouse mode. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PointerPositionMessage { // LDDM may specify FALSE here, XDDM generally will probably always specify TRUE. pub is_visible: u8, @@ -344,7 +345,7 @@ pub struct PointerPositionMessage { // VSC to VSP #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PointerShapeMessage { // When a cursor is larger than the maximum VMBus payload size, // it is split up. This 0-based index indicates which portion @@ -396,7 +397,7 @@ pub const CURSOR_COMPLETE: u8 = 0xff; // VSC responsible for bringing VSP up-to-date with at least one message // of the relevant type if one of these goes from FALSE to TRUE. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureChangeMessage { pub is_dirt_needed: u8, pub is_pointer_position_updates_needed: u8, @@ -405,7 +406,7 @@ pub struct FeatureChangeMessage { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FeatureChangeMessageV2 { pub is_dirt_needed: u8, pub is_pointer_position_updates_needed: u8, @@ -417,7 +418,7 @@ pub struct FeatureChangeMessageV2 { // VSC to VSP // This message is used to communicate dirty regions to the VSP. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DirtMessage { // 0 is the only valid value for 2D Video VSP 1.0 pub video_output: u8, @@ -426,7 +427,7 @@ pub struct DirtMessage { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Rectangle { pub left: i32p, pub top: i32p, diff --git a/vm/devices/user_driver/Cargo.toml b/vm/devices/user_driver/Cargo.toml index 698b103d41..369bcc742f 100644 --- a/vm/devices/user_driver/Cargo.toml +++ b/vm/devices/user_driver/Cargo.toml @@ -28,7 +28,6 @@ parking_lot.workspace = true tracing.workspace = true vfio-bindings.workspace = true zerocopy.workspace = true - [target.'cfg(target_os = "linux")'.dependencies] fs-err.workspace = true futures.workspace = true diff --git a/vm/devices/user_driver/src/lockmem.rs b/vm/devices/user_driver/src/lockmem.rs index 5eaa50b28e..b3ebfc1aa6 100644 --- a/vm/devices/user_driver/src/lockmem.rs +++ b/vm/devices/user_driver/src/lockmem.rs @@ -10,7 +10,7 @@ use std::fs::File; use std::io::Read; use std::io::Seek; use std::io::SeekFrom; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; const PAGE_SIZE: usize = 4096; @@ -66,7 +66,7 @@ impl Mapping { let n = self.len / PAGE_SIZE; let mut pfns = vec![0u64; n]; pagemap - .read(pfns.as_bytes_mut()) + .read(pfns.as_mut_bytes()) .context("failed to read from pagemap")?; for pfn in &mut pfns { if *pfn & (1 << 63) == 0 { diff --git a/vm/devices/user_driver/src/memory.rs b/vm/devices/user_driver/src/memory.rs index b655945100..39d59ab224 100644 --- a/vm/devices/user_driver/src/memory.rs +++ b/vm/devices/user_driver/src/memory.rs @@ -6,8 +6,10 @@ use safeatomic::AtomicSliceOps; use std::sync::atomic::AtomicU8; use std::sync::Arc; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// The 4KB page size used by user-mode devices. pub const PAGE_SIZE: usize = 4096; @@ -155,7 +157,7 @@ impl MemoryBlock { } /// Reads an object from the buffer at `offset`. - pub fn read_obj(&self, offset: usize) -> T { + pub fn read_obj(&self, offset: usize) -> T { self.as_slice()[offset..][..size_of::()].atomic_read_obj() } @@ -165,7 +167,7 @@ impl MemoryBlock { } /// Writes an object into the buffer at `offset`. - pub fn write_obj(&self, offset: usize, data: &T) { + pub fn write_obj(&self, offset: usize, data: &T) { self.as_slice()[offset..][..size_of::()].atomic_write_obj(data); } diff --git a/vm/devices/user_driver/src/vfio.rs b/vm/devices/user_driver/src/vfio.rs index 78d6a662e1..3c9e6615b4 100644 --- a/vm/devices/user_driver/src/vfio.rs +++ b/vm/devices/user_driver/src/vfio.rs @@ -34,8 +34,10 @@ use vfio_sys::IommuType; use vfio_sys::IrqInfo; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub trait VfioDmaBuffer: 'static + Send + Sync { /// Create a new DMA buffer of the given `len` bytes. Guaranteed to be zero-initialized. @@ -421,7 +423,7 @@ impl MappedRegionWithFallback { unsafe { self.mapping.as_ptr().byte_add(offset).cast() } } - fn read_from_mapping( + fn read_from_mapping( &self, offset: usize, ) -> Result { @@ -429,7 +431,7 @@ impl MappedRegionWithFallback { unsafe { sparse_mmap::try_read_volatile(self.mapping::(offset)) } } - fn write_to_mapping( + fn write_to_mapping( &self, offset: usize, data: T, diff --git a/vm/devices/vga/Cargo.toml b/vm/devices/vga/Cargo.toml index 55dc043112..06d4641e0b 100644 --- a/vm/devices/vga/Cargo.toml +++ b/vm/devices/vga/Cargo.toml @@ -24,6 +24,5 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vga/src/emu.rs b/vm/devices/vga/src/emu.rs index ba230bfdb2..5b1bb09900 100644 --- a/vm/devices/vga/src/emu.rs +++ b/vm/devices/vga/src/emu.rs @@ -31,9 +31,11 @@ use std::ops::Index; use std::ops::IndexMut; use vmcore::vmtime::VmTimeAccess; use vmcore::vmtime::VmTimeSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Inspect)] pub struct Emulator { @@ -434,7 +436,7 @@ impl VideoS3DeviceState { vga_attrib_reg_flip_flop: true, vga_graphics_reg_index: VgaGraphicsReg(0), vga_graphics_reg_index_shadow: 0, - pel_colors: FromZeroes::new_zeroed(), + pel_colors: FromZeros::new_zeroed(), pel_reg_write_index: 0, pel_reg_read_index: 0, pel_mask_register: 0xFF, @@ -462,7 +464,7 @@ impl VideoS3DeviceState { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] struct PelColor { red: u8, green: u8, @@ -867,13 +869,13 @@ impl Emulator { within_vram } - fn read_vram(&self, address: u32) -> T { + fn read_vram(&self, address: u32) -> T { self.vram .read_plain(address.into()) .expect("framebuffer is mapped") } - fn write_vram(&self, address: u32, value: T) { + fn write_vram(&self, address: u32, value: T) { self.vram .write_plain(address.into(), &value) .expect("framebuffer is mapped") @@ -2803,7 +2805,7 @@ impl Emulator { } fn write_pel_data_register(&mut self, data: u8) { - let pel_reg_entry = self.state.persistent_state.pel_colors.as_bytes_mut(); + let pel_reg_entry = self.state.persistent_state.pel_colors.as_mut_bytes(); let len = pel_reg_entry.len(); // diff --git a/vm/devices/vga/src/render.rs b/vm/devices/vga/src/render.rs index c616da6360..a493585d44 100644 --- a/vm/devices/vga/src/render.rs +++ b/vm/devices/vga/src/render.rs @@ -18,7 +18,7 @@ use task_control::StopTask; use task_control::TaskControl; use video_core::FramebufferFormat; use vmcore::vm_task::VmTaskDriver; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; const VRAM_RENDER_OFFSET: usize = 0x400000; @@ -224,7 +224,7 @@ impl RendererCore { self.vram .read_at( (row * state.line_offset_pixels as usize * 2) as u64, - line.as_bytes_mut(), + line.as_mut_bytes(), ) .unwrap(); for (s, d) in line.iter().zip(&mut wide_line) { diff --git a/vm/devices/virtio/virtio/Cargo.toml b/vm/devices/virtio/virtio/Cargo.toml index 83f859cdc1..437cc90514 100644 --- a/vm/devices/virtio/virtio/Cargo.toml +++ b/vm/devices/virtio/virtio/Cargo.toml @@ -33,7 +33,6 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] mesh.workspace = true pal_async.workspace = true diff --git a/vm/devices/virtio/virtio/src/spec.rs b/vm/devices/virtio/virtio/src/spec.rs index 5c38d438cd..e7358b8cf6 100644 --- a/vm/devices/virtio/virtio/src/spec.rs +++ b/vm/devices/virtio/virtio/src/spec.rs @@ -50,12 +50,13 @@ pub mod queue { use super::u64_le; use bitfield_struct::bitfield; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Descriptor { pub address: u64_le, pub length: u32_le, @@ -70,7 +71,7 @@ pub mod queue { } #[bitfield(u16)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct DescriptorFlags { pub next: bool, pub write: bool, @@ -113,7 +114,7 @@ pub mod queue { pub const USED_ELEMENT_SIZE: u64 = size_of::() as u64; #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct UsedElement { pub id: u32_le, pub len: u32_le, diff --git a/vm/devices/virtio/virtio/src/transport/pci.rs b/vm/devices/virtio/virtio/src/transport/pci.rs index a5f4270e2e..2faac7abcf 100644 --- a/vm/devices/virtio/virtio/src/transport/pci.rs +++ b/vm/devices/virtio/virtio/src/transport/pci.rs @@ -653,10 +653,12 @@ pub(crate) mod capabilities { use crate::spec::pci::VIRTIO_PCI_CAP_NOTIFY_CFG; use pci_core::spec::caps::CapabilityId; - use zerocopy::AsBytes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; #[repr(C)] - #[derive(Debug, AsBytes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout)] pub struct VirtioCapabilityCommon { cap_id: u8, cap_next: u8, @@ -686,7 +688,7 @@ pub(crate) mod capabilities { } #[repr(C)] - #[derive(Debug, AsBytes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout)] pub struct VirtioCapability { common: VirtioCapabilityCommon, } @@ -707,7 +709,7 @@ pub(crate) mod capabilities { } #[repr(C)] - #[derive(Debug, AsBytes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout)] pub struct VirtioCapability64 { common: VirtioCapabilityCommon, offset_hi: u32, @@ -732,7 +734,7 @@ pub(crate) mod capabilities { } #[repr(C)] - #[derive(Debug, AsBytes)] + #[derive(Debug, IntoBytes, Immutable, KnownLayout)] pub struct VirtioNotifyCapability { common: VirtioCapabilityCommon, offset_multiplier: u32, diff --git a/vm/devices/virtio/virtio_net/Cargo.toml b/vm/devices/virtio/virtio_net/Cargo.toml index f9fd761caf..9b3d8a7442 100644 --- a/vm/devices/virtio/virtio_net/Cargo.toml +++ b/vm/devices/virtio/virtio_net/Cargo.toml @@ -31,6 +31,5 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/virtio/virtio_net/src/buffers.rs b/vm/devices/virtio/virtio_net/src/buffers.rs index d1ec4b1839..08a485d90c 100644 --- a/vm/devices/virtio/virtio_net/src/buffers.rs +++ b/vm/devices/virtio/virtio_net/src/buffers.rs @@ -11,8 +11,8 @@ use net_backend::RxMetadata; use parking_lot::Mutex; use std::sync::Arc; use virtio::VirtioQueueCallbackWork; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Default)] struct RxPacket { @@ -121,7 +121,7 @@ impl BufferAccess for VirtioWorkPool { let virtio_net_header = VirtioNetHeader { num_buffers: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let locked_packet = self.rx_packets[id.0 as usize].lock(); let work = locked_packet.work.as_ref().expect("invalid buffer index"); diff --git a/vm/devices/virtio/virtio_net/src/lib.rs b/vm/devices/virtio/virtio_net/src/lib.rs index f32d8fcb9c..4d0cfb4d39 100644 --- a/vm/devices/virtio/virtio_net/src/lib.rs +++ b/vm/devices/virtio/virtio_net/src/lib.rs @@ -42,13 +42,14 @@ use virtio::VirtioQueue; use virtio::VirtioQueueCallbackWork; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // These correspond to VIRTIO_NET_F_ flags. #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct NetworkFeatures { pub csum: bool, pub guest_csum: bool, @@ -91,7 +92,7 @@ struct NetworkFeatures { // These correspond to VIRTIO_NET_S_ flags. #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct NetStatus { pub link_up: bool, pub announce: bool, @@ -119,7 +120,7 @@ struct NetConfig { // These correspond to VIRTIO_NET_HDR_F_ flags. #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct VirtioNetHeaderFlags { pub needs_csum: bool, pub data_valid: bool, @@ -129,7 +130,7 @@ struct VirtioNetHeaderFlags { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct VirtioNetHeaderGso { #[bits(3)] pub protocol: VirtioNetHeaderGsoProtocol, @@ -140,7 +141,7 @@ struct VirtioNetHeaderGso { // These correspond to VIRTIO_NET_HDR_GSO_ values. open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] enum VirtioNetHeaderGsoProtocol: u8 { NONE = 0, TCPV4 = 1, @@ -160,7 +161,7 @@ impl VirtioNetHeaderGsoProtocol { } } -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(C)] struct VirtioNetHeader { pub flags: u8, diff --git a/vm/devices/virtio/virtiofs/Cargo.toml b/vm/devices/virtio/virtiofs/Cargo.toml index 2735acd567..398f47705a 100644 --- a/vm/devices/virtio/virtiofs/Cargo.toml +++ b/vm/devices/virtio/virtiofs/Cargo.toml @@ -28,7 +28,6 @@ futures.workspace = true parking_lot.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] ntapi.workspace = true diff --git a/vm/devices/virtio/virtiofs/src/file.rs b/vm/devices/virtio/virtiofs/src/file.rs index 67029f9fdd..19c73aba8d 100644 --- a/vm/devices/virtio/virtiofs/src/file.rs +++ b/vm/devices/virtio/virtiofs/src/file.rs @@ -10,7 +10,7 @@ use fuse::DirEntryWriter; use lxutil::LxFile; use parking_lot::RwLock; use std::sync::Arc; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; /// Implements file callbacks for virtio-fs. pub struct VirtioFsFile { diff --git a/vm/devices/virtio/virtiofs/src/virtio.rs b/vm/devices/virtio/virtiofs/src/virtio.rs index 84e71045f9..0f84a19ee5 100644 --- a/vm/devices/virtio/virtiofs/src/virtio.rs +++ b/vm/devices/virtio/virtiofs/src/virtio.rs @@ -23,13 +23,15 @@ use virtio::VirtioQueueWorker; use virtio::VirtioQueueWorkerContext; use vmcore::vm_task::VmTaskDriver; use vmcore::vm_task::VmTaskDriverSource; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const VIRTIO_DEVICE_TYPE_FS: u16 = 26; /// PCI configuration space values for virtio-fs devices. #[repr(C)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] struct VirtioFsDeviceConfig { tag: [u8; 36], num_request_queues: u32, diff --git a/vm/devices/vmbus/vmbfs/Cargo.toml b/vm/devices/vmbus/vmbfs/Cargo.toml index 3f5300950d..8463c0d107 100644 --- a/vm/devices/vmbus/vmbfs/Cargo.toml +++ b/vm/devices/vmbus/vmbfs/Cargo.toml @@ -25,7 +25,5 @@ bitfield-struct.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbfs/src/lib.rs b/vm/devices/vmbus/vmbfs/src/lib.rs index e3245c0400..9b0db56663 100644 --- a/vm/devices/vmbus/vmbfs/src/lib.rs +++ b/vm/devices/vmbus/vmbfs/src/lib.rs @@ -33,9 +33,8 @@ use vmbus_channel::bus::OfferParams; use vmbus_channel::gpadl_ring::GpadlRingMem; use vmbus_channel::simple::SimpleVmbusDevice; use vmcore::save_restore::SavedStateNotSupported; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy_helpers::FromBytesExt; +use zerocopy::IntoBytes; /// A vmbfs device. #[derive(InspectMut)] @@ -274,18 +273,19 @@ impl VmbfsChannel { let buf = &self.buf[..n]; let (header, buf) = - protocol::MessageHeader::read_from_prefix_split(buf).ok_or(DeviceError::TooShort)?; + protocol::MessageHeader::read_from_prefix(buf).map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err let request = match header.message_type { protocol::MessageType::VERSION_REQUEST => { - let version = - protocol::VersionRequest::read_from_prefix(buf).ok_or(DeviceError::TooShort)?; + let version = protocol::VersionRequest::read_from_prefix(buf) + .map_err(|_| DeviceError::TooShort)? + .0; // todo: zerocopy: map_err Request::Version(version.requested_version) } protocol::MessageType::GET_FILE_INFO_REQUEST => Request::GetFileInfo(parse_path(buf)?), protocol::MessageType::READ_FILE_REQUEST => { - let (read, buf) = protocol::ReadFileRequest::read_from_prefix_split(buf) - .ok_or(DeviceError::TooShort)?; + let (read, buf) = protocol::ReadFileRequest::read_from_prefix(buf) + .map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err Request::ReadFile { byte_count: read.byte_count, offset: read.offset.get(), @@ -301,7 +301,7 @@ impl VmbfsChannel { } fn parse_path(buf: &[u8]) -> Result { - let buf = u16::slice_from(buf).ok_or(DeviceError::Unaligned)?; + let buf = <[u16]>::ref_from_bytes(buf).map_err(|_| DeviceError::Unaligned)?; // todo: zerocopy: map_err if buf.contains(&0) { return Err(DeviceError::NullTerminatorInPath); } diff --git a/vm/devices/vmbus/vmbfs/src/protocol.rs b/vm/devices/vmbus/vmbfs/src/protocol.rs index 7c319737d6..29eff98c4e 100644 --- a/vm/devices/vmbus/vmbfs/src/protocol.rs +++ b/vm/devices/vmbus/vmbfs/src/protocol.rs @@ -7,9 +7,10 @@ use bitfield_struct::bitfield; use guid::Guid; use open_enum::open_enum; use zerocopy::little_endian::U64 as u64_le; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const INTERFACE_TYPE: Guid = Guid::from_static_str("c376c1c3-d276-48d2-90a9-c04748072c60"); pub const IMC_INSTANCE: Guid = Guid::from_static_str("c4e5e7d1-d748-4afc-979d-683167910a55"); @@ -20,14 +21,14 @@ pub const MAX_READ_SIZE: usize = MAX_MESSAGE_SIZE - size_of::() - size_of::(); open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum Version: u32 { WIN10 = 0x00010000, } } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum MessageType: u32 { INVALID = 0, VERSION_REQUEST = 1, @@ -42,7 +43,7 @@ open_enum! { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FileInfoFlags { pub directory: bool, pub rdma_capable: bool, @@ -51,20 +52,20 @@ pub struct FileInfoFlags { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MessageHeader { pub message_type: MessageType, pub reserved: u32, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionRequest { pub requested_version: Version, } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum VersionStatus: u32 { SUPPORTED = 0, UNSUPPORTED = 1, @@ -72,19 +73,19 @@ open_enum! { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VersionResponse { pub status: VersionStatus, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetFileInfoRequest { // Followed by a UTF-16 file path. } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum Status: u32 { SUCCESS = 0, NOT_FOUND = 1, @@ -94,7 +95,7 @@ open_enum! { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetFileInfoResponse { pub status: Status, pub flags: FileInfoFlags, @@ -102,7 +103,7 @@ pub struct GetFileInfoResponse { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadFileRequest { pub byte_count: u32, pub offset: u64_le, @@ -110,14 +111,14 @@ pub struct ReadFileRequest { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadFileResponse { pub status: Status, // Followed by the data. } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadFileRdmaRequest { pub handle: u32, pub byte_count: u32, @@ -127,7 +128,7 @@ pub struct ReadFileRdmaRequest { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ReadFileRdmaResponse { pub status: Status, pub byte_count: u32, diff --git a/vm/devices/vmbus/vmbus_async/Cargo.toml b/vm/devices/vmbus/vmbus_async/Cargo.toml index a4a6b63b70..57a8066a31 100644 --- a/vm/devices/vmbus/vmbus_async/Cargo.toml +++ b/vm/devices/vmbus/vmbus_async/Cargo.toml @@ -20,6 +20,5 @@ pal_async.workspace = true futures.workspace = true thiserror.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_async/src/pipe.rs b/vm/devices/vmbus/vmbus_async/src/pipe.rs index d28dfb48aa..48dfa1bc2f 100644 --- a/vm/devices/vmbus/vmbus_async/src/pipe.rs +++ b/vm/devices/vmbus/vmbus_async/src/pipe.rs @@ -30,8 +30,8 @@ use vmbus_channel::RawAsyncChannel; use vmbus_ring as ring; use vmbus_ring::FlatRingMem; use vmbus_ring::RingMem; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Debug, Error)] enum Error { @@ -358,7 +358,7 @@ impl PipeReader<'_, M> { let mut reader = payload.reader(self.core.in_ring()); let bytes_read = if !self.state.raw { let mut header = ring::PipeHeader::new_zeroed(); - reader.read(header.as_bytes_mut())?; + reader.read(header.as_mut_bytes())?; if header.packet_type != ring::PIPE_PACKET_TYPE_DATA { return Err(TryReadError::Pipe(Error::InvalidPipePacketType( header.packet_type, @@ -411,7 +411,7 @@ impl PipeReader<'_, M> { }) => { let mut reader = payload.reader(self.core.in_ring()); let mut header = ring::PipeHeader::new_zeroed(); - reader.read(header.as_bytes_mut())?; + reader.read(header.as_mut_bytes())?; let (off, len) = match header.packet_type { ring::PIPE_PACKET_TYPE_DATA => { // A zero-byte packet indicates EOF--the opposite @@ -916,7 +916,7 @@ mod tests { use pal_async::DefaultDriver; use std::io::ErrorKind; use std::time::Duration; - use zerocopy::AsBytes; + use zerocopy::IntoBytes; #[async_test] async fn test_async_channel_close() { @@ -963,10 +963,10 @@ mod tests { let mut timer = PolledTimer::new(&driver); timer.sleep(Duration::from_millis(200)).await; let mut v = [0_u16; 2000]; - let n = host.recv(v.as_bytes_mut()).await.unwrap(); + let n = host.recv(v.as_mut_bytes()).await.unwrap(); assert_eq!(n, v.as_bytes().len()); assert!(v.iter().copied().eq(0..2000_u16)); - let n = host.recv(v.as_bytes_mut()).await.unwrap(); + let n = host.recv(v.as_mut_bytes()).await.unwrap(); assert_eq!(n, v.as_bytes().len()); assert!(v.iter().copied().eq(2000..4000_u16)); }; @@ -986,7 +986,7 @@ mod tests { let mut timer = PolledTimer::new(&driver); timer.sleep(Duration::from_millis(200)).await; let mut v = [0_u16; 10000]; - host.read_exact(v.as_bytes_mut()).await.unwrap(); + host.read_exact(v.as_mut_bytes()).await.unwrap(); assert!(v.iter().copied().eq(0..10000_u16)); }; futures::future::join(guest_write, host_read).await; diff --git a/vm/devices/vmbus/vmbus_async/src/queue.rs b/vm/devices/vmbus/vmbus_async/src/queue.rs index 154a3cab8a..25dcd96310 100644 --- a/vm/devices/vmbus/vmbus_async/src/queue.rs +++ b/vm/devices/vmbus/vmbus_async/src/queue.rs @@ -34,9 +34,9 @@ use vmbus_ring::FlatRingMem; use vmbus_ring::IncomingPacketType; use vmbus_ring::IncomingRing; use vmbus_ring::RingMem; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// A queue error. #[derive(Debug, Error)] @@ -256,15 +256,17 @@ impl DataPacket<'_, T> { return Err(AccessError::OutOfRange(0, 0)); } - let mut buf: GpnList = smallvec![FromZeroes::new_zeroed(); len]; - reader.read(buf.as_bytes_mut())?; + let mut buf: GpnList = smallvec![FromZeros::new_zeroed(); len]; + reader.read(buf.as_mut_bytes())?; // Construct an array of the form [#1 offset/length][page1][page2][...][#2 offset/length][page1][page2]... // See MultiPagedRangeIter for more details. let transfer_buf: GpnList = buf .iter() .map(|range| { - let range_data = TransferPageRange::read_from_prefix(range.as_bytes()).unwrap(); + let range_data = TransferPageRange::read_from_prefix(range.as_bytes()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let sub_range = transfer_buf .subrange( range_data.byte_offset as usize, @@ -297,7 +299,7 @@ impl DataPacket<'_, T> { let len = reader.len() / 8; let mut buf = zeroed_gpn_list(len); reader - .read(buf.as_bytes_mut()) + .read(buf.as_mut_bytes()) .map_err(ExternalDataError::Access)?; MultiPagedRangeBuf::new(self.external_data.0 as usize, buf) .map_err(ExternalDataError::GpaRange) diff --git a/vm/devices/vmbus/vmbus_client/Cargo.toml b/vm/devices/vmbus/vmbus_client/Cargo.toml index 70f1d368d5..f6c540ff81 100644 --- a/vm/devices/vmbus/vmbus_client/Cargo.toml +++ b/vm/devices/vmbus/vmbus_client/Cargo.toml @@ -22,7 +22,6 @@ futures.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] parking_lot.workspace = true pal_async.workspace = true diff --git a/vm/devices/vmbus/vmbus_client/src/hvsock.rs b/vm/devices/vmbus/vmbus_client/src/hvsock.rs index 663b5835ba..4929d84db7 100644 --- a/vm/devices/vmbus/vmbus_client/src/hvsock.rs +++ b/vm/devices/vmbus/vmbus_client/src/hvsock.rs @@ -82,7 +82,7 @@ mod tests { use vmbus_core::protocol::HvsockUserDefinedParameters; use vmbus_core::protocol::OfferFlags; use vmbus_core::protocol::UserDefinedData; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; #[test] fn test_check_result() { @@ -183,7 +183,7 @@ mod tests { .with_named_pipe_mode(true) .with_tlnpi_provider(hvsock), user_defined, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } diff --git a/vm/devices/vmbus/vmbus_client/src/lib.rs b/vm/devices/vmbus/vmbus_client/src/lib.rs index 13b3125037..d40e5e1388 100644 --- a/vm/devices/vmbus/vmbus_client/src/lib.rs +++ b/vm/devices/vmbus/vmbus_client/src/lib.rs @@ -41,7 +41,9 @@ use vmbus_core::MonitorPageGpas; use vmbus_core::OutgoingMessage; use vmbus_core::TaggedStream; use vmbus_core::VersionInfo; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const SINT: u8 = 2; const VTL: u8 = 0; @@ -1356,11 +1358,16 @@ struct ClientTaskInner { } impl ClientTaskInner { - fn send(&self, msg: &T) { + fn send( + &self, + msg: &T, + ) { send_message(self.synic.as_ref(), msg, &[]) } - fn send_with_data( + fn send_with_data< + T: IntoBytes + protocol::VmbusMessage + std::fmt::Debug + Immutable + KnownLayout, + >( &self, msg: &T, data: &[u8], @@ -1373,7 +1380,9 @@ impl ClientTaskInner { } } -fn send_message( +fn send_message< + T: IntoBytes + protocol::VmbusMessage + std::fmt::Debug + Immutable + KnownLayout, +>( synic: &dyn SynicClient, msg: &T, data: &[u8], @@ -1399,13 +1408,15 @@ mod tests { use vmbus_core::protocol::MessageType; use vmbus_core::protocol::OfferFlags; use vmbus_core::protocol::UserDefinedData; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; const VMBUS_TEST_CLIENT_ID: Guid = Guid::from_static_str("e6e6e6e6-e6e6-e6e6-e6e6-e6e6e6e6e6e6"); - fn in_msg(message_type: MessageType, t: T) -> Vec { + fn in_msg(message_type: MessageType, t: T) -> Vec { let mut data = Vec::new(); data.extend_from_slice(&message_type.0.to_ne_bytes()); data.extend_from_slice(&0u32.to_ne_bytes()); @@ -1592,7 +1603,7 @@ mod tests { parent_to_child_monitor_page_gpa: 0, child_to_parent_monitor_page_gpa: 0, }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) ); } @@ -1616,7 +1627,7 @@ mod tests { parent_to_child_monitor_page_gpa: 0, child_to_parent_monitor_page_gpa: 0, }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) ); @@ -1658,7 +1669,7 @@ mod tests { parent_to_child_monitor_page_gpa: 0, child_to_parent_monitor_page_gpa: 0, }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) ); @@ -1733,7 +1744,7 @@ mod tests { parent_to_child_monitor_page_gpa: 0, child_to_parent_monitor_page_gpa: 0, }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) ); diff --git a/vm/devices/vmbus/vmbus_client_hcl/Cargo.toml b/vm/devices/vmbus/vmbus_client_hcl/Cargo.toml index f3372f904f..7eb08efe90 100644 --- a/vm/devices/vmbus/vmbus_client_hcl/Cargo.toml +++ b/vm/devices/vmbus/vmbus_client_hcl/Cargo.toml @@ -18,6 +18,5 @@ anyhow.workspace = true futures.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_client_hcl/src/lib.rs b/vm/devices/vmbus/vmbus_client_hcl/src/lib.rs index 6b35b81709..fee04a1afd 100644 --- a/vm/devices/vmbus/vmbus_client_hcl/src/lib.rs +++ b/vm/devices/vmbus/vmbus_client_hcl/src/lib.rs @@ -28,7 +28,7 @@ use std::task::Poll; use vmbus_async::async_dgram::AsyncRecv; use vmbus_client::SynicClient; use vmbus_client::VmbusMessageSource; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Returns the synic client and message source for use with /// [`vmbus_client::VmbusClient`]. @@ -113,7 +113,7 @@ impl AsyncRecv for MessageSource { mut bufs: &mut [IoSliceMut<'_>], ) -> Poll> { let mut msg = HvMessage::default(); - let size = ready!(Pin::new(&mut self.pipe).poll_read(cx, msg.as_bytes_mut()))?; + let size = ready!(Pin::new(&mut self.pipe).poll_read(cx, msg.as_mut_bytes()))?; if size == 0 { return Ok(0).into(); } diff --git a/vm/devices/vmbus/vmbus_core/Cargo.toml b/vm/devices/vmbus/vmbus_core/Cargo.toml index d24099a4b5..9596aed8f9 100644 --- a/vm/devices/vmbus/vmbus_core/Cargo.toml +++ b/vm/devices/vmbus/vmbus_core/Cargo.toml @@ -18,7 +18,5 @@ futures.workspace = true static_assertions.workspace = true thiserror.workspace = true zerocopy.workspace = true -zerocopy_helpers.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_core/src/lib.rs b/vm/devices/vmbus/vmbus_core/src/lib.rs index 3c2ce13b28..839b67b3b7 100644 --- a/vm/devices/vmbus/vmbus_core/src/lib.rs +++ b/vm/devices/vmbus/vmbus_core/src/lib.rs @@ -15,7 +15,9 @@ use protocol::MAX_MESSAGE_SIZE; use std::future::Future; use std::str::FromStr; use std::task::Poll; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug)] pub struct TaggedStream(Option, S); @@ -126,7 +128,7 @@ pub struct OutgoingMessage { /// Represents a vmbus message to be sent using the synic. impl OutgoingMessage { /// Creates a new `OutgoingMessage` for the specified protocol message. - pub fn new(message: &T) -> Self { + pub fn new(message: &T) -> Self { let mut data = [0; MAX_MESSAGE_SIZE]; let header = MessageHeader::new(T::MESSAGE_TYPE); let message_bytes = message.as_bytes(); @@ -141,7 +143,10 @@ impl OutgoingMessage { /// Creates a new `OutgoingMessage` for the specified protocol message, including additional /// data at the end of the message. - pub fn with_data(message: &T, data: &[u8]) -> Self { + pub fn with_data( + message: &T, + data: &[u8], + ) -> Self { let mut message = OutgoingMessage::new(message); let old_len = message.len as usize; let len = old_len + data.len(); diff --git a/vm/devices/vmbus/vmbus_core/src/protocol.rs b/vm/devices/vmbus/vmbus_core/src/protocol.rs index 4a41ddc2f7..9e98482985 100644 --- a/vm/devices/vmbus/vmbus_core/src/protocol.rs +++ b/vm/devices/vmbus/vmbus_core/src/protocol.rs @@ -15,9 +15,11 @@ use std::ops::BitOr; use std::ops::Deref; use std::ops::DerefMut; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Unalign; #[macro_use] @@ -125,7 +127,7 @@ pub trait VmbusMessage: Sized { /// The header of a vmbus message. #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct MessageHeader { message_type: MessageType, padding: u32, @@ -146,7 +148,7 @@ impl MessageHeader { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] pub struct FeatureFlags { /// Feature which allows the guest to specify an event flag and connection ID when opening /// a channel. If not used, the event flag defaults to the channel ID and the connection ID @@ -219,9 +221,10 @@ impl BitOr for FeatureFlags { Ord, PartialOrd, Hash, - AsBytes, + IntoBytes, FromBytes, - FromZeroes, + Immutable, + KnownLayout, Protobuf, )] #[mesh(package = "vmbus")] @@ -238,9 +241,10 @@ pub struct GpadlId(pub u32); Ord, PartialOrd, Hash, - AsBytes, + IntoBytes, FromBytes, - FromZeroes, + Immutable, + KnownLayout, Protobuf, )] #[inspect(transparent)] @@ -256,7 +260,7 @@ impl ConnectionId { } #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct InitiateContact { pub version_requested: u32, pub target_message_vp: u32, @@ -268,7 +272,7 @@ pub struct InitiateContact { /// Initiate contact message used with `FeatureFlags::CLIENT_ID` when the feature is supported /// (Copper and above). #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct InitiateContact2 { pub initiate_contact: InitiateContact, pub client_id: Guid, @@ -278,14 +282,14 @@ impl From for InitiateContact2 { fn from(value: InitiateContact) -> Self { Self { initiate_contact: value, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } /// Helper struct to interpret the `InitiateContact::interrupt_page_or_target_info` field. #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TargetInfo { pub sint: u8, pub vtl: u8, @@ -307,12 +311,12 @@ impl TargetInfo { /// Interprets a 64 bit value as the `TargetInfo` struct. pub fn from_u64(value: &u64) -> &Self { - Self::ref_from_prefix(value.as_bytes()).unwrap() + Self::ref_from_prefix(value.as_bytes()).unwrap().0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } /// Represents the `TargetInfo` struct as a 64 bit number. pub fn as_u64(&self) -> &u64 { - u64::ref_from_prefix(self.as_bytes()).unwrap() + u64::ref_from_prefix(self.as_bytes()).unwrap().0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } } @@ -338,7 +342,7 @@ pub enum Version { open_enum! { /// Possible values for the `VersionResponse::connection_state` field. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum ConnectionState: u8 { SUCCESSFUL = 0, FAILED_LOW_RESOURCES = 1, @@ -347,7 +351,7 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VersionResponse { pub version_supported: u8, pub connection_state: ConnectionState, @@ -360,7 +364,7 @@ pub struct VersionResponse { /// above and the version is supported. For unsupported versions, the original `VersionResponse` /// is always sent. #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct VersionResponse2 { pub version_response: VersionResponse, pub supported_features: u32, @@ -370,13 +374,25 @@ impl From for VersionResponse2 { fn from(value: VersionResponse) -> Self { Self { version_response: value, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } /// User-defined data provided by a device as part of an offer or open request. -#[derive(Copy, Clone, Debug, PartialEq, Eq, AsBytes, FromBytes, FromZeroes, Protobuf, Inspect)] +#[derive( + Copy, + Clone, + Debug, + PartialEq, + Eq, + IntoBytes, + FromBytes, + Immutable, + KnownLayout, + Protobuf, + Inspect, +)] #[repr(C, align(4))] #[mesh(transparent)] #[inspect(transparent)] @@ -384,22 +400,28 @@ pub struct UserDefinedData([u8; 120]); impl UserDefinedData { pub fn as_pipe_params(&self) -> &PipeUserDefinedParameters { - PipeUserDefinedParameters::ref_from(&self.0[0..size_of::()]) - .expect("from bytes should not fail") + PipeUserDefinedParameters::ref_from_bytes( + &self.0[0..size_of::()], + ) + .expect("from bytes should not fail") } pub fn as_pipe_params_mut(&mut self) -> &mut PipeUserDefinedParameters { - PipeUserDefinedParameters::mut_from(&mut self.0[0..size_of::()]) - .expect("from bytes should not fail") + PipeUserDefinedParameters::mut_from_bytes( + &mut self.0[0..size_of::()], + ) + .expect("from bytes should not fail") } pub fn as_hvsock_params(&self) -> &HvsockUserDefinedParameters { - HvsockUserDefinedParameters::ref_from(&self.0[0..size_of::()]) - .expect("from bytes should not fail") + HvsockUserDefinedParameters::ref_from_bytes( + &self.0[0..size_of::()], + ) + .expect("from bytes should not fail") } pub fn as_hvsock_params_mut(&mut self) -> &mut HvsockUserDefinedParameters { - HvsockUserDefinedParameters::mut_from( + HvsockUserDefinedParameters::mut_from_bytes( &mut self.0[0..size_of::()], ) .expect("from bytes should not fail") @@ -439,7 +461,9 @@ impl Default for UserDefinedData { } #[repr(C)] -#[derive(Copy, Clone, Debug, Inspect, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive( + Copy, Clone, Debug, Inspect, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout, +)] pub struct OfferChannel { pub interface_id: Guid, pub instance_id: Guid, @@ -459,7 +483,7 @@ pub struct OfferChannel { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq, Protobuf)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq, Protobuf)] #[mesh(transparent)] pub struct OfferFlags { pub enumerate_device_interface: bool, // 0x1 @@ -480,7 +504,7 @@ pub struct OfferFlags { open_enum! { /// Possible values for the `PipeUserDefinedParameters::pipe_type` field. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum PipeType: u32 { BYTE = 0, MESSAGE = 4, @@ -489,13 +513,13 @@ open_enum! { /// First 4 bytes of user_defined for named pipe offers. #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct PipeUserDefinedParameters { pub pipe_type: PipeType, } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct HvsockUserDefinedParameters { pub pipe_params: PipeUserDefinedParameters, pub is_for_guest_accept: u8, @@ -522,7 +546,7 @@ impl HvsockUserDefinedParameters { open_enum! { /// Possible values for the `PipeUserDefinedParameters::pipe_type` field. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum HvsockParametersVersion: u32 { PRE_RS5 = 0, RS5 = 1, @@ -530,13 +554,13 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RescindChannelOffer { pub channel_id: ChannelId, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GpadlHeader { pub channel_id: ChannelId, pub gpadl_id: GpadlId, @@ -550,7 +574,7 @@ impl GpadlHeader { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GpadlBody { pub rsvd: u32, pub gpadl_id: GpadlId, @@ -562,7 +586,7 @@ impl GpadlBody { } #[repr(C)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GpadlCreated { pub channel_id: ChannelId, pub gpadl_id: GpadlId, @@ -573,7 +597,7 @@ pub struct GpadlCreated { pub const VP_INDEX_DISABLE_INTERRUPT: u32 = u32::MAX; #[repr(C)] -#[derive(Debug, Copy, Clone, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct OpenChannel { pub channel_id: ChannelId, pub open_id: u32, @@ -584,7 +608,7 @@ pub struct OpenChannel { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)] pub struct OpenChannelFlags { /// Indicates the host-to-guest interrupt for this channel should be sent to the redirected /// VTL and SINT. This has no effect if the server is not using redirection. @@ -597,7 +621,7 @@ pub struct OpenChannelFlags { /// Open channel message used if `FeatureFlags::GUEST_SPECIFIED_SIGNAL_PARAMETERS` or /// `FeatureFlags::CHANNEL_INTERRUPT_REDIRECTION` is supported. #[repr(C)] -#[derive(Debug, Copy, Clone, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct OpenChannel2 { pub open_channel: OpenChannel, @@ -613,13 +637,13 @@ impl From for OpenChannel2 { fn from(value: OpenChannel) -> Self { Self { open_channel: value, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } #[repr(C)] -#[derive(PartialEq, Eq, Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct OpenResult { pub channel_id: ChannelId, pub open_id: u32, @@ -627,32 +651,32 @@ pub struct OpenResult { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CloseChannel { pub channel_id: ChannelId, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RelIdReleased { pub channel_id: ChannelId, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GpadlTeardown { pub channel_id: ChannelId, pub gpadl_id: GpadlId, } #[repr(C)] -#[derive(Debug, Copy, Clone, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct GpadlTorndown { pub gpadl_id: GpadlId, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct OpenReservedChannel { pub channel_id: ChannelId, pub target_vp: u32, @@ -662,7 +686,7 @@ pub struct OpenReservedChannel { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CloseReservedChannel { pub channel_id: ChannelId, pub target_vp: u32, @@ -670,20 +694,20 @@ pub struct CloseReservedChannel { } #[repr(C)] -#[derive(PartialEq, Eq, Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct CloseReservedChannelResponse { pub channel_id: ChannelId, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TlConnectRequest { pub endpoint_id: Guid, pub service_id: Guid, } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TlConnectRequest2 { pub base: TlConnectRequest, pub silo_id: Guid, @@ -693,13 +717,13 @@ impl From for TlConnectRequest2 { fn from(value: TlConnectRequest) -> Self { Self { base: value, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct TlConnectResult { pub endpoint_id: Guid, pub service_id: Guid, @@ -707,28 +731,28 @@ pub struct TlConnectResult { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyChannel { pub channel_id: ChannelId, pub target_vp: u32, } #[repr(C)] -#[derive(PartialEq, Eq, Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyChannelResponse { pub channel_id: ChannelId, pub status: i32, } #[repr(C)] -#[derive(PartialEq, Eq, Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyConnection { pub parent_to_child_monitor_page_gpa: u64, pub child_to_parent_monitor_page_gpa: u64, } #[repr(C)] -#[derive(PartialEq, Eq, Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, Debug, Copy, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct ModifyConnectionResponse { pub connection_state: ConnectionState, } @@ -737,17 +761,17 @@ pub struct ModifyConnectionResponse { // to allow for consistent use of the VmbusMessage trait for all messages. #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct RequestOffers {} #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct Unload {} #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct UnloadComplete {} #[repr(C)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoBytes, FromBytes, Immutable, KnownLayout)] pub struct AllOffersDelivered {} diff --git a/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs b/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs index c50e258ed0..265b7b7bce 100644 --- a/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs +++ b/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs @@ -6,7 +6,7 @@ macro_rules! vmbus_message_type { (pub enum $enum_name:ident, $open_enum_name:ident { $( $num:literal $name:ident $rest:tt, )* }) => { open_enum! { /// Represents the message type value that identifies a vmbus protocol message. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)] pub enum $open_enum_name: u32 { $($name = $num,)* } @@ -31,22 +31,22 @@ macro_rules! vmbus_message_enum { /// Use `None` for the version to only parse messages that are accepted in a /// disconnected state. pub fn parse(data: &'a [u8], version: Option) -> Result { - use zerocopy_helpers::FromBytesExt as _; - let (version, features) = if let Some(version) = version { (Some(version.version), version.feature_flags) } else { (None, FeatureFlags::new()) }; - let (header, data) = MessageHeader::read_from_prefix_split(data).ok_or(ParseError::MessageTooSmall(None))?; + // todo: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. + let (header, data) = MessageHeader::read_from_prefix(data).map_err(|_| ParseError::MessageTooSmall(None))?; let message = match header.message_type { $( $($open_enum_name::$name if vmbus_message_enum!(@create_conditions $type version features data $min_version $($condition_name:$condition_value)*) => { - let (message, remaining) = $type::read_from_prefix_split(data).ok_or(ParseError::MessageTooSmall(Some(header.message_type)))?; + // todo: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. + let (message, remaining) = $type::read_from_prefix(data).map_err(|_| ParseError::MessageTooSmall(Some(header.message_type)))?; Self::$type(message, remaining) })* diff --git a/vm/devices/vmbus/vmbus_proxy/Cargo.toml b/vm/devices/vmbus/vmbus_proxy/Cargo.toml index 5de16bd9ca..8a6f9e61c2 100644 --- a/vm/devices/vmbus/vmbus_proxy/Cargo.toml +++ b/vm/devices/vmbus/vmbus_proxy/Cargo.toml @@ -20,6 +20,5 @@ ntapi.workspace = true tracing.workspace = true winapi = { workspace = true, features = ["debug", "winioctl"] } zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_proxy/src/lib.rs b/vm/devices/vmbus/vmbus_proxy/src/lib.rs index 735f4eefca..3d95c8656f 100644 --- a/vm/devices/vmbus/vmbus_proxy/src/lib.rs +++ b/vm/devices/vmbus/vmbus_proxy/src/lib.rs @@ -30,7 +30,10 @@ use winapi::shared::winerror::ERROR_CANCELLED; use winapi::um::ioapiset::DeviceIoControl; use winapi::um::winnt::GENERIC_ALL; use winapi::um::winnt::SYNCHRONIZE; -use zerocopy::AsBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub mod vmbusioctl { #![allow( @@ -94,7 +97,10 @@ mod proxyioctl { use winapi::um::winioctl::FILE_READ_ACCESS; use winapi::um::winioctl::FILE_WRITE_ACCESS; use winapi::um::winioctl::METHOD_BUFFERED; - use zerocopy::AsBytes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; const fn CTL_CODE(DeviceType: u32, Function: u32, Method: u32, Access: u32) -> u32 { (DeviceType << 16) | (Access << 14) | (Function << 2) | Method @@ -190,7 +196,7 @@ mod proxyioctl { } #[repr(C)] - #[derive(Copy, Clone, AsBytes)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout)] pub struct VMBUS_PROXY_CREATE_GPADL_INPUT { pub ChannelId: u64, pub GpadlId: u32, diff --git a/vm/devices/vmbus/vmbus_relay_intercept_device/Cargo.toml b/vm/devices/vmbus/vmbus_relay_intercept_device/Cargo.toml index 87967b7077..2a7847b3b0 100644 --- a/vm/devices/vmbus/vmbus_relay_intercept_device/Cargo.toml +++ b/vm/devices/vmbus/vmbus_relay_intercept_device/Cargo.toml @@ -29,6 +29,5 @@ futures-concurrency.workspace = true tracelimit.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_relay_intercept_device/src/lib.rs b/vm/devices/vmbus/vmbus_relay_intercept_device/src/lib.rs index 643dfde74c..abf3865b9f 100644 --- a/vm/devices/vmbus/vmbus_relay_intercept_device/src/lib.rs +++ b/vm/devices/vmbus/vmbus_relay_intercept_device/src/lib.rs @@ -60,7 +60,7 @@ use vmcore::notify::PolledNotify; use vmcore::save_restore::NoSavedState; use vmcore::save_restore::SavedStateBlob; use vmcore::save_restore::SavedStateRoot; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; pub enum OfferResponse { Ignore, diff --git a/vm/devices/vmbus/vmbus_ring/Cargo.toml b/vm/devices/vmbus/vmbus_ring/Cargo.toml index 8355c5ccc0..25a1af128a 100644 --- a/vm/devices/vmbus/vmbus_ring/Cargo.toml +++ b/vm/devices/vmbus/vmbus_ring/Cargo.toml @@ -15,7 +15,6 @@ safeatomic.workspace = true smallvec.workspace = true thiserror.workspace = true zerocopy.workspace = true - [dev-dependencies] criterion = { workspace = true, features = ["rayon", "cargo_bench_support"] } diff --git a/vm/devices/vmbus/vmbus_ring/src/gparange.rs b/vm/devices/vmbus/vmbus_ring/src/gparange.rs index e5891e22be..3f52bb263b 100644 --- a/vm/devices/vmbus/vmbus_ring/src/gparange.rs +++ b/vm/devices/vmbus/vmbus_ring/src/gparange.rs @@ -5,20 +5,22 @@ use guestmem::ranges::PagedRange; use smallvec::smallvec; use smallvec::SmallVec; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const PAGE_SIZE: usize = 4096; pub type GpnList = SmallVec<[u64; 64]>; pub fn zeroed_gpn_list(len: usize) -> GpnList { - smallvec![FromZeroes::new_zeroed(); len] + smallvec![FromZeros::new_zeroed(); len] } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GpaRange { pub len: u32, pub offset: u32, @@ -201,7 +203,9 @@ impl<'a> Iterator for MultiPagedRangeIter<'a> { if self.count == 0 { return None; } - let hdr = GpaRange::read_from_prefix(self.buf[0].as_bytes()).unwrap(); + let hdr = GpaRange::read_from_prefix(self.buf[0].as_bytes()) + .unwrap() + .0; // todo: zerocopy: use-rest-of-range let page_count = ((hdr.offset + hdr.len) as usize).div_ceil(PAGE_SIZE); // N.B. already validated let (this, rest) = self.buf.split_at(page_count + 1); let range = PagedRange::new(hdr.offset as usize, hdr.len as usize, &this[1..]).unwrap(); diff --git a/vm/devices/vmbus/vmbus_ring/src/lib.rs b/vm/devices/vmbus/vmbus_ring/src/lib.rs index 9067171f33..0a5ac54c6c 100644 --- a/vm/devices/vmbus/vmbus_ring/src/lib.rs +++ b/vm/devices/vmbus/vmbus_ring/src/lib.rs @@ -35,18 +35,19 @@ use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use std::sync::Arc; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; mod pipe_protocol { - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; /// Pipe channel packets are prefixed with this header to allow for /// non-8-multiple lengths. #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PipeHeader { pub packet_type: u32, pub len: u32, @@ -75,16 +76,17 @@ mod protocol { use std::fmt::Debug; use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; /// VmBus ring buffers are sized in multiples 4KB pages, with a 4KB control page. pub const PAGE_SIZE: usize = 4096; /// The descriptor header on every packet. #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PacketDescriptor { pub packet_type: u16, pub data_offset8: u16, @@ -150,7 +152,7 @@ mod protocol { /// A transfer range specifying a length and offset within a transfer page /// set. Only used by NetVSP. #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TransferPageRange { pub byte_count: u32, pub byte_offset: u32, @@ -159,7 +161,7 @@ mod protocol { /// The extended portion of the packet descriptor that describes a transfer /// page packet. #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TransferPageHeader { pub transfer_page_set_id: u16, pub reserved: u16, // may have garbage non-zero values @@ -168,7 +170,7 @@ mod protocol { /// The extended portion of the packet descriptor describing a GPA direct packet. #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GpaDirectHeader { pub reserved: u32, // may have garbage non-zero values pub range_count: u32, @@ -178,7 +180,7 @@ mod protocol { /// The packet footer. #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Footer { pub reserved: u32, /// The ring offset of the packet. @@ -354,7 +356,7 @@ fn parse_packet( avail: u32, ) -> Result<(u32, IncomingPacket), ReadError> { let mut desc = PacketDescriptor::new_zeroed(); - ring.read_aligned(ring_off as usize, desc.as_bytes_mut()); + ring.read_aligned(ring_off as usize, desc.as_mut_bytes()); let len = desc.length8 as u32 * 8; if desc.length8 < desc.data_offset8 || desc.data_offset8 < 2 || avail < len { return Err(ReadError::Corrupt(Error::InvalidDescriptorLengths)); @@ -375,7 +377,7 @@ fn parse_packet( PACKET_TYPE_COMPLETION => IncomingPacketType::Completion, PACKET_TYPE_TRANSFER_PAGES => { let mut tph = TransferPageHeader::new_zeroed(); - ring.read_aligned(ring_off as usize + 16, tph.as_bytes_mut()); + ring.read_aligned(ring_off as usize + 16, tph.as_mut_bytes()); IncomingPacketType::TransferPages( tph.transfer_page_set_id, tph.range_count, @@ -387,7 +389,7 @@ fn parse_packet( } PACKET_TYPE_GPA_DIRECT => { let mut gph = GpaDirectHeader::new_zeroed(); - ring.read_aligned(ring_off as usize + 16, gph.as_bytes_mut()); + ring.read_aligned(ring_off as usize + 16, gph.as_mut_bytes()); if gph.range_count == 0 { return Err(ReadError::Corrupt( Error::InvalidDescriptorGpaDirectRangeCount, diff --git a/vm/devices/vmbus/vmbus_server/Cargo.toml b/vm/devices/vmbus/vmbus_server/Cargo.toml index 9370667364..1009a81630 100644 --- a/vm/devices/vmbus/vmbus_server/Cargo.toml +++ b/vm/devices/vmbus/vmbus_server/Cargo.toml @@ -35,14 +35,12 @@ tracelimit.workspace = true tracing.workspace = true unicycle.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies] vmbus_proxy.workspace = true winapi.workspace = true [dev-dependencies] test_with_tracing.workspace = true -zerocopy_helpers.workspace = true [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_server/src/channels.rs b/vm/devices/vmbus/vmbus_server/src/channels.rs index a91a0502e0..ab7a45b90e 100644 --- a/vm/devices/vmbus/vmbus_server/src/channels.rs +++ b/vm/devices/vmbus/vmbus_server/src/channels.rs @@ -43,8 +43,10 @@ use vmbus_core::OutgoingMessage; use vmbus_core::VersionInfo; use vmbus_ring::gparange; use vmcore::monitor::MonitorId; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// An error caused by a channel operation. #[derive(Debug, Error)] @@ -1119,7 +1121,7 @@ impl Gpadl { let data = &data[..len]; let start = buf.len(); buf.resize(buf.len() + data.len() / 8, 0); - buf[start..].as_bytes_mut().copy_from_slice(data); + buf[start..].as_mut_bytes().copy_from_slice(data); Ok(if buf.len() == buf.capacity() { gparange::MultiPagedRangeBuf::>::validate(self.count as usize, buf) .map_err(ChannelError::InvalidGpaRange)?; @@ -3445,7 +3447,10 @@ fn revoke( } /// Sends a VMBus channel message to the guest. -fn send_message( +fn send_message< + N: Notifier, + T: IntoBytes + protocol::VmbusMessage + std::fmt::Debug + Immutable + KnownLayout, +>( notifier: &mut N, msg: &T, ) { @@ -3453,7 +3458,10 @@ fn send_message( +fn send_message_with_target< + N: Notifier, + T: IntoBytes + protocol::VmbusMessage + std::fmt::Debug + Immutable + KnownLayout, +>( notifier: &mut N, msg: &T, target: MessageTarget, @@ -3561,12 +3569,16 @@ mod tests { use std::sync::mpsc; use test_with_tracing::test; use vmbus_core::protocol::TargetInfo; + use zerocopy::FromBytes; - fn in_msg(message_type: protocol::MessageType, t: T) -> SynicMessage { + fn in_msg( + message_type: protocol::MessageType, + t: T, + ) -> SynicMessage { in_msg_ex(message_type, t, false, false) } - fn in_msg_ex( + fn in_msg_ex( message_type: protocol::MessageType, t: T, multiclient: bool, @@ -3936,14 +3948,12 @@ mod tests { assert!(self.messages.is_empty()); } - fn get_message(&mut self) -> T { - use zerocopy_helpers::FromBytesExt; + fn get_message(&mut self) -> T { let (message, _) = self.messages.pop_front().unwrap(); - let (header, data) = - protocol::MessageHeader::read_from_prefix_split(message.data()).unwrap(); + let (header, data) = protocol::MessageHeader::read_from_prefix(message.data()).unwrap(); assert_eq!(header.message_type(), T::MESSAGE_TYPE); - T::read_from_prefix(data).unwrap() + T::read_from_prefix(data).unwrap().0 // todo: zerocopy: use-rest-of-range } fn check_messages(&mut self, messages: &[OutgoingMessage]) { @@ -4123,7 +4133,7 @@ mod tests { let version_response = protocol::VersionResponse { version_supported: 1, selected_version_or_connection_id: 1, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if version >= Version::Copper { @@ -4469,9 +4479,9 @@ mod tests { .handle_open_channel(&protocol::OpenChannel2 { open_channel: protocol::OpenChannel { channel_id: ChannelId(id), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }) .unwrap() } @@ -4492,7 +4502,7 @@ mod tests { target_vp, target_sint, ring_buffer_gpadl: GpadlId(id), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, version, ) @@ -4565,7 +4575,7 @@ mod tests { .as_u64(), child_to_parent_monitor_page_gpa: 0x123f000, parent_to_child_monitor_page_gpa: 0x321f000, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, client_id: Guid::ZERO, }, @@ -4633,9 +4643,9 @@ mod tests { &protocol::InitiateContact2 { initiate_contact: protocol::InitiateContact { version_requested: Version::Win10 as u32, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, &SynicMessage::default(), true, @@ -5029,7 +5039,7 @@ mod tests { env.notifier.check_message_with_target( OutgoingMessage::new(&protocol::OpenResult { channel_id: ChannelId(1), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }), MessageTarget::ReservedChannel(offer_id1), ); diff --git a/vm/devices/vmbus/vmbus_server/src/lib.rs b/vm/devices/vmbus/vmbus_server/src/lib.rs index 75a0ca9c6c..71e9164b13 100644 --- a/vm/devices/vmbus/vmbus_server/src/lib.rs +++ b/vm/devices/vmbus/vmbus_server/src/lib.rs @@ -1829,9 +1829,12 @@ mod tests { use vmbus_core::protocol::ChannelId; use vmbus_core::protocol::VmbusMessage; use vmcore::synic::SynicPortAccess; - use zerocopy::AsBytes; use zerocopy::FromBytes; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; + struct MockSynicInner { message_port: Option>, } @@ -1849,11 +1852,14 @@ mod tests { } } - fn send_message(&self, msg: impl VmbusMessage + AsBytes) { + fn send_message(&self, msg: impl VmbusMessage + IntoBytes + Immutable + KnownLayout) { self.send_message_core(OutgoingMessage::new(&msg), false); } - fn send_message_trusted(&self, msg: impl VmbusMessage + AsBytes) { + fn send_message_trusted( + &self, + msg: impl VmbusMessage + IntoBytes + Immutable + KnownLayout, + ) { self.send_message_core(OutgoingMessage::new(&msg), true); } @@ -2102,17 +2108,17 @@ mod tests { async fn expect_response(&mut self, expected: protocol::MessageType) { let data = self.message_recv.next().await.unwrap(); - let header = protocol::MessageHeader::read_from_prefix(&data).unwrap(); - + let header = protocol::MessageHeader::read_from_prefix(&data).unwrap().0; // todo: zerocopy: use-rest-of-range assert_eq!(expected, header.message_type()) } - async fn get_response(&mut self) -> T { - use zerocopy_helpers::FromBytesExt; + async fn get_response( + &mut self, + ) -> T { let data = self.message_recv.next().await.unwrap(); - let (header, message) = protocol::MessageHeader::read_from_prefix_split(&data).unwrap(); + let (header, message) = protocol::MessageHeader::read_from_prefix(&data).unwrap(); // TODO: zerocopy: unwrap assert_eq!(T::MESSAGE_TYPE, header.message_type()); - T::read_from_prefix(message).unwrap() + T::read_from_prefix(message).unwrap().0 // todo: zerocopy: use-rest-of-range } fn initiate_contact( diff --git a/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs b/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs index d6b602ae7a..8364c1ca19 100644 --- a/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs +++ b/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs @@ -43,7 +43,10 @@ use vmbus_proxy::ProxyAction; use vmbus_proxy::VmbusProxy; use vmcore::interrupt::Interrupt; use winapi::shared::winerror::ERROR_CANCELLED; -use zerocopy::AsBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub struct ProxyIntegration { cancel: Cancel, diff --git a/vm/devices/vmbus/vmbus_user_channel/Cargo.toml b/vm/devices/vmbus/vmbus_user_channel/Cargo.toml index 59c2bb594e..fbd71fa5c4 100644 --- a/vm/devices/vmbus/vmbus_user_channel/Cargo.toml +++ b/vm/devices/vmbus/vmbus_user_channel/Cargo.toml @@ -23,6 +23,5 @@ parking_lot.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/devices/vmbus/vmbus_user_channel/src/lib.rs b/vm/devices/vmbus/vmbus_user_channel/src/lib.rs index 0fbdd922f8..0db5a0c527 100644 --- a/vm/devices/vmbus/vmbus_user_channel/src/lib.rs +++ b/vm/devices/vmbus/vmbus_user_channel/src/lib.rs @@ -53,7 +53,7 @@ use vmbus_channel::SignalVmbusChannel; use vmbus_ring::IncomingRing; use vmbus_ring::OutgoingRing; use vmbus_ring::RingMem; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Ring buffer memory backed by a memory mapped channel. #[derive(Debug)] diff --git a/vm/hv1/hv1_emulator/Cargo.toml b/vm/hv1/hv1_emulator/Cargo.toml index c72079ff39..e8b3f58718 100644 --- a/vm/hv1/hv1_emulator/Cargo.toml +++ b/vm/hv1/hv1_emulator/Cargo.toml @@ -20,7 +20,6 @@ tracelimit.workspace = true parking_lot.workspace = true tracing.workspace = true zerocopy.workspace = true - [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vm/hv1/hv1_emulator/src/hv.rs b/vm/hv1/hv1_emulator/src/hv.rs index 7f3106743f..5dae0adfae 100644 --- a/vm/hv1/hv1_emulator/src/hv.rs +++ b/vm/hv1/hv1_emulator/src/hv.rs @@ -24,7 +24,7 @@ use vm_topology::processor::VpIndex; use vmcore::reference_time_source::ReferenceTimeSource; use vtl_array::VtlArray; use x86defs::cpuid::Vendor; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; /// The partition-wide hypervisor state. #[derive(Inspect)] @@ -244,7 +244,7 @@ impl ProcessorVtlHv { as u64; let reference_page = hvdef::HvReferenceTscPage { tsc_scale, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if let Err(err) = gm.write_plain(gpa, &reference_page) { tracelimit::warn_ratelimited!( diff --git a/vm/hv1/hv1_emulator/src/synic.rs b/vm/hv1/hv1_emulator/src/synic.rs index a5f20c050a..5fc5a4b0a1 100644 --- a/vm/hv1/hv1_emulator/src/synic.rs +++ b/vm/hv1/hv1_emulator/src/synic.rs @@ -27,7 +27,7 @@ use std::array; use std::sync::Arc; use virt::x86::MsrError; use vm_topology::processor::VpIndex; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// The virtual processor synthetic interrupt controller state. #[derive(Inspect)] diff --git a/vm/hv1/hv1_hypercall/Cargo.toml b/vm/hv1/hv1_hypercall/Cargo.toml index ed5dd124a0..f8ea357290 100644 --- a/vm/hv1/hv1_hypercall/Cargo.toml +++ b/vm/hv1/hv1_hypercall/Cargo.toml @@ -14,7 +14,6 @@ tracelimit.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] open_enum.workspace = true sparse_mmap.workspace = true diff --git a/vm/hv1/hv1_hypercall/src/imp.rs b/vm/hv1/hv1_hypercall/src/imp.rs index 386de4e56a..dacdf5f17e 100644 --- a/vm/hv1/hv1_hypercall/src/imp.rs +++ b/vm/hv1/hv1_hypercall/src/imp.rs @@ -23,7 +23,7 @@ use hvdef::HvRepResult; use hvdef::HvResult; use hvdef::HypercallCode; use hvdef::Vtl; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; trait MapToHypercallResult { fn map_to_hypercall_result( diff --git a/vm/hv1/hv1_hypercall/src/support.rs b/vm/hv1/hv1_hypercall/src/support.rs index 4856bdc4df..e14dc04c2d 100644 --- a/vm/hv1/hv1_hypercall/src/support.rs +++ b/vm/hv1/hv1_hypercall/src/support.rs @@ -13,8 +13,10 @@ use hvdef::HV_PAGE_SIZE; use hvdef::HV_PAGE_SIZE_USIZE; use std::marker::PhantomData; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Ref; /// A hypercall definition. @@ -275,7 +277,7 @@ impl<'a, T: HypercallIo> InnerDispatcher<'a, T> { HypercallParameters { control, input: &input.as_bytes()[..input_len], - output: &mut output.as_bytes_mut()[..output_len], + output: &mut output.as_mut_bytes()[..output_len], elements_processed: elements_processed.as_mut(), }, ); @@ -313,8 +315,8 @@ impl<'a, T: HypercallIo> InnerDispatcher<'a, T> { check_buffer(self.handler.input_gpa(), input_len)?; check_buffer(self.handler.output_gpa(), output_len)?; - let input = &mut input_buffer.0.as_bytes_mut()[..input_len]; - let output = &mut output_buffer.0.as_bytes_mut()[..output_len]; + let input = &mut input_buffer.0.as_mut_bytes()[..input_len]; + let output = &mut output_buffer.0.as_mut_bytes()[..output_len]; // FUTURE: consider copying only the header and entries after // `rep_start` for rep hypercalls. @@ -499,14 +501,14 @@ pub struct SimpleHypercall(PhantomData<(In, Out)>); impl SimpleHypercall where - In: AsBytes + FromBytes, - Out: AsBytes + FromBytes, + In: IntoBytes + FromBytes + Immutable + KnownLayout, + Out: IntoBytes + FromBytes + Immutable + KnownLayout, { /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&In, &mut Out) { ( - FromBytes::ref_from_prefix(params.input).unwrap(), - FromBytes::mut_from_prefix(params.output).unwrap(), + FromBytes::ref_from_prefix(params.input).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range, err + FromBytes::mut_from_prefix(params.output).unwrap().0, // todo: zerocopy: mut-from-prefix: use-rest-of-range, err ) } } @@ -526,16 +528,16 @@ pub struct VariableHypercall(PhantomData<(In, Out)>); impl VariableHypercall where - In: AsBytes + FromBytes, - Out: AsBytes + FromBytes, + In: IntoBytes + FromBytes + Immutable + KnownLayout, + Out: IntoBytes + FromBytes + Immutable + KnownLayout, { /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&In, &[u64], &mut Out) { - let (input, rest) = Ref::<_, In>::new_from_prefix(params.input).unwrap(); + let (input, rest) = Ref::<_, In>::from_prefix(params.input).unwrap(); ( - input.into_ref(), - u64::slice_from(rest).unwrap(), - Out::mut_from_prefix(params.output).unwrap(), + Ref::into_ref(input), + <[u64]>::ref_from_bytes(rest).unwrap(), //todo: zerocopy: err + Out::mut_from_prefix(params.output).unwrap().0, //todo: zerocopy: err ) } } @@ -555,26 +557,35 @@ pub struct RepHypercall(PhantomData<(Hdr, In, Out impl RepHypercall where - Hdr: AsBytes + FromBytes, - In: AsBytes + FromBytes, - Out: AsBytes + FromBytes, + Hdr: IntoBytes + FromBytes + Immutable + KnownLayout, + In: IntoBytes + FromBytes + Immutable + KnownLayout, + Out: IntoBytes + FromBytes + Immutable + KnownLayout, { /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&Hdr, &[In], &mut [Out], &mut usize) { - let (header, rest) = Ref::<_, Hdr>::new_from_prefix(params.input).unwrap(); + let (header, rest) = Ref::<_, Hdr>::from_prefix(params.input).unwrap(); let input = if size_of::() == 0 { &[] } else { - &In::slice_from(rest).unwrap()[params.control.rep_start()..] + // todo: zerocopy: review carefully! + // todo: zerocopy: err + &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] }; let output = if size_of::() == 0 { &mut [] } else { - &mut Out::mut_slice_from(params.output).unwrap()[params.control.rep_start()..] + // todo: zerocopy: review carefully! + // todo: zerocopy: err + &mut <[Out]>::mut_from_prefix_with_elems( + params.output, + params.output.len() / size_of::(), + ) + .unwrap() + .0[params.control.rep_start()..] }; ( - header.into_ref(), + Ref::into_ref(header), input, output, params.elements_processed.unwrap(), @@ -598,28 +609,37 @@ pub struct VariableRepHypercall(PhantomData<(Hdr, impl VariableRepHypercall where - Hdr: AsBytes + FromBytes, - In: AsBytes + FromBytes, - Out: AsBytes + FromBytes, + Hdr: IntoBytes + FromBytes + Immutable + KnownLayout, + In: IntoBytes + FromBytes + Immutable + KnownLayout, + Out: IntoBytes + FromBytes + Immutable + KnownLayout, { /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&Hdr, &[u64], &[In], &mut [Out], &mut usize) { - let (header, rest) = Ref::<_, Hdr>::new_from_prefix(params.input).unwrap(); + let (header, rest) = Ref::<_, Hdr>::from_prefix(params.input).unwrap(); let (var_header, rest) = - u64::slice_from_prefix(rest, params.control.variable_header_size()).unwrap(); + <[u64]>::ref_from_prefix_with_elems(rest, params.control.variable_header_size()) + .unwrap(); let input = if size_of::() == 0 { &[] } else { - &In::slice_from(rest).unwrap()[params.control.rep_start()..] + &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] + // todo: zerocopy: review carefully! }; let output = if size_of::() == 0 { &mut [] } else { - &mut Out::mut_slice_from(params.output).unwrap()[params.control.rep_start()..] + // todo: zerocopy: review carefully! + // todo: zerocopy: err + &mut <[Out]>::mut_from_prefix_with_elems( + params.output, + params.output.len() / size_of::(), + ) + .unwrap() + .0[params.control.rep_start()..] }; ( - header.into_ref(), + Ref::into_ref(header), var_header, input, output, @@ -646,7 +666,7 @@ pub struct VtlHypercall(()); impl VtlHypercall { pub fn parse(params: HypercallParameters<'_>) -> (u64, Control) { - (u64::read_from(params.input).unwrap(), params.control) + (u64::read_from_bytes(params.input).unwrap(), params.control) } } diff --git a/vm/hv1/hv1_hypercall/src/tests.rs b/vm/hv1/hv1_hypercall/src/tests.rs index ec6398789f..69f8ddd19d 100644 --- a/vm/hv1/hv1_hypercall/src/tests.rs +++ b/vm/hv1/hv1_hypercall/src/tests.rs @@ -27,9 +27,11 @@ use open_enum::open_enum; use sparse_mmap::SparseMapping; use std::vec; use test_with_tracing::test; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // A useful base pattern to fill into hypercall input and output. const FILL_PATTERN: u64 = 0x123456789abcdef0; @@ -360,7 +362,7 @@ struct TestController { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] enum TestHypercallCode: u16 { #![allow(non_upper_case_globals)] CallSimpleNoOutput = 0x1001, @@ -379,11 +381,11 @@ open_enum! { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] struct TestInput([u8; 16]); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] struct TestOutput([u8; 16]); // Simple hypercall with no input or output. @@ -680,7 +682,7 @@ impl TestMemory { let mut buffers = [TestHypercallAlignedPage::new_zeroed(); 2]; for buffer in buffers.iter_mut() { - let buffer = buffer.0.as_bytes_mut(); + let buffer = buffer.0.as_mut_bytes(); buffer.fill(BACK_BYTE); } @@ -717,7 +719,7 @@ impl TestMemory { self.gm .read_at( TestMemory::INPUT_BASE as u64, - self.internal_buffers[Self::IN_INDEX].0.as_bytes_mut(), + self.internal_buffers[Self::IN_INDEX].0.as_mut_bytes(), ) .unwrap(); } @@ -726,7 +728,7 @@ impl TestMemory { self.gm .read_at( TestMemory::OUTPUT_BASE as u64, - self.internal_buffers[Self::OUT_INDEX].0.as_bytes_mut(), + self.internal_buffers[Self::OUT_INDEX].0.as_mut_bytes(), ) .unwrap(); } @@ -764,7 +766,7 @@ impl TestController { fn simple_no_output(&self, input_header: &InputT) -> HvResult<()> where - InputT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("simple_no_output"); match self.test_result { @@ -782,8 +784,8 @@ impl TestController { fn simple(&self, input: &InputT) -> HvResult where - InputT: AsBytes + FromBytes + Sized + Copy, - OutputT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + OutputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("simple"); match self.test_result { @@ -802,8 +804,8 @@ impl TestController { fn rep_no_output(&self, header: &InputT, input: &[InRepT]) -> HvRepResult where - InputT: AsBytes + FromBytes + Sized + Copy, - InRepT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + InRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("rep_no_output"); let (rep_start, rep_count) = self.reps.unwrap(); @@ -830,9 +832,9 @@ impl TestController { output: &mut [OutRepT], ) -> HvRepResult where - InputT: AsBytes + FromBytes + Sized + Copy, - InRepT: AsBytes + FromBytes + Sized + Copy, - OutRepT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + InRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + OutRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("rep"); let (rep_start, rep_count) = self.reps.unwrap(); @@ -861,7 +863,7 @@ impl TestController { fn variable_no_output(&self, input: &InputT, var_header: &[u64]) -> HvResult<()> where - InputT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("simple_variable_no_output"); match self.test_result { @@ -884,8 +886,8 @@ impl TestController { fn variable(&self, input: &InputT, var_header: &[u64]) -> HvResult where - InputT: AsBytes + FromBytes + Sized + Copy, - OutputT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + OutputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("simple_variable"); match self.test_result { @@ -914,9 +916,9 @@ impl TestController { output: &mut [OutRepT], ) -> HvRepResult where - InputT: AsBytes + FromBytes + Sized + Copy, - InRepT: AsBytes + FromBytes + Sized + Copy, - OutRepT: AsBytes + FromBytes + Sized + Copy, + InputT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + InRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, + OutRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { println!("var_rep"); let (rep_start, rep_count) = self.reps.unwrap(); @@ -949,10 +951,11 @@ impl TestController { fn generate_test_input() -> InputHeaderT where - InputHeaderT: AsBytes + FromBytes + Sized + Copy, + InputHeaderT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { assert!(size_of::() % 8 == 0); - *InputHeaderT::ref_from(vec![FILL_PATTERN; size_of::() / 8].as_bytes()).unwrap() + *InputHeaderT::ref_from_bytes(vec![FILL_PATTERN; size_of::() / 8].as_bytes()) + .unwrap() } fn generate_var_header(size: usize) -> Vec { @@ -963,7 +966,7 @@ impl TestController { fn generate_input_reps(rep_count: usize) -> Vec where - InRepT: AsBytes + FromBytes + Sized + Copy, + InRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { let size = rep_count * size_of::(); let pattern_count = (size + 7) / 8; @@ -972,21 +975,22 @@ impl TestController { reps.push(FILL_PATTERN + 2 + i as u64); } - let (reps, _) = InRepT::slice_from_prefix(reps.as_bytes(), rep_count).unwrap(); + let (reps, _) = <[InRepT]>::ref_from_prefix_with_elems(reps.as_bytes(), rep_count).unwrap(); reps.to_vec() } fn generate_test_output() -> OutputT where - OutputT: AsBytes + FromBytes + FromZeroes + Sized + Copy, + OutputT: IntoBytes + FromBytes + FromZeros + Sized + Copy + Immutable + KnownLayout, { assert!(size_of::() % 16 == 0); - *OutputT::ref_from(vec![!FILL_PATTERN; size_of::() / 8].as_bytes()).unwrap() + *OutputT::ref_from_bytes(vec![!FILL_PATTERN; size_of::() / 8].as_bytes()) + .unwrap() } fn generate_output_reps(rep_count: usize) -> Vec where - OutRepT: AsBytes + FromBytes + Sized + Copy, + OutRepT: IntoBytes + FromBytes + Sized + Copy + Immutable + KnownLayout, { let size = rep_count * size_of::(); let pattern_count = (size + 7) / 8; @@ -995,7 +999,8 @@ impl TestController { reps.push(!FILL_PATTERN - 2 - i as u64); } - let (reps, _) = OutRepT::slice_from_prefix(reps.as_bytes(), rep_count).unwrap(); + let (reps, _) = + <[OutRepT]>::ref_from_prefix_with_elems(reps.as_bytes(), rep_count).unwrap(); reps.to_vec() } } @@ -1250,10 +1255,10 @@ fn invoke_hypercall( output_reps: &mut [OutRepT], ) -> (HypercallOutput, Control) where - InputT: AsBytes + FromBytes + Sized, - InRepT: AsBytes + FromBytes + Sized, - OutputT: AsBytes + FromBytes + Sized, - OutRepT: AsBytes + FromBytes + Sized, + InputT: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, + InRepT: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, + OutputT: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, + OutRepT: IntoBytes + FromBytes + Sized + Immutable + KnownLayout, { assert!(size_of::() % 8 == 0); assert!(size_of::() % 8 == 0); @@ -1349,7 +1354,7 @@ where let len = combined_input.len().min(PAGE_SIZE - params.in_offset); let input_buffer = &mut test_mem.internal_buffers[TestMemory::IN_INDEX] .0 - .as_bytes_mut()[params.in_offset..params.in_offset + len]; + .as_mut_bytes()[params.in_offset..params.in_offset + len]; input_buffer.copy_from_slice(&combined_input[..len]); // Write the input to guest memory. @@ -1372,7 +1377,7 @@ where if pair_count != 0 { let mut input_buffer = vec![[0u64; 2]; pair_count]; - input_buffer.as_bytes_mut()[..combined_input.len()] + input_buffer.as_mut_bytes()[..combined_input.len()] .copy_from_slice(combined_input.as_bytes()); io.set_fast_input(&input_buffer[..pair_count]); @@ -1428,19 +1433,19 @@ where let output_buffer = &mut test_mem.internal_buffers[TestMemory::OUT_INDEX] .0 - .as_bytes_mut()[params.out_offset..params.out_offset + output_len]; + .as_mut_bytes()[params.out_offset..params.out_offset + output_len]; output_buffer.as_bytes().split_at(size_of::()) } else { output_buffer = vec![[0u64; 2]; (output_len + 15) / 16]; io.get_fast_output(input_register_pairs.unwrap(), &mut output_buffer); - let output_buffer = &mut output_buffer.as_bytes_mut()[..output_len]; + let output_buffer = &mut output_buffer.as_mut_bytes()[..output_len]; output_buffer.as_bytes().split_at(size_of::()) }; - output.as_bytes_mut().copy_from_slice(hdr); - output_reps.as_bytes_mut().copy_from_slice(reps); + output.as_mut_bytes().copy_from_slice(hdr); + output_reps.as_mut_bytes().copy_from_slice(reps); } (result, control) diff --git a/vm/hv1/hvdef/Cargo.toml b/vm/hv1/hvdef/Cargo.toml index c27ee2c32d..db94e9b0d1 100644 --- a/vm/hv1/hvdef/Cargo.toml +++ b/vm/hv1/hvdef/Cargo.toml @@ -11,6 +11,5 @@ open_enum.workspace = true bitfield-struct.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/hv1/hvdef/src/lib.rs b/vm/hv1/hvdef/src/lib.rs index e3442357c3..fa22d8bd61 100644 --- a/vm/hv1/hvdef/src/lib.rs +++ b/vm/hv1/hvdef/src/lib.rs @@ -10,9 +10,11 @@ use core::fmt::Debug; use core::mem::size_of; use open_enum::open_enum; use static_assertions::const_assert; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const HV_PAGE_SIZE: u64 = 4096; pub const HV_PAGE_SIZE_USIZE: usize = 4096; @@ -95,7 +97,7 @@ pub struct HvPartitionPrivilege { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvPartitionIsolationType: u8 { NONE = 0, VBS = 1, @@ -244,7 +246,7 @@ pub struct HvIsolationConfiguration { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HypercallCode: u16 { #![allow(non_upper_case_globals)] @@ -343,7 +345,7 @@ pub const HV_X64_MSR_GUEST_CRASH_CTL: u32 = 0x40000105; pub const HV_X64_GUEST_CRASH_PARAMETER_MSRS: usize = 5; open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvError: u16 { #![allow(non_upper_case_globals)] @@ -538,7 +540,7 @@ pub struct GuestCrashCtl { } #[repr(C, align(16))] -#[derive(Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct AlignedU128([u8; 16]); impl AlignedU128 { @@ -594,7 +596,7 @@ impl From for u128 { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvMessageType: u32 { #![allow(non_upper_case_globals)] @@ -650,7 +652,7 @@ pub const NUM_SINTS: usize = 16; pub const NUM_TIMERS: usize = 4; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMessageHeader { pub typ: HvMessageType, pub len: u8, @@ -660,7 +662,7 @@ pub struct HvMessageHeader { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMessageFlags { pub message_pending: bool, #[bits(7)] @@ -672,7 +674,7 @@ const_assert!(HV_MESSAGE_SIZE == 256); pub const HV_MESSAGE_PAYLOAD_SIZE: usize = 240; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMessage { pub header: HvMessageHeader, pub payload_buffer: [u8; HV_MESSAGE_PAYLOAD_SIZE], @@ -681,7 +683,7 @@ pub struct HvMessage { impl Default for HvMessage { fn default() -> Self { Self { - header: FromZeroes::new_zeroed(), + header: FromZeros::new_zeroed(), payload_buffer: [0; 240], } } @@ -711,7 +713,7 @@ impl HvMessage { pub fn from_bytes(b: [u8; HV_MESSAGE_SIZE]) -> Self { let mut msg = Self::default(); - msg.as_bytes_mut().copy_from_slice(&b); + msg.as_mut_bytes().copy_from_slice(&b); msg } @@ -723,7 +725,7 @@ impl HvMessage { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TimerMessagePayload { pub timer_index: u32, pub reserved: u32, @@ -766,7 +768,7 @@ pub mod hypercall { /// The hypercall output value returned to the guest. #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[must_use] pub struct HypercallOutput { /// The HV_STATUS returned by the hypervisor. @@ -798,7 +800,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvRegisterAssoc { pub name: HvRegisterName, pub pad: [u32; 3], @@ -828,7 +830,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MsrHypercallContents { pub enable: bool, pub locked: bool, @@ -839,7 +841,7 @@ pub mod hypercall { } #[repr(C, align(8))] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PostMessage { pub connection_id: u32, pub padding: u32, @@ -849,7 +851,7 @@ pub mod hypercall { } #[repr(C, align(8))] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SignalEvent { pub connection_id: u32, pub flag_number: u16, @@ -857,7 +859,7 @@ pub mod hypercall { } #[repr(C, packed)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PostMessageDirect { pub partition_id: u64, pub vp_index: u32, @@ -869,7 +871,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SignalEventDirect { pub target_partition: u64, pub target_vp: u32, @@ -879,14 +881,14 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SignalEventDirectOutput { pub newly_signaled: u8, pub rsvd: [u8; 7], } #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InterruptEntry { pub source: HvInterruptSource, pub rsvd: u32, @@ -894,7 +896,7 @@ pub mod hypercall { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvInterruptSource: u32 { MSI = 1, IO_APIC = 2, @@ -902,7 +904,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InterruptTarget { pub vector: u32, pub flags: HvInterruptTargetFlags, @@ -910,7 +912,7 @@ pub mod hypercall { } #[bitfield(u32)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvInterruptTargetFlags { pub multicast: bool, pub processor_set: bool, @@ -925,7 +927,7 @@ pub mod hypercall { pub const HV_GENERIC_SET_ALL: u64 = 1; #[repr(C)] - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct RetargetDeviceInterrupt { pub partition_id: u64, pub device_id: u64, @@ -935,7 +937,7 @@ pub mod hypercall { } #[bitfield(u8)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvInputVtl { #[bits(4)] pub target_vtl_value: u8, @@ -975,7 +977,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetSetVpRegisters { pub partition_id: u64, pub vp_index: u32, @@ -1060,7 +1062,7 @@ pub mod hypercall { pub const HV_INTERCEPT_ACCESS_MASK_EXECUTE: u32 = 0x04; open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvInterceptType: u32 { #![allow(non_upper_case_globals)] HvInterceptTypeX64IoPort = 0x00000000, @@ -1076,7 +1078,7 @@ pub mod hypercall { } #[repr(transparent)] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, Debug)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] pub struct HvInterceptParameters(u64); impl HvInterceptParameters { @@ -1114,7 +1116,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, Debug)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] pub struct InstallIntercept { pub partition_id: u64, pub access_type_mask: u32, @@ -1123,7 +1125,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, Debug)] + #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] pub struct AssertVirtualInterrupt { pub partition_id: u64, pub interrupt_control: HvInterruptControl, @@ -1135,7 +1137,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartVirtualProcessorX64 { pub partition_id: u64, pub vp_index: u32, @@ -1146,7 +1148,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InitialVpContextX64 { pub rip: u64, pub rsp: u64, @@ -1169,7 +1171,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StartVirtualProcessorArm64 { pub partition_id: u64, pub vp_index: u32, @@ -1180,7 +1182,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct InitialVpContextArm64 { pub pc: u64, pub sp_elh: u64, @@ -1228,7 +1230,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaControlFlagsX64 { /// Request data read access pub validate_read: bool, @@ -1277,7 +1279,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaControlFlagsArm64 { /// Request data read access pub validate_read: bool, @@ -1322,7 +1324,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateVirtualAddressX64 { pub partition_id: u64, pub vp_index: u32, @@ -1333,7 +1335,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateVirtualAddressArm64 { pub partition_id: u64, pub vp_index: u32, @@ -1368,7 +1370,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaResult { pub result_code: u32, pub cache_type: u8, @@ -1378,14 +1380,14 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateVirtualAddressOutput { pub translation_result: TranslateGvaResult, pub gpa_page: u64, } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaResultExX64 { pub result: TranslateGvaResult, pub reserved: u64, @@ -1395,7 +1397,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x30); #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateGvaResultExArm64 { pub result: TranslateGvaResult, } @@ -1403,7 +1405,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x8); #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateVirtualAddressExOutputX64 { pub translation_result: TranslateGvaResultExX64, pub gpa_page: u64, @@ -1414,7 +1416,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x40); #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TranslateVirtualAddressExOutputArm64 { pub translation_result: TranslateGvaResultExArm64, pub gpa_page: u64, @@ -1423,7 +1425,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x10); #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GetVpIndexFromApicId { pub partition_id: u64, pub target_vtl: u8, @@ -1431,7 +1433,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EnableVpVtlX64 { pub partition_id: u64, pub vp_index: u32, @@ -1441,7 +1443,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EnableVpVtlArm64 { pub partition_id: u64, pub vp_index: u32, @@ -1451,7 +1453,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModifyVtlProtectionMask { pub partition_id: u64, pub map_flags: HvMapGpaFlags, @@ -1460,7 +1462,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CheckSparseGpaPageVtlAccess { pub partition_id: u64, pub target_vtl: HvInputVtl, @@ -1471,7 +1473,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x10); #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct CheckSparseGpaPageVtlAccessOutput { pub result_code: u8, pub denied_access: u8, @@ -1494,7 +1496,7 @@ pub mod hypercall { pub const HV_VTL_PERMISSION_SET_SIZE: usize = 2; #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VtlPermissionSet { /// VTL permissions for the GPA page, starting from VTL 1. pub vtl_permission_from_1: [u16; HV_VTL_PERMISSION_SET_SIZE], @@ -1514,7 +1516,7 @@ pub mod hypercall { /// read access and upper bit representing host write access, hardware /// platforms do not support that form of isolation. Only support /// private or full shared in this definition. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HostVisibilityType: u8 { PRIVATE = 0, SHARED = 3, @@ -1534,7 +1536,7 @@ pub mod hypercall { /// Attributes for accepting pages. See [`AcceptGpaPages`] #[bitfield(u32)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct AcceptPagesAttributes { #[bits(6)] /// Supplies the expected memory type [`AcceptMemoryType`]. @@ -1550,7 +1552,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct AcceptGpaPages { /// Supplies the partition ID of the partition this request is for. pub partition_id: u64, @@ -1587,7 +1589,7 @@ pub mod hypercall { const_assert!(size_of::() == 0x18); #[bitfield(u32)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModifyHostVisibility { #[bits(2)] pub host_visibility: HostVisibilityType, @@ -1596,7 +1598,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ModifySparsePageVisibility { pub partition_id: u64, pub host_visibility: ModifyHostVisibility, @@ -1604,13 +1606,13 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QuerySparsePageVisibility { pub partition_id: u64, } #[bitfield(u8)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EnablePartitionVtlFlags { pub enable_mbec: bool, pub enable_supervisor_shadow_stack: bool, @@ -1620,7 +1622,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct EnablePartitionVtl { pub partition_id: u64, pub target_vtl: u8, @@ -1630,7 +1632,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FlushVirtualAddressSpace { pub address_space: u64, pub flags: HvFlushFlags, @@ -1638,7 +1640,7 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FlushVirtualAddressSpaceEx { pub address_space: u64, pub flags: HvFlushFlags, @@ -1646,13 +1648,13 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PinUnpinGpaPageRangesHeader { pub reserved: u64, } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvFlushFlags { pub all_processors: bool, pub all_virtual_address_spaces: bool, @@ -1670,7 +1672,7 @@ pub mod hypercall { _reserved2: u64, } - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(transparent)] pub struct HvGvaRange(pub u64); @@ -1689,7 +1691,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGvaRangeSimple { /// The number of pages beyond one. #[bits(12)] @@ -1700,7 +1702,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGvaRangeExtended { /// The number of pages beyond one. #[bits(11)] @@ -1713,7 +1715,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGvaRangeExtendedLargePage { /// The number of pages beyond one. #[bits(11)] @@ -1731,7 +1733,7 @@ pub mod hypercall { pub gva_large_page_number: u64, } - #[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] + #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(transparent)] pub struct HvGpaRange(pub u64); @@ -1750,7 +1752,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGpaRangeSimple { /// The number of pages beyond one. #[bits(12)] @@ -1761,7 +1763,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGpaRangeExtended { /// The number of pages beyond one. #[bits(11)] @@ -1774,7 +1776,7 @@ pub mod hypercall { } #[bitfield(u64)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvGpaRangeExtendedLargePage { /// The number of pages beyond one. #[bits(11)] @@ -1795,7 +1797,7 @@ pub mod hypercall { pub const HV_HYPERCALL_MMIO_MAX_DATA_LENGTH: usize = 64; #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MemoryMappedIoRead { pub gpa: u64, pub access_width: u32, @@ -1803,13 +1805,13 @@ pub mod hypercall { } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MemoryMappedIoReadOutput { pub data: [u8; HV_HYPERCALL_MMIO_MAX_DATA_LENGTH], } #[repr(C)] - #[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] + #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MemoryMappedIoWrite { pub gpa: u64, pub access_width: u32, @@ -1827,7 +1829,7 @@ macro_rules! registers { $(,)? }) => { open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum $name: u32 { #![allow(non_upper_case_globals)] $($variant = $value,)* @@ -1942,7 +1944,7 @@ macro_rules! registers { /// This exists only to pass registers through layers where the architecture /// type has been lost. In general, you should use the arch-specific registers. #[repr(C)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvRegisterName(pub u32); registers! { @@ -2216,7 +2218,7 @@ registers! { } #[repr(C)] -#[derive(Clone, Copy, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvRegisterValue(pub AlignedU128); impl HvRegisterValue { @@ -2241,11 +2243,15 @@ impl HvRegisterValue { } pub fn as_table(&self) -> HvX64TableRegister { - HvX64TableRegister::read_from_prefix(self.as_bytes()).unwrap() + HvX64TableRegister::read_from_prefix(self.as_bytes()) + .unwrap() + .0 // todo: zerocopy: use-rest-of-range } pub fn as_segment(&self) -> HvX64SegmentRegister { - HvX64SegmentRegister::read_from_prefix(self.as_bytes()).unwrap() + HvX64SegmentRegister::read_from_prefix(self.as_bytes()) + .unwrap() + .0 // todo: zerocopy: use-rest-of-range } } @@ -2280,7 +2286,7 @@ impl From for HvRegisterValue { } #[repr(C)] -#[derive(Clone, Copy, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64TableRegister { pub pad: [u16; 3], pub limit: u16, @@ -2289,18 +2295,18 @@ pub struct HvX64TableRegister { impl From for HvRegisterValue { fn from(val: HvX64TableRegister) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap() + Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range } } impl From for HvX64TableRegister { fn from(val: HvRegisterValue) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap() + Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range } } #[repr(C)] -#[derive(Clone, Copy, Debug, Eq, PartialEq, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64SegmentRegister { pub base: u64, pub limit: u32, @@ -2310,18 +2316,18 @@ pub struct HvX64SegmentRegister { impl From for HvRegisterValue { fn from(val: HvX64SegmentRegister) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap() + Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range } } impl From for HvX64SegmentRegister { fn from(val: HvRegisterValue) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap() + Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range } } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct HvDeliverabilityNotificationsRegister { /// x86_64 only. pub nmi_notification: bool, @@ -2337,7 +2343,7 @@ pub struct HvDeliverabilityNotificationsRegister { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvVtlEntryReason: u32 { /// This reason is reserved and is not used. RESERVED = 0, @@ -2354,7 +2360,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvVpVtlControl { // // The hypervisor updates the entry reason with an indication as to why the @@ -2375,7 +2381,7 @@ pub struct HvVpVtlControl { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvRegisterVsmVina { pub vector: u8, pub enabled: bool, @@ -2386,7 +2392,7 @@ pub struct HvRegisterVsmVina { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvVpAssistPage { /// APIC assist for optimized EOI processing. pub apic_assist: u32, @@ -2408,7 +2414,7 @@ pub struct HvVpAssistPage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvVpAssistPageActionSignalEvent { pub action_type: u64, pub target_vp: u32, @@ -2418,7 +2424,7 @@ pub struct HvVpAssistPageActionSignalEvent { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvInterceptAccessType: u8 { READ = 0, WRITE = 1, @@ -2427,7 +2433,7 @@ open_enum! { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64VpExecutionState { #[bits(2)] pub cpl: u8, @@ -2446,7 +2452,7 @@ pub struct HvX64VpExecutionState { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64VpExecutionState { #[bits(2)] pub cpl: u8, @@ -2460,7 +2466,7 @@ pub struct HvArm64VpExecutionState { } #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64InterceptMessageHeader { pub vp_index: u32, pub instruction_length_and_cr8: u8, @@ -2482,7 +2488,7 @@ impl HvX64InterceptMessageHeader { } #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64InterceptMessageHeader { pub vp_index: u32, pub instruction_length: u8, @@ -2494,7 +2500,7 @@ pub struct HvArm64InterceptMessageHeader { const_assert!(size_of::() == 0x18); #[repr(transparent)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64IoPortAccessInfo(pub u8); impl HvX64IoPortAccessInfo { @@ -2526,7 +2532,7 @@ impl HvX64IoPortAccessInfo { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64IoPortInterceptMessage { pub header: HvX64InterceptMessageHeader, pub port_number: u16, @@ -2543,7 +2549,7 @@ pub struct HvX64IoPortInterceptMessage { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64MemoryAccessInfo { pub gva_valid: bool, pub gva_gpa_valid: bool, @@ -2555,7 +2561,7 @@ pub struct HvX64MemoryAccessInfo { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64MemoryAccessInfo { pub gva_valid: bool, pub gva_gpa_valid: bool, @@ -2565,7 +2571,7 @@ pub struct HvArm64MemoryAccessInfo { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvCacheType: u32 { #![allow(non_upper_case_globals)] HvCacheTypeUncached = 0, @@ -2577,7 +2583,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64MemoryInterceptMessage { pub header: HvX64InterceptMessageHeader, pub cache_type: HvCacheType, @@ -2592,7 +2598,7 @@ pub struct HvX64MemoryInterceptMessage { const_assert!(size_of::() == 0x50); #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64MemoryInterceptMessage { pub header: HvArm64InterceptMessageHeader, pub cache_type: HvCacheType, @@ -2608,7 +2614,7 @@ pub struct HvArm64MemoryInterceptMessage { const_assert!(size_of::() == 0x40); #[repr(C)] -#[derive(Debug, FromBytes, FromZeroes)] +#[derive(Debug, FromBytes)] pub struct HvArm64MmioInterceptMessage { pub header: HvArm64InterceptMessageHeader, pub guest_physical_address: u64, @@ -2618,7 +2624,7 @@ pub struct HvArm64MmioInterceptMessage { const_assert!(size_of::() == 0x48); #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64MsrInterceptMessage { pub header: HvX64InterceptMessageHeader, pub msr_number: u32, @@ -2628,7 +2634,7 @@ pub struct HvX64MsrInterceptMessage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64SipiInterceptMessage { pub header: HvX64InterceptMessageHeader, pub target_vp_index: u32, @@ -2636,7 +2642,7 @@ pub struct HvX64SipiInterceptMessage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64SynicSintDeliverableMessage { pub header: HvX64InterceptMessageHeader, pub deliverable_sints: u16, @@ -2645,7 +2651,7 @@ pub struct HvX64SynicSintDeliverableMessage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64SynicSintDeliverableMessage { pub header: HvArm64InterceptMessageHeader, pub deliverable_sints: u16, @@ -2654,7 +2660,7 @@ pub struct HvArm64SynicSintDeliverableMessage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64InterruptionDeliverableMessage { pub header: HvX64InterceptMessageHeader, pub deliverable_type: HvX64PendingInterruptionType, @@ -2663,7 +2669,7 @@ pub struct HvX64InterruptionDeliverableMessage { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvX64PendingInterruptionType: u8 { HV_X64_PENDING_INTERRUPT = 0, HV_X64_PENDING_NMI = 2, @@ -2675,7 +2681,7 @@ open_enum! { } #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64HypercallInterceptMessage { pub header: HvX64InterceptMessageHeader, pub rax: u64, @@ -2691,7 +2697,7 @@ pub struct HvX64HypercallInterceptMessage { } #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64HypercallInterceptMessage { pub header: HvArm64InterceptMessageHeader, pub immediate: u16, @@ -2701,7 +2707,7 @@ pub struct HvArm64HypercallInterceptMessage { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvHypercallInterceptMessageFlags { pub is_isolated: bool, #[bits(31)] @@ -2709,7 +2715,7 @@ pub struct HvHypercallInterceptMessageFlags { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64CpuidInterceptMessage { pub header: HvX64InterceptMessageHeader, pub rax: u64, @@ -2723,7 +2729,7 @@ pub struct HvX64CpuidInterceptMessage { } #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64ExceptionInfo { pub error_code_valid: bool, pub software_exception: bool, @@ -2732,7 +2738,7 @@ pub struct HvX64ExceptionInfo { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64ExceptionInterceptMessage { pub header: HvX64InterceptMessageHeader, pub vector: u16, @@ -2763,33 +2769,33 @@ pub struct HvX64ExceptionInterceptMessage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvInvalidVpRegisterMessage { pub vp_index: u32, pub reserved: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64ApicEoiMessage { pub vp_index: u32, pub interrupt_vector: u32, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64UnrecoverableExceptionMessage { pub header: HvX64InterceptMessageHeader, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64HaltMessage { pub header: HvX64InterceptMessageHeader, } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvArm64ResetInterceptMessage { pub header: HvArm64InterceptMessageHeader, pub reset_type: HvArm64ResetType, @@ -2797,7 +2803,7 @@ pub struct HvArm64ResetInterceptMessage { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvArm64ResetType: u32 { POWER_OFF = 0, REBOOT = 1, @@ -2805,7 +2811,7 @@ open_enum! { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvInterruptType : u32 { #![allow(non_upper_case_globals)] HvArm64InterruptTypeFixed = 0x0000, @@ -2829,7 +2835,7 @@ open_enum! { /// checks as adding that will require `guest_arch` support and /// a large refactoring. To sum up, choosing expediency. #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvInterruptControl { interrupt_type_value: u32, pub x86_level_triggered: bool, @@ -2950,7 +2956,7 @@ pub struct HvRegisterVsmCodePageOffsets { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvStimerState { pub undelivered_message_pending: u32, pub reserved: u32, @@ -2961,7 +2967,7 @@ pub struct HvStimerState { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvSyntheticTimersState { pub timers: [HvStimerState; 4], pub reserved: [u64; 5], @@ -3064,7 +3070,7 @@ pub struct HvX64PendingVirtualizationFaultEvent { /// Part of [`HvX64PendingEventMemoryIntercept`] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingEventMemoryInterceptPendingEventHeader { pub event_pending: bool, #[bits(3)] @@ -3075,7 +3081,7 @@ pub struct HvX64PendingEventMemoryInterceptPendingEventHeader { /// Part of [`HvX64PendingEventMemoryIntercept`] #[bitfield(u8)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingEventMemoryInterceptAccessFlags { /// Indicates if the guest linear address is valid. pub guest_linear_address_valid: bool, @@ -3088,7 +3094,7 @@ pub struct HvX64PendingEventMemoryInterceptAccessFlags { /// Provides information about a memory intercept. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingEventMemoryIntercept { pub event_header: HvX64PendingEventMemoryInterceptPendingEventHeader, /// VTL at which the memory intercept is targeted. @@ -3157,7 +3163,7 @@ pub struct HvX64PendingShadowIptEvent { } #[bitfield(u128)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingEventReg0 { pub event_pending: bool, #[bits(3)] @@ -3169,7 +3175,7 @@ pub struct HvX64PendingEventReg0 { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingEvent { pub reg_0: HvX64PendingEventReg0, pub reg_1: AlignedU128, @@ -3186,7 +3192,7 @@ impl From for HvX64PendingEvent { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64PendingInterruptionRegister { pub interruption_pending: bool, #[bits(3)] @@ -3202,7 +3208,7 @@ pub struct HvX64PendingInterruptionRegister { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64InterruptStateRegister { pub interrupt_shadow: bool, pub nmi_masked: bool, @@ -3211,7 +3217,7 @@ pub struct HvX64InterruptStateRegister { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvInstructionEmulatorHintsRegister { /// Indicates whether any secure VTL is enabled for the partition. pub partition_secure_vtl_enabled: bool, @@ -3223,7 +3229,7 @@ pub struct HvInstructionEmulatorHintsRegister { } open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum HvAarch64PendingEventType: u8 { EXCEPTION = 0, SYNTHETIC_EXCEPTION = 1, @@ -3243,7 +3249,7 @@ impl HvAarch64PendingEventType { } #[bitfield[u8]] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvAarch64PendingEventHeader { #[bits(1)] pub event_pending: bool, @@ -3254,7 +3260,7 @@ pub struct HvAarch64PendingEventHeader { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvAarch64PendingExceptionEvent { pub header: HvAarch64PendingEventHeader, pub _padding: [u8; 7], @@ -3263,7 +3269,7 @@ pub struct HvAarch64PendingExceptionEvent { } #[bitfield[u8]] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvAarch64PendingHypercallOutputEventFlags { #[bits(1)] pub retired: u8, @@ -3272,7 +3278,7 @@ pub struct HvAarch64PendingHypercallOutputEventFlags { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvAarch64PendingHypercallOutputEvent { pub header: HvAarch64PendingEventHeader, pub flags: HvAarch64PendingHypercallOutputEventFlags, @@ -3282,7 +3288,7 @@ pub struct HvAarch64PendingHypercallOutputEvent { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvAarch64PendingEvent { pub header: HvAarch64PendingEventHeader, pub event_data: [u8; 15], @@ -3290,7 +3296,7 @@ pub struct HvAarch64PendingEvent { } #[bitfield(u32)] -#[derive(PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMapGpaFlags { pub readable: bool, pub writable: bool, @@ -3315,7 +3321,7 @@ pub const HV_MAP_GPA_PERMISSIONS_ALL: HvMapGpaFlags = HvMapGpaFlags::new() .with_user_executable(true); #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMonitorPage { pub trigger_state: HvMonitorTriggerState, pub reserved1: u32, @@ -3329,7 +3335,7 @@ pub struct HvMonitorPage { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMonitorPageSmall { pub trigger_state: HvMonitorTriggerState, pub reserved1: u32, @@ -3337,14 +3343,14 @@ pub struct HvMonitorPageSmall { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMonitorTriggerGroup { pub pending: u32, pub armed: u32, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMonitorParameter { pub connection_id: u32, pub flag_number: u16, @@ -3352,7 +3358,7 @@ pub struct HvMonitorParameter { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvMonitorTriggerState { #[bits(4)] pub group_enable: u32, @@ -3361,7 +3367,7 @@ pub struct HvMonitorTriggerState { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvPmTimerInfo { #[bits(16)] pub port: u16, @@ -3376,7 +3382,7 @@ pub struct HvPmTimerInfo { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64RegisterSevControl { pub enable_encrypted_state: bool, #[bits(11)] @@ -3386,7 +3392,7 @@ pub struct HvX64RegisterSevControl { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvRegisterReferenceTsc { pub enable: bool, #[bits(11)] @@ -3396,7 +3402,7 @@ pub struct HvRegisterReferenceTsc { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvReferenceTscPage { pub tsc_sequence: u32, pub reserved1: u32, @@ -3410,7 +3416,7 @@ pub struct HvReferenceTscPage { pub const HV_REFERENCE_TSC_SEQUENCE_INVALID: u32 = 0; #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64VmgexitInterceptMessageFlags { pub ghcb_page_valid: bool, pub ghcb_request_error: bool, @@ -3419,7 +3425,7 @@ pub struct HvX64VmgexitInterceptMessageFlags { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64VmgexitInterceptMessageGhcbPageStandard { pub ghcb_protocol_version: u16, _reserved: [u16; 3], @@ -3430,7 +3436,7 @@ pub struct HvX64VmgexitInterceptMessageGhcbPageStandard { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64VmgexitInterceptMessageGhcbPage { pub ghcb_usage: u32, _reserved: u32, @@ -3438,7 +3444,7 @@ pub struct HvX64VmgexitInterceptMessageGhcbPage { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64VmgexitInterceptMessage { pub header: HvX64InterceptMessageHeader, pub ghcb_msr: u64, @@ -3462,7 +3468,7 @@ pub const HV_X64_REGISTER_CLASS_SEGMENT: u8 = 3; pub const HV_X64_REGISTER_CLASS_FLAGS: u8 = 4; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HvX64RegisterPage { pub version: u16, pub is_valid: u8, diff --git a/vm/loader/Cargo.toml b/vm/loader/Cargo.toml index dc31636619..446cff88e2 100644 --- a/vm/loader/Cargo.toml +++ b/vm/loader/Cargo.toml @@ -25,7 +25,7 @@ object = { workspace = true, features = ["elf", "std", "read_core"] } open_enum.workspace = true thiserror.workspace = true tracing.workspace = true -zerocopy = { workspace = true, features = ["alloc"] } +zerocopy.workspace = true [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vm/loader/igvmfilegen/Cargo.toml b/vm/loader/igvmfilegen/Cargo.toml index b939f9acae..d54cf19645 100644 --- a/vm/loader/igvmfilegen/Cargo.toml +++ b/vm/loader/igvmfilegen/Cargo.toml @@ -32,7 +32,6 @@ thiserror.workspace = true tracing-subscriber = { workspace = true, features = ["env-filter"] } tracing.workspace = true zerocopy.workspace = true - [target.'cfg(all(target_arch = "x86_64", target_os = "linux"))'.build-dependencies] loader_defs.workspace = true diff --git a/vm/loader/igvmfilegen/src/file_loader.rs b/vm/loader/igvmfilegen/src/file_loader.rs index 2e4d20f943..c9e2fd5f08 100644 --- a/vm/loader/igvmfilegen/src/file_loader.rs +++ b/vm/loader/igvmfilegen/src/file_loader.rs @@ -54,8 +54,8 @@ use sha2::Sha384; use std::collections::BTreeMap; use std::fmt::Debug; use std::fmt::Display; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; pub const DEFAULT_COMPATIBILITY_MASK: u32 = 0x1; @@ -834,7 +834,7 @@ impl IgvmLoader { gpa: page_base * PAGE_SIZE_4K, compatibility_mask: DEFAULT_COMPATIBILITY_MASK, vp_index: 0, - vmsa: Box::new(SevVmsa::read_from(data).expect("should be correct size")), + vmsa: Box::new(SevVmsa::read_from_bytes(data).expect("should be correct size")), // todo: zerocopy: map_err }); } else { for page in page_base..page_base + page_count { diff --git a/vm/loader/igvmfilegen/src/main.rs b/vm/loader/igvmfilegen/src/main.rs index 58274a52f8..9ae16ddcdc 100644 --- a/vm/loader/igvmfilegen/src/main.rs +++ b/vm/loader/igvmfilegen/src/main.rs @@ -41,8 +41,8 @@ use std::path::PathBuf; use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::EnvFilter; use underhill_confidentiality::OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; #[derive(Parser)] #[clap(name = "igvmfilegen", about = "Tool to generate IGVM files")] @@ -92,7 +92,8 @@ fn main() -> anyhow::Result<()> { Options::Dump { file_path } => { let image = fs_err::read(file_path).context("reading input file")?; let fixed_header = IGVM_FIXED_HEADER::read_from_prefix(image.as_bytes()) - .expect("Invalid fixed header"); + .expect("Invalid fixed header") + .0; // todo: zerocopy: use-rest-of-range let igvm_data = IgvmFile::new_from_binary(&image, None).expect("should be valid"); println!("Total file size: {} bytes\n", fixed_header.total_file_size); diff --git a/vm/loader/igvmfilegen/src/signed_measurement/snp.rs b/vm/loader/igvmfilegen/src/signed_measurement/snp.rs index 804c29a77a..cbaeb716bc 100644 --- a/vm/loader/igvmfilegen/src/signed_measurement/snp.rs +++ b/vm/loader/igvmfilegen/src/signed_measurement/snp.rs @@ -16,7 +16,7 @@ use thiserror::Error; use x86defs::snp::SnpPageInfo; use x86defs::snp::SnpPageType; use x86defs::snp::SnpPspIdBlock; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub enum Error { diff --git a/vm/loader/igvmfilegen/src/signed_measurement/tdx.rs b/vm/loader/igvmfilegen/src/signed_measurement/tdx.rs index d780ea3c9c..5702d1c6b1 100644 --- a/vm/loader/igvmfilegen/src/signed_measurement/tdx.rs +++ b/vm/loader/igvmfilegen/src/signed_measurement/tdx.rs @@ -11,9 +11,10 @@ use sha2::Digest; use sha2::Sha384; use std::collections::HashMap; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug, Error)] pub enum Error { @@ -23,7 +24,7 @@ pub enum Error { /// Measure adding a page to TD. #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdxPageAdd { /// MEM.PAGE.ADD pub operation: [u8; 16], @@ -37,7 +38,7 @@ const TDX_EXTEND_CHUNK_SIZE: usize = 256; /// Measure adding a chunk of data to TD. #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdxMrExtend { /// MR.EXTEND pub operation: [u8; 16], diff --git a/vm/loader/igvmfilegen/src/signed_measurement/vbs.rs b/vm/loader/igvmfilegen/src/signed_measurement/vbs.rs index 8d2086d76a..e51b3cf195 100644 --- a/vm/loader/igvmfilegen/src/signed_measurement/vbs.rs +++ b/vm/loader/igvmfilegen/src/signed_measurement/vbs.rs @@ -25,7 +25,7 @@ use vbs_defs::VBS_VM_GPA_PAGE_BOOT_METADATA; use vbs_defs::VBS_VP_CHUNK_SIZE_BYTES; use vbs_defs::VM_GPA_PAGE_READABLE; use vbs_defs::VM_GPA_PAGE_WRITABLE; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub enum Error { diff --git a/vm/loader/igvmfilegen/src/vp_context_builder/snp.rs b/vm/loader/igvmfilegen/src/vp_context_builder/snp.rs index 8e6fa9e187..5402cdd631 100644 --- a/vm/loader/igvmfilegen/src/vp_context_builder/snp.rs +++ b/vm/loader/igvmfilegen/src/vp_context_builder/snp.rs @@ -17,8 +17,8 @@ use std::fmt::Debug; use x86defs::snp::SevSelector; use x86defs::snp::SevVmsa; use x86defs::X64_EFER_SVME; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// The interrupt injection type to use for the highest vmpl's VMSA. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -60,7 +60,7 @@ impl SnpHardwareContext { shared_gpa_boundary: u64, injection_type: InjectionType, ) -> Self { - let mut vmsa: SevVmsa = FromZeroes::new_zeroed(); + let mut vmsa: SevVmsa = FromZeros::new_zeroed(); // Fill in reset values that are needed for consistency. vmsa.efer = X64_EFER_SVME; @@ -116,7 +116,7 @@ impl VpContextBuilder for SnpHardwareContext { SevSelector { limit: reg.limit as u32, base: reg.base, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } }; diff --git a/vm/loader/igvmfilegen/src/vp_context_builder/tdx.rs b/vm/loader/igvmfilegen/src/vp_context_builder/tdx.rs index 4aca88a702..7037ad65a9 100644 --- a/vm/loader/igvmfilegen/src/vp_context_builder/tdx.rs +++ b/vm/loader/igvmfilegen/src/vp_context_builder/tdx.rs @@ -12,7 +12,9 @@ use loader::importer::X86Register; use std::mem::offset_of; use x86defs::X64_EFER_LME; use x86defs::X86X_MSR_DEFAULT_PAT; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Fields in the trampoline context must be loaded from memory by the /// trampoline code. @@ -21,7 +23,7 @@ use zerocopy::AsBytes; /// the code placed in the reset vector will use this format to figure out what /// register state to load. #[repr(C)] -#[derive(Debug, Default, Clone, Copy, AsBytes)] +#[derive(Debug, Default, Clone, Copy, IntoBytes, Immutable, KnownLayout)] pub struct TdxTrampolineContext { start_gate: u32, diff --git a/vm/loader/loader_defs/Cargo.toml b/vm/loader/loader_defs/Cargo.toml index 70b09c96b9..cd3cafd8c8 100644 --- a/vm/loader/loader_defs/Cargo.toml +++ b/vm/loader/loader_defs/Cargo.toml @@ -18,6 +18,5 @@ inspect = { workspace = true, optional = true } bitfield-struct.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/loader/loader_defs/src/linux.rs b/vm/loader/loader_defs/src/linux.rs index 6fae3cbc1f..8e207f1335 100644 --- a/vm/loader/loader_defs/src/linux.rs +++ b/vm/loader/loader_defs/src/linux.rs @@ -9,9 +9,11 @@ #![expect(missing_docs)] use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -22,7 +24,7 @@ mod packed_nums { use self::packed_nums::*; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct apm_bios_info { pub version: u16, pub cseg: u16, @@ -36,7 +38,7 @@ pub struct apm_bios_info { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct screen_info { pub orig_x: u8, pub orig_y: u8, @@ -76,14 +78,14 @@ pub struct screen_info { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct sys_desc_table { pub length: u16, pub table: [u8; 14], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct olpc_ofw_header { pub ofw_magic: u32, pub ofw_version: u32, @@ -92,13 +94,13 @@ pub struct olpc_ofw_header { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct edid_info { pub dummy: [u8; 128], } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct efi_info { pub efi_loader_signature: u32, pub efi_systab: u32, @@ -111,7 +113,7 @@ pub struct efi_info { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct setup_header { pub setup_sects: u8, pub root_flags: u16_ne, @@ -161,7 +163,7 @@ pub const E820_NVS: u32 = 4; pub const E820_UNUSABLE: u32 = 5; #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct e820entry { pub addr: u64_ne, pub size: u64_ne, @@ -169,7 +171,7 @@ pub struct e820entry { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct edd_info { pub device: u8, pub version: u8, @@ -181,7 +183,7 @@ pub struct edd_info { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct edd_device_params { pub length: u16, pub info_flags: u16, @@ -204,7 +206,7 @@ pub struct edd_device_params { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ist_info { pub signature: u32, pub command: u32, @@ -213,7 +215,7 @@ pub struct ist_info { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct boot_params { pub screen_info: screen_info, pub apm_bios_info: apm_bios_info, @@ -251,7 +253,7 @@ pub struct boot_params { impl Default for boot_params { fn default() -> Self { - FromZeroes::new_zeroed() + FromZeros::new_zeroed() } } @@ -259,7 +261,7 @@ const_assert_eq!(size_of::(), 4096); // This must be aligned so that it doesn't straddle a page boundary. #[repr(C, align(16))] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct setup_data { pub next: u64, pub ty: u32, @@ -271,7 +273,7 @@ pub const SETUP_DTB: u32 = 2; pub const SETUP_CC_BLOB: u32 = 7; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct cc_blob_sev_info { pub magic: u32, pub version: u16, @@ -287,7 +289,7 @@ pub struct cc_blob_sev_info { pub const CC_BLOB_SEV_INFO_MAGIC: u32 = 0x45444d41; #[repr(C, align(16))] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct cc_setup_data { pub header: setup_data, pub cc_blob_address: u32, diff --git a/vm/loader/loader_defs/src/paravisor.rs b/vm/loader/loader_defs/src/paravisor.rs index b00ce6ca4e..640c6ff5af 100644 --- a/vm/loader/loader_defs/src/paravisor.rs +++ b/vm/loader/loader_defs/src/paravisor.rs @@ -10,9 +10,10 @@ use hvdef::HV_PAGE_SIZE; use inspect::Inspect; use open_enum::open_enum; use static_assertions::const_assert_eq; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Number of pages for each type of parameter in the vtl 2 unmeasured config // region. @@ -110,7 +111,7 @@ pub const PARAVISOR_LOCAL_MAP_SIZE: u64 = 0x200000; open_enum! { /// Underhill command line policy. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum CommandLinePolicy : u16 { /// Use the static command line encoded only. STATIC = 0, @@ -125,7 +126,7 @@ pub const COMMAND_LINE_SIZE: usize = 4092; /// Command line information. This structure is an exclusive measured page. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ParavisorCommandLine { /// The policy Underhill should use. pub policy: CommandLinePolicy, @@ -151,7 +152,7 @@ const_assert_eq!(size_of::(), HV_PAGE_SIZE as usize); /// Describes a region of guest memory. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct PageRegionDescriptor { /// Guest physical page number for the base of this region. pub base_page_number: u64, @@ -204,7 +205,7 @@ impl PageRegionDescriptor { /// The header field of the imported pages region page. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct ImportedRegionsPageHeader { /// The cryptographic hash of the unaccepted pages. pub sha384_hash: [u8; 48], @@ -212,7 +213,7 @@ pub struct ImportedRegionsPageHeader { /// Describes a region of guest memory that has been imported into VTL2. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes, PartialEq)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq)] pub struct ImportedRegionDescriptor { /// Guest physical page number for the base of this region. pub base_page_number: u64, @@ -274,7 +275,7 @@ impl ImportedRegionDescriptor { /// Measured config about linux loaded into VTL0. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "inspect", derive(Inspect))] pub struct LinuxInfo { /// The memory the kernel was loaded into. @@ -291,7 +292,7 @@ pub struct LinuxInfo { /// Measured config about UEFI loaded into VTL0. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "inspect", derive(Inspect))] pub struct UefiInfo { /// The information about where UEFI's firmware and misc pages are. @@ -303,7 +304,7 @@ pub struct UefiInfo { /// Measured config about what this image can support loading in VTL0. #[cfg_attr(feature = "inspect", derive(Inspect))] #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SupportedVtl0LoadInfo { /// This image supports UEFI. #[bits(1)] @@ -324,7 +325,7 @@ pub struct SupportedVtl0LoadInfo { /// information is known at file build time, measured, and deposited as part of /// the initial launch data. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "inspect", derive(Inspect))] pub struct ParavisorMeasuredVtl0Config { /// Magic value. Must be [`Self::MAGIC`]. @@ -357,7 +358,7 @@ pub const PARAVISOR_VTL0_MEASURED_CONFIG_BASE_PAGE_AARCH64: u64 = 16 << (20 - 12 /// Paravisor measured config for vtl2. #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "inspect", derive(Inspect))] pub struct ParavisorMeasuredVtl2Config { /// Magic value. Must be [`Self::MAGIC`]. diff --git a/vm/loader/loader_defs/src/shim.rs b/vm/loader/loader_defs/src/shim.rs index 12acf385f6..44c2610a58 100644 --- a/vm/loader/loader_defs/src/shim.rs +++ b/vm/loader/loader_defs/src/shim.rs @@ -4,15 +4,16 @@ //! Loader definitions for the openhcl boot loader (`openhcl_boot`). use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Shim parameters set by the loader at IGVM build time. These contain shim /// base relative offsets and sizes instead of absolute addresses. Sizes are in /// bytes. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ShimParamsRaw { /// The offset to the Linux kernel entry point. pub kernel_entry_offset: i64, @@ -56,7 +57,7 @@ pub struct ShimParamsRaw { open_enum! { /// Possible isolation types supported by the shim. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum SupportedIsolationType: u32 { // Starting from 1 for consistency with None usually being 0, but // the IGVM file for None and Vbs will likely be the same, so None will diff --git a/vm/loader/page_table/Cargo.toml b/vm/loader/page_table/Cargo.toml index 8b52920373..6cb10f4710 100644 --- a/vm/loader/page_table/Cargo.toml +++ b/vm/loader/page_table/Cargo.toml @@ -10,6 +10,5 @@ rust-version.workspace = true bitfield-struct.workspace = true tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/loader/page_table/src/x64.rs b/vm/loader/page_table/src/x64.rs index a90df672d0..11ed4ea8a6 100644 --- a/vm/loader/page_table/src/x64.rs +++ b/vm/loader/page_table/src/x64.rs @@ -4,9 +4,11 @@ //! Methods to construct page tables on x64. use crate::IdentityMapSize; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; const X64_PTE_PRESENT: u64 = 1; const X64_PTE_READ_WRITE: u64 = 1 << 1; @@ -28,7 +30,7 @@ pub const X64_LARGE_PAGE_SIZE: u64 = 0x200000; /// Number of bytes in a 1GB page for X64. pub const X64_1GB_PAGE_SIZE: u64 = 0x40000000; -#[derive(Copy, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(transparent)] pub struct PageTableEntry { pub(crate) entry: u64, @@ -194,7 +196,7 @@ impl PageTableEntry { } #[repr(C)] -#[derive(Debug, Clone, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PageTable { entries: [PageTableEntry; PAGE_TABLE_ENTRY_COUNT], } diff --git a/vm/loader/src/common.rs b/vm/loader/src/common.rs index bd17dae4a6..225df3be44 100644 --- a/vm/loader/src/common.rs +++ b/vm/loader/src/common.rs @@ -13,8 +13,8 @@ use vm_topology::memory::MemoryLayout; use x86defs::GdtEntry; use x86defs::X64_DEFAULT_CODE_SEGMENT_ATTRIBUTES; use x86defs::X64_DEFAULT_DATA_SEGMENT_ATTRIBUTES; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; const DEFAULT_GDT_COUNT: usize = 4; /// The size of the default GDT table, in bytes. diff --git a/vm/loader/src/cpuid.rs b/vm/loader/src/cpuid.rs index ae0ccc14cb..28a8f51ff3 100644 --- a/vm/loader/src/cpuid.rs +++ b/vm/loader/src/cpuid.rs @@ -4,13 +4,15 @@ //! Provides common CPUID values and functions. use x86defs::cpuid::CpuidFunction; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// CPUID information used to build the CPUID page for SNP. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SNP_REQUIRED_CPUID_LEAF { pub eax: u32, pub ecx: u32, @@ -91,7 +93,7 @@ pub const SNP_REQUIRED_CPUID_LEAF_LIST_PARAVISOR: [SNP_REQUIRED_CPUID_LEAF; 35] ]; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] pub struct HV_PSP_CPUID_LEAF { pub eax_in: u32, pub ecx_in: u32, @@ -107,7 +109,7 @@ pub struct HV_PSP_CPUID_LEAF { pub const HV_PSP_CPUID_LEAF_COUNT_MAX: usize = 64; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct HV_PSP_CPUID_PAGE { pub count: u32, pub reserved_z1: u32, diff --git a/vm/loader/src/elf.rs b/vm/loader/src/elf.rs index a7e79ded33..21e522e482 100644 --- a/vm/loader/src/elf.rs +++ b/vm/loader/src/elf.rs @@ -47,9 +47,7 @@ pub enum Error { LoadOffsetOverflow { load_offset: u64, p_paddr: u64 }, #[error("invalid ELF program header memory offset {mem_offset}, below start {start_address}")] InvalidProgramHeaderMemoryOffset { mem_offset: u64, start_address: u64 }, - #[error( - "adding reloc bias {reloc_bias} and load offset {load_offset} to paddr {p_paddr} overflowed" - )] + #[error("adding reloc bias {reloc_bias} and load offset {load_offset} to paddr {p_paddr} overflowed")] RelocBiasOverflow { load_offset: u64, reloc_bias: u64, diff --git a/vm/loader/src/linux.rs b/vm/loader/src/linux.rs index 679ccbd210..d42d1a6a11 100644 --- a/vm/loader/src/linux.rs +++ b/vm/loader/src/linux.rs @@ -27,9 +27,11 @@ use page_table::IdentityMapSize; use std::ffi::CString; use thiserror::Error; use vm_topology::memory::MemoryLayout; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Construct a zero page from the following parameters. /// TODO: support different acpi_base other than 0xe0000 @@ -53,9 +55,9 @@ pub fn build_zero_page( ramdisk_image: initrd_base.into(), ramdisk_size: initrd_size.into(), kernel_alignment: 0x100000.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let mut ram = mem_layout.ram().iter().cloned(); @@ -461,7 +463,7 @@ where } open_enum::open_enum! { - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Aarch64ImagePageSize: u64 { UNSPECIFIED = 0, PAGE4_K = 1, @@ -509,7 +511,7 @@ struct Aarch64ImageFlags { // Kernel boot protocol is specified in the Linux kernel // Documentation/arm64/booting.txt. -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[repr(C)] struct Aarch64ImageHeader { /// Executable code @@ -571,7 +573,7 @@ where let mut header = Aarch64ImageHeader::new_zeroed(); kernel_image - .read_exact(header.as_bytes_mut()) + .read_exact(header.as_mut_bytes()) .map_err(|_| Error::FlatLoader(FlatLoaderError::ReadKernelImage))?; tracing::debug!("aarch64 kernel header {header:x?}"); diff --git a/vm/loader/src/paravisor.rs b/vm/loader/src/paravisor.rs index 5b4a334a4f..1fb0ffd385 100644 --- a/vm/loader/src/paravisor.rs +++ b/vm/loader/src/paravisor.rs @@ -46,8 +46,8 @@ use x86defs::GdtEntry; use x86defs::X64_BUSY_TSS_SEGMENT_ATTRIBUTES; use x86defs::X64_DEFAULT_CODE_SEGMENT_ATTRIBUTES; use x86defs::X64_DEFAULT_DATA_SEGMENT_ATTRIBUTES; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Debug)] pub struct Vtl0Linux<'a> { @@ -673,7 +673,7 @@ where let mut free_page = 1; let mut measured_config = ParavisorMeasuredVtl0Config { magic: ParavisorMeasuredVtl0Config::MAGIC, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; let Vtl0Config { @@ -1057,7 +1057,7 @@ where let mut measured_config = ParavisorMeasuredVtl0Config { magic: ParavisorMeasuredVtl0Config::MAGIC, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; if let Some((uefi, vp_context)) = &supports_uefi { diff --git a/vm/loader/src/uefi/config.rs b/vm/loader/src/uefi/config.rs index a9626ba7ee..ed29b6841c 100644 --- a/vm/loader/src/uefi/config.rs +++ b/vm/loader/src/uefi/config.rs @@ -6,9 +6,10 @@ use bitfield_struct::bitfield; use core::mem::size_of; use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; fn align_8(x: usize) -> usize { (x + 7) & !7 @@ -110,7 +111,7 @@ impl Default for Blob { } } -pub trait BlobStructure: AsBytes + FromBytes { +pub trait BlobStructure: IntoBytes + FromBytes + Immutable + KnownLayout { const STRUCTURE_TYPE: BlobStructureType; } @@ -200,7 +201,7 @@ pub enum BlobStructureType { // header. // #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Header { pub structure_type: u32, pub length: u32, @@ -213,14 +214,14 @@ pub struct Header { // NOTE: TotalConfigBlobSize is in bytes. // #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct StructureCount { pub total_structure_count: u32, pub total_config_blob_size: u32, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BiosInformation { pub bios_size_pages: u32, // struct { @@ -247,7 +248,7 @@ pub const VM_MEMORY_RANGE_FLAG_PERSISTENT: u32 = 0x2; pub const VM_MEMORY_RANGE_FLAG_SPECIFIC_PURPOSE: u32 = 0x4; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MemoryRangeV5 { pub base_address: u64, pub length: u64, @@ -256,7 +257,7 @@ pub struct MemoryRangeV5 { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Entropy(pub [u8; 64]); impl Default for Entropy { @@ -266,11 +267,11 @@ impl Default for Entropy { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct BiosGuid(pub Guid); #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Smbios31ProcessorInformation { pub processor_id: u64, pub external_clock: u16, @@ -286,7 +287,7 @@ pub struct Smbios31ProcessorInformation { } #[bitfield(u64, debug = false)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Flags { pub serial_controllers_enabled: bool, pub pause_after_boot_failure: bool, @@ -374,7 +375,7 @@ impl MemoryProtection { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ProcessorInformation { pub max_processor_count: u32, pub processor_count: u32, @@ -383,31 +384,31 @@ pub struct ProcessorInformation { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes, Copy, Clone)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Copy, Clone)] pub struct Mmio { pub mmio_page_number_start: u64, pub mmio_size_in_pages: u64, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct MmioRanges(pub [Mmio; 2]); #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct NvdimmCount { pub count: u16, pub padding: [u16; 3], } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VpciInstanceFilter { pub instance_guid: Guid, } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Gic { pub gic_distributor_base: u64, pub gic_redistributors_base: u64, @@ -419,9 +420,11 @@ mod tests { fn read(bytes: &[u8]) -> T where - T: FromBytes, + T: FromBytes + Immutable + KnownLayout, { - T::read_from_prefix(bytes).expect("byte slice should always be big enough") + T::read_from_prefix(bytes) + .expect("byte slice should always be big enough") + .0 } fn add_one_dynamic(length: usize) { diff --git a/vm/loader/src/uefi/mod.rs b/vm/loader/src/uefi/mod.rs index 6e80b23584..cc1fb98434 100644 --- a/vm/loader/src/uefi/mod.rs +++ b/vm/loader/src/uefi/mod.rs @@ -18,9 +18,10 @@ pub use arch::IMAGE_SIZE; use guid::Guid; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Constant defining the offset within the image where the SEC volume starts. // TODO: Revisit this when we reorganize the firmware layout. One option @@ -47,7 +48,7 @@ const TE_IMAGE_HEADER_SIGNATURE: u16 = signature_16(b"VZ"); const EFI_FVH_SIGNATURE: u32 = signature_32(b"_FVH"); #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ImageDosHeader { e_magic: u16, // Magic number e_cblp: u16, // Bytes on last page of file @@ -71,7 +72,7 @@ struct ImageDosHeader { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct TeImageHeader { signature: u16, machine: u16, @@ -85,7 +86,7 @@ struct TeImageHeader { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ImageNtHeaders32 { signature: u32, file_header: ImageFileHeader, @@ -93,7 +94,7 @@ struct ImageNtHeaders32 { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ImageFileHeader { machine: u16, number_of_sections: u16, @@ -105,7 +106,7 @@ struct ImageFileHeader { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ImageOptionalHeader32 { magic: u16, major_linker_version: u8, @@ -141,14 +142,14 @@ struct ImageOptionalHeader32 { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ImageDataDirectory { virtual_address: u32, size: u32, } fn pe_get_entry_point_offset(pe32_data: &[u8]) -> Option { - let dos_header = ImageDosHeader::read_from_prefix(pe32_data)?; + let dos_header = ImageDosHeader::read_from_prefix(pe32_data).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error let nt_headers_offset = if dos_header.e_magic == IMAGE_DOS_SIGNATURE { // DOS image header is present, so read the PE header after the DOS image header. dos_header.e_lfanew as usize @@ -157,15 +158,21 @@ fn pe_get_entry_point_offset(pe32_data: &[u8]) -> Option { 0 }; - let signature = u32::read_from_prefix(&pe32_data[nt_headers_offset..])?; + let signature = u32::read_from_prefix(&pe32_data[nt_headers_offset..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error // Calculate the entry point relative to the start of the image. // AddressOfEntryPoint is common for PE32 & PE32+ if signature as u16 == TE_IMAGE_HEADER_SIGNATURE { - let te = TeImageHeader::read_from_prefix(&pe32_data[nt_headers_offset..])?; + let te = TeImageHeader::read_from_prefix(&pe32_data[nt_headers_offset..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error Some(te.address_of_entry_point + size_of_val(&te) as u32 - te.stripped_size as u32) } else if signature == IMAGE_NT_SIGNATURE { - let pe = ImageNtHeaders32::read_from_prefix(&pe32_data[nt_headers_offset..])?; + let pe = ImageNtHeaders32::read_from_prefix(&pe32_data[nt_headers_offset..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error Some(pe.optional_header.address_of_entry_point) } else { None @@ -173,7 +180,7 @@ fn pe_get_entry_point_offset(pe32_data: &[u8]) -> Option { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct EFI_FIRMWARE_VOLUME_HEADER { zero_vector: [u8; 16], file_system_guid: Guid, @@ -188,7 +195,7 @@ struct EFI_FIRMWARE_VOLUME_HEADER { } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct EFI_FFS_FILE_HEADER { name: Guid, integrity_check: u16, @@ -201,7 +208,7 @@ struct EFI_FFS_FILE_HEADER { const EFI_FV_FILETYPE_SECURITY_CORE: u8 = 3; #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct EFI_COMMON_SECTION_HEADER { size: [u8; 3], typ: u8, @@ -215,7 +222,9 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { let mut image_offset = SEC_FIRMWARE_VOLUME_OFFSET; // Expect a firmware volume header for SEC volume. - let fvh = EFI_FIRMWARE_VOLUME_HEADER::read_from_prefix(&image[image_offset as usize..])?; + let fvh = EFI_FIRMWARE_VOLUME_HEADER::read_from_prefix(&image[image_offset as usize..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if fvh.signature != EFI_FVH_SIGNATURE { return None; } @@ -232,7 +241,9 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { image_offset += new_volume_offset - volume_offset; volume_offset = new_volume_offset; } - let fh = EFI_FFS_FILE_HEADER::read_from_prefix(&image[image_offset as usize..])?; + let fh = EFI_FFS_FILE_HEADER::read_from_prefix(&image[image_offset as usize..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if fh.typ == EFI_FV_FILETYPE_SECURITY_CORE { sec_core_file_header = Some(fh); break; @@ -263,7 +274,9 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { file_offset += new_file_offset - file_offset; } - let sh = EFI_COMMON_SECTION_HEADER::read_from_prefix(&image[image_offset as usize..])?; + let sh = EFI_COMMON_SECTION_HEADER::read_from_prefix(&image[image_offset as usize..]) + .ok()? + .0; // todo: zerocopy: use-rest-of-range, option-to-error if sh.typ == EFI_SECTION_PE32 { let pe_offset = pe_get_entry_point_offset( &image[image_offset as usize + size_of::()..], @@ -281,13 +294,15 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { /// Definitions shared by UEFI and the loader when loaded with parameters passed in IGVM format. mod igvm { - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; /// The structure used to tell UEFI where the IGVM loaded parameters are. #[repr(C)] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct UEFI_IGVM_PARAMETER_INFO { pub parameter_page_count: u32, pub cpuid_pages_offset: u32, @@ -360,8 +375,8 @@ pub mod x86_64 { use page_table::x64::align_up_to_page_size; use page_table::x64::build_page_tables_64; use page_table::IdentityMapSize; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::IntoBytes; pub const IMAGE_SIZE: u64 = 0x00600000; // 6 MB. See MsvmPkg\MsvmPkgX64.fdf const IMAGE_GPA_BASE: u64 = 0x100000; // 1MB @@ -841,7 +856,8 @@ pub mod aarch64 { use crate::importer::ImageLoad; use aarch64defs::Cpsr64; use hvdef::HV_PAGE_SIZE; - use zerocopy::AsBytes; + + use zerocopy::IntoBytes; pub const IMAGE_SIZE: u64 = 0x800000; pub const CONFIG_BLOB_GPA_BASE: u64 = 0x824000; diff --git a/vm/vbs_defs/Cargo.toml b/vm/vbs_defs/Cargo.toml index b28a1684d4..2d5f2a4ddb 100644 --- a/vm/vbs_defs/Cargo.toml +++ b/vm/vbs_defs/Cargo.toml @@ -12,6 +12,5 @@ igvm_defs.workspace = true open_enum.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/vbs_defs/src/lib.rs b/vm/vbs_defs/src/lib.rs index 8a7ac06da5..68bee60feb 100644 --- a/vm/vbs_defs/src/lib.rs +++ b/vm/vbs_defs/src/lib.rs @@ -9,14 +9,16 @@ use bitfield_struct::bitfield; use igvm_defs::PAGE_SIZE_4K; use open_enum::open_enum; use static_assertions::const_assert; -use zerocopy::AsBytes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const VBS_VP_CHUNK_SIZE_BYTES: usize = PAGE_SIZE_4K as usize + size_of::(); /// Structure containing the completed VBS boot measurement of the IGVM file. /// The signature of the hash of this struct is the signature for [`igvm_defs::IGVM_VHS_VBS_MEASUREMENT`] #[repr(C)] -#[derive(AsBytes, Debug)] +#[derive(IntoBytes, Immutable, KnownLayout, Debug)] pub struct VBS_VM_BOOT_MEASUREMENT_SIGNED_DATA { /// The version of the signature structure pub version: u32, @@ -57,7 +59,7 @@ pub struct VBS_VM_BOOT_MEASUREMENT_SIGNED_DATA { /// /// Structure describing the chunk to be measured #[repr(C)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] pub struct VbsChunkHeader { /// The full size to be measured pub byte_count: u32, @@ -67,7 +69,7 @@ pub struct VbsChunkHeader { /// Structure describing the register being measured. Will be padded to [`VBS_VP_CHUNK_SIZE_BYTES`] when hashed to generate digest #[repr(C)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] pub struct VbsRegisterChunk { pub header: VbsChunkHeader, pub reserved: u32, @@ -83,7 +85,7 @@ const_assert!(size_of::() <= VBS_VP_CHUNK_SIZE_BYTES); /// Structure describing the page to be measured. /// Page data is hashed after struct to generate digest, if not a full page, measurable data will be padded to [`VBS_VP_CHUNK_SIZE_BYTES`] #[repr(C)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] pub struct VpGpaPageChunk { pub header: VbsChunkHeader, pub metadata: u64, @@ -91,7 +93,7 @@ pub struct VpGpaPageChunk { } open_enum! { -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] pub enum BootMeasurementType: u32 { VP_REGISTER = 0, VP_VTL_ENABLED = 1, @@ -113,7 +115,7 @@ pub struct VBS_VM_GPA_PAGE_BOOT_METADATA { /// Flags defining the security policy for the guest #[bitfield(u32)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] pub struct VBS_POLICY_FLAGS { /// Guest supports debugging #[bits(1)] diff --git a/vm/vhd1_defs/Cargo.toml b/vm/vhd1_defs/Cargo.toml index 9b73f1368a..f86ba8ce60 100644 --- a/vm/vhd1_defs/Cargo.toml +++ b/vm/vhd1_defs/Cargo.toml @@ -10,6 +10,5 @@ rust-version.workspace = true guid.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/vhd1_defs/src/lib.rs b/vm/vhd1_defs/src/lib.rs index f44e24defe..1831cc91db 100644 --- a/vm/vhd1_defs/src/lib.rs +++ b/vm/vhd1_defs/src/lib.rs @@ -9,9 +9,11 @@ use self::packed_nums::*; use guid::Guid; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -20,7 +22,7 @@ mod packed_nums { } #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VhdFooter { pub cookie: u64_be, pub features: u32_be, @@ -61,7 +63,7 @@ impl VhdFooter { original_size: size.into(), current_size: size.into(), disk_type: Self::DISK_TYPE_FIXED.into(), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; footer.unique_id = guid; diff --git a/vm/vmcore/Cargo.toml b/vm/vmcore/Cargo.toml index 399a3f1c94..abaec825c1 100644 --- a/vm/vmcore/Cargo.toml +++ b/vm/vmcore/Cargo.toml @@ -28,6 +28,5 @@ thiserror.workspace = true time = { workspace = true, optional = true } tracing.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/vmcore/guestmem/src/lib.rs b/vm/vmcore/guestmem/src/lib.rs index 4fd95dbbc6..d7ce15ae2e 100644 --- a/vm/vmcore/guestmem/src/lib.rs +++ b/vm/vmcore/guestmem/src/lib.rs @@ -22,9 +22,11 @@ use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use std::sync::Arc; use thiserror::Error; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Effective page size for page-related operations in this crate. pub const PAGE_SIZE: usize = 4096; @@ -229,7 +231,7 @@ impl AlignedHeapMemory { } /// Returns a mutable slice of bytes. - pub fn as_bytes_mut(&mut self) -> &mut [u8] { + pub fn as_mut_bytes(&mut self) -> &mut [u8] { self.as_mut() } } @@ -1447,7 +1449,11 @@ impl GuestMemory { /// /// FUTURE: once we are on Rust 1.79, add a method specifically for atomic /// accesses that const asserts that the size is appropriate. - pub fn write_plain(&self, gpa: u64, b: &T) -> Result<(), GuestMemoryError> { + pub fn write_plain( + &self, + gpa: u64, + b: &T, + ) -> Result<(), GuestMemoryError> { // Note that this is const, so the match below will compile out. let len = size_of::(); self.with_op(Some((gpa, len as u64)), GuestMemoryOperation::Write, || { @@ -1483,7 +1489,7 @@ impl GuestMemory { } /// Attempts a sequentially-consistent compare exchange of the value at `gpa`. - pub fn compare_exchange( + pub fn compare_exchange( &self, gpa: u64, current: T, @@ -1509,7 +1515,7 @@ impl GuestMemory { let mut current = current; let success = self.inner.imp.compare_exchange_fallback( gpa, - current.as_bytes_mut(), + current.as_mut_bytes(), new.as_bytes(), )?; @@ -1521,7 +1527,7 @@ impl GuestMemory { } /// Attempts a sequentially-consistent compare exchange of the value at `gpa`. - pub fn compare_exchange_bytes( + pub fn compare_exchange_bytes( &self, gpa: u64, current: &mut T, @@ -1547,7 +1553,7 @@ impl GuestMemory { |current| { let success = self.inner.imp.compare_exchange_fallback( gpa, - current.as_bytes_mut(), + current.as_mut_bytes(), new.as_bytes(), )?; @@ -1569,7 +1575,10 @@ impl GuestMemory { /// /// FUTURE: once we are on Rust 1.79, add a method specifically for atomic /// accesses that const asserts that the size is appropriate. - pub fn read_plain(&self, gpa: u64) -> Result { + pub fn read_plain( + &self, + gpa: u64, + ) -> Result { // Note that this is const, so the match below will compile out. let len = size_of::(); self.with_op(Some((gpa, len as u64)), GuestMemoryOperation::Read, || { @@ -1962,15 +1971,20 @@ pub trait MemoryRead { fn skip(&mut self, len: usize) -> Result<&mut Self, AccessError>; fn len(&self) -> usize; - fn read_plain(&mut self) -> Result { - let mut value: T = FromZeroes::new_zeroed(); - self.read(value.as_bytes_mut())?; + fn read_plain( + &mut self, + ) -> Result { + let mut value: T = FromZeros::new_zeroed(); + self.read(value.as_mut_bytes())?; Ok(value) } - fn read_n(&mut self, len: usize) -> Result, AccessError> { - let mut value = vec![FromZeroes::new_zeroed(); len]; - self.read(value.as_bytes_mut())?; + fn read_n( + &mut self, + len: usize, + ) -> Result, AccessError> { + let mut value = vec![FromZeros::new_zeroed(); len]; + self.read(value.as_mut_bytes())?; Ok(value) } diff --git a/vm/vmcore/src/monitor.rs b/vm/vmcore/src/monitor.rs index e1ab408bca..48cc326ce4 100644 --- a/vm/vmcore/src/monitor.rs +++ b/vm/vmcore/src/monitor.rs @@ -10,8 +10,8 @@ use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::Arc; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; // Four groups of 32 bits. const MAX_MONITORS: usize = 128; @@ -161,7 +161,7 @@ impl MonitorPage { let mut page = HvMonitorPageSmall::new_zeroed(); let offset = (gpa - page_gpa) as usize; - page.as_bytes_mut()[offset..offset + bytes.len()].copy_from_slice(bytes); + page.as_mut_bytes()[offset..offset + bytes.len()].copy_from_slice(bytes); for (group_index, group) in page.trigger_group.iter().enumerate() { let mut value = group.pending; while value != 0 { diff --git a/vm/vmgs/vmgs/Cargo.toml b/vm/vmgs/vmgs/Cargo.toml index bd3975263e..e4fd492470 100644 --- a/vm/vmgs/vmgs/Cargo.toml +++ b/vm/vmgs/vmgs/Cargo.toml @@ -35,7 +35,6 @@ openssl = { optional = true, features = ["vendored"], workspace = true } thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [target.'cfg(windows)'.dependencies.windows] workspace = true optional = true diff --git a/vm/vmgs/vmgs/src/encrypt/win.rs b/vm/vmgs/vmgs/src/encrypt/win.rs index 3f8bf4c579..567f6fa8b2 100644 --- a/vm/vmgs/vmgs/src/encrypt/win.rs +++ b/vm/vmgs/vmgs/src/encrypt/win.rs @@ -24,11 +24,11 @@ use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB; use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB_MAGIC; use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB_VERSION1; use windows::Win32::Security::Cryptography::BCRYPT_KEY_HANDLE; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; use zerocopy::Immutable; use zerocopy::KnownLayout; use zerocopy::FromZeros; // BCryptImportKey expects a key header immediately followed by a key of size key_len #[repr(C)] -#[derive(AsBytes)] +#[derive(IntoBytes, Immutable, KnownLayout)] struct KeyBlob { header_magic: u32, header_version: u32, diff --git a/vm/vmgs/vmgs/src/vmgs_impl.rs b/vm/vmgs/vmgs/src/vmgs_impl.rs index 498bd7412e..8c3a3afa94 100644 --- a/vm/vmgs/vmgs/src/vmgs_impl.rs +++ b/vm/vmgs/vmgs/src/vmgs_impl.rs @@ -30,9 +30,9 @@ use vmgs_format::VMGS_FILE_TABLE_BLOCK_SIZE; use vmgs_format::VMGS_MIN_FILE_BLOCK_OFFSET; use vmgs_format::VMGS_SIGNATURE; use vmgs_format::VMGS_VERSION_3_0; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; /// Info about a specific VMGS file. #[derive(Debug)] @@ -229,7 +229,9 @@ impl Vmgs { ))); } - let file_table = VmgsFileTable::ref_from_prefix(&file_table_buffer).unwrap(); + let file_table = VmgsFileTable::ref_from_prefix(&file_table_buffer) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range let file_control_blocks = initialize_file_metadata(file_table, version, storage.block_capacity())?; @@ -1064,8 +1066,9 @@ impl Vmgs { // Update the cached extended file table let extended_file_table = - VmgsExtendedFileTable::read_from_prefix(&extended_file_table_buffer[..]) - .context("Invalid decrypted extended file table")?; + VmgsExtendedFileTable::read_from_prefix(extended_file_table_buffer.as_bytes()) + .map_err(|_| anyhow!("Invalid decrypted extended file table"))? // todo: zerocopy: use result + .0; for (file_id, fcb) in self.fcbs.iter_mut() { fcb.attributes = extended_file_table.entries[*file_id].attributes; fcb.encryption_key = extended_file_table.entries[*file_id].encryption_key; @@ -1382,11 +1385,11 @@ async fn read_headers_inner(storage: &mut VmgsStorage) -> Result<(VmgsHeader, Vm .map_err(Error::ReadDisk)?; // first_two_blocks will contain enough bytes to read the first two headers - let header_1 = VmgsHeader::read_from_prefix(&first_two_blocks).unwrap(); + let header_1 = VmgsHeader::read_from_prefix(&first_two_blocks).unwrap().0; // todo: zerocopy: use-rest-of-range let header_2 = VmgsHeader::read_from_prefix(&first_two_blocks[storage.aligned_header_size() as usize..]) - .unwrap(); - + .unwrap() + .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range Ok((header_1, header_2)) } diff --git a/vm/vmgs/vmgs_format/Cargo.toml b/vm/vmgs/vmgs_format/Cargo.toml index ac4e1014c5..8afc3de3fe 100644 --- a/vm/vmgs/vmgs_format/Cargo.toml +++ b/vm/vmgs/vmgs_format/Cargo.toml @@ -13,6 +13,5 @@ inspect = { workspace = true, optional = true } bitfield-struct.workspace = true static_assertions.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/vmgs/vmgs_format/src/lib.rs b/vm/vmgs/vmgs_format/src/lib.rs index b8a62af6de..47a5e9ef7e 100644 --- a/vm/vmgs/vmgs_format/src/lib.rs +++ b/vm/vmgs/vmgs_format/src/lib.rs @@ -12,9 +12,10 @@ use core::ops::IndexMut; use inspect::Inspect; use open_enum::open_enum; use static_assertions::const_assert; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// The suggested default capacity of a VMGS disk in bytes, 4MB. /// @@ -73,7 +74,7 @@ pub type VmgsAuthTag = [u8; VMGS_AUTHENTICATION_TAG_SIZE]; pub type VmgsDatastoreKey = [u8; VMGS_ENCRYPTION_KEY_SIZE]; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VmgsFileEntry { // V2 fields pub offset: u32, @@ -104,7 +105,7 @@ impl IndexMut for [VmgsFileEntry] { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VmgsExtendedFileEntry { pub attributes: FileAttribute, pub encryption_key: VmgsDatastoreKey, @@ -129,7 +130,7 @@ impl IndexMut for [VmgsExtendedFileEntry] { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "inspect", derive(Inspect))] pub struct VmgsEncryptionKey { pub nonce: VmgsNonce, @@ -141,7 +142,7 @@ pub struct VmgsEncryptionKey { const_assert!(size_of::() == 64); #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VmgsHeader { // V1 compatible fields pub signature: u64, @@ -164,7 +165,7 @@ pub struct VmgsHeader { const_assert!(size_of::() == 168); #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes, Debug)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)] pub struct VmgsFileTable { pub entries: [VmgsFileEntry; VMGS_FILE_COUNT], } @@ -175,7 +176,7 @@ pub const VMGS_FILE_TABLE_BLOCK_SIZE: u32 = size_of::() as u32 / VMGS_BYTES_PER_BLOCK; #[repr(C)] -#[derive(Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct VmgsExtendedFileTable { pub entries: [VmgsExtendedFileEntry; VMGS_FILE_COUNT], } @@ -188,7 +189,7 @@ pub const VMGS_EXTENDED_FILE_TABLE_BLOCK_SIZE: u32 = /// File attribute for VMGS files #[cfg_attr(feature = "inspect", derive(Inspect))] #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct FileAttribute { pub encrypted: bool, pub authenticated: bool, @@ -200,7 +201,7 @@ open_enum! { /// Encryption algorithm used to encrypt VMGS file #[cfg_attr(feature = "inspect", derive(Inspect))] #[cfg_attr(feature = "inspect", inspect(debug))] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] pub enum EncryptionAlgorithm: u16 { /// No encryption algorithm NONE = 0, diff --git a/vm/whp/Cargo.toml b/vm/whp/Cargo.toml index e248d36859..95ec7d92fc 100644 --- a/vm/whp/Cargo.toml +++ b/vm/whp/Cargo.toml @@ -11,7 +11,6 @@ unstable_whp = [] [target.'cfg(windows)'.dependencies] zerocopy.workspace = true - [target.'cfg(windows)'.dependencies.winapi] workspace = true features = [ diff --git a/vm/whp/src/lib.rs b/vm/whp/src/lib.rs index e093ca01e4..c4ccbefef4 100644 --- a/vm/whp/src/lib.rs +++ b/vm/whp/src/lib.rs @@ -29,7 +29,10 @@ use winapi::shared::ntdef::LUID; use winapi::shared::winerror; use winapi::um::winnt::DEVICE_POWER_STATE; use winerror::ERROR_BAD_PATHNAME; -use zerocopy::AsBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; /// Functions to get the WHP platform's capabilities. pub mod capabilities { @@ -354,7 +357,7 @@ impl Partition { win32_bool: u32, banks: [u64; 8], } - fn set(t: &mut T, v: T) -> &[u8] { + fn set(t: &mut T, v: T) -> &[u8] { *t = v; t.as_bytes() } diff --git a/vm/x86/x86defs/Cargo.toml b/vm/x86/x86defs/Cargo.toml index e12c3ae22b..c22f79e708 100644 --- a/vm/x86/x86defs/Cargo.toml +++ b/vm/x86/x86defs/Cargo.toml @@ -12,6 +12,5 @@ open_enum.workspace = true arbitrary = { workspace = true, optional = true } bitfield-struct.workspace = true zerocopy.workspace = true - [lints] workspace = true diff --git a/vm/x86/x86defs/src/cpuid.rs b/vm/x86/x86defs/src/cpuid.rs index bf960d1712..2dfcc7d053 100644 --- a/vm/x86/x86defs/src/cpuid.rs +++ b/vm/x86/x86defs/src/cpuid.rs @@ -5,10 +5,11 @@ use bitfield_struct::bitfield; use core::fmt::Display; use open_enum::open_enum; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::KnownLayout; open_enum! { - #[derive(FromBytes, FromZeroes)] + #[derive(FromBytes, Immutable, KnownLayout)] pub enum CpuidFunction : u32 { #![expect(non_upper_case_globals, reason = "TODO: rename to SHOUTING_CASE")] BasicMinimum = 0x00000000, diff --git a/vm/x86/x86defs/src/lib.rs b/vm/x86/x86defs/src/lib.rs index a1475e215e..be9bd5b596 100644 --- a/vm/x86/x86defs/src/lib.rs +++ b/vm/x86/x86defs/src/lib.rs @@ -17,9 +17,11 @@ pub mod xsave; use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const X64_CR0_PE: u64 = 0x0000000000000001; // protection enable pub const X64_CR0_MP: u64 = 0x0000000000000002; // math present @@ -313,7 +315,7 @@ impl<'a> arbitrary::Arbitrary<'a> for RFlags { } #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IdtEntry64 { pub offset_low: u16, pub selector: u16, @@ -324,7 +326,7 @@ pub struct IdtEntry64 { } #[bitfield(u16)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct IdtAttributes { #[bits(3)] pub ist: u8, @@ -339,7 +341,7 @@ pub struct IdtAttributes { } #[repr(C)] -#[derive(Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GdtEntry { pub limit_low: u16, pub base_low: u16, @@ -350,7 +352,7 @@ pub struct GdtEntry { } #[repr(C)] -#[derive(Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LargeGdtEntry { pub limit_low: u16, pub base_low: u16, @@ -366,7 +368,7 @@ impl LargeGdtEntry { /// Get the large GDT entry as two smaller GDT entries, for building a GDT. pub fn get_gdt_entries(&self) -> [GdtEntry; 2] { let mut entries = [GdtEntry::new_zeroed(); 2]; - entries.as_bytes_mut().copy_from_slice(self.as_bytes()); + entries.as_mut_bytes().copy_from_slice(self.as_bytes()); entries } } @@ -408,7 +410,7 @@ pub struct PageFaultErrorCode { pub const X64_LARGE_PAGE_SIZE: u64 = 0x200000; #[bitfield(u64)] -#[derive(PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Pte { pub present: bool, pub read_write: bool, @@ -445,7 +447,7 @@ impl Pte { } #[bitfield(u64)] -#[derive(PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct LargePde { pub present: bool, pub read_write: bool, @@ -469,7 +471,7 @@ pub struct LargePde { } #[bitfield(u64)] -#[derive(PartialEq, Eq, AsBytes, FromBytes, FromZeroes)] +#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct X86xMcgStatusRegister { pub ripv: bool, // Restart IP is valid pub eipv: bool, // Error IP is valid diff --git a/vm/x86/x86defs/src/snp.rs b/vm/x86/x86defs/src/snp.rs index 0859a65e9d..4ae83ce8ac 100644 --- a/vm/x86/x86defs/src/snp.rs +++ b/vm/x86/x86defs/src/snp.rs @@ -4,9 +4,10 @@ //! AMD SEV-SNP specific definitions. use bitfield_struct::bitfield; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; // Interruption Information Field pub const SEV_INTR_TYPE_EXT: u32 = 0; @@ -19,7 +20,7 @@ pub const REG_TWEAK_BITMAP_OFFSET: usize = 0x100; pub const REG_TWEAK_BITMAP_SIZE: usize = 0x40; #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevEventInjectInfo { pub vector: u8, #[bits(3)] @@ -48,7 +49,7 @@ impl From for u8 { /// A X64 selector register. #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevSelector { pub selector: u16, pub attrib: u16, @@ -78,7 +79,7 @@ impl From for SevSelector { /// An X64 XMM register. #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevXmmRegister { low: u64, high: u64, @@ -100,7 +101,7 @@ impl From for SevXmmRegister { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevFeatures { pub snp: bool, pub vtom: bool, @@ -124,7 +125,7 @@ pub struct SevFeatures { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevVirtualInterruptControl { pub tpr: u8, pub irq: bool, @@ -144,7 +145,7 @@ pub struct SevVirtualInterruptControl { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevRmpAdjust { pub target_vmpl: u8, pub enable_read: bool, @@ -159,7 +160,7 @@ pub struct SevRmpAdjust { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevIoAccessInfo { pub read_access: bool, #[bits(1)] @@ -180,7 +181,7 @@ pub struct SevIoAccessInfo { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevNpfInfo { pub present: bool, pub read_write: bool, @@ -205,7 +206,7 @@ pub struct SevNpfInfo { /// SEV VMSA structure representing CPU state #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevVmsa { // Selector Info pub es: SevSelector, @@ -456,7 +457,7 @@ open_enum::open_enum! { /// Struct representing GHCB hypercall parameters. These are located at the GHCB /// page starting at [`GHCB_PAGE_HYPERCALL_PARAMETERS_OFFSET`]. #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct GhcbHypercallParameters { pub output_gpa: u64, pub input_control: u64, @@ -625,7 +626,7 @@ open_enum::open_enum! { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct GhcbMsr { #[bits(12)] pub info: u64, @@ -637,7 +638,7 @@ pub struct GhcbMsr { /// PSP data structures. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] pub struct HvPspCpuidLeaf { pub eax_in: u32, pub ecx_in: u32, @@ -653,7 +654,7 @@ pub struct HvPspCpuidLeaf { pub const HV_PSP_CPUID_LEAF_COUNT_MAX: usize = 64; #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Clone, Copy)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] pub struct HvPspCpuidPage { pub count: u32, pub reserved_z1: u32, @@ -666,7 +667,7 @@ pub struct HvPspCpuidPage { /// Each structure is hashed with the previous structures digest to create a final /// measurement #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpPageInfo { /// Set to the value of the previous page's launch digest pub digest_current: [u8; 48], @@ -687,7 +688,7 @@ pub struct SnpPageInfo { open_enum::open_enum! { /// The type of page described by [`SnpPageInfo`] - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SnpPageType: u8 { /// Reserved RESERVED = 0x0, @@ -710,7 +711,7 @@ open_enum::open_enum! { /// The signature of the hash of this struct is the id_key_signature for /// `igvm_defs::IGVM_VHS_SNP_ID_BLOCK`. #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SnpPspIdBlock { /// completed launch digest of IGVM file pub ld: [u8; 48], @@ -727,7 +728,7 @@ pub struct SnpPspIdBlock { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevStatusMsr { pub sev_enabled: bool, pub es_enabled: bool, @@ -751,7 +752,7 @@ pub struct SevStatusMsr { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevInvlpgbRax { pub va_valid: bool, pub pcid_valid: bool, @@ -766,7 +767,7 @@ pub struct SevInvlpgbRax { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevInvlpgbEdx { #[bits(16)] pub asid: u64, @@ -777,7 +778,7 @@ pub struct SevInvlpgbEdx { } #[bitfield(u32)] -#[derive(AsBytes, FromBytes, FromZeroes, PartialEq, Eq)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)] pub struct SevInvlpgbEcx { #[bits(16)] pub additional_count: u64, diff --git a/vm/x86/x86defs/src/tdx.rs b/vm/x86/x86defs/src/tdx.rs index 2e047cafd6..bd319169bd 100644 --- a/vm/x86/x86defs/src/tdx.rs +++ b/vm/x86/x86defs/src/tdx.rs @@ -6,9 +6,10 @@ use crate::vmx; use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; pub const TDX_SHARED_GPA_BOUNDARY_BITS: u8 = 47; pub const TDX_SHARED_GPA_BOUNDARY_ADDRESS_BIT: u64 = 1 << TDX_SHARED_GPA_BOUNDARY_BITS; @@ -201,7 +202,7 @@ pub enum TdVmCallSubFunction { open_enum! { /// Result code for `tdcall` to the TDX module, returned in RAX. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum TdCallResultCode: u32 { SUCCESS = 0x00000000, NON_RECOVERABLE_VCPU = 0x40000001, @@ -391,7 +392,7 @@ pub struct TdCallResult { open_enum! { /// The result returned by a tdg.vm.call in r10. - #[derive(AsBytes, FromBytes, FromZeroes)] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum TdVmCallR10Result: u64 { SUCCESS = 0, RETRY = 1, @@ -552,7 +553,7 @@ impl TdxExtendedExitQualificationType { /// The GPR list used for TDG.VP.ENTER. Specified in the TDX specification as /// L2_ENTER_GUEST_STATE. #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdxL2EnterGuestState { /// GPs in the usual order. pub gps: [u64; 16], @@ -706,7 +707,7 @@ pub struct TdGlaVmAndFlags { } #[bitfield(u64)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct TdxVmFlags { #[bits(2)] pub invd_translations: u8, diff --git a/vm/x86/x86defs/src/vmx.rs b/vm/x86/x86defs/src/vmx.rs index abac67b669..481d0e8196 100644 --- a/vm/x86/x86defs/src/vmx.rs +++ b/vm/x86/x86defs/src/vmx.rs @@ -7,9 +7,10 @@ use bitfield_struct::bitfield; use open_enum::open_enum; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; open_enum! { /// VMX exit reason @@ -356,14 +357,14 @@ pub struct SecondaryProcessorControls { } #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ApicRegister { pub value: u32, _reserved: [u32; 3], } #[repr(C)] -#[derive(Debug, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ApicPage { pub reserved_0: [ApicRegister; 2], pub id: ApicRegister, diff --git a/vm/x86/x86defs/src/xsave.rs b/vm/x86/x86defs/src/xsave.rs index 0d0a4dc9fb..b67bc6c098 100644 --- a/vm/x86/x86defs/src/xsave.rs +++ b/vm/x86/x86defs/src/xsave.rs @@ -3,12 +3,13 @@ //! Xsave-related definitions. -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[repr(C)] -#[derive(Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Fxsave { pub fcw: u16, pub fsw: u16, @@ -26,7 +27,7 @@ pub struct Fxsave { } #[repr(C)] -#[derive(Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct XsaveHeader { pub xstate_bv: u64, pub xcomp_bv: u64, diff --git a/vm/x86/x86emu/tests/tests/rep/lods.rs b/vm/x86/x86emu/tests/tests/rep/lods.rs index b35305de38..3cb95a9323 100644 --- a/vm/x86/x86emu/tests/tests/rep/lods.rs +++ b/vm/x86/x86emu/tests/tests/rep/lods.rs @@ -7,7 +7,7 @@ use x86defs::RFlags; use x86emu::Cpu; use x86emu::Gp; use x86emu::MAX_REP_LOOPS; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[test] fn lods() { diff --git a/vmm_core/Cargo.toml b/vmm_core/Cargo.toml index ef6de6735b..e598003d38 100644 --- a/vmm_core/Cargo.toml +++ b/vmm_core/Cargo.toml @@ -53,7 +53,6 @@ slab.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vmm_core/src/acpi_builder.rs b/vmm_core/src/acpi_builder.rs index d91dd2aa6b..1c8289df23 100644 --- a/vmm_core/src/acpi_builder.rs +++ b/vmm_core/src/acpi_builder.rs @@ -21,7 +21,7 @@ use vm_topology::processor::x86::X86Topology; use vm_topology::processor::ArchTopology; use vm_topology::processor::ProcessorTopology; use x86defs::apic::APIC_BASE_ADDRESS; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// Binary ACPI tables constructed by [`AcpiTablesBuilder`]. pub struct BuiltAcpiTables { diff --git a/vmm_core/virt/Cargo.toml b/vmm_core/virt/Cargo.toml index 350aba3484..ce72839fec 100644 --- a/vmm_core/virt/Cargo.toml +++ b/vmm_core/virt/Cargo.toml @@ -27,7 +27,6 @@ slab.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] [build-dependencies] diff --git a/vmm_core/virt/src/x86/vp.rs b/vmm_core/virt/src/x86/vp.rs index ad9de43b24..a190db8326 100644 --- a/vmm_core/virt/src/x86/vp.rs +++ b/vmm_core/virt/src/x86/vp.rs @@ -44,9 +44,11 @@ use x86defs::X64_CR0_ET; use x86defs::X64_CR0_NW; use x86defs::X64_EFER_NXE; use x86defs::X86X_MSR_DEFAULT_PAT; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; use zerocopy::Ref; #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Protobuf, Inspect)] @@ -707,9 +709,8 @@ pub struct Xsave { impl Xsave { fn normalize(&mut self) { - let (mut fxsave, data) = - Ref::<_, Fxsave>::new_from_prefix(self.data.as_bytes_mut()).unwrap(); - let header = XsaveHeader::mut_from_prefix(data).unwrap(); + let (mut fxsave, data) = Ref::<_, Fxsave>::from_prefix(self.data.as_mut_bytes()).unwrap(); + let header = XsaveHeader::mut_from_prefix(data).unwrap().0; // todo: zerocopy: ref-from-prefix: use-rest-of-range // Clear the mxcsr mask since it's ignored in the restore process and // will only cause xsave comparisons to fail. @@ -765,7 +766,7 @@ impl Xsave { pub fn from_compact(data: &[u8], caps: &X86PartitionCapabilities) -> Self { assert_eq!(data.len() % 8, 0); let mut aligned = vec![0; data.len() / 8]; - aligned.as_bytes_mut().copy_from_slice(data); + aligned.as_mut_bytes().copy_from_slice(data); let mut this = Self { data: aligned }; this.normalize(); @@ -776,8 +777,9 @@ impl Xsave { // penalty. if caps.xsaves_state_bv_broken { let header = - XsaveHeader::mut_from_prefix(&mut this.data.as_bytes_mut()[XSAVE_LEGACY_LEN..]) - .unwrap(); + XsaveHeader::mut_from_prefix(&mut this.data.as_mut_bytes()[XSAVE_LEGACY_LEN..]) + .unwrap() + .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range // Just enable supervisor states that were possible when the // hypervisor had the bug. Future ones will only be supported by @@ -793,13 +795,12 @@ impl Xsave { let mut this = Self { data: vec![0; caps.xsave.compact_len as usize / 8], }; - this.data.as_bytes_mut()[..XSAVE_VARIABLE_OFFSET] + this.data.as_mut_bytes()[..XSAVE_VARIABLE_OFFSET] .copy_from_slice(&src[..XSAVE_VARIABLE_OFFSET]); - let (mut header, data) = Ref::<_, XsaveHeader>::new_from_prefix( - &mut this.data.as_bytes_mut()[XSAVE_LEGACY_LEN..], - ) - .unwrap(); + let (mut header, data) = + Ref::<_, XsaveHeader>::from_prefix(&mut this.data.as_mut_bytes()[XSAVE_LEGACY_LEN..]) + .unwrap(); header.xcomp_bv = caps.xsave.features | caps.xsave.supervisor_features | XCOMP_COMPRESSED; let mut cur = 0; @@ -865,7 +866,7 @@ impl Xsave { /// Since this does not include `xstate_bv`, fields for disabled features /// will be set to their default values. pub fn fxsave(&self) -> Fxsave { - let mut fxsave = Fxsave::read_from_prefix(self.data.as_bytes()).unwrap(); + let mut fxsave = Fxsave::read_from_prefix(self.data.as_bytes()).unwrap().0; // todo: zerocopy: use-rest-of-range let header = self.xsave_header(); if header.xstate_bv & XFEATURE_X87 == 0 { fxsave.fcw = INIT_FCW; @@ -877,7 +878,9 @@ impl Xsave { } fn xsave_header(&self) -> &XsaveHeader { - XsaveHeader::ref_from_prefix(&self.data.as_bytes()[XSAVE_LEGACY_LEN..]).unwrap() + XsaveHeader::ref_from_prefix(&self.data.as_bytes()[XSAVE_LEGACY_LEN..]) + .unwrap() + .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range } } @@ -950,7 +953,10 @@ impl StateElement for Xsave { fn at_reset(caps: &X86PartitionCapabilities, _vp_info: &X86VpInfo) -> Self { let mut data = vec![0; caps.xsave.compact_len as usize]; - *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]).unwrap() = XsaveHeader { + *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]) + .unwrap() + .0 = XsaveHeader { + // todo: zerocopy: ref-from-prefix: use-rest-of-range xstate_bv: 0, xcomp_bv: XCOMP_COMPRESSED | caps.xsave.features | caps.xsave.supervisor_features, reserved: [0; 6], @@ -989,7 +995,7 @@ impl Debug for Apic { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes, Inspect)] +#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)] pub struct ApicRegisters { #[inspect(skip)] pub reserved_0: [u32; 2], @@ -1057,18 +1063,18 @@ const _: () = assert!(size_of::() == 0x100); impl From<&'_ [u32; 64]> for ApicRegisters { fn from(value: &'_ [u32; 64]) -> Self { - Self::read_from(value.as_bytes()).unwrap() + Self::read_from_bytes(value.as_bytes()).unwrap() } } impl From for [u32; 64] { fn from(value: ApicRegisters) -> Self { - Self::read_from(value.as_bytes()).unwrap() + Self::read_from_bytes(value.as_bytes()).unwrap() } } #[repr(C)] -#[derive(AsBytes, FromBytes, FromZeroes)] +#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] struct ApicRegister { value: u32, zero: [u32; 3], @@ -1096,7 +1102,7 @@ impl Apic { /// N.B. The MS hypervisor's APIC page format includes a non-architectural /// NMI pending bit that should be stripped first. pub fn from_page(apic_base: u64, page: &[u8; 1024]) -> Self { - let registers = <[ApicRegister; 64]>::read_from(page.as_slice()).unwrap(); + let registers = <[ApicRegister; 64]>::read_from_bytes(page.as_slice()).unwrap(); Self { apic_base, registers: registers.map(|reg| reg.value), diff --git a/vmm_core/virt_kvm/Cargo.toml b/vmm_core/virt_kvm/Cargo.toml index 7d2cf1aa24..84de5b7e9c 100644 --- a/vmm_core/virt_kvm/Cargo.toml +++ b/vmm_core/virt_kvm/Cargo.toml @@ -33,7 +33,6 @@ thiserror.workspace = true tracing.workspace = true tracelimit.workspace = true zerocopy.workspace = true - [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vmm_core/virt_kvm/src/arch/x86_64/mod.rs b/vmm_core/virt_kvm/src/arch/x86_64/mod.rs index 575ec8286f..4753bade05 100644 --- a/vmm_core/virt_kvm/src/arch/x86_64/mod.rs +++ b/vmm_core/virt_kvm/src/arch/x86_64/mod.rs @@ -83,7 +83,7 @@ use vp_state::KvmVpStateAccess; use x86defs::cpuid::CpuidFunction; use x86defs::msi::MsiAddress; use x86defs::msi::MsiData; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; // HACK: on certain machines, pcat spams these MSRs during boot. // diff --git a/vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs b/vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs index 6bba184cf4..6c8e1a20f6 100644 --- a/vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs +++ b/vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs @@ -14,7 +14,7 @@ use virt::x86::TableRegister; use virt::VpIndex; use vm_topology::processor::x86::X86VpInfo; use x86defs::SegmentAttributes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; pub struct KvmVpStateAccess<'a> { partition: &'a KvmPartitionInner, @@ -377,7 +377,7 @@ impl AccessVpState for KvmVpStateAccess<'_> { self.kvm() .get_msrs(&[x86defs::X86X_MSR_APIC_BASE], &mut apic_base)?; - let mut state = FromZeroes::new_zeroed(); + let mut state = FromZeros::new_zeroed(); self.kvm().get_lapic(&mut state)?; Ok(vp::Apic::from_page(apic_base[0], &state)) diff --git a/vmm_core/virt_mshv/Cargo.toml b/vmm_core/virt_mshv/Cargo.toml index 96933761b4..eaf5201c7a 100644 --- a/vmm_core/virt_mshv/Cargo.toml +++ b/vmm_core/virt_mshv/Cargo.toml @@ -33,7 +33,6 @@ thiserror.workspace = true tracing.workspace = true vmm-sys-util.workspace = true zerocopy.workspace = true - [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vmm_core/virt_mshv/src/lib.rs b/vmm_core/virt_mshv/src/lib.rs index e164396b4a..e671664fb0 100644 --- a/vmm_core/virt_mshv/src/lib.rs +++ b/vmm_core/virt_mshv/src/lib.rs @@ -76,7 +76,7 @@ use vmcore::interrupt::Interrupt; use vmcore::synic::GuestEventPort; use x86defs::RFlags; use x86defs::SegmentRegister; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; #[derive(Debug)] pub struct LinuxMshv; diff --git a/vmm_core/virt_mshv/src/vp_state.rs b/vmm_core/virt_mshv/src/vp_state.rs index 7c77644069..6906ba1ea6 100644 --- a/vmm_core/virt_mshv/src/vp_state.rs +++ b/vmm_core/virt_mshv/src/vp_state.rs @@ -11,7 +11,7 @@ use std::mem::offset_of; use virt::state::HvRegisterState; use virt::x86::vp; use virt::x86::vp::AccessVpState; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; impl MshvProcessor<'_> { pub(crate) fn set_register_state(&self, regs: &T) -> Result<(), Error> @@ -21,7 +21,7 @@ impl MshvProcessor<'_> { let mut assoc = regs.names().map(|name| HvRegisterAssoc { name: name.into(), pad: [0; 3], - value: FromZeroes::new_zeroed(), + value: FromZeros::new_zeroed(), }); regs.get_values(assoc.iter_mut().map(|assoc| &mut assoc.value)); @@ -42,7 +42,7 @@ impl MshvProcessor<'_> { let mut assoc = regs.names().map(|name| HvRegisterAssoc { name: name.into(), pad: [0; 3], - value: FromZeroes::new_zeroed(), + value: FromZeros::new_zeroed(), }); self.inner diff --git a/vmm_core/virt_support_aarch64emu/Cargo.toml b/vmm_core/virt_support_aarch64emu/Cargo.toml index 42926a5be9..078d3f327a 100644 --- a/vmm_core/virt_support_aarch64emu/Cargo.toml +++ b/vmm_core/virt_support_aarch64emu/Cargo.toml @@ -17,7 +17,6 @@ aarch64emu.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] [lints] diff --git a/vmm_core/virt_support_aarch64emu/src/emulate.rs b/vmm_core/virt_support_aarch64emu/src/emulate.rs index 26958a27f6..9293fc8e5c 100644 --- a/vmm_core/virt_support_aarch64emu/src/emulate.rs +++ b/vmm_core/virt_support_aarch64emu/src/emulate.rs @@ -20,8 +20,8 @@ use thiserror::Error; use virt::io::CpuIo; use virt::VpHaltReason; use vm_topology::processor::VpIndex; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// Support routines for the emulator. pub trait EmulatorSupport: AccessCpuState { @@ -614,7 +614,7 @@ pub fn make_exception_event(syndrome: EsrEl2, fault_address: u64) -> HvAarch64Pe let exception_event_bytes = exception_event.as_bytes(); let mut event = [0u8; 32]; event.as_mut_slice()[..exception_event_bytes.len()].copy_from_slice(exception_event_bytes); - HvAarch64PendingEvent::read_from(&event[..]).unwrap() + HvAarch64PendingEvent::read_from_bytes(&event[..]).unwrap() } /// Injects an event into the guest if appropriate. diff --git a/vmm_core/virt_support_x86emu/Cargo.toml b/vmm_core/virt_support_x86emu/Cargo.toml index 0322f83ba3..ce383f659e 100644 --- a/vmm_core/virt_support_x86emu/Cargo.toml +++ b/vmm_core/virt_support_x86emu/Cargo.toml @@ -18,7 +18,6 @@ x86emu.workspace = true thiserror.workspace = true tracing.workspace = true zerocopy.workspace = true - [dev-dependencies] pal_async.workspace = true iced-x86 = { workspace = true, features = ["code_asm"] } diff --git a/vmm_core/virt_support_x86emu/src/emulate.rs b/vmm_core/virt_support_x86emu/src/emulate.rs index f84c31d53e..6a85143a17 100644 --- a/vmm_core/virt_support_x86emu/src/emulate.rs +++ b/vmm_core/virt_support_x86emu/src/emulate.rs @@ -21,8 +21,8 @@ use x86defs::SegmentRegister; use x86emu::Gp; use x86emu::RegisterIndex; use x86emu::Segment; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// Support routines for the emulator. pub trait EmulatorSupport { @@ -995,7 +995,7 @@ fn vtl_access_event( _reserved3: 0, }; - hvdef::HvX64PendingEvent::read_from(memory_event.as_bytes()) + hvdef::HvX64PendingEvent::read_from_bytes(memory_event.as_bytes()) .expect("memory event and pending event should be the same size") } else { gpf_event() diff --git a/vmm_core/virt_support_x86emu/tests/tests/checkvtlaccess.rs b/vmm_core/virt_support_x86emu/tests/tests/checkvtlaccess.rs index 911233fbf6..2281a986a6 100644 --- a/vmm_core/virt_support_x86emu/tests/tests/checkvtlaccess.rs +++ b/vmm_core/virt_support_x86emu/tests/tests/checkvtlaccess.rs @@ -12,8 +12,8 @@ use x86defs::cpuid::Vendor; use x86defs::RFlags; use x86emu::Gp; use x86emu::Segment; -use zerocopy::AsBytes; use zerocopy::FromBytes; +use zerocopy::IntoBytes; /// Implements [`EmulatorSupport`] with some features for deliberately /// failing vtl permissions checks and checking the resulting injected @@ -229,7 +229,7 @@ fn validate_vtl_access_event( expected_vtl: Vtl, ) { let event = - hvdef::HvX64PendingEventMemoryIntercept::read_from(pending_event.as_bytes()).unwrap(); + hvdef::HvX64PendingEventMemoryIntercept::read_from_bytes(pending_event.as_bytes()).unwrap(); assert!(event.event_header.event_pending()); diff --git a/vmm_core/virt_support_x86emu/tests/tests/translate.rs b/vmm_core/virt_support_x86emu/tests/tests/translate.rs index e8d9e7e79a..af315790a6 100644 --- a/vmm_core/virt_support_x86emu/tests/tests/translate.rs +++ b/vmm_core/virt_support_x86emu/tests/tests/translate.rs @@ -12,7 +12,7 @@ use x86defs::cpuid::Vendor; use x86defs::RFlags; use x86emu::Gp; use x86emu::Segment; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; const INITIAL_GVA: u64 = 0x2000; const INITIAL_GPA: u64 = 0x1000; diff --git a/vmm_core/virt_whp/Cargo.toml b/vmm_core/virt_whp/Cargo.toml index 3e5e689ac2..6ae48ba4b3 100644 --- a/vmm_core/virt_whp/Cargo.toml +++ b/vmm_core/virt_whp/Cargo.toml @@ -45,7 +45,6 @@ thiserror.workspace = true tracing.workspace = true winapi.workspace = true zerocopy.workspace = true - [build-dependencies] build_rs_guest_arch.workspace = true diff --git a/vmm_core/virt_whp/src/hypercalls.rs b/vmm_core/virt_whp/src/hypercalls.rs index 6477f710b6..ddd7f84dfe 100644 --- a/vmm_core/virt_whp/src/hypercalls.rs +++ b/vmm_core/virt_whp/src/hypercalls.rs @@ -721,9 +721,11 @@ mod x86 { use whp::abi::WHV_REGISTER_VALUE; use whp::RegisterName; use whp::RegisterValue; - use zerocopy::AsBytes; use zerocopy::FromBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; pub(super) struct WhpHypercallRegisters<'a> { info: whp::abi::WHV_HYPERCALL_CONTEXT, @@ -1295,16 +1297,16 @@ mod x86 { Ok(TranslateResult { gpa, cache_info: _ }) => { hvdef::hypercall::TranslateVirtualAddressExOutputX64 { gpa_page: gpa / HV_PAGE_SIZE, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() } } Err(err) => hvdef::hypercall::TranslateVirtualAddressExOutputX64 { translation_result: hvdef::hypercall::TranslateGvaResultExX64 { result: hvdef::hypercall::TranslateGvaResult::new() .with_result_code(TranslateGvaResultCode::from(err).0), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, }; @@ -1694,7 +1696,6 @@ mod aarch64 { use virt_support_aarch64emu::translate::TranslateFlags; use virt_support_aarch64emu::translate::TranslationRegisters; use whp::RegisterValue; - use zerocopy::FromZeroes; pub(super) struct WhpHypercallRegisters<'a> { message: hvdef::HvArm64HypercallInterceptMessage, @@ -1969,14 +1970,14 @@ mod aarch64 { let result = match result { Ok(gpa) => hvdef::hypercall::TranslateVirtualAddressExOutputArm64 { gpa_page: gpa / HV_PAGE_SIZE, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, Err(err) => hvdef::hypercall::TranslateVirtualAddressExOutputArm64 { translation_result: hvdef::hypercall::TranslateGvaResultExArm64 { result: hvdef::hypercall::TranslateGvaResult::new() .with_result_code(TranslateGvaResultCode::from(err).0), }, - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }, }; diff --git a/vmm_core/virt_whp/src/vp.rs b/vmm_core/virt_whp/src/vp.rs index 6476f47e80..be7295e470 100644 --- a/vmm_core/virt_whp/src/vp.rs +++ b/vmm_core/virt_whp/src/vp.rs @@ -25,7 +25,10 @@ use virt::io::CpuIo; use virt::vp::AccessVpState; use virt::StopVp; use virt::VpHaltReason; -use zerocopy::AsBytes; +use zerocopy::FromZeros; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[derive(Debug, Error)] pub enum WhpRunVpError { @@ -594,8 +597,10 @@ mod x86 { use x86defs::apic::X2APIC_MSR_END; use x86defs::cpuid::CpuidFunction; use x86defs::X86X_MSR_APIC_BASE; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; // HACK: on certain machines, Windows booting from the PCAT BIOS spams these // MSRs during boot. @@ -971,7 +976,7 @@ mod x86 { deliverable_type: hvdef::HvX64PendingInterruptionType( info.DeliverableType.0 as u8, ), - ..FromZeroes::new_zeroed() + ..FromZeros::new_zeroed() }; self.vtl2_intercept( @@ -1793,29 +1798,33 @@ mod aarch64 { | HvMessageType::HvMessageTypeGpaIntercept => { self.handle_memory_access( dev, - FromBytes::ref_from_prefix(message).unwrap(), + FromBytes::ref_from_prefix(message).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range exit, ) .await?; &mut self.state.exits.memory } HvMessageType::HvMessageTypeSynicSintDeliverable => { - self.handle_sint_deliverable(FromBytes::ref_from_prefix(message).unwrap()); + self.handle_sint_deliverable( + FromBytes::ref_from_prefix(message).unwrap().0, + ); // todo: zerocopy: ref-from-prefix: use-rest-of-range &mut self.state.exits.sint_deliverable } HvMessageType::HvMessageTypeHypercallIntercept => { crate::hypercalls::WhpHypercallExit::handle( self, dev, - FromBytes::ref_from_prefix(message).unwrap(), + FromBytes::ref_from_prefix(message).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range ); &mut self.state.exits.hypercall } HvMessageType::HvMessageTypeArm64ResetIntercept => { - return Err(self.handle_reset(FromBytes::ref_from_prefix(message).unwrap())); + return Err( + self.handle_reset(FromBytes::ref_from_prefix(message).unwrap().0) + ); // todo: zerocopy: ref-from-prefix: use-rest-of-range } reason => { - return Err(VpHaltReason::Hypervisor(WhpRunVpError::UnknownExit(reason))) + return Err(VpHaltReason::Hypervisor(WhpRunVpError::UnknownExit(reason))); } }, }; diff --git a/vmm_core/virt_whp/src/vp_state.rs b/vmm_core/virt_whp/src/vp_state.rs index 8dbddabb29..693672de66 100644 --- a/vmm_core/virt_whp/src/vp_state.rs +++ b/vmm_core/virt_whp/src/vp_state.rs @@ -11,7 +11,6 @@ use hvdef::HvRegisterValue; use hvdef::Vtl; use virt::state::HvRegisterState; use whp::abi::WHV_REGISTER_VALUE; -use zerocopy::FromZeroes; pub struct WhpVpStateAccess<'a, 'b> { run: &'a mut WhpProcessor<'b>, @@ -75,8 +74,10 @@ mod x86 { use virt::state::StateElement; use virt::x86::vp; use virt::x86::vp::AccessVpState; - use zerocopy::AsBytes; - use zerocopy::FromZeroes; + use zerocopy::FromZeros; + use zerocopy::Immutable; + use zerocopy::IntoBytes; + use zerocopy::KnownLayout; impl AccessVpState for WhpVpStateAccess<'_, '_> { type Error = Error; @@ -251,7 +252,7 @@ mod x86 { .whp(self.vtl) .get_state( whp::abi::WHvVirtualProcessorStateTypeSynicTimerState, - state.as_bytes_mut(), + state.as_mut_bytes(), ) .for_op("get synic timer state")?; Ok(vp::SynicTimers::from_hv(state)) diff --git a/workers/vnc_worker/vnc/examples/vncserver.rs b/workers/vnc_worker/vnc/examples/vncserver.rs index 87a2531d15..5a7f763f24 100644 --- a/workers/vnc_worker/vnc/examples/vncserver.rs +++ b/workers/vnc_worker/vnc/examples/vncserver.rs @@ -7,7 +7,7 @@ use pal_async::local::block_with_io; use pal_async::socket::PolledSocket; use std::net::TcpListener; use vnc::Error; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; fn pixel(r: u8, g: u8, b: u8) -> u32 { (r as u32) << 16 | (g as u32) << 8 | b as u32 diff --git a/workers/vnc_worker/vnc/src/lib.rs b/workers/vnc_worker/vnc/src/lib.rs index 7bcd8e9787..0b3768b097 100644 --- a/workers/vnc_worker/vnc/src/lib.rs +++ b/workers/vnc_worker/vnc/src/lib.rs @@ -13,8 +13,8 @@ use futures::FutureExt; use futures::StreamExt; use pal_async::socket::PolledSocket; use thiserror::Error; -use zerocopy::AsBytes; -use zerocopy::FromZeroes; +use zerocopy::FromZeros; +use zerocopy::IntoBytes; #[derive(Debug, Error)] pub enum Error { @@ -115,7 +115,7 @@ impl Server { .await?; let mut version = rfb::ProtocolVersion::new_zeroed(); - socket.read_exact(version.as_bytes_mut()).await?; + socket.read_exact(version.as_mut_bytes()).await?; if version.0 != rfb::PROTOCOL_VERSION_33 { return Err(Error::UnsupportedVersion(version)); @@ -132,7 +132,7 @@ impl Server { .await?; let mut init = rfb::ClientInit::new_zeroed(); - socket.read_exact(init.as_bytes_mut()).await?; + socket.read_exact(init.as_mut_bytes()).await?; let mut fmt = rfb::PixelFormat { bits_per_pixel: 32, @@ -175,7 +175,7 @@ impl Server { .into(); futures::select! { // merge semantics _ = update => update_ready = true, - r = socket.read(message_type.as_bytes_mut()).fuse() => { + r = socket.read(message_type.as_mut_bytes()).fuse() => { if r? == 0 { return Ok(()) } @@ -247,7 +247,7 @@ impl Server { 1 => { let mut line = vec![0u8; width as usize]; for y in 0..height { - self.fb.read_line(y, src_line.as_bytes_mut()); + self.fb.read_line(y, src_line.as_mut_bytes()); for x in 0..width as usize { let p = src_line[x]; let (r, g, b) = (p & 0xff0000, p & 0xff00, p & 0xff); @@ -262,7 +262,7 @@ impl Server { 2 => { let mut line = vec![0u16; width as usize]; for y in 0..height { - self.fb.read_line(y, src_line.as_bytes_mut()); + self.fb.read_line(y, src_line.as_mut_bytes()); for x in 0..width as usize { let p = src_line[x]; let (r, g, b) = (p & 0xff0000, p & 0xff00, p & 0xff); @@ -279,14 +279,14 @@ impl Server { && shift_b == fmt.blue_shift as u32 => { for y in 0..height { - self.fb.read_line(y, src_line.as_bytes_mut()); + self.fb.read_line(y, src_line.as_mut_bytes()); socket.write_all(src_line.as_bytes()).await?; } } 4 => { let mut line = vec![0u32; width as usize]; for y in 0..height { - self.fb.read_line(y, src_line.as_bytes_mut()); + self.fb.read_line(y, src_line.as_mut_bytes()); for x in (width as usize & !3)..width as usize { let p = src_line[x]; let (r, g, b) = (p & 0xff0000, p & 0xff00, p & 0xff); @@ -307,15 +307,15 @@ impl Server { match message_type { rfb::CS_MESSAGE_SET_PIXEL_FORMAT => { let mut input = rfb::SetPixelFormat::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; fmt = input.pixel_format; } rfb::CS_MESSAGE_SET_ENCODINGS => { let mut input = rfb::SetEncodings::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; let mut encodings: Vec> = vec![0.into(); input.encoding_count.get().into()]; - socket.read_exact(encodings.as_bytes_mut()).await?; + socket.read_exact(encodings.as_mut_bytes()).await?; if !encodings.contains(&rfb::ENCODING_TYPE_DESKTOP_SIZE.into()) { // Can't really operate without being able to change the desktop size dynamically. return Err(Error::DesktopResizeNotSupported); @@ -346,12 +346,12 @@ impl Server { } rfb::CS_MESSAGE_FRAMEBUFFER_UPDATE_REQUEST => { let mut input = rfb::FramebufferUpdateRequest::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; ready_for_update = true; } rfb::CS_MESSAGE_KEY_EVENT => { let mut input = rfb::KeyEvent::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; // RFB key events are in xkeysym format. Convert them to // US keyboard scancodes and send them to the keyboard @@ -410,7 +410,7 @@ impl Server { } rfb::CS_MESSAGE_POINTER_EVENT => { let mut input = rfb::PointerEvent::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; //scale the mouse coordinates in the VNC itself let mut x = 0; let mut y = 0; @@ -431,7 +431,7 @@ impl Server { } rfb::CS_MESSAGE_CLIENT_CUT_TEXT => { let mut input = rfb::ClientCutText::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; let mut text_latin1 = vec![0; input.length.get() as usize]; socket.read_exact(&mut text_latin1).await?; // Latin1 characters map to the first 256 characters of Unicode (roughly). @@ -439,11 +439,11 @@ impl Server { } rfb::CS_MESSAGE_QEMU => { let mut input = rfb::QemuMessageHeader::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[1..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[1..]).await?; match input.submessage_type { rfb::QEMU_MESSAGE_EXTENDED_KEY_EVENT => { let mut input = rfb::QemuExtendedKeyEvent::new_zeroed(); - socket.read_exact(&mut input.as_bytes_mut()[2..]).await?; + socket.read_exact(&mut input.as_mut_bytes()[2..]).await?; let mut scancode = input.keycode.get() as u16; // An E0 prefix is sometimes encoded via the // high bit on a single byte. diff --git a/workers/vnc_worker/vnc/src/rfb.rs b/workers/vnc_worker/vnc/src/rfb.rs index 52d5672261..4675ae07cb 100644 --- a/workers/vnc_worker/vnc/src/rfb.rs +++ b/workers/vnc_worker/vnc/src/rfb.rs @@ -4,9 +4,10 @@ #![allow(dead_code)] use self::packed_nums::*; -use zerocopy::AsBytes; use zerocopy::FromBytes; -use zerocopy::FromZeroes; +use zerocopy::Immutable; +use zerocopy::IntoBytes; +use zerocopy::KnownLayout; #[allow(non_camel_case_types)] mod packed_nums { @@ -17,7 +18,7 @@ mod packed_nums { // As defined in https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#handshaking-messages #[repr(transparent)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ProtocolVersion(pub [u8; 12]); pub const PROTOCOL_VERSION_33: [u8; 12] = *b"RFB 003.003\n"; @@ -25,14 +26,14 @@ pub const PROTOCOL_VERSION_37: [u8; 12] = *b"RFB 003.007\n"; pub const PROTOCOL_VERSION_38: [u8; 12] = *b"RFB 003.008\n"; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Security33 { pub padding: [u8; 3], pub security_type: u8, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Security37 { pub type_count: u8, // types: [u8; N] @@ -45,7 +46,7 @@ pub const SECURITY_TYPE_TIGHT: u8 = 16; pub const SECURITY_TYPE_VENCRYPT: u8 = 19; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SecurityResult { pub status: u32_be, } @@ -55,13 +56,13 @@ pub const SECURITY_RESULT_STATUS_FAILED: u32 = 1; pub const SECURITY_RESULT_STATUS_FAILED_TOO_MANY_ATTEMPTS: u32 = 2; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClientInit { pub shared_flag: u8, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ServerInit { pub framebuffer_width: u16_be, pub framebuffer_height: u16_be, @@ -71,7 +72,7 @@ pub struct ServerInit { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PixelFormat { pub bits_per_pixel: u8, pub depth: u8, @@ -97,7 +98,7 @@ pub const CS_MESSAGE_CLIENT_CUT_TEXT: u8 = 6; pub const CS_MESSAGE_QEMU: u8 = 255; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetPixelFormat { pub message_type: u8, pub padding: [u8; 3], @@ -105,7 +106,7 @@ pub struct SetPixelFormat { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetEncodings { pub message_type: u8, pub padding: u8, @@ -128,7 +129,7 @@ pub const ENCODING_TYPE_DESKTOP_SIZE: u32 = -223i32 as u32; pub const ENCODING_TYPE_QEMU_EXTENDED_KEY_EVENT: u32 = -258i32 as u32; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FramebufferUpdateRequest { pub message_type: u8, pub incremental: u8, @@ -139,7 +140,7 @@ pub struct FramebufferUpdateRequest { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct KeyEvent { pub message_type: u8, pub down_flag: u8, @@ -148,7 +149,7 @@ pub struct KeyEvent { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct PointerEvent { pub message_type: u8, pub button_mask: u8, @@ -157,7 +158,7 @@ pub struct PointerEvent { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ClientCutText { pub message_type: u8, pub padding: [u8; 3], @@ -173,7 +174,7 @@ pub const SC_MESSAGE_TYPE_BELL: u8 = 2; pub const SC_MESSAGE_TYPE_SERVER_CUT_TEXT: u8 = 3; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct FramebufferUpdate { pub message_type: u8, pub padding: u8, @@ -182,7 +183,7 @@ pub struct FramebufferUpdate { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Rectangle { pub x: u16_be, pub y: u16_be, @@ -193,7 +194,7 @@ pub struct Rectangle { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct SetColorMapEntries { pub message_type: u8, pub padding: u8, @@ -203,7 +204,7 @@ pub struct SetColorMapEntries { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Color { pub red: u16_be, pub green: u16_be, @@ -211,13 +212,13 @@ pub struct Color { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct Bell { pub message_type: u8, } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct ServerCutText { pub message_type: u8, pub padding: [u8; 3], @@ -226,7 +227,7 @@ pub struct ServerCutText { } #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QemuMessageHeader { pub message_type: u8, pub submessage_type: u8, @@ -235,7 +236,7 @@ pub struct QemuMessageHeader { pub const QEMU_MESSAGE_EXTENDED_KEY_EVENT: u8 = 0; #[repr(C)] -#[derive(Copy, Clone, Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)] pub struct QemuExtendedKeyEvent { pub message_type: u8, pub submessage_type: u8, diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 4a907bd3d8..a6771dbed7 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -30,7 +30,6 @@ walkdir.workspace = true which.workspace = true xshell.workspace = true zerocopy.workspace = true - ci_logger.workspace = true clap_dyn_complete.workspace = true guid.workspace = true diff --git a/xtask/src/tasks/guest_test/uefi/gpt_efi_disk.rs b/xtask/src/tasks/guest_test/uefi/gpt_efi_disk.rs index dd8f8f2f2b..35a0a4badd 100644 --- a/xtask/src/tasks/guest_test/uefi/gpt_efi_disk.rs +++ b/xtask/src/tasks/guest_test/uefi/gpt_efi_disk.rs @@ -10,7 +10,7 @@ use guid::Guid; use std::io::Cursor; use std::io::Seek; use std::path::Path; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; const SECTOR_SIZE: usize = 512; const EFI_GUID: Guid = Guid::from_static_str("{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}"); From 5089cc17ff90152be11238e2e421c907ab4fa162 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Wed, 29 Jan 2025 13:40:18 -0800 Subject: [PATCH 02/14] Remove helper scripts --- rules/.gitkeep | 0 rules/cargo-toml-fixups.pl | 24 ------ rules/fixup_read_from_prefix_split.pl | 97 ------------------------- rules/remove-from-zeroes.yaml | 24 ------ rules/replace-asbytes-derive-macro.yaml | 29 -------- rules/replace-asbytes-derive.yaml | 29 -------- rules/replace-use-asbytes.yml | 11 --- rules/unwrap-header-for-x64.rs.pl | 24 ------ sgconfig.yml | 2 - 9 files changed, 240 deletions(-) delete mode 100644 rules/.gitkeep delete mode 100644 rules/cargo-toml-fixups.pl delete mode 100644 rules/fixup_read_from_prefix_split.pl delete mode 100644 rules/remove-from-zeroes.yaml delete mode 100644 rules/replace-asbytes-derive-macro.yaml delete mode 100644 rules/replace-asbytes-derive.yaml delete mode 100644 rules/replace-use-asbytes.yml delete mode 100644 rules/unwrap-header-for-x64.rs.pl delete mode 100644 sgconfig.yml diff --git a/rules/.gitkeep b/rules/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/rules/cargo-toml-fixups.pl b/rules/cargo-toml-fixups.pl deleted file mode 100644 index 8de69b9b4f..0000000000 --- a/rules/cargo-toml-fixups.pl +++ /dev/null @@ -1,24 +0,0 @@ -use strict; -use warnings; -use diagnostics; - -# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; - -# Check if filename is provided -if (@ARGV != 1) { - die "Usage: $0 filename\n"; -} - -my $filename = $ARGV[0]; - -# Open the file for reading -open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; - -# Read the entire file content into a single string -my $content = do { local $/; <$fh> }; -close $fh; - -$content =~ s/zerocopy_helpers.workspace = true[\r\n]//g; - -# Print the updated content -print $content; diff --git a/rules/fixup_read_from_prefix_split.pl b/rules/fixup_read_from_prefix_split.pl deleted file mode 100644 index 3604ad1d9c..0000000000 --- a/rules/fixup_read_from_prefix_split.pl +++ /dev/null @@ -1,97 +0,0 @@ -use strict; -use warnings; -use diagnostics; - -# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; - -# Check if filename is provided -if (@ARGV != 1) { - die "Usage: $0 filename\n"; -} - -my $filename = $ARGV[0]; - -# Open the file for reading -open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; - -# Read the entire file content into a single string -my $content = do { local $/; <$fh> }; -close $fh; - -# Apply regex substitutions -# 127,128c127,128 -# < let (vendor_guid, path_data) = Guid::read_from_prefix_split(path_data) -# < .ok_or(Error::InvalidLength)?; -# --- -# > let (vendor_guid, path_data) = Guid::read_from_prefix(path_data) -# > .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err -# 248c248 -$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.ok_or\(([^)]+)\)([;]?)([?]?)([;)]?)/read_from_prefix($1).map_err(|_| $2)$3$4$5 \/\/ todo: zerocopy: map_err/g; - -# - let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix_split(self.buf) -# - .expect("buf size validated in `new`"); -# --- -# + let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix(self.buf) -# + .expect("buf size validated in `new`"); // TODO: zerocopy: expect -$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.expect\(([^)]+)\)([;]?)/read_from_prefix($1).expect($2)$3 \/\/ TODO: zerocopy: expect/g; - -# - boot::EfiExpandedAcpiDevice::read_from_prefix_split(path_data) -# - .unwrap(); -# + boot::EfiExpandedAcpiDevice::read_from_prefix(path_data) -# + .unwrap(); // TODO: zerocopy: unwrap -$content =~ s/read_from_prefix_split\(([^)]+)\)\s*\.unwrap\(\)([;]?)/read_from_prefix($1).unwrap()$2 \/\/ TODO: zerocopy: unwrap/g; - -# Adjust use statements: -# * rename AsBytes -> IntoBytes -# * add KnownLayout, Immutable, FromZeros -# * remove references to FromZeroes -# -# We can't just replace FromZeroes -> FromZeros: each module that calls T::from_zeroes now needs to use `zerocopy::FromZeros`, which -# was not true for `zerocopy::FromZeroes`. -$content =~ s/use zerocopy::AsBytes;/use zerocopy::IntoBytes; use zerocopy::Immutable; use zerocopy::KnownLayout; use zerocopy::FromZeros;/g; -$content =~ s/use zerocopy::FromZeroes;[\r\n]//g; - -# Fixup derive(...FromZeroes...) (remove FromZeroes; it is no longer needed in zerocopy 0.8) -# But, if the *only* derive is FromZeroes, replace that with the standard zerocopy 0.8 derives. -$content =~ s/derive\(FromZeroes\)/derive(FromZeros, Immutable, KnownLayout)/g; -$content =~ s/(derive\(.*)\s*FromZeroes[,]?\s*([^)]*)/$1$2/g; - -# Now rename FromZeroes -> FromZeros (for example, for cases where smallvec![FromZeroes::new_zeroed(); len]) -$content =~ s/FromZeroes/FromZeros/g; - -# Fixup derive(...AsBytes...) (rename AsBytes -> IntoBytes, add Immutable, KnownLayout) -$content =~ s/(derive\(.*)\s*AsBytes([,]?)\s*([^)]*)/$1IntoBytes, Immutable, KnownLayout$2$3/g; - -# Fixup type bounds to include Immutable and KnownLayout if IntoBytes or FromBytes are present -#$content =~ s/([^\:][\:][^\:][^,>)]*AsBytes[^,>)]*|[^\:][\:][^\:][^,>)]*FromBytes([^,>)]*))/add_immutable_knownlayout_bounds($1)/egx; -$content =~ s/([^\:][\:][^\:][^,>){;]*AsBytes[^,>){]*|[^\:][\:][^\:][^,>){;]*FromBytes[^,>){]*)([>,){])/add_immutable_knownlayout_bounds($1, $2)/egx; - -sub add_immutable_knownlayout_bounds { - my ($bounds, $suffix) = @_; - $bounds .= ' + Immutable' unless $bounds =~ /Immutable/; - $bounds .= ' + KnownLayout' unless $bounds =~ /KnownLayout/; - return "$bounds$suffix"; -} - -$content =~ s/([^\:]\:[^\),>]*)AsBytes([^\),>]*)/$1IntoBytes$2/g; - -# Add .0 to read_from_prefix calls, e.g. -# let hdr = GpaRange::read_from_prefix(self.buf[0].as_bytes()).unwrap(); -$content =~ s/(read_from_prefix\(.*\.unwrap\(\))[^\.][^0](;?)/$1.0$2 \/\/ todo: zerocopy: use-rest-of-range/g; - -# let fh = EFI_FFS_FILE_HEADER::read_from_prefix(&image[image_offset as usize..])?; -$content =~ s/(read_from_prefix\([^)]*\))(\?)(;?)/$1.ok()$2.0$3 \/\/ todo: zerocopy: use-rest-of-range, option-to-error/g; - -$content =~ s/(read_from_prefix\([^)]*\)\s*)\.ok_or\(([^)]*\))([?]?)([;)]?)/$1.map_err(|_| $2$3.0$4 \/\/ todo: zerocopy: map_err/g; - -# < *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]).unwrap() = XsaveHeader { -# > *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]).unwrap().0 = XsaveHeader { // todo: zerocopy: mut-from-prefix unwrap -$content =~ s/((mut_from_prefix|read_from_prefix)\((?:[^)(]|\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\))*\)[\n\s]*.unwrap\(\))[^\.][^0]([^\n;]*)(;?)/$1.0$3$4 \/\/ todo: zerocopy: from-prefix ($2): use-rest-of-range/g; - -$content =~ s/(ref_from_prefix\(.*\.unwrap\(\))(;?)/$1.0$2 \/\/ todo: zerocopy: ref-from-prefix: use-rest-of-range/g; - - -$content =~ s/([\w_]+)\.into_ref\(\)/Ref::into_ref($1)/g; - -# Print the updated content -print $content; diff --git a/rules/remove-from-zeroes.yaml b/rules/remove-from-zeroes.yaml deleted file mode 100644 index 675aa44efa..0000000000 --- a/rules/remove-from-zeroes.yaml +++ /dev/null @@ -1,24 +0,0 @@ -id: remove-from-zeroes -language: rust -rule: - all: - - pattern: - context: "#[derive($$$ARGS)]" - selector: attribute -transform: - ARGS_NO_FROMZEROES: - replace: - source: $$$ARGS - replace: FromZeroes, - by: "" - COMMA_FIXUPS: - replace: - source: $ARGS_NO_FROMZEROES - replace: ", FromZeroes" - by: "" - COMMA_FIXUPS_2: - replace: - source: $COMMA_FIXUPS - replace: "FromZeroes" - by: "" -fix: 'derive($COMMA_FIXUPS_2)' diff --git a/rules/replace-asbytes-derive-macro.yaml b/rules/replace-asbytes-derive-macro.yaml deleted file mode 100644 index e405a3a4f1..0000000000 --- a/rules/replace-asbytes-derive-macro.yaml +++ /dev/null @@ -1,29 +0,0 @@ -id: replace-asbytes-derive-macro -language: rust -rule: - all: - - pattern: - context: "#[derive($$$ARGS)]" - selector: token_tree -transform: - ARGS_NO_ASBYTES: - replace: - source: $$$ARGS - replace: AsBytes - by: IntoBytes, Immutable, KnownLayout - ARGS_NO_FROMZEROES: - replace: - source: $ARGS_NO_ASBYTES - replace: FromZeroes, - by: "" - COMMA_FIXUPS: - replace: - source: $ARGS_NO_FROMZEROES - replace: ", FromZeroes" - by: "" - COMMA_FIXUPS_2: - replace: - source: $COMMA_FIXUPS - replace: "FromZeroes" - by: "" -fix: '($COMMA_FIXUPS_2)' diff --git a/rules/replace-asbytes-derive.yaml b/rules/replace-asbytes-derive.yaml deleted file mode 100644 index 4b5463de34..0000000000 --- a/rules/replace-asbytes-derive.yaml +++ /dev/null @@ -1,29 +0,0 @@ -id: replace-asbytes-derive -language: rust -rule: - all: - - pattern: - context: "#[derive($$$ARGS)]" - selector: attribute -transform: - ARGS_NO_ASBYTES: - replace: - source: $$$ARGS - replace: AsBytes - by: IntoBytes, Immutable, KnownLayout - ARGS_NO_FROMZEROES: - replace: - source: $ARGS_NO_ASBYTES - replace: FromZeroes, - by: "" - COMMA_FIXUPS: - replace: - source: $ARGS_NO_FROMZEROES - replace: ", FromZeroes" - by: "" - COMMA_FIXUPS_2: - replace: - source: $COMMA_FIXUPS - replace: "FromZeroes" - by: "" -fix: 'derive($COMMA_FIXUPS_2)' diff --git a/rules/replace-use-asbytes.yml b/rules/replace-use-asbytes.yml deleted file mode 100644 index d85cda7d22..0000000000 --- a/rules/replace-use-asbytes.yml +++ /dev/null @@ -1,11 +0,0 @@ -id: replace-use-asbytes -language: rust -rule: - pattern: use zerocopy::AsBytes; -fix: |- - use zerocopy::IntoBytes; - use zerocopy::Immutable; - use zerocopy::KnownLayout; - use zerocopy::FromZeros; - -#--- diff --git a/rules/unwrap-header-for-x64.rs.pl b/rules/unwrap-header-for-x64.rs.pl deleted file mode 100644 index 2df0f4bbbd..0000000000 --- a/rules/unwrap-header-for-x64.rs.pl +++ /dev/null @@ -1,24 +0,0 @@ -use strict; -use warnings; -use diagnostics; - -# USAGE: find . -iname "*.rs" -execdir sh -c 'perl ~/openvmm/rules/fixup_read_from_prefix_split.pl {} | sponge {}' \; - -# Check if filename is provided -if (@ARGV != 1) { - die "Usage: $0 filename\n"; -} - -my $filename = $ARGV[0]; - -# Open the file for reading -open my $fh, '<', $filename or die "Could not open '$filename' for reading: $!\n"; - -# Read the entire file content into a single string -my $content = do { local $/; <$fh> }; -close $fh; - -$content =~ s/\.unwrap\(\)(\s*)\.header/.unwrap().0$1.header/gm; - -# Print the updated content -print $content; diff --git a/sgconfig.yml b/sgconfig.yml deleted file mode 100644 index 96c1084251..0000000000 --- a/sgconfig.yml +++ /dev/null @@ -1,2 +0,0 @@ -ruleDirs: -- rules From 3794658eccb61e6654e839228510b1005513b662 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Wed, 29 Jan 2025 14:35:27 -0800 Subject: [PATCH 03/14] CI fixups --- openhcl/minimal_rt/src/arch/aarch64/hypercall.rs | 1 - support/pal/pal_async/src/windows/overlapped.rs | 1 - support/safeatomic/src/lib.rs | 4 ++-- vm/devices/net/vmswitch/src/dio.rs | 1 - vm/devices/support/fs/lxutil/src/windows/mod.rs | 1 - vm/devices/vmbus/vmbus_proxy/src/lib.rs | 5 +---- vm/devices/vmbus/vmbus_server/src/proxyintegration.rs | 3 --- vm/vmgs/vmgs/src/encrypt/win.rs | 2 +- vm/whp/src/lib.rs | 1 - 9 files changed, 4 insertions(+), 15 deletions(-) diff --git a/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs b/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs index 2cf9088125..8e73cde736 100644 --- a/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs +++ b/openhcl/minimal_rt/src/arch/aarch64/hypercall.rs @@ -45,7 +45,6 @@ use hvdef::HvRegisterName; use hvdef::HvRegisterValue; use hvdef::HvResult; use zerocopy::FromBytes; -use zerocopy::FromZeros; use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/support/pal/pal_async/src/windows/overlapped.rs b/support/pal/pal_async/src/windows/overlapped.rs index 333cf5f9a1..dc889dfb84 100644 --- a/support/pal/pal_async/src/windows/overlapped.rs +++ b/support/pal/pal_async/src/windows/overlapped.rs @@ -27,7 +27,6 @@ use winapi::um::ioapiset::CancelIoEx; use winapi::um::ioapiset::DeviceIoControl; use winapi::um::minwinbase::OVERLAPPED; use zerocopy::FromBytes; -use zerocopy::FromZeros; use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/support/safeatomic/src/lib.rs b/support/safeatomic/src/lib.rs index e23e3742d0..27a234b48b 100644 --- a/support/safeatomic/src/lib.rs +++ b/support/safeatomic/src/lib.rs @@ -20,7 +20,7 @@ pub trait AsAtomicBytes: IntoBytes + FromBytes + Immutable + KnownLayout { /// Casts the type to a slice of atomic bytes. fn as_atomic_bytes(&mut self) -> &[AtomicU8] { // SAFETY: IntoBytes guarantees that Self can be cast to a byte slice. - // And since we have exclusive ownership of self + Immutable + KnownLayout, it should be safe to + // And since we have exclusive ownership of self, it should be safe to // cast to an atomic byte slice (which can then be used by multiple // threads safely). // FromBytes guarantees that any value then assigned to these bytes @@ -63,7 +63,7 @@ unsafe impl Atomic for atomic::AtomicI64 {} pub trait AtomicSliceOps { /// # Safety /// The caller must ensure that `dest..dest+len` is a - /// [valid](core::ptr#safety + Immutable + KnownLayout) target for writes. + /// [valid](core::ptr#safety) target for writes. unsafe fn atomic_read_ptr(&self, dest: *mut u8, len: usize); /// # Safety diff --git a/vm/devices/net/vmswitch/src/dio.rs b/vm/devices/net/vmswitch/src/dio.rs index 7e95688b3e..7a7a8489c1 100644 --- a/vm/devices/net/vmswitch/src/dio.rs +++ b/vm/devices/net/vmswitch/src/dio.rs @@ -33,7 +33,6 @@ use winapi::um::ioapiset::CancelIo; use winapi::um::synchapi::WaitForSingleObject; use winapi::um::winbase::INFINITE; use zerocopy::FromBytes; -use zerocopy::FromZeros; use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/vm/devices/support/fs/lxutil/src/windows/mod.rs b/vm/devices/support/fs/lxutil/src/windows/mod.rs index 56d57fda90..0080f75244 100644 --- a/vm/devices/support/fs/lxutil/src/windows/mod.rs +++ b/vm/devices/support/fs/lxutil/src/windows/mod.rs @@ -32,7 +32,6 @@ use winapi::shared::ntdef; use winapi::shared::ntstatus; use winapi::um::winnt; use zerocopy::FromBytes; -use zerocopy::FromZeros; use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/vm/devices/vmbus/vmbus_proxy/src/lib.rs b/vm/devices/vmbus/vmbus_proxy/src/lib.rs index 3d95c8656f..e45d3fb49f 100644 --- a/vm/devices/vmbus/vmbus_proxy/src/lib.rs +++ b/vm/devices/vmbus/vmbus_proxy/src/lib.rs @@ -30,10 +30,7 @@ use winapi::shared::winerror::ERROR_CANCELLED; use winapi::um::ioapiset::DeviceIoControl; use winapi::um::winnt::GENERIC_ALL; use winapi::um::winnt::SYNCHRONIZE; -use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; pub mod vmbusioctl { #![allow( @@ -97,7 +94,7 @@ mod proxyioctl { use winapi::um::winioctl::FILE_READ_ACCESS; use winapi::um::winioctl::FILE_WRITE_ACCESS; use winapi::um::winioctl::METHOD_BUFFERED; - use zerocopy::FromZeros; + use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs b/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs index 8364c1ca19..254ec058cd 100644 --- a/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs +++ b/vm/devices/vmbus/vmbus_server/src/proxyintegration.rs @@ -43,10 +43,7 @@ use vmbus_proxy::ProxyAction; use vmbus_proxy::VmbusProxy; use vmcore::interrupt::Interrupt; use winapi::shared::winerror::ERROR_CANCELLED; -use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; pub struct ProxyIntegration { cancel: Cancel, diff --git a/vm/vmgs/vmgs/src/encrypt/win.rs b/vm/vmgs/vmgs/src/encrypt/win.rs index 567f6fa8b2..3e2f20b524 100644 --- a/vm/vmgs/vmgs/src/encrypt/win.rs +++ b/vm/vmgs/vmgs/src/encrypt/win.rs @@ -24,7 +24,7 @@ use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB; use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB_MAGIC; use windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB_VERSION1; use windows::Win32::Security::Cryptography::BCRYPT_KEY_HANDLE; -use zerocopy::IntoBytes; use zerocopy::Immutable; use zerocopy::KnownLayout; use zerocopy::FromZeros; +use zerocopy::IntoBytes; use zerocopy::Immutable; use zerocopy::KnownLayout; // BCryptImportKey expects a key header immediately followed by a key of size key_len #[repr(C)] diff --git a/vm/whp/src/lib.rs b/vm/whp/src/lib.rs index c4ccbefef4..ee52d45796 100644 --- a/vm/whp/src/lib.rs +++ b/vm/whp/src/lib.rs @@ -29,7 +29,6 @@ use winapi::shared::ntdef::LUID; use winapi::shared::winerror; use winapi::um::winnt::DEVICE_POWER_STATE; use winerror::ERROR_BAD_PATHNAME; -use zerocopy::FromZeros; use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; From f5242eb8ab9458afb322273d35e4c322fd9c268f Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Wed, 29 Jan 2025 14:53:14 -0800 Subject: [PATCH 04/14] ci fixes --- .../virt_mshv_vtl/src/processor/mshv/arm64.rs | 28 +++++++++++-------- support/mesh/mesh_remote/src/alpc_node.rs | 8 +++--- vm/devices/get/get_protocol/src/lib.rs | 2 +- .../pci_core/src/capabilities/read_only.rs | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs index 5bb87e12a1..c58fd53070 100644 --- a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs +++ b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs @@ -53,9 +53,7 @@ use virt_support_aarch64emu::emulate::EmuTranslateResult; use virt_support_aarch64emu::emulate::EmulatorSupport; use zerocopy::FromBytes; use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; /// A backing for hypervisor-backed partitions (non-isolated and /// software-isolated). @@ -164,7 +162,8 @@ impl BackingPrivate for HypervisorBackedArm64 { let message = hvdef::HvArm64ResetInterceptMessage::ref_from_prefix( this.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: err, use-rest-of-range match message.reset_type { HvArm64ResetType::POWER_OFF => return Err(VpHaltReason::PowerOff), HvArm64ResetType::REBOOT => return Err(VpHaltReason::Reset), @@ -236,7 +235,8 @@ impl UhProcessor<'_, HypervisorBackedArm64> { let message = hvdef::HvArm64SynicSintDeliverableMessage::ref_from_prefix( self.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: err, use-rest-of-range tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -261,7 +261,8 @@ impl UhProcessor<'_, HypervisorBackedArm64> { let message = hvdef::HvArm64HypercallInterceptMessage::ref_from_prefix( self.runner.exit_message().payload(), ) - .unwrap(); + .unwrap() + .0; // todo: zerocopy: err, use-rest-of-range tracing::trace!(msg = %format_args!("{:x?}", message), "hypercall"); @@ -293,8 +294,9 @@ impl UhProcessor<'_, HypervisorBackedArm64> { let message = hvdef::HvArm64MemoryInterceptMessage::ref_from_prefix( self.runner.exit_message().payload(), ) - .unwrap(); - // tracing::trace!(msg = %format_args!("{:x?}", message), "mmio"); + .unwrap() + .0; // todo: zerocopy: err, use-rest-of-range + // tracing::trace!(msg = %format_args!("{:x?}", message), "mmio"); let intercept_state = InterceptState { instruction_bytes: message.instruction_bytes, @@ -322,6 +324,7 @@ impl UhProcessor<'_, HypervisorBackedArm64> { self.runner.exit_message().payload(), ) .unwrap() + .0 // todo: zerocopy: err, use-rest-of-range .guest_physical_address; if self.partition.is_gpa_lower_vtl_ram(gpa) { @@ -523,10 +526,9 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedA HvMessageType::HvMessageTypeGpaIntercept | HvMessageType::HvMessageTypeUnmappedGpa | HvMessageType::HvMessageTypeUnacceptedGpa => { - let message = - hvdef::HvArm64MemoryInterceptMessage::ref_from_prefix(message.payload()) - .unwrap(); - Some(message.guest_physical_address) + hvdef::HvArm64MemoryInterceptMessage::ref_from_prefix(message.payload()) + .ok() + .map(|v| v.0.guest_physical_address) // todo: zerocopy: err, use-rest-of-range } _ => None, } @@ -543,7 +545,9 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedA let message = hvdef::HvArm64MemoryInterceptMessage::ref_from_prefix( self.vp.runner.exit_message().payload(), - )?; + ) + .ok()? + .0; // todo: zerocopy: err, use-rest-of-range if !message.memory_access_info.gva_gpa_valid() { tracing::trace!(?message.guest_virtual_address, ?message.guest_physical_address, "gva gpa not valid {:?}", self.vp.runner.exit_message().payload()); diff --git a/support/mesh/mesh_remote/src/alpc_node.rs b/support/mesh/mesh_remote/src/alpc_node.rs index c74bf44085..b8700f989f 100644 --- a/support/mesh/mesh_remote/src/alpc_node.rs +++ b/support/mesh/mesh_remote/src/alpc_node.rs @@ -56,9 +56,7 @@ use tracing_helpers::ErrorValueExt; use unicycle::FuturesUnordered; use zerocopy::FromBytes; use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; type InvitationMap = Arc)>>>; @@ -559,7 +557,8 @@ impl AlpcNode { .expect("port must exist"); match protocol::PacketHeader::read_from_prefix(buf) { - Some(header) => match header.packet_type { + Ok((header, _)) => match header.packet_type { + // todo: zerocopy: use-rest-of-range protocol::PacketType::EVENT => { local_node.event( connection.handle.id(), @@ -578,7 +577,8 @@ impl AlpcNode { tracing::error!(node = ?local_id, ?packet_type, "unknown packet type"); } }, - None => { + Err(_) => { + // todo: zerocopy: err tracing::error!(node = ?local_id, "invalid message"); } } diff --git a/vm/devices/get/get_protocol/src/lib.rs b/vm/devices/get/get_protocol/src/lib.rs index 40603db538..7e7482fe6a 100644 --- a/vm/devices/get/get_protocol/src/lib.rs +++ b/vm/devices/get/get_protocol/src/lib.rs @@ -162,7 +162,7 @@ open_enum! { } pub use header::*; -// UNSAFETY: The unsafe manual impl of AsBytes for HeaderGeneric +// UNSAFETY: The unsafe manual impl of IntoBytes for HeaderGeneric #[expect(unsafe_code)] pub mod header { use super::MessageTypes; diff --git a/vm/devices/pci/pci_core/src/capabilities/read_only.rs b/vm/devices/pci/pci_core/src/capabilities/read_only.rs index 6ec731e379..9d50571bf6 100644 --- a/vm/devices/pci/pci_core/src/capabilities/read_only.rs +++ b/vm/devices/pci/pci_core/src/capabilities/read_only.rs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! A generic, read-only PCI Capability (backed by an [`AsBytes`] type). +//! A generic, read-only PCI Capability (backed by an [`IntoBytes`] type). use super::PciCapability; use inspect::Inspect; From f008fca753d51d4b7451148a9393e06bb8d40f0a Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Wed, 29 Jan 2025 14:59:00 -0800 Subject: [PATCH 05/14] pr feedback: use commit hash for igvm --- Cargo.lock | 4 ++-- Cargo.toml | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4707a9a14d..267e45845b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,7 +3191,7 @@ dependencies = [ [[package]] name = "igvm" version = "0.3.4" -source = "git+https://github.com/microsoft/igvm?branch=main#365065d7e31da0a0116e7934de3ecd85f00bab70" +source = "git+https://github.com/microsoft/igvm?rev=365065d7e31da0a0116e7934de3ecd85f00bab70#365065d7e31da0a0116e7934de3ecd85f00bab70" dependencies = [ "bitfield-struct", "crc32fast", @@ -3208,7 +3208,7 @@ dependencies = [ [[package]] name = "igvm_defs" version = "0.3.4" -source = "git+https://github.com/microsoft/igvm?branch=main#365065d7e31da0a0116e7934de3ecd85f00bab70" +source = "git+https://github.com/microsoft/igvm?rev=365065d7e31da0a0116e7934de3ecd85f00bab70#365065d7e31da0a0116e7934de3ecd85f00bab70" dependencies = [ "bitfield-struct", "open-enum", diff --git a/Cargo.toml b/Cargo.toml index 2aee087334..2e33aaf3f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -435,12 +435,8 @@ iced-x86 = { version = "1.17", default-features = false, features = [ "no_d3now", ] } ignore = "0.4" -#igvm = "0.3.3" -igvm = {git = "https://github.com/microsoft/igvm", branch = "main"} -#igvm_defs = { version = "0.3.3", default-features = false, features = [ -# "unstable", -#] } -igvm_defs = {git = "https://github.com/microsoft/igvm", branch = "main", 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" From 94207daa5837756637f46df014cb9597ded5b943 Mon Sep 17 00:00:00 2001 From: Matt Kurjanowicz Date: Thu, 30 Jan 2025 08:32:15 -0800 Subject: [PATCH 06/14] windows build fixups --- vm/devices/vmbus/vmbus_proxy/src/lib.rs | 2 +- vmm_core/virt_whp/src/hypercalls.rs | 6 ++---- vmm_core/virt_whp/src/vp.rs | 5 ----- vmm_core/virt_whp/src/vp_state.rs | 3 +-- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/vm/devices/vmbus/vmbus_proxy/src/lib.rs b/vm/devices/vmbus/vmbus_proxy/src/lib.rs index e45d3fb49f..5641e077d4 100644 --- a/vm/devices/vmbus/vmbus_proxy/src/lib.rs +++ b/vm/devices/vmbus/vmbus_proxy/src/lib.rs @@ -94,7 +94,7 @@ mod proxyioctl { use winapi::um::winioctl::FILE_READ_ACCESS; use winapi::um::winioctl::FILE_WRITE_ACCESS; use winapi::um::winioctl::METHOD_BUFFERED; - + use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; diff --git a/vmm_core/virt_whp/src/hypercalls.rs b/vmm_core/virt_whp/src/hypercalls.rs index ddd7f84dfe..b1caa2e722 100644 --- a/vmm_core/virt_whp/src/hypercalls.rs +++ b/vmm_core/virt_whp/src/hypercalls.rs @@ -723,9 +723,7 @@ mod x86 { use whp::RegisterValue; use zerocopy::FromBytes; use zerocopy::FromZeros; - use zerocopy::Immutable; use zerocopy::IntoBytes; - use zerocopy::KnownLayout; pub(super) struct WhpHypercallRegisters<'a> { info: whp::abi::WHV_HYPERCALL_CONTEXT, @@ -1082,8 +1080,8 @@ mod x86 { match HvVpAssistPageActionSignalEvent::read_from_prefix( &actions[offset..], ) { - Some(v) => v, - None => break, + Ok((v, _)) => v, + Err(_) => break, // todo: zerocopy: err }; if let Err(err) = self.handle_action_signal_event(&signal_event) diff --git a/vmm_core/virt_whp/src/vp.rs b/vmm_core/virt_whp/src/vp.rs index be7295e470..c407de71e1 100644 --- a/vmm_core/virt_whp/src/vp.rs +++ b/vmm_core/virt_whp/src/vp.rs @@ -25,10 +25,7 @@ use virt::io::CpuIo; use virt::vp::AccessVpState; use virt::StopVp; use virt::VpHaltReason; -use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; #[derive(Debug, Error)] pub enum WhpRunVpError { @@ -598,9 +595,7 @@ mod x86 { use x86defs::cpuid::CpuidFunction; use x86defs::X86X_MSR_APIC_BASE; use zerocopy::FromZeros; - use zerocopy::Immutable; use zerocopy::IntoBytes; - use zerocopy::KnownLayout; // HACK: on certain machines, Windows booting from the PCAT BIOS spams these // MSRs during boot. diff --git a/vmm_core/virt_whp/src/vp_state.rs b/vmm_core/virt_whp/src/vp_state.rs index 693672de66..e2b1d6dfcd 100644 --- a/vmm_core/virt_whp/src/vp_state.rs +++ b/vmm_core/virt_whp/src/vp_state.rs @@ -11,6 +11,7 @@ use hvdef::HvRegisterValue; use hvdef::Vtl; use virt::state::HvRegisterState; use whp::abi::WHV_REGISTER_VALUE; +use zerocopy::FromZeros; pub struct WhpVpStateAccess<'a, 'b> { run: &'a mut WhpProcessor<'b>, @@ -75,9 +76,7 @@ mod x86 { use virt::x86::vp; use virt::x86::vp::AccessVpState; use zerocopy::FromZeros; - use zerocopy::Immutable; use zerocopy::IntoBytes; - use zerocopy::KnownLayout; impl AccessVpState for WhpVpStateAccess<'_, '_> { type Error = Error; From acad71a805cf8a2eedb60a4e01d290314b22b725 Mon Sep 17 00:00:00 2001 From: Matt Kurjanowicz Date: Thu, 30 Jan 2025 11:35:16 -0800 Subject: [PATCH 07/14] more ci fixups --- vm/devices/storage/storvsp/src/ioperf.rs | 3 --- vmm_core/virt_whp/src/hypercalls.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/vm/devices/storage/storvsp/src/ioperf.rs b/vm/devices/storage/storvsp/src/ioperf.rs index 013d5d6249..954e752add 100644 --- a/vm/devices/storage/storvsp/src/ioperf.rs +++ b/vm/devices/storage/storvsp/src/ioperf.rs @@ -18,10 +18,7 @@ use scsidisk::SimpleScsiDisk; use std::sync::Arc; use vmbus_async::queue::Queue; use vmbus_channel::connected_async_channels; -use zerocopy::FromZeros; -use zerocopy::Immutable; use zerocopy::IntoBytes; -use zerocopy::KnownLayout; pub struct PerfTester { _worker: TestWorker, diff --git a/vmm_core/virt_whp/src/hypercalls.rs b/vmm_core/virt_whp/src/hypercalls.rs index b1caa2e722..560ab22c1d 100644 --- a/vmm_core/virt_whp/src/hypercalls.rs +++ b/vmm_core/virt_whp/src/hypercalls.rs @@ -724,7 +724,6 @@ mod x86 { use zerocopy::FromBytes; use zerocopy::FromZeros; use zerocopy::IntoBytes; - pub(super) struct WhpHypercallRegisters<'a> { info: whp::abi::WHV_HYPERCALL_CONTEXT, rip: u64, @@ -1694,6 +1693,7 @@ mod aarch64 { use virt_support_aarch64emu::translate::TranslateFlags; use virt_support_aarch64emu::translate::TranslationRegisters; use whp::RegisterValue; + use zerocopy::FromZeros; pub(super) struct WhpHypercallRegisters<'a> { message: hvdef::HvArm64HypercallInterceptMessage, From bb65267561cbb368147a104af2c2226edcd55f4e Mon Sep 17 00:00:00 2001 From: Matt Kurjanowicz Date: Thu, 30 Jan 2025 12:44:06 -0800 Subject: [PATCH 08/14] pr feedback --- openhcl/openhcl_boot/src/hypercall.rs | 33 +++++++++++++++++-------- vm/devices/vmbus/vmbus_proxy/src/lib.rs | 1 - 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/openhcl/openhcl_boot/src/hypercall.rs b/openhcl/openhcl_boot/src/hypercall.rs index df6159710a..234baa4096 100644 --- a/openhcl/openhcl_boot/src/hypercall.rs +++ b/openhcl/openhcl_boot/src/hypercall.rs @@ -167,9 +167,10 @@ impl HvCall { rsvd: [0; 3], }; + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); let reg = hvdef::hypercall::HvRegisterAssoc { name, @@ -177,8 +178,9 @@ impl HvCall { value, }; + // PANIC: Infallable, since the hypercall parameter (plus size of header above) is less than the size of a page reg.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]) - .unwrap(); // PANIC: Infallable, since the hypercall parameter is less than the size of a page + .unwrap(); let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallSetVpRegisters, Some(1)); @@ -199,11 +201,13 @@ impl HvCall { rsvd: [0; 3], }; + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); + // PANIC: Infallable, since the hypercall parameter (plus size of header above) is less than the size of a page name.write_to_prefix(&mut Self::input_page().buffer[HEADER_SIZE..]) - .unwrap(); // PANIC: Infallable, since the hypercall payload is less than the size of a page + .unwrap(); let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallGetVpRegisters, Some(1)); output.result()?; @@ -231,16 +235,18 @@ impl HvCall { let remaining_pages = range.end_4k_gpn() - current_page; let count = remaining_pages.min(MAX_INPUT_ELEMENTS as u64); + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); let mut input_offset = HEADER_SIZE; for i in 0..count { let page_num = current_page + i; + // PANIC: Infallable, since the hypercall parameter (plus size of header above) is less than the size of a page page_num .write_to_prefix(&mut Self::input_page().buffer[input_offset..]) - .unwrap(); // PANIC: Infallable, since the hypercall data is less than the size of a page + .unwrap(); input_offset += size_of::(); } @@ -270,9 +276,10 @@ impl HvCall { vp_vtl_context: zerocopy::FromZeros::new_zeroed(), }; + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); let output = self.dispatch_hvcall(hvdef::HypercallCode::HvCallEnableVpVtl, None); match output.result() { @@ -309,9 +316,10 @@ impl HvCall { let remaining_pages = range.end_4k_gpn() - current_page; let count = remaining_pages.min(MAX_INPUT_ELEMENTS as u64); + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); let output = self.dispatch_hvcall( hvdef::HypercallCode::HvCallAcceptGpaPages, @@ -347,12 +355,17 @@ impl HvCall { const MAX_PER_CALL: usize = 512; for hw_ids in hw_ids.chunks(MAX_PER_CALL) { + // PANIC: Infallable, since the hypercall header is less than the size of a page header .write_to_prefix(Self::input_page().buffer.as_mut_slice()) - .unwrap(); // PANIC: Infallable, since the hypercall header is less than the size of a page + .unwrap(); + // PANIC: Infallable, since the hypercall parameters are chunked to be less + // than the remaining size (after the header) of the input page. + // todo: This is *not true* for aarch64, where the hw_ids are u64s. Tracked via + // https://github.com/microsoft/openvmm/issues/745 hw_ids .write_to_prefix(&mut Self::input_page().buffer[header.as_bytes().len()..]) - .unwrap(); // PANIC: Infallable, since the hypercall parameters are less than the size of a page + .unwrap(); // SAFETY: The input header and rep slice are the correct types for this hypercall. // The hypercall output is validated right after the hypercall is issued. diff --git a/vm/devices/vmbus/vmbus_proxy/src/lib.rs b/vm/devices/vmbus/vmbus_proxy/src/lib.rs index 5641e077d4..b47ab340c0 100644 --- a/vm/devices/vmbus/vmbus_proxy/src/lib.rs +++ b/vm/devices/vmbus/vmbus_proxy/src/lib.rs @@ -94,7 +94,6 @@ mod proxyioctl { use winapi::um::winioctl::FILE_READ_ACCESS; use winapi::um::winioctl::FILE_WRITE_ACCESS; use winapi::um::winioctl::METHOD_BUFFERED; - use zerocopy::Immutable; use zerocopy::IntoBytes; use zerocopy::KnownLayout; From c7be380ebde90e9e8fef78c17d99cb8d3b511b09 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Fri, 31 Jan 2025 13:14:47 -0800 Subject: [PATCH 09/14] bad merge --- vm/hv1/hv1_hypercall/src/support.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/hv1/hv1_hypercall/src/support.rs b/vm/hv1/hv1_hypercall/src/support.rs index 991d04c9d2..5737962238 100644 --- a/vm/hv1/hv1_hypercall/src/support.rs +++ b/vm/hv1/hv1_hypercall/src/support.rs @@ -575,7 +575,7 @@ where { /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&Hdr, &[In], &mut [Out]) { - let (header, rest) = Ref::<_, Hdr>::from_prefix(params.input).unwrap().unwrap(); + let (header, rest) = Ref::<_, Hdr>::from_prefix(params.input).unwrap(); let input = if size_of::() == 0 { &[] } else { From bf3c65ca3f3155d3fd0c7bad648935fb75eacf49 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Fri, 31 Jan 2025 22:32:20 +0000 Subject: [PATCH 10/14] formatting only pr feedback --- openhcl/openhcl_boot/src/hypercall.rs | 4 +- openhcl/sidecar/src/arch/x86_64/mod.rs | 2 +- openhcl/sidecar/src/arch/x86_64/vp.rs | 8 +- openhcl/sidecar_defs/src/lib.rs | 2 +- .../src/igvm_attest/ak_cert.rs | 2 +- openhcl/underhill_attestation/src/vmgs.rs | 12 +- openhcl/underhill_core/src/loader/mod.rs | 2 +- openhcl/underhill_crash/src/lib.rs | 4 +- .../virt_mshv_vtl/src/processor/mshv/arm64.rs | 14 +-- .../virt_mshv_vtl/src/processor/mshv/x64.rs | 64 +++++----- .../virt_mshv_vtl/src/processor/snp/mod.rs | 8 +- support/fdt/src/parser.rs | 18 +-- support/mesh/mesh_node/src/local_node.rs | 8 +- .../mesh/mesh_node/src/local_node/protocol.rs | 2 +- support/mesh/mesh_protobuf/src/encoding.rs | 2 +- support/mesh/mesh_remote/src/alpc_node.rs | 4 +- support/mesh/mesh_remote/src/protocol.rs | 2 +- support/mesh/mesh_remote/src/unix_node.rs | 4 +- vm/acpi_spec/src/aspt.rs | 2 +- vm/acpi_spec/src/madt.rs | 10 +- vm/acpi_spec/src/srat.rs | 8 +- .../firmware_pcat/src/root_cpu_data.rs | 2 +- .../firmware_uefi/src/service/event_log.rs | 4 +- .../src/service/nvram/spec_services/mod.rs | 2 +- .../hcl_compat_uefi_nvram_storage/src/lib.rs | 10 +- .../hyperv_uefi_custom_vars_json/src/lib.rs | 2 +- .../uefi_nvram_specvars/src/boot_order.rs | 18 +-- .../uefi_nvram_specvars/src/signature_list.rs | 6 +- vm/devices/get/guest_crash_device/src/lib.rs | 2 +- .../get/guest_emulation_device/src/lib.rs | 34 ++--- .../src/test_utilities.rs | 10 +- vm/devices/get/guest_emulation_log/src/lib.rs | 2 +- .../src/process_loop.rs | 24 ++-- vm/devices/hyperv_ic/src/shutdown.rs | 6 +- vm/devices/hyperv_ic_guest/src/shutdown.rs | 8 +- vm/devices/hyperv_ic_protocol/src/lib.rs | 4 +- vm/devices/net/gdma/src/bnic.rs | 2 +- vm/devices/net/gdma/src/hwc.rs | 2 +- vm/devices/net/gdma_defs/src/lib.rs | 6 +- vm/devices/net/mana_driver/src/gdma_driver.rs | 6 +- vm/devices/net/net_mana/src/lib.rs | 4 +- vm/devices/net/netvsp/src/lib.rs | 2 +- vm/devices/net/netvsp/src/protocol.rs | 6 +- vm/devices/net/netvsp/src/rndisprot.rs | 10 +- vm/devices/net/vmswitch/src/dio.rs | 2 +- vm/devices/pci/vpci/src/device.rs | 26 ++-- vm/devices/pci/vpci/src/protocol.rs | 34 ++--- .../serial/vmbus_serial_guest/src/lib.rs | 8 +- .../serial/vmbus_serial_host/src/lib.rs | 4 +- .../serial/vmbus_serial_protocol/src/lib.rs | 12 +- .../storage/disk_blockdevice/src/ioctl.rs | 2 +- .../storage/disk_blockdevice/src/nvme.rs | 8 +- .../disk_nvme/nvme_driver/src/driver.rs | 2 +- .../disk_nvme/nvme_driver/src/namespace.rs | 2 +- vm/devices/storage/ide/src/lib.rs | 4 +- vm/devices/storage/nvme/src/namespace.rs | 6 +- vm/devices/storage/nvme/src/workers/admin.rs | 2 +- vm/devices/storage/nvme_spec/src/nvm.rs | 2 +- vm/devices/storage/scsi_defs/src/lib.rs | 10 +- vm/devices/storage/scsi_defs/src/srb.rs | 2 +- vm/devices/storage/scsidisk/src/atapi_scsi.rs | 4 +- .../storage/scsidisk/src/getlbastatus.rs | 2 +- vm/devices/storage/scsidisk/src/inquiry.rs | 2 +- vm/devices/storage/scsidisk/src/lib.rs | 40 +++--- .../storage/scsidisk/src/reservation.rs | 4 +- .../storage/scsidisk/src/scsidvd/mod.rs | 42 +++---- vm/devices/storage/scsidisk/src/unmap.rs | 8 +- vm/devices/storage/storvsp/src/lib.rs | 2 +- vm/devices/storage/storvsp/src/protocol.rs | 4 +- vm/devices/tpm/src/lib.rs | 10 +- vm/devices/tpm/src/tpm20proto.rs | 116 +++++++++--------- vm/devices/uidevices/src/keyboard/mod.rs | 12 +- vm/devices/uidevices/src/mouse/mod.rs | 12 +- vm/devices/uidevices/src/video/mod.rs | 18 +-- vm/devices/virtio/virtio_net/src/lib.rs | 2 +- vm/devices/vmbus/vmbfs/src/lib.rs | 8 +- vm/devices/vmbus/vmbfs/src/protocol.rs | 8 +- vm/devices/vmbus/vmbus_async/src/queue.rs | 2 +- vm/devices/vmbus/vmbus_core/src/protocol.rs | 4 +- .../vmbus/vmbus_core/src/protocol/macros.rs | 4 +- vm/devices/vmbus/vmbus_ring/src/gparange.rs | 2 +- vm/devices/vmbus/vmbus_server/src/channels.rs | 2 +- vm/devices/vmbus/vmbus_server/src/lib.rs | 6 +- vm/hv1/hv1_hypercall/src/support.rs | 22 ++-- vm/hv1/hv1_hypercall/src/tests.rs | 2 +- vm/hv1/hvdef/src/lib.rs | 42 +++---- vm/loader/igvmfilegen/src/file_loader.rs | 2 +- vm/loader/igvmfilegen/src/main.rs | 2 +- vm/loader/loader_defs/src/linux.rs | 2 +- vm/loader/loader_defs/src/paravisor.rs | 2 +- vm/loader/loader_defs/src/shim.rs | 2 +- vm/loader/src/uefi/mod.rs | 14 +-- vm/vmgs/vmgs/src/vmgs_impl.rs | 8 +- vm/vmgs/vmgs_format/src/lib.rs | 2 +- vmm_core/virt/src/x86/vp.rs | 10 +- vmm_core/virt_whp/src/hypercalls.rs | 2 +- vmm_core/virt_whp/src/vp.rs | 8 +- 97 files changed, 457 insertions(+), 457 deletions(-) diff --git a/openhcl/openhcl_boot/src/hypercall.rs b/openhcl/openhcl_boot/src/hypercall.rs index 81ca02ecbb..6cb004e736 100644 --- a/openhcl/openhcl_boot/src/hypercall.rs +++ b/openhcl/openhcl_boot/src/hypercall.rs @@ -213,7 +213,7 @@ impl HvCall { output.result()?; let value = hvdef::HvRegisterValue::read_from_prefix(&Self::output_page().buffer) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) Ok(value) } @@ -373,7 +373,7 @@ impl HvCall { ); let n = r.elements_processed(); - //todo: zerocopy: review carefully! + //TODO: zerocopy: review carefully! (https://github.com/microsoft/openvmm/issues/759) output.extend( <[u32]>::ref_from_bytes(&Self::output_page().buffer[..n * 4]) .unwrap() diff --git a/openhcl/sidecar/src/arch/x86_64/mod.rs b/openhcl/sidecar/src/arch/x86_64/mod.rs index d9bd9574e2..a731eb35b7 100644 --- a/openhcl/sidecar/src/arch/x86_64/mod.rs +++ b/openhcl/sidecar/src/arch/x86_64/mod.rs @@ -257,7 +257,7 @@ fn get_hv_vp_register( hypercall(HypercallCode::HvCallGetVpRegisters, 1)?; // SAFETY: the output is not concurrently accessed. let output = unsafe { &*addr_space::hypercall_output() }; - Ok(HvRegisterValue::read_from_prefix(output).unwrap().0) // todo: zerocopy: use-rest-of-range + Ok(HvRegisterValue::read_from_prefix(output).unwrap().0) // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } fn set_hv_vp_register( diff --git a/openhcl/sidecar/src/arch/x86_64/vp.rs b/openhcl/sidecar/src/arch/x86_64/vp.rs index 80bca3f321..0d28c6f671 100644 --- a/openhcl/sidecar/src/arch/x86_64/vp.rs +++ b/openhcl/sidecar/src/arch/x86_64/vp.rs @@ -407,7 +407,7 @@ fn get_vp_registers(command_page: &mut CommandPage) { } = FromBytes::mut_from_bytes(request).unwrap(); let Ok((regs, _)) = <[HvRegisterAssoc]>::mut_from_prefix_with_elems(regs, count.into()) else { - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) set_error( command_page, format_args!("invalid register name count: {count}"), @@ -458,7 +458,7 @@ fn set_vp_registers(command_page: &mut CommandPage) { } = FromBytes::mut_from_bytes(request).unwrap(); let Ok((assoc, _)) = <[HvRegisterAssoc]>::ref_from_prefix_with_elems(regs, count.into()) else { - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) set_error( command_page, format_args!("invalid register count: {count}"), @@ -496,7 +496,7 @@ fn translate_gva(command_page: &mut CommandPage) { let TranslateGvaRequest { gvn, control_flags } = FromBytes::read_from_prefix(command_page.request_data.as_bytes()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) { // SAFETY: the input page is not concurrently accessed. let input = unsafe { &mut *addr_space::hypercall_input() }; @@ -517,7 +517,7 @@ fn translate_gva(command_page: &mut CommandPage) { Ok(()) => { // SAFETY: the output is not concurrently accessed let output = unsafe { &*addr_space::hypercall_output() }; - (HvError(0), FromBytes::read_from_prefix(output).unwrap().0) // todo: zerocopy: use-rest-of-range + (HvError(0), FromBytes::read_from_prefix(output).unwrap().0) // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } Err(err) => (err, FromZeros::new_zeroed()), }; diff --git a/openhcl/sidecar_defs/src/lib.rs b/openhcl/sidecar_defs/src/lib.rs index 8d3462964d..f9a27c3b68 100644 --- a/openhcl/sidecar_defs/src/lib.rs +++ b/openhcl/sidecar_defs/src/lib.rs @@ -186,7 +186,7 @@ const _: () = assert!(size_of::() == PAGE_SIZE); open_enum! { /// The sidecar command. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SidecarCommand: u32 { /// No command. NONE = 0, diff --git a/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs b/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs index b6e5ebe0c7..f1d66054de 100644 --- a/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs +++ b/openhcl/underhill_attestation/src/igvm_attest/ak_cert.rs @@ -34,7 +34,7 @@ pub fn parse_response(response: &[u8]) -> Result, AkCertError> { .map_err(|_| AkCertError::SizeTooSmall { size: response.len(), minimum_size: HEADER_SIZE, - })? // todo: zerocopy: map_err + })? // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) .0; let size = header.data_size as usize; diff --git a/openhcl/underhill_attestation/src/vmgs.rs b/openhcl/underhill_attestation/src/vmgs.rs index 6d17a65833..1df8ef4e13 100644 --- a/openhcl/underhill_attestation/src/vmgs.rs +++ b/openhcl/underhill_attestation/src/vmgs.rs @@ -98,7 +98,7 @@ pub async fn read_key_protector( // read_from_prefix expects input bytes to be larger than or equal to size_of::() KeyProtector::read_from_prefix(&data[..]) .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id)) - .map(|k| k.0) // todo: zerocopy: map_err + .map(|k| k.0) // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } Err(vmgs::Error::FileInfoAllocated) => Ok(KeyProtector::new_zeroed()), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { vmgs_err, file_id }), @@ -128,13 +128,13 @@ pub async fn read_key_protector_by_id( let file_id = FileId::VM_UNIQUE_ID; match vmgs.read_file(file_id).await { Ok(data) => match KeyProtectorById::read_from_prefix(&data[..]) - .ok() // todo: zerocopy: ok + .ok() // TODO: zerocopy: ok (https://github.com/microsoft/openvmm/issues/759) .map(|k| k.0) { Some(key_protector_by_id) => Ok(key_protector_by_id), None => { let id_guid = Guid::read_from_prefix(&data[..]) - .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? // todo: zerocopy: map_err + .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) .0; Ok(KeyProtectorById { @@ -195,7 +195,7 @@ pub async fn read_security_profile(vmgs: &mut Vmgs) -> Result() Ok(SecurityProfile::read_from_prefix(&data[..]) .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? - .0) // todo: zerocopy: map_err + .0) // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } Err(vmgs::Error::FileInfoAllocated) => Ok(SecurityProfile::new_zeroed()), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { file_id, vmgs_err })?, @@ -224,7 +224,7 @@ pub async fn read_hardware_key_protector( HardwareKeyProtector::read_from_prefix(&data) .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id)) - .map(|k| k.0) // todo: zerocopy: map_err + .map(|k| k.0) // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } /// Write Key Protector Id (current Id) to the VMGS file. @@ -263,7 +263,7 @@ pub async fn read_guest_secret_key(vmgs: &mut Vmgs) -> Result() Ok(GuestSecretKey::read_from_prefix(&data[..]) .map_err(|_| ReadFromVmgsError::InvalidFormat(file_id))? - .0) // todo: zerocopy: map_err + .0) // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } Err(vmgs::Error::FileInfoAllocated) => Err(ReadFromVmgsError::EntryNotFound(file_id)), Err(vmgs_err) => Err(ReadFromVmgsError::ReadFromVmgs { file_id, vmgs_err }), diff --git a/openhcl/underhill_core/src/loader/mod.rs b/openhcl/underhill_core/src/loader/mod.rs index bb73fc489c..84e246c8c4 100644 --- a/openhcl/underhill_core/src/loader/mod.rs +++ b/openhcl/underhill_core/src/loader/mod.rs @@ -425,7 +425,7 @@ pub fn write_uefi_config( if !isolated { for table in &platform_config.acpi_tables { let header = acpi_spec::Header::ref_from_prefix(table) - .map_err(|_| Error::InvalidAcpiTableLength)? // todo: zerocopy: map_err + .map_err(|_| Error::InvalidAcpiTableLength)? // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) .0; match &header.signature { b"APIC" => { diff --git a/openhcl/underhill_crash/src/lib.rs b/openhcl/underhill_crash/src/lib.rs index 9d09746aff..1d23be63ec 100644 --- a/openhcl/underhill_crash/src/lib.rs +++ b/openhcl/underhill_crash/src/lib.rs @@ -115,7 +115,7 @@ async fn read_message( ) -> anyhow::Result { let mut message = T::new_zeroed(); pipe.recv_exact(message.as_mut_bytes()).await?; - let header = Header::read_from_prefix(message.as_bytes()).unwrap().0; // todo: zerocopy: use-rest-of-range + let header = Header::read_from_prefix(message.as_bytes()).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) check_header(&header)?; Ok(message) } @@ -528,7 +528,7 @@ impl<'a> DumpStreamer<'a> { let phnum = std::cmp::min(phnum_remaining, max); let phdrs_size = phnum * size_of::(); self.read(&mut buf[..phdrs_size], true).await; - // todo: zerocopy: review carefully! + // TODO: zerocopy: review carefully! (https://github.com/microsoft/openvmm/issues/759) let phdrs: &mut [Elf64_Phdr] = <[Elf64_Phdr]>::mut_from_bytes(&mut buf[..phdrs_size]).unwrap(); diff --git a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs index cfd52cc6de..9c2f24c44f 100644 --- a/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs +++ b/openhcl/virt_mshv_vtl/src/processor/mshv/arm64.rs @@ -163,7 +163,7 @@ impl BackingPrivate for HypervisorBackedArm64 { this.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: err, use-rest-of-range + .0; // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) match message.reset_type { HvArm64ResetType::POWER_OFF => return Err(VpHaltReason::PowerOff), HvArm64ResetType::REBOOT => return Err(VpHaltReason::Reset), @@ -243,7 +243,7 @@ impl UhProcessor<'_, HypervisorBackedArm64> { self.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: err, use-rest-of-range + .0; // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -269,7 +269,7 @@ impl UhProcessor<'_, HypervisorBackedArm64> { self.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: err, use-rest-of-range + .0; // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(msg = %format_args!("{:x?}", message), "hypercall"); @@ -302,7 +302,7 @@ impl UhProcessor<'_, HypervisorBackedArm64> { self.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: err, use-rest-of-range + .0; // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // tracing::trace!(msg = %format_args!("{:x?}", message), "mmio"); let intercept_state = InterceptState { @@ -331,7 +331,7 @@ impl UhProcessor<'_, HypervisorBackedArm64> { self.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: err, use-rest-of-range + .0 // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) .guest_physical_address; if self.partition.is_gpa_lower_vtl_ram(gpa) { @@ -535,7 +535,7 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedA | HvMessageType::HvMessageTypeUnacceptedGpa => { hvdef::HvArm64MemoryInterceptMessage::ref_from_prefix(message.payload()) .ok() - .map(|v| v.0.guest_physical_address) // todo: zerocopy: err, use-rest-of-range + .map(|v| v.0.guest_physical_address) // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } _ => None, } @@ -554,7 +554,7 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedA self.vp.runner.exit_message().payload(), ) .ok()? - .0; // todo: zerocopy: err, use-rest-of-range + .0; // TODO: zerocopy: err, use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if !message.memory_access_info.gva_gpa_valid() { tracing::trace!(?message.guest_virtual_address, ?message.guest_physical_address, "gva gpa not valid {:?}", self.vp.runner.exit_message().payload()); diff --git a/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs b/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs index 057f0c7526..db3e459910 100644 --- a/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs +++ b/openhcl/virt_mshv_vtl/src/processor/mshv/x64.rs @@ -346,7 +346,7 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { HvMessageType::HvMessageTypeX64IoPortIntercept => { let message = hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) SidecarRemoveExit::Io { port: message.port_number, write: message.header.intercept_access_type == HvInterceptAccessType::WRITE, @@ -355,7 +355,7 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { HvMessageType::HvMessageTypeUnmappedGpa | HvMessageType::HvMessageTypeGpaIntercept => { let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) SidecarRemoveExit::Mmio { gpa: message.guest_physical_address, write: message.header.intercept_access_type == HvInterceptAccessType::WRITE, @@ -364,7 +364,7 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { HvMessageType::HvMessageTypeHypercallIntercept => { let message = hvdef::HvX64HypercallInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let is_64bit = message.header.execution_state.cr0_pe() && message.header.execution_state.efer_lma(); let control = if is_64bit { @@ -379,7 +379,7 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { HvMessageType::HvMessageTypeX64CpuidIntercept => { let message = hvdef::HvX64CpuidInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) SidecarRemoveExit::Cpuid { leaf: message.rax as u32, subleaf: message.rcx as u32, @@ -388,7 +388,7 @@ fn parse_sidecar_exit(message: &hvdef::HvMessage) -> SidecarRemoveExit { HvMessageType::HvMessageTypeMsrIntercept => { let message = hvdef::HvX64MsrInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) SidecarRemoveExit::Msr { msr: message.msr_number, value: (message.header.intercept_access_type == HvInterceptAccessType::WRITE) @@ -429,7 +429,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeUnmappedGpa @@ -438,7 +438,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeUnacceptedGpa => { @@ -446,7 +446,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeHypercallIntercept => { @@ -454,7 +454,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeSynicSintDeliverable => { @@ -462,7 +462,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeX64InterruptionDeliverable => { @@ -470,7 +470,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeX64CpuidIntercept => { @@ -478,7 +478,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeMsrIntercept => { @@ -486,7 +486,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeUnrecoverableException => { @@ -494,7 +494,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeX64Halt => { @@ -502,7 +502,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } &HvMessageType::HvMessageTypeExceptionIntercept => { @@ -510,7 +510,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: erro (https://github.com/microsoft/openvmm/issues/759) .header } reason => unreachable!("unknown exit reason: {:#x?}", reason), @@ -537,7 +537,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) assert_eq!( message.deliverable_type, @@ -578,7 +578,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -608,7 +608,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(msg = %format_args!("{:x?}", message), "hypercall"); @@ -638,7 +638,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(msg = %format_args!("{:x?}", message), "mmio"); @@ -689,7 +689,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(msg = %format_args!("{:x?}", message), "io_port"); @@ -726,7 +726,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) .guest_physical_address; if self.vp.partition.is_gpa_lower_vtl_ram(gpa) { @@ -753,7 +753,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let default_result = [ message.default_result_rax as u32, @@ -784,7 +784,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let rip = next_rip(&message.header); tracing::trace!(msg = %format_args!("{:x?}", message), "msr"); @@ -832,7 +832,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { let message = hvdef::HvX64ApicEoiMessage::ref_from_prefix(self.vp.runner.exit_message().payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(msg = %format_args!("{:x?}", message), "eoi"); @@ -851,7 +851,7 @@ impl<'a, 'b> InterceptHandler<'a, 'b> { self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) match x86defs::Exception(message.vector as u8) { x86defs::Exception::DEBUG if cfg!(feature = "gdb") => { @@ -1021,7 +1021,7 @@ impl UhProcessor<'_, HypervisorBackedX86> { let message = self.runner.exit_message(); let header = HvX64InterceptMessageHeader::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) MshvEmulationCache { rsp: rsp.as_u64(), @@ -1110,7 +1110,7 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX let message = self.vp.runner.exit_message(); let header = HvX64InterceptMessageHeader::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) from_seg(header.cs_segment) } x86emu::Segment::ES => self.cache.es, @@ -1146,14 +1146,14 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) &message.instruction_bytes[..message.instruction_byte_count as usize] } HvMessageType::HvMessageTypeX64IoPortIntercept => { let message = hvdef::HvX64IoPortInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) &message.instruction_bytes[..message.instruction_byte_count as usize] } _ => unreachable!(), @@ -1169,7 +1169,7 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX let message = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(message.payload()) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) Some(message.guest_physical_address) } _ => None, @@ -1189,7 +1189,7 @@ impl EmulatorSupport for UhEmulationState<'_, '_, T, HypervisorBackedX self.vp.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) if !message.memory_access_info.gva_gpa_valid() { tracing::trace!(?message.guest_virtual_address, ?message.guest_physical_address, "gva gpa not valid {:?}", self.vp.runner.exit_message().payload()); diff --git a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs index 573395f66a..66a6809573 100644 --- a/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs +++ b/openhcl/virt_mshv_vtl/src/processor/snp/mod.rs @@ -788,7 +788,7 @@ impl UhProcessor<'_, SnpBacked> { self.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!( deliverable_sints = message.deliverable_sints, @@ -810,7 +810,7 @@ impl UhProcessor<'_, SnpBacked> { self.runner.exit_message().payload(), ) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let ghcb_msr = x86defs::snp::GhcbMsr::from(message.ghcb_msr); tracing::trace!(?ghcb_msr, "vmgexit intercept"); @@ -1190,7 +1190,7 @@ impl UhProcessor<'_, SnpBacked> { let exception_message = hvdef::HvX64ExceptionInterceptMessage::ref_from_prefix(payload) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) exception_message.vector == x86defs::Exception::SEV_VMM_COMMUNICATION.0 as u16 @@ -1204,7 +1204,7 @@ impl UhProcessor<'_, SnpBacked> { let gpa_message: &hvdef::HvX64MemoryInterceptMessage = hvdef::HvX64MemoryInterceptMessage::ref_from_prefix(payload) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Only the page numbers need to match. (gpa_message.guest_physical_address >> hvdef::HV_PAGE_SHIFT) diff --git a/support/fdt/src/parser.rs b/support/fdt/src/parser.rs index 9d546cf550..c32230367f 100644 --- a/support/fdt/src/parser.rs +++ b/support/fdt/src/parser.rs @@ -174,7 +174,7 @@ impl<'a> Parser<'a> { pub fn read_total_size(buf: &[u8]) -> Result> { let header = spec::Header::read_from_prefix(buf) .map_err(|_| Error(ErrorKind::NoHeader))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if u32::from(header.magic) != spec::MAGIC { Err(Error(ErrorKind::HeaderMagic)) @@ -191,7 +191,7 @@ impl<'a> Parser<'a> { let header = spec::Header::read_from_prefix(buf) .map_err(|_| Error(ErrorKind::NoHeader))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if u32::from(header.magic) != spec::MAGIC { return Err(Error(ErrorKind::HeaderMagic)); @@ -218,7 +218,7 @@ impl<'a> Parser<'a> { .ok_or(Error(ErrorKind::MemoryReservationBlock))?; loop { let (entry, rest) = spec::ReserveEntry::read_from_prefix(mem_rsvmap) - .map_err(|_| Error(ErrorKind::MemoryReservationBlockEnd))?; // todo: zerocopy: map_err + .map_err(|_| Error(ErrorKind::MemoryReservationBlockEnd))?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if u64::from(entry.address) == 0 && u64::from(entry.size) == 0 { break; @@ -361,7 +361,7 @@ impl Display for ParseTokenError { /// Read to the next token from `buf`, returning `(token, remaining_buffer)`. fn read_token(buf: &[u8]) -> Result<(ParsedToken<'_>, &[u8]), ParseTokenError> { - let (token, rest) = U32b::read_from_prefix(buf).map_err(|_| ParseTokenError::BufLen)?; // todo: zerocopy: map_err + let (token, rest) = U32b::read_from_prefix(buf).map_err(|_| ParseTokenError::BufLen)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let token = u32::from(token); match token { spec::BEGIN_NODE => { @@ -383,7 +383,7 @@ fn read_token(buf: &[u8]) -> Result<(ParsedToken<'_>, &[u8]), ParseTokenError> { spec::PROP => { // Read the property header let (header, rest) = spec::PropHeader::read_from_prefix(rest) - .map_err(|_| ParseTokenError::PropHeader)?; // todo: zerocopy: map_err + .map_err(|_| ParseTokenError::PropHeader)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let len = u32::from(header.len) as usize; let align_up_len = (len + 4 - 1) & !(4 - 1); @@ -637,10 +637,10 @@ impl<'a> Property<'a> { // read types that are greater than 4 bytes, we must bound T to accept // unaligned types so LayoutVerified does not apply alignment and read // incorrect values. - // todo: zerocopy: review carefully! (manual) + // TODO: zerocopy: review carefully! (manual) (https://github.com/microsoft/openvmm/issues/759) <[T]>::ref_from_bytes(self.data) .map_err(|_| { - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Error(ErrorKind::PropertyDataTypeBuffer { node_name: self.node_name, prop_name: self.name, @@ -682,7 +682,7 @@ impl<'a> Property<'a> { pub fn as_64_list(&self) -> Result + use<'a>, Error<'a>> { Ok(<[U64b]>::ref_from_bytes(self.data) .map_err(|_| { - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Error(ErrorKind::PropertyDataTypeBuffer { node_name: self.node_name, prop_name: self.name, @@ -726,7 +726,7 @@ impl<'a> MemoryReserveIter<'a> { } let (entry, rest) = spec::ReserveEntry::read_from_prefix(self.memory_reservations) - .map_err(|_| ErrorKind::MemoryReservationBlock)?; // todo: zerocopy: map_err + .map_err(|_| ErrorKind::MemoryReservationBlock)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if u64::from(entry.address) == 0 && u64::from(entry.size) == 0 { return Ok(None); diff --git a/support/mesh/mesh_node/src/local_node.rs b/support/mesh/mesh_node/src/local_node.rs index 886cd97c9e..990f2f9802 100644 --- a/support/mesh/mesh_node/src/local_node.rs +++ b/support/mesh/mesh_node/src/local_node.rs @@ -1896,12 +1896,12 @@ impl LocalNode { /// Processes a node event. pub fn event(&self, remote_node_id: &NodeId, event: &[u8], os_resources: &mut Vec) { let parse = || { - let header = protocol::Event::read_from_prefix(event).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = protocol::Event::read_from_prefix(event).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let (resources, message) = Ref::from_prefix_with_elems( &event[size_of_val(&header)..], header.resource_count as usize, ) - .ok()?; // todo: zerocopy: err + .ok()?; // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let message = message.get(..header.message_size as usize)?; Some((header, resources, message)) }; @@ -1972,7 +1972,7 @@ impl LocalNode { protocol::EventType::CHANGE_PEER => { let data = protocol::ChangePeerData::read_from_prefix(message) .map_err(|_| EventError::Truncated)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let port = self .get_port(Address { node: NodeId(data.node.into()), @@ -1993,7 +1993,7 @@ impl LocalNode { protocol::EventType::FAIL_PORT => { let data = protocol::FailPortData::read_from_prefix(message) .map_err(|_| EventError::Truncated)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) NonMessageEvent::FailPort(NodeError::new( remote_node_id, RemotePortError(NodeId(data.node.into())), diff --git a/support/mesh/mesh_node/src/local_node/protocol.rs b/support/mesh/mesh_node/src/local_node/protocol.rs index 1817ed696e..725a60d913 100644 --- a/support/mesh/mesh_node/src/local_node/protocol.rs +++ b/support/mesh/mesh_node/src/local_node/protocol.rs @@ -44,7 +44,7 @@ pub struct Event { } open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum EventType: u8 { MESSAGE = 1, CLOSE_PORT = 2, diff --git a/support/mesh/mesh_protobuf/src/encoding.rs b/support/mesh/mesh_protobuf/src/encoding.rs index 7c51afb8ac..1e645ecb94 100644 --- a/support/mesh/mesh_protobuf/src/encoding.rs +++ b/support/mesh/mesh_protobuf/src/encoding.rs @@ -1452,7 +1452,7 @@ impl<'a, T: zerocopy::FromBytes + Immutable + KnownLayout, R> FieldDecode<'a, T, for ZeroCopyEncoding { fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> { - item.set(T::read_from_bytes(reader.bytes()?).map_err(|_| Error::new(InvalidZeroCopySize))?); // todo: zerocopy: better use error here + item.set(T::read_from_bytes(reader.bytes()?).map_err(|_| Error::new(InvalidZeroCopySize))?); // TODO: zerocopy: better use error here (https://github.com/microsoft/openvmm/issues/759) Ok(()) } diff --git a/support/mesh/mesh_remote/src/alpc_node.rs b/support/mesh/mesh_remote/src/alpc_node.rs index b8700f989f..ce3068f401 100644 --- a/support/mesh/mesh_remote/src/alpc_node.rs +++ b/support/mesh/mesh_remote/src/alpc_node.rs @@ -558,7 +558,7 @@ impl AlpcNode { match protocol::PacketHeader::read_from_prefix(buf) { Ok((header, _)) => match header.packet_type { - // todo: zerocopy: use-rest-of-range + // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) protocol::PacketType::EVENT => { local_node.event( connection.handle.id(), @@ -578,7 +578,7 @@ impl AlpcNode { } }, Err(_) => { - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) tracing::error!(node = ?local_id, "invalid message"); } } diff --git a/support/mesh/mesh_remote/src/protocol.rs b/support/mesh/mesh_remote/src/protocol.rs index c0cf8bf7b4..5f9a3ccfb7 100644 --- a/support/mesh/mesh_remote/src/protocol.rs +++ b/support/mesh/mesh_remote/src/protocol.rs @@ -22,7 +22,7 @@ pub struct ReleaseFds { } open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum PacketType: u8 { EVENT = 1, RELEASE_FDS = 2, diff --git a/support/mesh/mesh_remote/src/unix_node.rs b/support/mesh/mesh_remote/src/unix_node.rs index e921020bf3..f9bc5f0a88 100644 --- a/support/mesh/mesh_remote/src/unix_node.rs +++ b/support/mesh/mesh_remote/src/unix_node.rs @@ -644,7 +644,7 @@ async fn run_receive( let buf = &buf[..len]; let header = protocol::PacketHeader::read_from_prefix(buf) .map_err(|_| ReceiveError::NoHeader)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) match header.packet_type { protocol::PacketType::EVENT => { local_node.event(remote_id, &buf[size_of_val(&header)..], &mut fds); @@ -653,7 +653,7 @@ async fn run_receive( protocol::PacketType::RELEASE_FDS => { let release_fds = protocol::ReleaseFds::read_from_prefix(buf) .map_err(|_| ReceiveError::BadReleaseFds)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let _ = send.unbounded_send(SenderCommand::ReleaseFds { count: release_fds.count as usize, }); diff --git a/vm/acpi_spec/src/aspt.rs b/vm/acpi_spec/src/aspt.rs index 4ddcdd2ef3..b78b900260 100644 --- a/vm/acpi_spec/src/aspt.rs +++ b/vm/acpi_spec/src/aspt.rs @@ -49,7 +49,7 @@ pub mod structs { use zerocopy::KnownLayout; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum AsptStructType: u16 { ASP_GLOBAL_REGISTERS = 0, SEV_MAILBOX_REGISTERS = 1, diff --git a/vm/acpi_spec/src/madt.rs b/vm/acpi_spec/src/madt.rs index 1f78ba5f73..8dbf104707 100644 --- a/vm/acpi_spec/src/madt.rs +++ b/vm/acpi_spec/src/madt.rs @@ -265,7 +265,7 @@ impl<'a> MadtParser<'a> { pub fn new(table: &'a [u8]) -> Result { let header = crate::Header::read_from_prefix(table) .map_err(|_| ParserError)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if (header.length.get() as usize) < size_of::() { return Err(ParserError); } @@ -355,9 +355,9 @@ pub struct MadtIter<'a> { impl MadtIter<'_> { fn parse(&mut self) -> Result, ParserError> { - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) while let Ok((header, _)) = MadtEntryHeader::read_from_prefix(self.entries) { - // todo: zerocopy: ok + // TODO: zerocopy: ok (https://github.com/microsoft/openvmm/issues/759) if self.entries.len() < header.length as usize { return Err(ParserError); } @@ -366,11 +366,11 @@ impl MadtIter<'_> { let entry = match header.typ { MadtType::APIC => { MadtEntry::Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0) - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } MadtType::X2APIC => { MadtEntry::X2Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0) - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) } _ => continue, }; diff --git a/vm/acpi_spec/src/srat.rs b/vm/acpi_spec/src/srat.rs index edac8686f2..bf848f046b 100644 --- a/vm/acpi_spec/src/srat.rs +++ b/vm/acpi_spec/src/srat.rs @@ -243,7 +243,7 @@ pub fn parse_srat<'a>( ) -> Result<(&'a crate::Header, &'a SratHeader), ParseSratError> { let raw_srat_len = raw_srat.len(); let (acpi_header, buf) = Ref::<_, crate::Header>::from_prefix(raw_srat) - .map_err(|_| ParseSratError::MissingAcpiHeader)?; // todo: zerocopy: map_err + .map_err(|_| ParseSratError::MissingAcpiHeader)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if acpi_header.signature != *b"SRAT" { return Err(ParseSratError::InvalidSignature(acpi_header.signature)); @@ -257,19 +257,19 @@ pub fn parse_srat<'a>( } let (srat_header, mut buf) = - Ref::<_, SratHeader>::from_prefix(buf).map_err(|_| ParseSratError::MissingFixedHeader)?; // todo: zerocopy: map_err + Ref::<_, SratHeader>::from_prefix(buf).map_err(|_| ParseSratError::MissingFixedHeader)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) while !buf.is_empty() { buf = match SratType(buf[0]) { SratType::APIC => { let (apic, rest) = - Ref::<_, SratApic>::from_prefix(buf).map_err(|_| ParseSratError::BadApic)?; // todo: zerocopy: map_err + Ref::<_, SratApic>::from_prefix(buf).map_err(|_| ParseSratError::BadApic)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) on_apic(Ref::into_ref(apic)); rest } SratType::MEMORY => { let (mem, rest) = Ref::<_, SratMemory>::from_prefix(buf) - .map_err(|_| ParseSratError::BadMemory)?; // todo: zerocopy: map_err + .map_err(|_| ParseSratError::BadMemory)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) on_memory(Ref::into_ref(mem)); rest } diff --git a/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs b/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs index 0f2d2d9d4a..0c8dbcf7e8 100644 --- a/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs +++ b/vm/devices/firmware/firmware_pcat/src/root_cpu_data.rs @@ -175,7 +175,7 @@ const MAX_SMBIOS_STRING_TABLE_LENGTH: usize = /// reSearch query: `SMBIOS_CPU_INFO_STRINGS_LEGACY` #[repr(C, packed)] #[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Clone, Copy)] -// todo: zerocopy: remove `pub(crate)` once this issue is resolved: https://github.com/google/zerocopy/issues/2177 +// TODO: zerocopy: remove `pub(crate)` once this issue is resolved: https://github.com/google/zerocopy/issues/2177 (https://github.com/microsoft/openvmm/issues/759) pub(crate) struct SmbiosCpuInfoStringsLegacy { string_table: [u8; MAX_SMBIOS_STRING_TABLE_LEGACY_LENGTH], } diff --git a/vm/devices/firmware/firmware_uefi/src/service/event_log.rs b/vm/devices/firmware/firmware_uefi/src/service/event_log.rs index 6516634e97..eceaaa30b8 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/event_log.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/event_log.rs @@ -84,7 +84,7 @@ impl EventLogServices { while !event_data.is_empty() { let desc = EfiEventDescriptor::read_from_prefix(event_data) .map_err(|_| EventLogError::ConvertBytes)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let data = event_data .get(desc.header_size as usize..) @@ -99,7 +99,7 @@ impl EventLogServices { uefi_specs::hyperv::boot_bios_log::BOOT_DEVICE_EVENT_ID => { let boot_entry = BootEventDeviceEntry::read_from_prefix(data) .map_err(|_| EventLogError::BootEventSize)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::debug!(?boot_entry, "boot log entry"); diff --git a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs index 00ab6aacd9..224a23638a 100644 --- a/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs +++ b/vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs @@ -710,7 +710,7 @@ impl NvramSpecServices { }; // extract EFI_VARIABLE_AUTHENTICATION_2 header - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let auth_hdr = match EFI_VARIABLE_AUTHENTICATION_2::read_from_prefix(data.as_slice()).ok() { Some((hdr, _)) => hdr, diff --git a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs index 859b8c0de0..8bfbcce92d 100644 --- a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs +++ b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs @@ -46,7 +46,7 @@ mod format { use static_assertions::const_assert_eq; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum NvramHeaderType: u32 { VARIABLE = 0, } @@ -168,8 +168,8 @@ impl HclCompatNvram { self.in_memory.clear(); self.nvram_buf = nvram_buf; let mut buf = self.nvram_buf.as_slice(); - // todo: zerocopy: error propagation - // todo: zerocopy: review carefully! manual fixup + // TODO: zerocopy: error propagation (https://github.com/microsoft/openvmm/issues/759) + // TODO: zerocopy: review carefully! manual fixup (https://github.com/microsoft/openvmm/issues/759) while let Ok((header, _)) = format::NvramHeader::read_from_prefix(buf) { if buf.len() < header.length as usize { return Err(NvramStorageError::Load( @@ -202,8 +202,8 @@ impl HclCompatNvram { let (var_header, var_name, var_data) = { let (var_header, var_length_data) = - // todo: zerocopy: error propagation - // todo: zerocopy: manual fix - review carefully! + // TODO: zerocopy: error propagation (https://github.com/microsoft/openvmm/issues/759) + // TODO: zerocopy: manual fix - review carefully! (https://github.com/microsoft/openvmm/issues/759) format::NvramVariable::read_from_prefix(entry_buf).map_err(|_| NvramStorageError::Load("variable entry too short".into()))?; if var_length_data.len() diff --git a/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs b/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs index 323bd2ac42..b01e240c05 100644 --- a/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs +++ b/vm/devices/firmware/hyperv_uefi_custom_vars_json/src/lib.rs @@ -275,7 +275,7 @@ mod json { v.len() ))); } - Ok(Guid::read_from_prefix(v.as_slice()).unwrap().0) // todo: zerocopy: use-rest-of-range + Ok(Guid::read_from_prefix(v.as_slice()).unwrap().0) // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } } diff --git a/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs b/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs index 1d32fa4583..fbddc9ad91 100644 --- a/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs +++ b/vm/devices/firmware/uefi_nvram_specvars/src/boot_order.rs @@ -99,7 +99,7 @@ pub enum EfiDevicePathProtocol<'a> { impl<'a> EfiDevicePathProtocol<'a> { pub fn parse(data: &'a [u8]) -> Result<(Self, &'a [u8]), Error> { let (header, path_data) = boot::EfiDevicePathProtocol::read_from_prefix(data) - .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let length = u16::from_le_bytes(header.length) as usize; // TODO: Switch to split_at_checked below once stable and remove this check @@ -120,12 +120,12 @@ impl<'a> EfiDevicePathProtocol<'a> { boot::EfiHardwareDeviceSubType::MEMORY_MAPPED => { HardwareDevice::MemoryMapped( boot::EfiMemoryMappedDevice::read_from_bytes(path_data) - .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) ) } boot::EfiHardwareDeviceSubType::VENDOR => { let (vendor_guid, path_data) = Guid::read_from_prefix(path_data) - .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) HardwareDevice::Vendor { vendor_guid, data: path_data, @@ -145,7 +145,7 @@ impl<'a> EfiDevicePathProtocol<'a> { return Err(Error::InvalidLength); } let (numeric, path_data) = - boot::EfiExpandedAcpiDevice::read_from_prefix(path_data).unwrap(); // TODO: zerocopy: unwrap + boot::EfiExpandedAcpiDevice::read_from_prefix(path_data).unwrap(); // TODO: zerocopy: unwrap (https://github.com/microsoft/openvmm/issues/759) let hidstr = CStr::from_bytes_until_nul(path_data) .map_err(Error::NullTerminated)?; let path_data = &path_data[hidstr.to_bytes_with_nul().len()..]; @@ -174,7 +174,7 @@ impl<'a> EfiDevicePathProtocol<'a> { match boot::EfiMessagingDeviceSubType(header.sub_type) { boot::EfiMessagingDeviceSubType::SCSI => MessagingDevice::Scsi( boot::EfiScsiDevice::read_from_bytes(path_data) - .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) ), device_subtype => MessagingDevice::Unknown { device_subtype, @@ -186,7 +186,7 @@ impl<'a> EfiDevicePathProtocol<'a> { match boot::EfiMediaDeviceSubType(header.sub_type) { boot::EfiMediaDeviceSubType::HARD_DRIVE => MediaDevice::HardDrive( boot::EfiHardDriveDevice::read_from_bytes(path_data) - .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) ), boot::EfiMediaDeviceSubType::FILE => { let file_name = Ucs2LeSlice::from_slice_with_nul(path_data) @@ -199,13 +199,13 @@ impl<'a> EfiDevicePathProtocol<'a> { boot::EfiMediaDeviceSubType::PIWG_FIRMWARE_FILE => { MediaDevice::PiwgFirmwareFile( Guid::read_from_bytes(path_data) - .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) ) } boot::EfiMediaDeviceSubType::PIWG_FIRMWARE_VOLUME => { MediaDevice::PiwgFirmwareVolume( Guid::read_from_bytes(path_data) - .map_err(|_| Error::InvalidLength)?, // todo: zerocopy: map_err + .map_err(|_| Error::InvalidLength)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) ) } device_subtype => MediaDevice::Unknown { @@ -246,7 +246,7 @@ pub struct EfiLoadOption<'a> { impl<'a> EfiLoadOption<'a> { pub fn parse(data: &'a [u8]) -> Result { let (header, data) = - boot::EfiLoadOption::read_from_prefix(data).map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err + boot::EfiLoadOption::read_from_prefix(data).map_err(|_| Error::InvalidLength)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let description = Ucs2LeSlice::from_slice_with_nul(data).map_err(Error::InvalidUcs2)?; let mut data = &data[description.as_bytes().len()..]; diff --git a/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs b/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs index d5c8452835..d79e8b400b 100644 --- a/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs +++ b/vm/devices/firmware/uefi_nvram_specvars/src/signature_list.rs @@ -250,7 +250,7 @@ impl<'a> ParseSignatureLists<'a> { }, buf, ) = EFI_SIGNATURE_LIST::read_from_prefix(self.buf) - .map_err(|_| ParseError::InvalidHeader)?; // TODO: zerocopy: map_err + .map_err(|_| ParseError::InvalidHeader)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_data_len = signature_list_size as usize - size_of::(); if buf.len() < expected_data_len { @@ -314,7 +314,7 @@ impl<'a> ParseSignatureX509<'a> { } let (header, buf) = EFI_SIGNATURE_DATA::read_from_prefix(self.buf) - .map_err(|_| ParseError::X509InvalidHeader)?; // TODO: zerocopy: map_err + .map_err(|_| ParseError::X509InvalidHeader)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let val: Cow<'a, [u8]> = buf.into(); let res = SignatureData::new_x509(header.signature_owner, val); @@ -360,7 +360,7 @@ impl<'a> ParseSignatureSha256<'a> { } let (header, buf) = - EFI_SIGNATURE_DATA::read_from_prefix(self.buf).expect("buf size validated in `new`"); // TODO: zerocopy: map_err + EFI_SIGNATURE_DATA::read_from_prefix(self.buf).expect("buf size validated in `new`"); // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_data_len = 32; assert!(buf.len() >= expected_data_len, "validated in new()"); diff --git a/vm/devices/get/guest_crash_device/src/lib.rs b/vm/devices/get/guest_crash_device/src/lib.rs index 7d557e6133..16b285f223 100644 --- a/vm/devices/get/guest_crash_device/src/lib.rs +++ b/vm/devices/get/guest_crash_device/src/lib.rs @@ -323,7 +323,7 @@ impl GuestCrashDevice { match header.message_type { crash::MessageType::REQUEST_NIX_DUMP_WRITE_V1 => { let request = crash::DumpWriteRequestV1::read_from_prefix(message) - .map_err(|_| anyhow!("truncated message"))? // todo: zerocopy: anyhow! + .map_err(|_| anyhow!("truncated message"))? // TODO: zerocopy: anyhow! (https://github.com/microsoft/openvmm/issues/759) .0; *payload = Some((request.offset, request.size)); } diff --git a/vm/devices/get/guest_emulation_device/src/lib.rs b/vm/devices/get/guest_emulation_device/src/lib.rs index e2f32fc2e1..7660761e7b 100644 --- a/vm/devices/get/guest_emulation_device/src/lib.rs +++ b/vm/devices/get/guest_emulation_device/src/lib.rs @@ -454,7 +454,7 @@ impl GedChannel { ) -> Result<(), Error> { let header = get_protocol::HeaderRaw::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if header.message_version != get_protocol::MessageVersions::HEADER_VERSION_1 { return Err(Error::HeaderVersion(header.message_version)); @@ -605,7 +605,7 @@ impl GedChannel { fn handle_bios_boot_finalize(&mut self, message_buf: &[u8]) -> Result<(), Error> { let msg = get_protocol::BiosBootFinalizeRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(?msg, "Bios Boot Finalize request"); @@ -666,7 +666,7 @@ impl GedChannel { ) -> Result<(), Error> { let message = get_protocol::VmgsReadRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let (status, payload) = if let Some(vmgs) = &mut state.vmgs { let len = message.sector_count as u64 * vmgs.disk.sector_size() as u64; @@ -717,7 +717,7 @@ impl GedChannel { message_buf: &[u8], ) -> Result<(), Error> { let (message, rest) = get_protocol::VmgsWriteRequest::read_from_prefix(message_buf) - .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let status = if let Some(vmgs) = &mut state.vmgs { let len = message.sector_count as u64 * vmgs.disk.sector_size() as u64; @@ -792,7 +792,7 @@ impl GedChannel { &message_buf.as_bytes()[..size_of::()], ) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: err + .0; // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let mut response = get_protocol::GuestStateProtectionResponse::new_zeroed(); response.message_header = HeaderGeneric::new(HostRequests::GUEST_STATE_PROTECTION); @@ -819,7 +819,7 @@ impl GedChannel { fn handle_igvm_attest(&mut self, message_buf: &[u8]) -> Result<(), Error> { let request = IgvmAttestRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) // Request sanitization (match GED behavior) if request.agent_data_length as usize > request.agent_data.len() @@ -831,7 +831,7 @@ impl GedChannel { let request_payload = IgvmAttestRequestHeader::read_from_prefix(&request.report) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let response = match request_payload.request_type { IgvmAttestRequestType::AK_CERT_REQUEST => { @@ -874,7 +874,7 @@ impl GedChannel { let save = self.save.as_mut().ok_or(Error::InvalidSequence)?; let (request_header, remaining) = get_protocol::SaveGuestVtl2StateRequest::read_from_prefix(message_buf) - .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let r = match request_header.save_status { get_protocol::GuestVtl2SaveRestoreStatus::MORE_DATA => { save.buffer.extend_from_slice(remaining); @@ -927,7 +927,7 @@ impl GedChannel { if let Some(framebuffer_control) = state.framebuffer_control.as_mut() { let message = get_protocol::MapFramebufferRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let gpa = message.gpa; tracing::debug!("Received map framebuffer request from guest {:#x}", gpa); framebuffer_control.map(gpa).await; @@ -966,7 +966,7 @@ impl GedChannel { fn handle_create_ram_gpa_range(&mut self, message_buf: &[u8]) -> Result<(), Error> { let request = get_protocol::CreateRamGpaRangeRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::info!(?request, "create ram gpa range request"); @@ -982,7 +982,7 @@ impl GedChannel { fn handle_reset_ram_gpa_range(&mut self, message_buf: &[u8]) -> Result<(), Error> { let _request = get_protocol::ResetRamGpaRangeRequest::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let response = get_protocol::ResetRamGpaRangeResponse::new(); self.channel .try_send(response.as_bytes()) @@ -1043,7 +1043,7 @@ impl GedChannel { ) -> Result<(), Error> { let msg = get_protocol::EventLogNotification::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!("[Event Log] {:?}", msg); let event = match msg.event_log_id { get_protocol::EventLogId::BOOT_SUCCESS => GuestEvent::BootSuccess, @@ -1093,7 +1093,7 @@ impl GedChannel { let message = get_protocol::RestoreGuestVtl2StateHostNotification::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let success = match message.status { get_protocol::GuestVtl2SaveRestoreStatus::SUCCESS => true, get_protocol::GuestVtl2SaveRestoreStatus::FAILURE => false, @@ -1110,7 +1110,7 @@ impl GedChannel { ) -> Result<(), Error> { let (message, remaining) = get_protocol::StartVtl0CompleteNotification::read_from_prefix(message_buf) - .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_len = message.result_document_size as usize; if remaining.len() != expected_len { return Err(Error::InvalidFieldValue); @@ -1141,7 +1141,7 @@ impl GedChannel { fn handle_vtl_crash(&mut self, message_buf: &[u8]) -> Result<(), Error> { let msg = get_protocol::VtlCrashNotification::read_from_prefix(message_buf) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::info!("Guest has reported a system crash {msg:x?}"); Ok(()) } @@ -1152,7 +1152,7 @@ impl GedChannel { message_buf: &[u8], ) -> Result<(), Error> { let (msg, remaining) = get_protocol::TripleFaultNotification::read_from_prefix(message_buf) - .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_len = msg.register_count as usize * size_of::(); if remaining.len() != expected_len { return Err(Error::InvalidFieldValue); @@ -1169,7 +1169,7 @@ impl GedChannel { fn handle_modify_vtl2_settings_completed(&mut self, message_buf: &[u8]) -> Result<(), Error> { let (msg, remaining) = get_protocol::ModifyVtl2SettingsCompleteNotification::read_from_prefix(message_buf) - .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err + .map_err(|_| Error::MessageTooSmall)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let modify = self.modify.take().ok_or(Error::InvalidSequence)?; let r = match msg.modify_status { diff --git a/vm/devices/get/guest_emulation_device/src/test_utilities.rs b/vm/devices/get/guest_emulation_device/src/test_utilities.rs index 2378b55eeb..d085f2edae 100644 --- a/vm/devices/get/guest_emulation_device/src/test_utilities.rs +++ b/vm/devices/get/guest_emulation_device/src/test_utilities.rs @@ -127,7 +127,7 @@ impl TestGedChannel { let header = get_protocol::HeaderRaw::read_from_prefix(&message_buf[..4]) .map_err(|_| Error::MessageTooSmall)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if header.message_version != get_protocol::MessageVersions::HEADER_VERSION_1 { return Err(Error::HeaderVersion(header.message_version)); @@ -142,7 +142,7 @@ impl TestGedChannel { &message_buf[..size_of::()], ) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) self.vmgs[0] = notification.event_log_id.0 as u8; } HostNotifications::POWER_OFF => { @@ -162,7 +162,7 @@ impl TestGedChannel { let response_header = get_protocol::HeaderRaw::read_from_prefix(&response[..4]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Check if response needs special handling. Otherwise, send // response directly back to the guest. match response_header.message_type { @@ -179,7 +179,7 @@ impl TestGedChannel { ) .unwrap() .0; - let offset = request.sector_offset as usize // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + let offset = request.sector_offset as usize // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) * TEST_VMGS_SECTOR_SIZE as usize; let length = request.sector_count as usize * TEST_VMGS_SECTOR_SIZE as usize; @@ -194,7 +194,7 @@ impl TestGedChannel { ) .unwrap() .0; - let buf = &message_buf[request_size..]; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + let buf = &message_buf[request_size..]; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let offset = request.sector_offset as usize * TEST_VMGS_SECTOR_SIZE as usize; let length = request.sector_count as usize diff --git a/vm/devices/get/guest_emulation_log/src/lib.rs b/vm/devices/get/guest_emulation_log/src/lib.rs index e10adb4826..c6a3061767 100644 --- a/vm/devices/get/guest_emulation_log/src/lib.rs +++ b/vm/devices/get/guest_emulation_log/src/lib.rs @@ -184,7 +184,7 @@ impl GelChannel { let (header, buffer) = get_protocol::TraceLoggingNotificationHeader::read_from_prefix(buffer) - .map_err(|_| Error::InvalidPayloadSize(n))?; // TODO: zerocopy: map_err + .map_err(|_| Error::InvalidPayloadSize(n))?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let message = buffer .get( diff --git a/vm/devices/get/guest_emulation_transport/src/process_loop.rs b/vm/devices/get/guest_emulation_transport/src/process_loop.rs index 578803522f..363823bfab 100644 --- a/vm/devices/get/guest_emulation_transport/src/process_loop.rs +++ b/vm/devices/get/guest_emulation_transport/src/process_loop.rs @@ -612,7 +612,7 @@ impl HostRequestPipeAccess { let response = self.recv_response().await; let header = get_protocol::HeaderHostRequest::read_from_prefix(response.as_bytes()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if id != header.message_id { return Err(FatalError::ResponseHeaderMismatchId(header.message_id, id)); } @@ -633,7 +633,7 @@ impl HostRequestPipeAccess { self.send_message(data.as_bytes().to_vec()); let req_header = get_protocol::HeaderHostRequest::read_from_prefix(data.as_bytes()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) self.recv_response_fixed_size(req_header.message_id).await } @@ -789,7 +789,7 @@ impl ProcessLoop { // message down the wire. if let Ok((header, _)) = get_protocol::HeaderRaw::read_from_prefix(outgoing.as_ref()) - // todo: zerocopy: use-rest-of-range, zerocopy: err + // TODO: zerocopy: use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) { match header.message_type { get_protocol::MessageTypes::HOST_REQUEST => { @@ -916,7 +916,7 @@ impl ProcessLoop { let buf = &buf[..len]; let header = get_protocol::HeaderRaw::read_from_prefix(buf) .map_err(|_| FatalError::MessageSizeHeader(len))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) match header.message_type { get_protocol::MessageTypes::HOST_RESPONSE => { @@ -1349,7 +1349,7 @@ impl ProcessLoop { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS, } - })?; // todo: zerocopy: map_ + })?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_len = request.size as usize; if remaining.len() != expected_len { @@ -1375,7 +1375,7 @@ impl ProcessLoop { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS_REV1, }, - )?; // TODO: zerocopy: map_err + )?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let expected_len = request.size as usize; if remaining.len() != expected_len { @@ -1561,7 +1561,7 @@ async fn request_device_platform_settings_v2( let buf = access.recv_response().await; let header = get_protocol::HeaderHostResponse::read_from_prefix(buf.as_slice()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Protocol wart: request is sent as a // `HostRequests::DEVICE_PLATFORM_SETTINGS_V2`, but the host will send @@ -1584,7 +1584,7 @@ async fn request_device_platform_settings_v2( .map_err(|_| FatalError::MessageSizeHostResponse { len: buf.len(), response: HostRequests::DEVICE_PLATFORM_SETTINGS_V2, - })?; // todo: zerocopy: map_err + })?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if response.size as usize != remaining.len() { return Err(FatalError::DevicePlatformSettingsV2Payload { @@ -1604,7 +1604,7 @@ async fn request_device_platform_settings_v2( .map_err(|_| FatalError::MessageSizeGuestNotification { len: buf.len(), notification: get_protocol::GuestNotifications::MODIFY_VTL2_SETTINGS_REV1, - })?; // todo: zerocopy: map_err + })?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if remaining.len() != (response.size as usize) { return Err(FatalError::DevicePlatformSettingsV2Payload { @@ -1655,7 +1655,7 @@ async fn request_vmgs_read( .map_err(|_| FatalError::MessageSizeHostResponse { len: buf.len(), response: HostRequests::VMGS_READ, - })?; // todo: zerocopy: map_err + })?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if response.message_header.message_id != HostRequests::VMGS_READ { return Err(FatalError::ResponseHeaderMismatchId( @@ -1785,7 +1785,7 @@ async fn request_saved_state( .map_err(|_| FatalError::MessageSizeHostResponse { len: message_buf.len(), response: HostRequests::RESTORE_GUEST_VTL2_STATE, - })?; // todo: zerocopy: map_err + })?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let message_id = response_header.message_header.message_id; if message_id != HostRequests::RESTORE_GUEST_VTL2_STATE { @@ -1861,7 +1861,7 @@ async fn request_igvm_attest( let response = access.recv_response().await; // Validate the response and returns the validated data. - // todo: zerocopy: use error here, use rest of range + // TODO: zerocopy: use error here, use rest of range (https://github.com/microsoft/openvmm/issues/759) let Ok((response, _)) = get_protocol::IgvmAttestResponse::read_from_prefix(&response) else { Err(FatalError::DeserializeIgvmAttestResponse)? }; diff --git a/vm/devices/hyperv_ic/src/shutdown.rs b/vm/devices/hyperv_ic/src/shutdown.rs index 9abb04aa62..9a9e378a85 100644 --- a/vm/devices/hyperv_ic/src/shutdown.rs +++ b/vm/devices/hyperv_ic/src/shutdown.rs @@ -209,14 +209,14 @@ impl ShutdownChannel { let (_result, buf) = read_response(&mut self.pipe).await?; let (message, rest) = hyperv_ic_protocol::NegotiateMessage::read_from_prefix(buf.as_slice()) - .map_err(|_| Error::TruncatedMessage)?; // todo: zerocopy: map_err + .map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if message.framework_version_count != 1 || message.message_version_count != 1 { return Err(Error::NoSupportedVersions); } let [framework_version, message_version] = <[hyperv_ic_protocol::Version; 2]>::read_from_prefix(rest) .map_err(|_| Error::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) self.state = ChannelState::Ready { framework_version, @@ -294,7 +294,7 @@ async fn read_response(pipe: &mut MessagePipe) -> Result<(u32, Vec let n = pipe.recv(&mut buf).await.map_err(Error::Ring)?; let buf = &buf[..n]; let (header, rest) = - hyperv_ic_protocol::Header::read_from_prefix(buf).map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err + hyperv_ic_protocol::Header::read_from_prefix(buf).map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if header.transaction_id != 0 || !header.flags.transaction() || !header.flags.response() { return Err(Error::InvalidVersionResponse); diff --git a/vm/devices/hyperv_ic_guest/src/shutdown.rs b/vm/devices/hyperv_ic_guest/src/shutdown.rs index cc69cbd9b8..a3927f3ef3 100644 --- a/vm/devices/hyperv_ic_guest/src/shutdown.rs +++ b/vm/devices/hyperv_ic_guest/src/shutdown.rs @@ -119,7 +119,7 @@ impl ShutdownGuestChannel { } async fn handle_host_message(&mut self, buf: &[u8], ic: &ShutdownGuestIc) { - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) let (header, rest) = match hyperv_ic_protocol::Header::read_from_prefix(buf).ok() { Some((h, r)) => (h, r), None => { @@ -163,7 +163,7 @@ impl ShutdownGuestChannel { let mut next_version; let mut latest_version = None; for _ in 0..count { - // todo: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) (next_version, rest) = match hyperv_ic_protocol::Version::read_from_prefix(rest).ok() { Some((n, r)) => (n, r), None => { @@ -196,7 +196,7 @@ impl ShutdownGuestChannel { msg: &[u8], ) -> Result<(), Error> { let (prefix, rest) = hyperv_ic_protocol::NegotiateMessage::read_from_prefix(msg) - .map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err + .map_err(|_| Error::TruncatedMessage)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let (latest_framework_version, rest) = Self::find_latest_supported_version( rest, prefix.framework_version_count as usize, @@ -273,7 +273,7 @@ impl ShutdownGuestChannel { let message = hyperv_ic_protocol::shutdown::ShutdownMessage::read_from_prefix(buf) .map_err(|_| Error::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let shutdown_type = if message.flags.restart() { ShutdownType::Reboot } else if message.flags.hibernate() { diff --git a/vm/devices/hyperv_ic_protocol/src/lib.rs b/vm/devices/hyperv_ic_protocol/src/lib.rs index 98ca5639d7..df27bc6b64 100644 --- a/vm/devices/hyperv_ic_protocol/src/lib.rs +++ b/vm/devices/hyperv_ic_protocol/src/lib.rs @@ -41,7 +41,7 @@ impl Display for Version { open_enum! { /// Type of message - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum MessageType: u16 { /// Initial version negotiation between host and guest. VERSION_NEGOTIATION = 0, @@ -136,7 +136,7 @@ pub mod heartbeat { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] /// Current state of guest. pub enum ApplicationState: u32 { /// Guest is in an unknown state. diff --git a/vm/devices/net/gdma/src/bnic.rs b/vm/devices/net/gdma/src/bnic.rs index e13778fc4b..de90f6ecaa 100644 --- a/vm/devices/net/gdma/src/bnic.rs +++ b/vm/devices/net/gdma/src/bnic.rs @@ -521,7 +521,7 @@ impl TxRxTask { ManaTxOob::read_from_prefix(oob).unwrap().0 } else { ManaTxOob { - // todo: zerocopy: use details from SizeError in the returned context + // TODO: zerocopy: use details from SizeError in the returned context (https://github.com/microsoft/openvmm/issues/759) s_oob: ManaTxShortOob::read_from_prefix(oob) .map_err(|_| anyhow!("oob too small"))? .0, diff --git a/vm/devices/net/gdma/src/hwc.rs b/vm/devices/net/gdma/src/hwc.rs index 43f045b797..ed9558a767 100644 --- a/vm/devices/net/gdma/src/hwc.rs +++ b/vm/devices/net/gdma/src/hwc.rs @@ -202,7 +202,7 @@ impl HwControl { let queues = self.state.queues.clone(); let tx_oob = HwcTxOob::read_from_prefix(sqe.oob()) .map_err(|_| anyhow!("reading tx oob"))? - .0; // todo: zerocopy: map_err, use-rest-of-range, use error details in the returned `anyhow!` + .0; // TODO: zerocopy: map_err, use-rest-of-range, use error details in the returned `anyhow!` (https://github.com/microsoft/openvmm/issues/759) if tx_oob.flags3.vscq_id() != self.cq_id { anyhow::bail!( "mismatched cq id: {} != {}", diff --git a/vm/devices/net/gdma_defs/src/lib.rs b/vm/devices/net/gdma_defs/src/lib.rs index 12b6320474..a587bf2620 100644 --- a/vm/devices/net/gdma_defs/src/lib.rs +++ b/vm/devices/net/gdma_defs/src/lib.rs @@ -295,7 +295,7 @@ pub const HWC_INIT_DATA_PDID: u8 = 8; pub const HWC_INIT_DATA_GPA_MKEY: u8 = 9; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum GdmaRequestType : u32 { GDMA_VERIFY_VF_DRIVER_VERSION = 1, GDMA_QUERY_MAX_RESOURCES = 2, @@ -334,7 +334,7 @@ pub struct GdmaDevId { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum GdmaDevType: u16 { GDMA_DEVICE_NONE = 0, GDMA_DEVICE_HWC = 1, @@ -560,7 +560,7 @@ pub struct GdmaCreateQueueReq { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum GdmaQueueType: u32 { GDMA_SQ = 1, GDMA_RQ = 2, diff --git a/vm/devices/net/mana_driver/src/gdma_driver.rs b/vm/devices/net/mana_driver/src/gdma_driver.rs index 5a19250026..6d5995e595 100644 --- a/vm/devices/net/mana_driver/src/gdma_driver.rs +++ b/vm/devices/net/mana_driver/src/gdma_driver.rs @@ -371,13 +371,13 @@ impl GdmaDriver { tracing::debug!(event_type = eqe.params.event_type(), "got init eqe"); match eqe.params.event_type() { GDMA_EQE_HWC_INIT_EQ_ID_DB => { - let data = HwcInitEqIdDb::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let data = HwcInitEqIdDb::read_from_prefix(&eqe.data[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) eq.set_id(data.eq_id().into()); eq.set_doorbell(DoorbellPage::new(bar0.clone(), data.doorbell().into())?); db_id = Some(data.doorbell()); } GDMA_EQE_HWC_INIT_DATA => { - let data = HwcInitTypeData::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let data = HwcInitTypeData::read_from_prefix(&eqe.data[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) match data.ty() { HWC_INIT_DATA_CQID => cq_id = Some(data.value()), HWC_INIT_DATA_RQID => rq_id = Some(data.value()), @@ -790,7 +790,7 @@ impl GdmaDriver { GDMA_EQE_COMPLETION => self.cq_armed = false, GDMA_EQE_TEST_EVENT => self.test_events += 1, GDMA_EQE_HWC_RECONFIG_DATA => { - let data = EqeDataReconfig::read_from_prefix(&eqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let data = EqeDataReconfig::read_from_prefix(&eqe.data[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let mut value: [u8; 4] = [0; 4]; value[0..3].copy_from_slice(&data.data); let value: u32 = u32::from_le_bytes(value); diff --git a/vm/devices/net/net_mana/src/lib.rs b/vm/devices/net/net_mana/src/lib.rs index b3dc469ced..3d46528824 100644 --- a/vm/devices/net/net_mana/src/lib.rs +++ b/vm/devices/net/net_mana/src/lib.rs @@ -797,7 +797,7 @@ impl Queue for ManaQueue { while i < packets.len() { if let Some(cqe) = self.rx_cq.pop() { let rx = self.posted_rx.pop_front().unwrap(); - let rx_oob = ManaRxcompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let rx_oob = ManaRxcompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) match rx_oob.cqe_hdr.cqe_type() { CQE_RX_OKAY => { let ip_checksum = if rx_oob.flags.rx_iphdr_csum_succeed() { @@ -902,7 +902,7 @@ impl Queue for ManaQueue { let mut i = 0; while i < done.len() { let id = if let Some(cqe) = self.tx_cq.pop() { - let tx_oob = ManaTxCompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let tx_oob = ManaTxCompOob::read_from_prefix(&cqe.data[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) match tx_oob.cqe_hdr.cqe_type() { CQE_TX_OKAY => { self.stats.tx_packets += 1; diff --git a/vm/devices/net/netvsp/src/lib.rs b/vm/devices/net/netvsp/src/lib.rs index 3802e4b94e..a88c0f4c88 100644 --- a/vm/devices/net/netvsp/src/lib.rs +++ b/vm/devices/net/netvsp/src/lib.rs @@ -3521,7 +3521,7 @@ fn read_ndis_object( validate_ndis_object_header( &rndisprot::NdisObjectHeader::read_from_prefix(buffer.as_bytes()) .unwrap() - .0, // todo: zerocopy: use-rest-of-range + .0, // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) sent_size, object_type, min_revision, diff --git a/vm/devices/net/netvsp/src/protocol.rs b/vm/devices/net/netvsp/src/protocol.rs index 789437019b..fbb6430c51 100644 --- a/vm/devices/net/netvsp/src/protocol.rs +++ b/vm/devices/net/netvsp/src/protocol.rs @@ -205,7 +205,7 @@ pub const MESSAGE6_MAX: u32 = MESSAGE6_TYPE_PD_POST_BATCH; */ open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Status: u32 { NONE = 0, SUCCESS = 1, @@ -458,7 +458,7 @@ pub struct Message4SendVfAssociation { // in NVSP_4_MESSAGE_SWITCH_DATA_PATH structure // open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum DataPath: u32 { SYNTHETIC = 0, VF = 1, @@ -504,7 +504,7 @@ pub struct Message5OidQueryExComplete { // primary channel's channel close callback. // open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SubchannelOperation: u32 { NONE = 0, ALLOCATE = 1, diff --git a/vm/devices/net/netvsp/src/rndisprot.rs b/vm/devices/net/netvsp/src/rndisprot.rs index 8fba61ff90..5885da7303 100644 --- a/vm/devices/net/netvsp/src/rndisprot.rs +++ b/vm/devices/net/netvsp/src/rndisprot.rs @@ -107,7 +107,7 @@ pub const STATUS_TOKEN_RING_OPEN_ERROR: Status = 0xC0011000; // open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Oid: u32 { OID_GEN_SUPPORTED_LIST = 0x00010101, OID_GEN_HARDWARE_STATUS = 0x00010102, @@ -746,7 +746,7 @@ pub struct MessageHeader { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum NdisObjectType: u8 { DEFAULT = 0x80, RSS_CAPABILITIES = 0x88, @@ -1020,7 +1020,7 @@ pub struct NdisOffloadParameters { pub const NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1: usize = 20; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum OffloadParametersChecksum: u8 { NO_CHANGE = 0, TX_RX_DISABLED = 1, @@ -1043,7 +1043,7 @@ impl OffloadParametersChecksum { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum OffloadParametersSimple: u8 { NO_CHANGE = 0, DISABLED = 1, @@ -1073,7 +1073,7 @@ pub struct RndisConfigParameterInfo { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum NdisParameterType: u32 { INTEGER = 0, HEX_INTEGER = 1, diff --git a/vm/devices/net/vmswitch/src/dio.rs b/vm/devices/net/vmswitch/src/dio.rs index 7a7a8489c1..db5fd351f9 100644 --- a/vm/devices/net/vmswitch/src/dio.rs +++ b/vm/devices/net/vmswitch/src/dio.rs @@ -227,7 +227,7 @@ impl DioQueue { let (buf_index, offset) = self.state.in_next_full; let buf = &self.state.in_buf[buf_index][offset..]; - let (header, data) = DioNicPacketHeader::read_from_prefix(buf).unwrap(); // TODO: zerocopy: unwrap + let (header, data) = DioNicPacketHeader::read_from_prefix(buf).unwrap(); // TODO: zerocopy: unwrap (https://github.com/microsoft/openvmm/issues/759) let len = header.len as usize; let r = f(&data[..len]); if header.next != 0 { diff --git a/vm/devices/pci/vpci/src/device.rs b/vm/devices/pci/vpci/src/device.rs index de63739b77..0f59d41eba 100644 --- a/vm/devices/pci/vpci/src/device.rs +++ b/vm/devices/pci/vpci/src/device.rs @@ -270,12 +270,12 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let (msg, rest) = Ref::<_, protocol::DeviceTranslate>::from_prefix(buf) - .map_err(|_| PacketError::PacketTooSmall("translate"))?; // todo: zerocopy: map_err + .map_err(|_| PacketError::PacketTooSmall("translate"))?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if msg.msi_resource_count > protocol::MAX_SUPPORTED_INTERRUPT_MESSAGES { return Err(PacketError::TooManyMsis(msg.msi_resource_count)); @@ -294,7 +294,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result(packet: &queue::DataPacket<'_, T>) -> Result(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::PdoMessage::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("release"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, @@ -339,7 +339,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::CreateInterrupt::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("interrupt"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::CreateInterrupt { @@ -350,7 +350,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::CreateInterrupt2::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("interrupt2"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::CreateInterrupt { @@ -361,7 +361,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::DeleteInterrupt::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("delete_interrupt"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::DeleteInterrupt { @@ -372,7 +372,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::QueryResourceRequirements::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("query_req"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::QueryResources, @@ -381,7 +381,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::GetResources::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("get_resources"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::GetResources, @@ -390,7 +390,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::FdoD0Entry::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("power_on"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::FdoD0Entry { mmio_start: msg.mmio_start, } @@ -400,7 +400,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::QueryProtocolVersion::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("query_version"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::QueryProtocolVersion { version: msg.protocol_version, } @@ -408,7 +408,7 @@ fn parse_packet(packet: &queue::DataPacket<'_, T>) -> Result { let msg = protocol::DevicePowerChange::read_from_prefix(buf) .map_err(|_| PacketError::PacketTooSmall("device_power_state"))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) PacketData::DeviceRequest { slot: msg.slot, request: DeviceRequest::DevicePowerChange { diff --git a/vm/devices/pci/vpci/src/protocol.rs b/vm/devices/pci/vpci/src/protocol.rs index c82ae418c9..aa555fc72a 100644 --- a/vm/devices/pci/vpci/src/protocol.rs +++ b/vm/devices/pci/vpci/src/protocol.rs @@ -23,7 +23,7 @@ pub const MMIO_PAGE_CONFIG_SPACE: u64 = 0x1000; pub const MMIO_PAGE_MASK: u64 = !0xfff; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum MessageType: u32 { BUS_RELATIONS = 0x42490000, QUERY_BUS_RELATIONS = 0x42490001, @@ -55,7 +55,7 @@ open_enum! { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum ResourceType: u8 { NULL = 0, PORT = 1, @@ -72,7 +72,7 @@ pub const GUID_VPCI_VSP_CHANNEL_TYPE: Guid = Guid::from_static_str("44C4F61D-4444-4400-9D52-802E27EDE19F"); open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum ProtocolVersion: u32 { WIN8 = 0x00010000, WIN10 = 0x00010001, @@ -92,7 +92,7 @@ pub struct QueryProtocolVersion { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Status: u32 { SUCCESS = 0, REVISION_MISMATCH = 0xC0000059, @@ -298,26 +298,26 @@ impl MsiResource { pub fn remapped(&self) -> &MsiResourceRemapped { MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) pub fn descriptor(&self) -> &MsiResourceDescriptor { MsiResourceDescriptor::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor { MsiResourceDescriptor::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } // >= VPCI_PROTOCOL_VERSION_RS1 @@ -348,26 +348,26 @@ impl MsiResource2 { pub fn remapped(&self) -> &MsiResourceRemapped { MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) pub fn descriptor(&self) -> &MsiResourceDescriptor2 { MsiResourceDescriptor2::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor2 { MsiResourceDescriptor2::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } #[repr(C)] @@ -397,26 +397,26 @@ impl MsiResource3 { pub fn remapped(&self) -> &MsiResourceRemapped { MsiResourceRemapped::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn remapped_mut(&mut self) -> &mut MsiResourceRemapped { MsiResourceRemapped::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) pub fn descriptor(&self) -> &MsiResourceDescriptor3 { MsiResourceDescriptor3::ref_from_prefix(self.resource_data.as_bytes()) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn descriptor_mut(&mut self) -> &mut MsiResourceDescriptor3 { MsiResourceDescriptor3::mut_from_prefix(self.resource_data.as_mut_bytes()) .unwrap() .0 - } // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + } // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub const MAX_SUPPORTED_INTERRUPT_MESSAGES: u32 = 494; // 500 resources minus 6 for the BARs. @@ -484,7 +484,7 @@ pub struct DevicePowerChange { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum DevicePowerState: u32 { D0 = 1, D3 = 4, diff --git a/vm/devices/serial/vmbus_serial_guest/src/lib.rs b/vm/devices/serial/vmbus_serial_guest/src/lib.rs index f03ee553d5..107be0c854 100644 --- a/vm/devices/serial/vmbus_serial_guest/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_guest/src/lib.rs @@ -227,7 +227,7 @@ impl VmbusSerialDriver { let n = self.pipe.as_mut().recv(&mut buf).await?; let response = protocol::VersionRequestResponse::read_from_prefix(&buf[..n]) .map_err(|_| ErrorInner::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let host_response = response .header @@ -305,7 +305,7 @@ impl VmbusSerialDriver { fn handle_message(&mut self, buf: &[u8]) -> Result<(), ErrorInner> { let header = protocol::Header::read_from_prefix(buf) .map_err(|_| ErrorInner::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if header.message_version != MessageVersions::HEADER_VERSION_1 { return Err(ErrorInner::InvalidMessageVersion(header.message_version)); } @@ -314,7 +314,7 @@ impl VmbusSerialDriver { HostRequests::GET_RX_DATA => { let response = protocol::RxDataResponse::read_from_prefix(buf) .map_err(|_| ErrorInner::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let b = response .buffer @@ -339,7 +339,7 @@ impl VmbusSerialDriver { GuestNotifications::SET_MODEM_STATUS => { let status = protocol::SetModumStatusMessage::read_from_prefix(buf) .map_err(|_| ErrorInner::TruncatedMessage)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) self.connected = status.is_connected != 0; } diff --git a/vm/devices/serial/vmbus_serial_host/src/lib.rs b/vm/devices/serial/vmbus_serial_host/src/lib.rs index 45d65b95b1..30d53330e5 100644 --- a/vm/devices/serial/vmbus_serial_host/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_host/src/lib.rs @@ -372,7 +372,7 @@ impl SerialChannel { // Extract header from read buf. let header = protocol::Header::read_from_prefix(buf) .map_err(|_| Error::MessageSizeHeader(buf.len()))? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) tracing::trace!("read header {:?}", &header); @@ -415,7 +415,7 @@ impl SerialChannel { HostNotifications::TX_DATA_AVAILABLE => { let message = protocol::TxDataAvailableMessage::read_from_prefix(buf) .map_err(|_| { - // todo: zerocopy: map_err + // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Error::MessageSizeHostNotification { len: buf.len(), notification, diff --git a/vm/devices/serial/vmbus_serial_protocol/src/lib.rs b/vm/devices/serial/vmbus_serial_protocol/src/lib.rs index 91bbe94f3b..f0c473115d 100644 --- a/vm/devices/serial/vmbus_serial_protocol/src/lib.rs +++ b/vm/devices/serial/vmbus_serial_protocol/src/lib.rs @@ -48,7 +48,7 @@ const fn make_version(major: u16, minor: u16) -> u32 { open_enum! { /// Protocol versions. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum ProtocolVersions: u32 { /// Represents the MANGANESE protocol version. MANGANESE = make_version(1, 0), @@ -57,7 +57,7 @@ open_enum! { open_enum! { /// Header message versions. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum MessageVersions: u8 { /// Invalid version. INVALID = 0, @@ -68,7 +68,7 @@ open_enum! { open_enum! { /// Enum for the different message types. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum MessageTypes: u8 { /// Invalid message type. INVALID = 0, @@ -86,7 +86,7 @@ open_enum! { open_enum! { /// Enum for the different host notification messages. /// These are aysynchronous messages sent by the HCL to the Host. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HostNotifications: u8 { /// Invalid message. INVALID = 0, @@ -100,7 +100,7 @@ open_enum! { open_enum! { /// Enum for the different guest notification messages. /// These are asynchronous messages sent by the Host to the HCL. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum GuestNotifications: u8 { /// Invalid message. INVALID = 0, @@ -119,7 +119,7 @@ open_enum! { /// These are synchronous messages sent by the HCL to the host. /// Note that the host response shares the same enum. /// (Each request has a response of the same ID) - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HostRequests: u16 { /// Invalid message. INVALID = 0, diff --git a/vm/devices/storage/disk_blockdevice/src/ioctl.rs b/vm/devices/storage/disk_blockdevice/src/ioctl.rs index 57a9219cf4..83e2320a1b 100644 --- a/vm/devices/storage/disk_blockdevice/src/ioctl.rs +++ b/vm/devices/storage/disk_blockdevice/src/ioctl.rs @@ -47,7 +47,7 @@ ioctl_none_bad!(blk_eject_ioctl, 0x5309); ioctl_write_int_bad!(blk_lockdoor_ioctl, 0x5329); open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] enum BlkStatus: u8 { BLK_STS_OK = 0, BLK_STS_NOTSUPP = 1, diff --git a/vm/devices/storage/disk_blockdevice/src/nvme.rs b/vm/devices/storage/disk_blockdevice/src/nvme.rs index e841740516..a503741900 100644 --- a/vm/devices/storage/disk_blockdevice/src/nvme.rs +++ b/vm/devices/storage/disk_blockdevice/src/nvme.rs @@ -197,7 +197,7 @@ fn nvme_reservation_report( let report_header = nvm::ReservationReportExtended::read_from_prefix(&*buffer) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let mut controllers = Vec::new(); // Return all controllers or none so caller can set correct buffer size and call again @@ -212,7 +212,7 @@ fn nvme_reservation_report( let controller = nvm::RegisteredControllerExtended::read_from_prefix(&buffer[source..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) tracing::debug!(controller = ?controller, "nvme_reservation_report"); controllers.push(controller); source += source_step; @@ -268,7 +268,7 @@ pub fn nvme_identify_namespace_data( &cmd, )?; - let data = nvm::IdentifyNamespace::read_from_prefix(buffer).unwrap().0; // todo: zerocopy: use-rest-of-range + let data = nvm::IdentifyNamespace::read_from_prefix(buffer).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) tracing::trace!(?data, "nvme_identify_namespace_data"); Ok(data) } @@ -293,7 +293,7 @@ pub fn nvme_identify_controller_data(file: &fs::File) -> io::Result NvmeDriver { admin: None, // Updated below. identify: Some(Arc::new( spec::IdentifyController::read_from_bytes(saved_state.identify_ctrl.as_bytes()) - .map_err(|_| RestoreError::InvalidData)?, // todo: zerocopy: map_err + .map_err(|_| RestoreError::InvalidData)?, // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) )), driver: driver.clone(), io_issuers, diff --git a/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs b/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs index 1724cfceb9..adf48f2e99 100644 --- a/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs +++ b/vm/devices/storage/disk_nvme/nvme_driver/src/namespace.rs @@ -406,7 +406,7 @@ impl Namespace { let header = nvm::ReservationReportExtended::read_from_prefix(&data[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let len = size_of_val(&header) + header.report.regctl.get() as usize * size_of::(); diff --git a/vm/devices/storage/ide/src/lib.rs b/vm/devices/storage/ide/src/lib.rs index 5f558cb055..315de6af49 100644 --- a/vm/devices/storage/ide/src/lib.rs +++ b/vm/devices/storage/ide/src/lib.rs @@ -2294,7 +2294,7 @@ mod tests { ide_device.io_read(IdeIoPort::PRI_DATA.0, data).unwrap(); let features = protocol::IdeFeatures::read_from_prefix(&data[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let ex_features = protocol::IdeFeatures { config_bits: 0x85C0, serial_no: *b" ", @@ -2340,7 +2340,7 @@ mod tests { ide_device.io_read(IdeIoPort::PRI_DATA.0, data).unwrap(); let features = protocol::IdeFeatures::read_from_prefix(&data[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let total_chs_sectors: u32 = geometry.sectors_per_track * geometry.cylinder_count * geometry.head_count; diff --git a/vm/devices/storage/nvme/src/namespace.rs b/vm/devices/storage/nvme/src/namespace.rs index 28b578f40a..ffd1662b66 100644 --- a/vm/devices/storage/nvme/src/namespace.rs +++ b/vm/devices/storage/nvme/src/namespace.rs @@ -40,7 +40,7 @@ impl Namespace { } pub fn identify(&self, buf: &mut [u8]) { - let id = nvm::IdentifyNamespace::mut_from_prefix(buf).unwrap().0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + let id = nvm::IdentifyNamespace::mut_from_prefix(buf).unwrap().0; // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let size = self.disk.sector_count(); let rescap = if let Some(pr) = self.disk.pr() { @@ -71,7 +71,7 @@ impl Namespace { pub fn namespace_id_descriptor(&self, buf: &mut [u8]) { let id = nvm::NamespaceIdentificationDescriptor::mut_from_prefix(buf) .unwrap() - .0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let mut nid = [0u8; 0x10]; if let Some(guid) = self.disk.disk_id() { nid = guid; @@ -182,7 +182,7 @@ impl Namespace { nvm::NvmOpcode::DSM => { let cdw10 = nvm::Cdw10Dsm::from(command.cdw10); let cdw11 = nvm::Cdw11Dsm::from(command.cdw11); - // todo: zerocopy: manual: review carefully! + // TODO: zerocopy: manual: review carefully! (https://github.com/microsoft/openvmm/issues/759) let mut dsm_ranges = <[nvm::DsmRange]>::new_box_zeroed_with_elems(cdw10.nr_z() as usize + 1) .unwrap(); diff --git a/vm/devices/storage/nvme/src/workers/admin.rs b/vm/devices/storage/nvme/src/workers/admin.rs index edf59c0bec..ad147c0377 100644 --- a/vm/devices/storage/nvme/src/workers/admin.rs +++ b/vm/devices/storage/nvme/src/workers/admin.rs @@ -562,7 +562,7 @@ impl AdminHandler { let buf = buf.as_mut_bytes(); match spec::Cns(cdw10.cns()) { spec::Cns::CONTROLLER => { - let id = spec::IdentifyController::mut_from_prefix(buf).unwrap().0; // todo: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range + let id = spec::IdentifyController::mut_from_prefix(buf).unwrap().0; // TODO: zerocopy: from-prefix (mut_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) *id = self.identify_controller(); write!( diff --git a/vm/devices/storage/nvme_spec/src/nvm.rs b/vm/devices/storage/nvme_spec/src/nvm.rs index 2017331195..71eb26af3d 100644 --- a/vm/devices/storage/nvme_spec/src/nvm.rs +++ b/vm/devices/storage/nvme_spec/src/nvm.rs @@ -286,7 +286,7 @@ open_enum! { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum ReservationType: u8 { WRITE_EXCLUSIVE = 1, EXCLUSIVE_ACCESS = 2, diff --git a/vm/devices/storage/scsi_defs/src/lib.rs b/vm/devices/storage/scsi_defs/src/lib.rs index c638144fe7..45163d1938 100644 --- a/vm/devices/storage/scsi_defs/src/lib.rs +++ b/vm/devices/storage/scsi_defs/src/lib.rs @@ -18,7 +18,7 @@ type U32BE = zerocopy::byteorder::U32; type U64BE = zerocopy::byteorder::U64; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum ScsiOp: u8 { TEST_UNIT_READY = 0x00, REZERO_UNIT = 0x01, @@ -595,7 +595,7 @@ impl SenseData { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SenseKey: u8 { NO_SENSE = 0x00, RECOVERED_ERROR = 0x01, @@ -617,7 +617,7 @@ open_enum! { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SenseDataErrorCode: u8 { FIXED_CURRENT = 0x70, FIXED_DEFERRED = 0x71, @@ -627,7 +627,7 @@ open_enum! { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum AdditionalSenseCode: u8 { NO_SENSE = 0x00, NO_SEEK_COMPLETE = 0x02, @@ -713,7 +713,7 @@ pub const SCSI_SENSEQ_INCOMPATIBLE_FORMAT: u8 = 0x02; pub const SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED: u8 = 0x02; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum ScsiStatus: u8 { GOOD = 0x00, diff --git a/vm/devices/storage/scsi_defs/src/srb.rs b/vm/devices/storage/scsi_defs/src/srb.rs index ab849a70c3..cca8bc2d66 100644 --- a/vm/devices/storage/scsi_defs/src/srb.rs +++ b/vm/devices/storage/scsi_defs/src/srb.rs @@ -33,7 +33,7 @@ impl SrbStatusAndFlags { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SrbStatus: u8 { PENDING = 0x00, SUCCESS = 0x01, diff --git a/vm/devices/storage/scsidisk/src/atapi_scsi.rs b/vm/devices/storage/scsidisk/src/atapi_scsi.rs index 470dd7f704..1e98915bbe 100644 --- a/vm/devices/storage/scsidisk/src/atapi_scsi.rs +++ b/vm/devices/storage/scsidisk/src/atapi_scsi.rs @@ -140,7 +140,7 @@ impl AtapiScsiDisk { ) -> ScsiResult { let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; let min = size_of::(); @@ -195,7 +195,7 @@ impl AtapiScsiDisk { ) -> ScsiResult { let cdb = scsi::ReportLuns::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; if allocation_length == 0 { return ScsiResult { diff --git a/vm/devices/storage/scsidisk/src/getlbastatus.rs b/vm/devices/storage/scsidisk/src/getlbastatus.rs index 06b028246e..a3b9e3329f 100644 --- a/vm/devices/storage/scsidisk/src/getlbastatus.rs +++ b/vm/devices/storage/scsidisk/src/getlbastatus.rs @@ -93,7 +93,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::GetLbaStatus::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Validate the request parameters. let start_lba = cdb.start_lba.get(); diff --git a/vm/devices/storage/scsidisk/src/inquiry.rs b/vm/devices/storage/scsidisk/src/inquiry.rs index e4d9e6a1c8..127fc16b17 100644 --- a/vm/devices/storage/scsidisk/src/inquiry.rs +++ b/vm/devices/storage/scsidisk/src/inquiry.rs @@ -471,7 +471,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; if external_data.len() < allocation_length { diff --git a/vm/devices/storage/scsidisk/src/lib.rs b/vm/devices/storage/scsidisk/src/lib.rs index 6ac2ca0c30..7b8dc45462 100644 --- a/vm/devices/storage/scsidisk/src/lib.rs +++ b/vm/devices/storage/scsidisk/src/lib.rs @@ -278,7 +278,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; let min = size_of::(); @@ -325,14 +325,14 @@ impl SimpleScsiDisk { if is_mode_select_10 { let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) request_length = cdb.parameter_list_length.get() as usize; header_size = MODE_PARAMETER_HEADER10_SIZE; is_spbit_set = cdb.flags.spbit(); } else { let cdb = scsi::ModeSelect::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) request_length = cdb.parameter_list_length as usize; header_size = MODE_PARAMETER_HEADER_SIZE; is_spbit_set = cdb.flags.spbit(); @@ -373,13 +373,13 @@ impl SimpleScsiDisk { &buffer[..MODE_PARAMETER_HEADER10_SIZE], ) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) usize::from(temp10.block_descriptor_length) } else { let temp = scsi::ModeParameterHeader::read_from_prefix(&buffer[..MODE_PARAMETER_HEADER_SIZE]) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) temp.block_descriptor_length as usize }; @@ -398,7 +398,7 @@ impl SimpleScsiDisk { &buffer[skipped..skipped + MODE_CACHING_PAGE_SIZE], ) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) if page.page_code != scsi::MODE_PAGE_CACHING || (page.page_length as usize) < MODE_CACHING_PAGE_SIZE || ((page.flags & scsi::MODE_CACHING_WRITE_CACHE_ENABLE == 0) @@ -450,7 +450,7 @@ impl SimpleScsiDisk { if is_mode_sense_10 { let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) allocation_length = cdb.allocation_length.get() as usize; page_code = cdb.flags2.page_code(); page_control = cdb.flags2.pc() << 6; @@ -458,7 +458,7 @@ impl SimpleScsiDisk { } else { let cdb = scsi::ModeSense::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) allocation_length = cdb.allocation_length as usize; page_code = cdb.flags2.page_code(); page_control = cdb.flags2.pc() << 6; @@ -551,7 +551,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::ServiceActionIn16::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) match cdb.service_action & 0x1f { scsi::SERVICE_ACTION_READ_CAPACITY16 => { let min = size_of::(); @@ -638,7 +638,7 @@ impl SimpleScsiDisk { tracing::debug!("handle_verify_validation"); let (start_lba, lba_count) = match op { ScsiOp::VERIFY | ScsiOp::WRITE_VERIFY => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -649,7 +649,7 @@ impl SimpleScsiDisk { ) } ScsiOp::VERIFY12 | ScsiOp::WRITE_VERIFY12 => { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -660,7 +660,7 @@ impl SimpleScsiDisk { ) } ScsiOp::VERIFY16 | ScsiOp::WRITE_VERIFY16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) (cdb.logical_block.get(), cdb.transfer_blocks.get() as u64) } _ => unreachable!(), @@ -680,7 +680,7 @@ impl SimpleScsiDisk { tracing::debug!("handle_send_diagnostic_validation"); let cdb = scsi::SendDiagnostic::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.self_test_code() == 0 && !cdb.flags.page_format() && cdb.parameter_list_length.get() == 0 @@ -739,7 +739,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -775,7 +775,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::Cdb6ReadWrite::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let len = cdb.transfer_blocks as u64; let offset = u32::from_be_bytes([ 0, @@ -813,7 +813,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -846,7 +846,7 @@ impl SimpleScsiDisk { request: &Request, sector_count: u64, ) -> Result { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let len = cdb.transfer_blocks.get() as u64; let offset = cdb.logical_block.get(); let sector_shift = self.sector_shift; @@ -879,7 +879,7 @@ impl SimpleScsiDisk { let op = request.scsiop(); let mut p = match op { ScsiOp::WRITE_SAME => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.flags.relative_address() { tracing::debug!(flags = ?cdb.flags, "doesn't support relative address"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); @@ -893,7 +893,7 @@ impl SimpleScsiDisk { } } ScsiOp::WRITE_SAME16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) WriteSameParameters { start_lba: cdb.logical_block.get(), lba_count: cdb.transfer_blocks.get() as usize, @@ -1218,7 +1218,7 @@ impl SimpleScsiDisk { async fn handle_start_stop(&self, request: &Request) -> Result { let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if cdb.immediate & scsi::IMMEDIATE_BIT != 0 { tracing::debug!("immediate bit is not supported"); return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); diff --git a/vm/devices/storage/scsidisk/src/reservation.rs b/vm/devices/storage/scsidisk/src/reservation.rs index b0e083ee90..bab2c14ee7 100644 --- a/vm/devices/storage/scsidisk/src/reservation.rs +++ b/vm/devices/storage/scsidisk/src/reservation.rs @@ -287,7 +287,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::PersistentReserveIn::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; if allocation_length > external_data.len() { tracelimit::error_ratelimited!( @@ -343,7 +343,7 @@ impl SimpleScsiDisk { ) -> Result { let cdb = scsi::PersistentReserveOut::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let service_action = cdb.service_action.service_action(); const EXPECT_PARAMETER_LIST_LENGTH: usize = size_of::(); diff --git a/vm/devices/storage/scsidisk/src/scsidvd/mod.rs b/vm/devices/storage/scsidisk/src/scsidvd/mod.rs index 06d5a21c9b..461106f193 100644 --- a/vm/devices/storage/scsidisk/src/scsidvd/mod.rs +++ b/vm/devices/storage/scsidisk/src/scsidvd/mod.rs @@ -332,7 +332,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbInquiry::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; @@ -421,7 +421,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbGetEventStatusNotification::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.event_list_length.get() as usize; let mut pending_medium_event = IsoMediumEvent::None; @@ -703,7 +703,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbGetConfiguration::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let request_type = cdb.flags.request_type(); let starting_feature = cdb.starting_feature.get() as usize; let allocation_length = cdb.allocation_length.get() as usize; @@ -816,7 +816,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbReadToc::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; let format = cdb.format2 & 0x0f; let msf = cdb.flag1.msf(); @@ -911,7 +911,7 @@ impl SimpleScsiDvd { async fn handle_start_stop_unit(&self, request: &Request) -> Result { let cdb = scsi::StartStop::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let start = cdb.flag.start(); let load_eject = cdb.flag.load_eject(); @@ -979,7 +979,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbRequestSense::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length as usize; let new_sense_data = SenseData::new(SenseKey::NO_SENSE, AdditionalSenseCode::NO_SENSE, 0x00); @@ -1005,7 +1005,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::ModeSense10::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let page_code = cdb.flags2.page_code(); let allocation_length = cdb.allocation_length.get() as usize; let pc = cdb.flags2.pc() << 6; @@ -1078,7 +1078,7 @@ impl SimpleScsiDvd { fn handle_medium_removal_iso(&self, request: &Request) -> Result { let cdb = scsi::CdbMediaRemoval::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // prevent/allow media removal based on the Persistent/Prevent bits let mut media_state = self.media_state.lock(); @@ -1094,7 +1094,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::ModeSelect10::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let sp_bit = cdb.flags.spbit(); let request_length = cdb.parameter_list_length.get() as usize; @@ -1152,7 +1152,7 @@ impl SimpleScsiDvd { + size_of::()], ) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, zerocopy: err (https://github.com/microsoft/openvmm/issues/759) match mode_page_error_recovery.page_code { scsi::MODE_PAGE_ERROR_RECOVERY => { // ModePageErrorRecovery = (PMODE_READ_WRITE_RECOVERY_PAGE) (Buffer + sizeof (MODE_PARAMETER_HEADER10)); @@ -1183,7 +1183,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbReadTrackInformation::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let number_type = cdb.flag.number_type(); let open = cdb.flag.open(); let logical_track_number = cdb.logical_track_number.get() as usize; @@ -1278,7 +1278,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbReadDVDStructure::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let media_type = cdb.media_type; let layer = cdb.layer; let allocation_length = cdb.allocation_length.get() as usize; @@ -1387,7 +1387,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbGetPerformance::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let data_type = cdb.data_type; let write = cdb.flags.write(); let tolerance = cdb.flags.tolerance(); @@ -1481,7 +1481,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbMechStatus::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let allocation_length = cdb.allocation_length.get() as usize; if allocation_length > external_data.len() { @@ -1511,7 +1511,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbReadBufferCapacity::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let block_info = cdb.flags.block_info(); let allocation_length = cdb.allocation_length.get() as usize; @@ -1542,7 +1542,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbReadDiscInformation::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let data_type = cdb.flags.data_type(); let allocation_length = cdb.allocation_length.get() as usize; @@ -1595,7 +1595,7 @@ impl SimpleScsiDvd { ) -> Result { let cdb = scsi::CdbSetStreaming::read_from_prefix(&request.cdb[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let parameter_list_length = usize::from(cdb.parameter_list_length); let mut buffer = vec![0; parameter_list_length]; @@ -1628,7 +1628,7 @@ impl SimpleScsiDvd { let performance_descriptor = scsi::SetStreamingPerformanceDescriptor::read_from_prefix(&buffer[..]) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // If RDD bit is set to one, it shall indicate that the drive is to return to its // default performance settings and the remaining fields in this descriptor shall be ignored. @@ -2089,21 +2089,21 @@ impl SimpleScsiDvd { ) -> Result { let (len, offset) = match op { ScsiOp::READ => { - let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb10::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) ( cdb.transfer_blocks.get() as u64, cdb.logical_block.get() as u64, ) } ScsiOp::READ12 => { - let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb12::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) ( cdb.transfer_blocks.get() as u64, cdb.logical_block.get() as u64, ) } ScsiOp::READ16 => { - let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Cdb16::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) (cdb.transfer_blocks.get() as u64, cdb.logical_block.get()) } _ => unreachable!(), diff --git a/vm/devices/storage/scsidisk/src/unmap.rs b/vm/devices/storage/scsidisk/src/unmap.rs index ba61d7e5f1..1af218369f 100644 --- a/vm/devices/storage/scsidisk/src/unmap.rs +++ b/vm/devices/storage/scsidisk/src/unmap.rs @@ -31,8 +31,8 @@ fn validate_unmap_list_header( let unmap_list_header = scsi::UnmapListHeader::read_from_prefix(&buffer[0..size_of::()]) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range - let unmap_list_header_length = unmap_list_header.data_length.get() as usize; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) + let unmap_list_header_length = unmap_list_header.data_length.get() as usize; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let expected = allocation_length - size_of_val(&unmap_list_header.data_length); if unmap_list_header_length != expected { tracelimit::error_ratelimited!(unmap_list_header_length, expected, "validate_unmap_error"); @@ -109,7 +109,7 @@ impl SimpleScsiDisk { &buffer[unmap_info.offset..unmap_info.offset + size_of::()], ) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, err + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range, err (https://github.com/microsoft/openvmm/issues/759) let start_lba = block_descriptor.start_lba.get(); let lba_count = block_descriptor.lba_count.get() as u64; @@ -136,7 +136,7 @@ impl SimpleScsiDisk { return Err(ScsiError::IllegalRequest(AdditionalSenseCode::INVALID_CDB)); } - let cdb = scsi::Unmap::read_from_prefix(&request.cdb[..]).unwrap().0; // todo: zerocopy: use-rest-of-range + let cdb = scsi::Unmap::read_from_prefix(&request.cdb[..]).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // make sure the data buffer is large enough for UNMAP_LIST_HEADER let allocation_length = cdb.allocation_length.get() as usize; diff --git a/vm/devices/storage/storvsp/src/lib.rs b/vm/devices/storage/storvsp/src/lib.rs index 2358933cd6..13b87c9f1b 100644 --- a/vm/devices/storage/storvsp/src/lib.rs +++ b/vm/devices/storage/storvsp/src/lib.rs @@ -628,7 +628,7 @@ impl ScsiCommandQueue { ScsiOp::INQUIRY => { let cdb = scsi::CdbInquiry::ref_from_prefix(&request.payload) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) if external_data.len() < cdb.allocation_length.get() as usize || request.data_in != protocol::SCSI_IOCTL_DATA_IN || (cdb.allocation_length.get() as usize) < size_of::() diff --git a/vm/devices/storage/storvsp/src/protocol.rs b/vm/devices/storage/storvsp/src/protocol.rs index a3aa1fb79b..6c814778e7 100644 --- a/vm/devices/storage/storvsp/src/protocol.rs +++ b/vm/devices/storage/storvsp/src/protocol.rs @@ -45,7 +45,7 @@ pub const VERSION_BLUE: u16 = version(6, 0); pub const VERSION_THRESHOLD: u16 = version(6, 2); open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum NtStatus: u32 { SUCCESS = 0x0000_0000, @@ -79,7 +79,7 @@ pub struct Packet { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum Operation: u32 { COMPLETE_IO = 1, diff --git a/vm/devices/tpm/src/lib.rs b/vm/devices/tpm/src/lib.rs index 192fd2f78f..e415586d9e 100644 --- a/vm/devices/tpm/src/lib.rs +++ b/vm/devices/tpm/src/lib.rs @@ -1160,7 +1160,7 @@ impl MmioIntercept for Tpm { let cmd_header = tpm20proto::protocol::common::CmdHeader::ref_from_prefix( &self.command_buffer, ) - .ok() // todo: zerocopy: err + .ok() // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) .and_then(|(cmd_header, _)| cmd_header.command_code.into_enum()); tracing::debug!( @@ -1192,7 +1192,7 @@ impl MmioIntercept for Tpm { response_code = ?tpm20proto::protocol::common::ReplyHeader::ref_from_prefix( &self.tpm_engine_helper.reply_buffer, ) - .map(|(reply, _)| reply.response_code), // todo: zerocopy: manual: review carefully! + .map(|(reply, _)| reply.response_code), // TODO: zerocopy: manual: review carefully! (https://github.com/microsoft/openvmm/issues/759) "response code from guest tpm cmd", ); @@ -1242,7 +1242,7 @@ mod io_port_interface { open_enum::open_enum! { /// I/O port command definitions - #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes)] #[inspect(debug)] pub enum TpmIoCommand: u32 { /// It can be used for engine vs. guest version negotiation. Not used. @@ -1282,7 +1282,7 @@ mod io_port_interface { /// Table 2: Physical Presence Interface Operation Summary for TPM 2.0 /// /// Part of the Physical Presence Interface Specification - TCG PC Client Platform - #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(Inspect, IntoBytes, Immutable, KnownLayout, FromBytes)] #[inspect(debug)] pub enum PpiOperation: u32 { NO_OP = 0, @@ -1331,7 +1331,7 @@ mod persist_restore { } pub(crate) fn deserialize_ppi_state(buf: Vec) -> Option { - let saved = state::PersistedPpiState::read_from_bytes(buf.as_bytes()).ok()?; // todo: zerocopy: map_err + let saved = state::PersistedPpiState::read_from_bytes(buf.as_bytes()).ok()?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let state::PersistedPpiState { pending_ppi_operation, in_query_ppi_operation, diff --git a/vm/devices/tpm/src/tpm20proto.rs b/vm/devices/tpm/src/tpm20proto.rs index fb5bf877ff..3d305d2808 100644 --- a/vm/devices/tpm/src/tpm20proto.rs +++ b/vm/devices/tpm/src/tpm20proto.rs @@ -909,7 +909,7 @@ pub mod protocol { // `Reply::deserialize` guarantees this should not fail let header = ReplyHeader::ref_from_prefix(self.as_bytes()) .expect("unexpected response size") - .0; // todo: zerocopy: error + .0; // TODO: zerocopy: error (https://github.com/microsoft/openvmm/issues/759) header.base_validation(session_tag, self.payload_size() as u32) } fn deserialize(bytes: &[u8]) -> Option; @@ -962,7 +962,7 @@ pub mod protocol { return None; } - let size: u16 = u16_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify + let size: u16 = u16_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) if size as usize > MAX_DIGEST_BUFFER_SIZE { return None; } @@ -1034,7 +1034,7 @@ pub mod protocol { return None; } - let count: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify + let count: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) if count > 5 { return None; } @@ -1174,12 +1174,12 @@ pub mod protocol { return None; } - let scheme = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let scheme = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let hash_alg = if scheme != AlgIdEnum::NULL.into() { start = end; end += size_of::(); - AlgId::read_from_prefix(&bytes[start..end]).ok()?.0 // todo: zerocopy: use-rest-of-range, option-to-error + AlgId::read_from_prefix(&bytes[start..end]).ok()?.0 // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) } else { AlgId::new(0) }; @@ -1243,16 +1243,16 @@ pub mod protocol { return None; } - let algorithm = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let algorithm = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let (key_bits, mode) = if algorithm != AlgIdEnum::NULL.into() { start = end; end += size_of::(); - let key_bits = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let key_bits = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); - let mode = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let mode = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) (key_bits, mode) } else { @@ -1327,7 +1327,7 @@ pub mod protocol { let scheme = TpmtRsaScheme::deserialize(&bytes[start..])?; end += scheme.payload_size(); - // todo: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid + // TODO: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid (https://github.com/microsoft/openvmm/issues/759) // manual size checks. Leaving this code as-is to reduce risk of the 0.7 -> 0.8 move. start = end; end += size_of::(); @@ -1336,7 +1336,7 @@ pub mod protocol { } let key_bits = u16_be::read_from_bytes(&bytes[start..end]).ok()?; - // todo: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid + // TODO: zerocopy: as of zerocopy 0.8 this can be simplified with `read_from_bytes`....ok()?, to avoid (https://github.com/microsoft/openvmm/issues/759) // manual size checks. Leaving this code as-is to reduce risk of the 0.7 -> 0.8 move. start = end; end += size_of::(); @@ -1420,21 +1420,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let r#type = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let r#type = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let object_attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify + let object_attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let auth_policy = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1508,7 +1508,7 @@ pub mod protocol { return None; } - let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let public_area = TpmtPublic::deserialize(&bytes[start..])?; @@ -1563,7 +1563,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parent_name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let parent_name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; let parent_name = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1619,7 +1619,7 @@ pub mod protocol { return None; } - let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let creation_data = TpmsCreationData::deserialize(&bytes[start..])?; @@ -1656,14 +1656,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let tag = SessionTag::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let tag = SessionTag::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let hierarchy = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let hierarchy = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; let digest = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1735,21 +1735,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let nv_index: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify + let nv_index: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let name_alg = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // todo: zerocopy: simplify + let attributes: u32 = u32_be::read_from_bytes(&bytes[start..end]).ok()?.into(); // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let auth_policy = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -1760,7 +1760,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let data_size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let data_size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) Some(Self { nv_index: nv_index.into(), @@ -1822,7 +1822,7 @@ pub mod protocol { return None; } - let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let size = u16_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let nv_public = TpmsNvPublic::deserialize(&bytes[start..])?; @@ -1885,7 +1885,7 @@ pub mod protocol { type Command = ClearControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -1936,7 +1936,7 @@ pub mod protocol { type Command = ClearCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -1986,7 +1986,7 @@ pub mod protocol { type Command = StartupCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2026,7 +2026,7 @@ pub mod protocol { type Command = SelfTestCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2084,7 +2084,7 @@ pub mod protocol { type Command = HierarchyControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2119,7 +2119,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let hash = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let hash = AlgId::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); @@ -2249,7 +2249,7 @@ pub mod protocol { type Command = PcrAllocateCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2301,7 +2301,7 @@ pub mod protocol { type Command = ChangeSeedCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: option-to-error + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: option-to-error (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2420,7 +2420,7 @@ pub mod protocol { fn deserialize(bytes: &[u8]) -> Option { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -2431,11 +2431,11 @@ pub mod protocol { start = end; end += size_of::(); - let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); - let param_size = u32_be::read_from_bytes(&bytes[start..end]).ok()?; // todo: zerocopy: simplify + let param_size = u32_be::read_from_bytes(&bytes[start..end]).ok()?; // TODO: zerocopy: simplify (https://github.com/microsoft/openvmm/issues/759) start = end; let out_public = Tpm2bPublic::deserialize(&bytes[start..])?; @@ -2461,7 +2461,7 @@ pub mod protocol { end += size_of::(); let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if header.size.get() as usize != end { return None; @@ -2533,7 +2533,7 @@ pub mod protocol { type Command = FlushContextCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2589,7 +2589,7 @@ pub mod protocol { type Command = EvictControlCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: error-to-option + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: error-to-option (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2635,7 +2635,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -2767,7 +2767,7 @@ pub mod protocol { type Command = NvDefineSpaceCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2819,7 +2819,7 @@ pub mod protocol { type Command = NvUndefineSpaceCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -2865,7 +2865,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -3016,7 +3016,7 @@ pub mod protocol { type Command = NvWriteCmd; fn deserialize(bytes: &[u8]) -> Option { - Some(Self::read_from_prefix(bytes).ok()?.0) // todo: zerocopy: tpm better error? + Some(Self::read_from_prefix(bytes).ok()?.0) // TODO: zerocopy: tpm better error? (https://github.com/microsoft/openvmm/issues/759) } fn payload_size(&self) -> usize { @@ -3071,7 +3071,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let header = CmdHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = CmdHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if header.command_code != CommandCodeEnum::NV_Read.into() { return None; @@ -3082,21 +3082,21 @@ pub mod protocol { if bytes.len() < end { return None; } - let auth_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let auth_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let nv_index = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let nv_index = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let auth_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let auth_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Skip authorization area end += auth_size.get() as usize; @@ -3106,14 +3106,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let size = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let size = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let offset = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let offset = u16_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) Some(Self { header, @@ -3149,7 +3149,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -3166,7 +3166,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; let data = Tpm2bBuffer::deserialize(&bytes[start..])?; @@ -3179,7 +3179,7 @@ pub mod protocol { } let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if header.size.get() as usize != end { return None; @@ -3350,7 +3350,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -3367,7 +3367,7 @@ pub mod protocol { if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let expected_auth_start = end + parameter_size.get() as usize; start = end; @@ -3384,7 +3384,7 @@ pub mod protocol { } let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if header.size.get() as usize != end { return None; @@ -3498,7 +3498,7 @@ pub mod protocol { let mut start = 0; let mut end = size_of::(); - let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let header = ReplyHeader::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Handle the command failure. if header.size.get() as usize == end { @@ -3516,14 +3516,14 @@ pub mod protocol { if bytes.len() < end { return None; } - let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let object_handle = ReservedHandle::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) start = end; end += size_of::(); if bytes.len() < end { return None; } - let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let parameter_size = u32_be::read_from_prefix(&bytes[start..end]).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let expected_auth_start = end + parameter_size.get() as usize; start = end; @@ -3540,7 +3540,7 @@ pub mod protocol { } let auth = common::ReplyAuth::read_from_prefix(&bytes[start..end]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if header.size.get() as usize != end { return None; diff --git a/vm/devices/uidevices/src/keyboard/mod.rs b/vm/devices/uidevices/src/keyboard/mod.rs index d7b31af626..c2ce6bcf5d 100644 --- a/vm/devices/uidevices/src/keyboard/mod.rs +++ b/vm/devices/uidevices/src/keyboard/mod.rs @@ -57,19 +57,19 @@ async fn recv_packet(reader: &mut impl AsyncRecv) -> Result { let n = reader.recv(&mut buf).await.map_err(Error::Io)?; let buf = &buf[..n]; let (header, buf) = - protocol::MessageHeader::read_from_prefix(buf).map_err(|_| Error::BadPacket)?; // TODO: zerocopy: map_err + protocol::MessageHeader::read_from_prefix(buf).map_err(|_| Error::BadPacket)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let request = match header.message_type { protocol::MESSAGE_PROTOCOL_REQUEST => { let message = protocol::MessageProtocolRequest::read_from_prefix(buf) .map_err(|_| Error::BadPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::ProtocolRequest(message.version) } protocol::MESSAGE_SET_LED_INDICATORS => { // We don't have any actual LEDs to set, so check the message for validity but ignore its contents. let _message = protocol::MessageLedIndicatorsState::read_from_prefix(buf) .map_err(|_| Error::BadPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::SetLedIndicators } typ => return Err(Error::UnknownMessageType(typ)), @@ -331,13 +331,13 @@ mod tests { return None; } let packet = &packet[..n]; - let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap + let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap (https://github.com/microsoft/openvmm/issues/759) Some(match header.message_type { protocol::MESSAGE_PROTOCOL_RESPONSE => { Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap().0) - // todo: zerocopy: use-rest-of-range + // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } - protocol::MESSAGE_EVENT => Packet::Event(FromBytes::read_from_prefix(rest).unwrap().0), // todo: zerocopy: use-rest-of-range + protocol::MESSAGE_EVENT => Packet::Event(FromBytes::read_from_prefix(rest).unwrap().0), // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) _ => panic!("unknown packet type {}", header.message_type), }) } diff --git a/vm/devices/uidevices/src/mouse/mod.rs b/vm/devices/uidevices/src/mouse/mod.rs index 82b05b5dfa..1b9fc42126 100644 --- a/vm/devices/uidevices/src/mouse/mod.rs +++ b/vm/devices/uidevices/src/mouse/mod.rs @@ -86,19 +86,19 @@ async fn recv_packet(reader: &mut (impl AsyncRecv + Unpin)) -> Result { let message = protocol::MessageProtocolRequest::read_from_prefix(buf) .map_err(|_| Error::BadPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::ProtocolRequest(message.version) } protocol::SYNTHHID_INIT_DEVICE_INFO_ACK => { // We don't need the message contents, but we do still want to ensure it's valid. let _message = protocol::MessageDeviceInfoAck::read_from_prefix(buf) .map_err(|_| Error::BadPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::DeviceInfoAck } typ => return Err(Error::UnknownMessageType(typ)), @@ -427,15 +427,15 @@ mod tests { return None; } let packet = &packet[..n]; - let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap + let (header, rest) = protocol::MessageHeader::read_from_prefix(packet).unwrap(); // TODO: zerocopy: unwrap (https://github.com/microsoft/openvmm/issues/759) Some(match header.message_type { protocol::SYNTHHID_PROTOCOL_RESPONSE => { Packet::ProtocolResponse(FromBytes::read_from_prefix(rest).unwrap().0) - // todo: zerocopy: use-rest-of-range + // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } protocol::SYNTHHID_INIT_DEVICE_INFO => { Packet::DeviceInfo(FromBytes::read_from_prefix(rest).unwrap().0) - // todo: zerocopy: use-rest-of-range + // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } _ => panic!("unknown packet type {}", header.message_type), }) diff --git a/vm/devices/uidevices/src/video/mod.rs b/vm/devices/uidevices/src/video/mod.rs index a9844ab8e8..3b678e42d2 100644 --- a/vm/devices/uidevices/src/video/mod.rs +++ b/vm/devices/uidevices/src/video/mod.rs @@ -76,18 +76,18 @@ enum Request { fn parse_packet(buf: &[u8]) -> Result { let (header, buf) = - Ref::<_, protocol::MessageHeader>::from_prefix(buf).map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err + Ref::<_, protocol::MessageHeader>::from_prefix(buf).map_err(|_| Error::InvalidPacket)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let request = match header.typ.to_ne() { protocol::MESSAGE_VERSION_REQUEST => { let message = protocol::VersionRequestMessage::ref_from_prefix(buf) .map_err(|_| Error::InvalidPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::Version(message.version) } protocol::MESSAGE_VRAM_LOCATION => { let message = protocol::VramLocationMessage::ref_from_prefix(buf) .map_err(|_| Error::InvalidPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let address = if message.is_vram_gpa_address_specified != 0 { Some(message.vram_gpa_address.into()) } else { @@ -101,7 +101,7 @@ fn parse_packet(buf: &[u8]) -> Result { protocol::MESSAGE_SITUATION_UPDATE => { let message = protocol::SituationUpdateMessage::ref_from_prefix(buf) .map_err(|_| Error::InvalidPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::SituationUpdate { user_context: message.user_context.into(), situation: message.video_output, @@ -110,7 +110,7 @@ fn parse_packet(buf: &[u8]) -> Result { protocol::MESSAGE_POINTER_POSITION => { let message = protocol::PointerPositionMessage::ref_from_prefix(buf) .map_err(|_| Error::InvalidPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::PointerPosition { is_visible: message.is_visible != 0, x: message.image_x.into(), @@ -118,18 +118,18 @@ fn parse_packet(buf: &[u8]) -> Result { } } protocol::MESSAGE_POINTER_SHAPE => { - //let message = protocol::PointerShapeMessage::from_bytes(buf).map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err + //let message = protocol::PointerShapeMessage::from_bytes(buf).map_err(|_| Error::InvalidPacket)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::PointerShape } protocol::MESSAGE_DIRT => { let (message, buf) = Ref::<_, protocol::DirtMessage>::from_prefix(buf) - .map_err(|_| Error::InvalidPacket)?; // todo: zerocopy: map_err + .map_err(|_| Error::InvalidPacket)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::Dirt( <[protocol::Rectangle]>::ref_from_prefix_with_elems( buf, message.dirt_count as usize, ) - .map_err(|_| Error::InvalidPacket)? // todo: zerocopy: map_err + .map_err(|_| Error::InvalidPacket)? // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) .0 .into(), ) @@ -138,7 +138,7 @@ fn parse_packet(buf: &[u8]) -> Result { protocol::MESSAGE_SUPPORTED_RESOLUTIONS_REQUEST => { let message = protocol::SupportedResolutionsRequestMessage::ref_from_prefix(buf) .map_err(|_| Error::InvalidPacket)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::SupportedResolutions { maximum_count: message.maximum_resolution_count, } diff --git a/vm/devices/virtio/virtio_net/src/lib.rs b/vm/devices/virtio/virtio_net/src/lib.rs index 4d0cfb4d39..2ffc075026 100644 --- a/vm/devices/virtio/virtio_net/src/lib.rs +++ b/vm/devices/virtio/virtio_net/src/lib.rs @@ -141,7 +141,7 @@ struct VirtioNetHeaderGso { // These correspond to VIRTIO_NET_HDR_GSO_ values. open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] enum VirtioNetHeaderGsoProtocol: u8 { NONE = 0, TCPV4 = 1, diff --git a/vm/devices/vmbus/vmbfs/src/lib.rs b/vm/devices/vmbus/vmbfs/src/lib.rs index 9b0db56663..a57bc366e0 100644 --- a/vm/devices/vmbus/vmbfs/src/lib.rs +++ b/vm/devices/vmbus/vmbfs/src/lib.rs @@ -273,19 +273,19 @@ impl VmbfsChannel { let buf = &self.buf[..n]; let (header, buf) = - protocol::MessageHeader::read_from_prefix(buf).map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err + protocol::MessageHeader::read_from_prefix(buf).map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) let request = match header.message_type { protocol::MessageType::VERSION_REQUEST => { let version = protocol::VersionRequest::read_from_prefix(buf) .map_err(|_| DeviceError::TooShort)? - .0; // todo: zerocopy: map_err + .0; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::Version(version.requested_version) } protocol::MessageType::GET_FILE_INFO_REQUEST => Request::GetFileInfo(parse_path(buf)?), protocol::MessageType::READ_FILE_REQUEST => { let (read, buf) = protocol::ReadFileRequest::read_from_prefix(buf) - .map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err + .map_err(|_| DeviceError::TooShort)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) Request::ReadFile { byte_count: read.byte_count, offset: read.offset.get(), @@ -301,7 +301,7 @@ impl VmbfsChannel { } fn parse_path(buf: &[u8]) -> Result { - let buf = <[u16]>::ref_from_bytes(buf).map_err(|_| DeviceError::Unaligned)?; // todo: zerocopy: map_err + let buf = <[u16]>::ref_from_bytes(buf).map_err(|_| DeviceError::Unaligned)?; // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) if buf.contains(&0) { return Err(DeviceError::NullTerminatorInPath); } diff --git a/vm/devices/vmbus/vmbfs/src/protocol.rs b/vm/devices/vmbus/vmbfs/src/protocol.rs index 29eff98c4e..960bcde714 100644 --- a/vm/devices/vmbus/vmbfs/src/protocol.rs +++ b/vm/devices/vmbus/vmbfs/src/protocol.rs @@ -21,14 +21,14 @@ pub const MAX_READ_SIZE: usize = MAX_MESSAGE_SIZE - size_of::() - size_of::(); open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Version: u32 { WIN10 = 0x00010000, } } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum MessageType: u32 { INVALID = 0, VERSION_REQUEST = 1, @@ -65,7 +65,7 @@ pub struct VersionRequest { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum VersionStatus: u32 { SUPPORTED = 0, UNSUPPORTED = 1, @@ -85,7 +85,7 @@ pub struct GetFileInfoRequest { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum Status: u32 { SUCCESS = 0, NOT_FOUND = 1, diff --git a/vm/devices/vmbus/vmbus_async/src/queue.rs b/vm/devices/vmbus/vmbus_async/src/queue.rs index 25dcd96310..85a701b7ed 100644 --- a/vm/devices/vmbus/vmbus_async/src/queue.rs +++ b/vm/devices/vmbus/vmbus_async/src/queue.rs @@ -266,7 +266,7 @@ impl DataPacket<'_, T> { .map(|range| { let range_data = TransferPageRange::read_from_prefix(range.as_bytes()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let sub_range = transfer_buf .subrange( range_data.byte_offset as usize, diff --git a/vm/devices/vmbus/vmbus_core/src/protocol.rs b/vm/devices/vmbus/vmbus_core/src/protocol.rs index 9e98482985..11a8f6c532 100644 --- a/vm/devices/vmbus/vmbus_core/src/protocol.rs +++ b/vm/devices/vmbus/vmbus_core/src/protocol.rs @@ -311,12 +311,12 @@ impl TargetInfo { /// Interprets a 64 bit value as the `TargetInfo` struct. pub fn from_u64(value: &u64) -> &Self { - Self::ref_from_prefix(value.as_bytes()).unwrap().0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + Self::ref_from_prefix(value.as_bytes()).unwrap().0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } /// Represents the `TargetInfo` struct as a 64 bit number. pub fn as_u64(&self) -> &u64 { - u64::ref_from_prefix(self.as_bytes()).unwrap().0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + u64::ref_from_prefix(self.as_bytes()).unwrap().0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } diff --git a/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs b/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs index 265b7b7bce..acd7dc02eb 100644 --- a/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs +++ b/vm/devices/vmbus/vmbus_core/src/protocol/macros.rs @@ -37,7 +37,7 @@ macro_rules! vmbus_message_enum { (None, FeatureFlags::new()) }; - // todo: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. + // TODO: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. (https://github.com/microsoft/openvmm/issues/759) let (header, data) = MessageHeader::read_from_prefix(data).map_err(|_| ParseError::MessageTooSmall(None))?; let message = match header.message_type { @@ -45,7 +45,7 @@ macro_rules! vmbus_message_enum { $($open_enum_name::$name if vmbus_message_enum!(@create_conditions $type version features data $min_version $($condition_name:$condition_value)*) => { - // todo: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. + // TODO: zerocopy: use Result returned by `read_from_prefix` in the returned `MessageTooSmall` error. (https://github.com/microsoft/openvmm/issues/759) let (message, remaining) = $type::read_from_prefix(data).map_err(|_| ParseError::MessageTooSmall(Some(header.message_type)))?; Self::$type(message, remaining) diff --git a/vm/devices/vmbus/vmbus_ring/src/gparange.rs b/vm/devices/vmbus/vmbus_ring/src/gparange.rs index 3f52bb263b..565deefb5d 100644 --- a/vm/devices/vmbus/vmbus_ring/src/gparange.rs +++ b/vm/devices/vmbus/vmbus_ring/src/gparange.rs @@ -205,7 +205,7 @@ impl<'a> Iterator for MultiPagedRangeIter<'a> { } let hdr = GpaRange::read_from_prefix(self.buf[0].as_bytes()) .unwrap() - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let page_count = ((hdr.offset + hdr.len) as usize).div_ceil(PAGE_SIZE); // N.B. already validated let (this, rest) = self.buf.split_at(page_count + 1); let range = PagedRange::new(hdr.offset as usize, hdr.len as usize, &this[1..]).unwrap(); diff --git a/vm/devices/vmbus/vmbus_server/src/channels.rs b/vm/devices/vmbus/vmbus_server/src/channels.rs index ab7a45b90e..4a60f43cac 100644 --- a/vm/devices/vmbus/vmbus_server/src/channels.rs +++ b/vm/devices/vmbus/vmbus_server/src/channels.rs @@ -3953,7 +3953,7 @@ mod tests { let (header, data) = protocol::MessageHeader::read_from_prefix(message.data()).unwrap(); assert_eq!(header.message_type(), T::MESSAGE_TYPE); - T::read_from_prefix(data).unwrap().0 // todo: zerocopy: use-rest-of-range + T::read_from_prefix(data).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } fn check_messages(&mut self, messages: &[OutgoingMessage]) { diff --git a/vm/devices/vmbus/vmbus_server/src/lib.rs b/vm/devices/vmbus/vmbus_server/src/lib.rs index 71e9164b13..a8242e2fb4 100644 --- a/vm/devices/vmbus/vmbus_server/src/lib.rs +++ b/vm/devices/vmbus/vmbus_server/src/lib.rs @@ -2108,7 +2108,7 @@ mod tests { async fn expect_response(&mut self, expected: protocol::MessageType) { let data = self.message_recv.next().await.unwrap(); - let header = protocol::MessageHeader::read_from_prefix(&data).unwrap().0; // todo: zerocopy: use-rest-of-range + let header = protocol::MessageHeader::read_from_prefix(&data).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) assert_eq!(expected, header.message_type()) } @@ -2116,9 +2116,9 @@ mod tests { &mut self, ) -> T { let data = self.message_recv.next().await.unwrap(); - let (header, message) = protocol::MessageHeader::read_from_prefix(&data).unwrap(); // TODO: zerocopy: unwrap + let (header, message) = protocol::MessageHeader::read_from_prefix(&data).unwrap(); // TODO: zerocopy: unwrap (https://github.com/microsoft/openvmm/issues/759) assert_eq!(T::MESSAGE_TYPE, header.message_type()); - T::read_from_prefix(message).unwrap().0 // todo: zerocopy: use-rest-of-range + T::read_from_prefix(message).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } fn initiate_contact( diff --git a/vm/hv1/hv1_hypercall/src/support.rs b/vm/hv1/hv1_hypercall/src/support.rs index 5737962238..bad4b0a836 100644 --- a/vm/hv1/hv1_hypercall/src/support.rs +++ b/vm/hv1/hv1_hypercall/src/support.rs @@ -485,8 +485,8 @@ where /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&In, &mut Out) { ( - FromBytes::ref_from_prefix(params.input).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range, err - FromBytes::mut_from_prefix(params.output).unwrap().0, // todo: zerocopy: mut-from-prefix: use-rest-of-range, err + FromBytes::ref_from_prefix(params.input).unwrap().0, // TODO: zerocopy: ref-from-prefix: use-rest-of-range, err + FromBytes::mut_from_prefix(params.output).unwrap().0, // TODO: zerocopy: mut-from-prefix: use-rest-of-range, err ) } @@ -528,8 +528,8 @@ where let (input, rest) = Ref::<_, In>::from_prefix(params.input).unwrap(); ( Ref::into_ref(input), - <[u64]>::ref_from_bytes(rest).unwrap(), //todo: zerocopy: err - Out::mut_from_prefix(params.output).unwrap().0, //todo: zerocopy: err + <[u64]>::ref_from_bytes(rest).unwrap(), //TODO: zerocopy: err + Out::mut_from_prefix(params.output).unwrap().0, //TODO: zerocopy: err ) } @@ -579,15 +579,15 @@ where let input = if size_of::() == 0 { &[] } else { - // todo: zerocopy: review carefully! - // todo: zerocopy: err + // TODO: zerocopy: review carefully! + // TODO: zerocopy: err &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] }; let output = if size_of::() == 0 { &mut [] } else { - // todo: zerocopy: review carefully! - // todo: zerocopy: err + // TODO: zerocopy: review carefully! + // TODO: zerocopy: err &mut <[Out]>::mut_from_prefix_with_elems( params.output, params.output.len() / size_of::(), @@ -648,13 +648,13 @@ where &[] } else { &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] - // todo: zerocopy: review carefully! + // TODO: zerocopy: review carefully! }; let output = if size_of::() == 0 { &mut [] } else { - // todo: zerocopy: review carefully! - // todo: zerocopy: err + // TODO: zerocopy: review carefully! + // TODO: zerocopy: err &mut <[Out]>::mut_from_prefix_with_elems( params.output, params.output.len() / size_of::(), diff --git a/vm/hv1/hv1_hypercall/src/tests.rs b/vm/hv1/hv1_hypercall/src/tests.rs index 071111634b..84c9354c86 100644 --- a/vm/hv1/hv1_hypercall/src/tests.rs +++ b/vm/hv1/hv1_hypercall/src/tests.rs @@ -334,7 +334,7 @@ struct TestController { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] enum TestHypercallCode: u16 { #![allow(non_upper_case_globals)] CallSimpleNoOutput = 0x1001, diff --git a/vm/hv1/hvdef/src/lib.rs b/vm/hv1/hvdef/src/lib.rs index f29a645f57..14e499234e 100644 --- a/vm/hv1/hvdef/src/lib.rs +++ b/vm/hv1/hvdef/src/lib.rs @@ -97,7 +97,7 @@ pub struct HvPartitionPrivilege { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvPartitionIsolationType: u8 { NONE = 0, VBS = 1, @@ -246,7 +246,7 @@ pub struct HvIsolationConfiguration { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HypercallCode: u16 { #![allow(non_upper_case_globals)] @@ -345,7 +345,7 @@ pub const HV_X64_MSR_GUEST_CRASH_CTL: u32 = 0x40000105; pub const HV_X64_GUEST_CRASH_PARAMETER_MSRS: usize = 5; open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvError: u16 { #![allow(non_upper_case_globals)] @@ -590,7 +590,7 @@ impl From for u128 { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvMessageType: u32 { #![allow(non_upper_case_globals)] @@ -887,7 +887,7 @@ pub mod hypercall { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvInterruptSource: u32 { MSI = 1, IO_APIC = 2, @@ -1053,7 +1053,7 @@ pub mod hypercall { pub const HV_INTERCEPT_ACCESS_MASK_EXECUTE: u32 = 0x04; open_enum::open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvInterceptType: u32 { #![allow(non_upper_case_globals)] HvInterceptTypeX64IoPort = 0x00000000, @@ -1507,7 +1507,7 @@ pub mod hypercall { /// read access and upper bit representing host write access, hardware /// platforms do not support that form of isolation. Only support /// private or full shared in this definition. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HostVisibilityType: u8 { PRIVATE = 0, SHARED = 3, @@ -1820,7 +1820,7 @@ macro_rules! registers { $(,)? }) => { open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum $name: u32 { #![allow(non_upper_case_globals)] $($variant = $value,)* @@ -2236,13 +2236,13 @@ impl HvRegisterValue { pub fn as_table(&self) -> HvX64TableRegister { HvX64TableRegister::read_from_prefix(self.as_bytes()) .unwrap() - .0 // todo: zerocopy: use-rest-of-range + .0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } pub fn as_segment(&self) -> HvX64SegmentRegister { HvX64SegmentRegister::read_from_prefix(self.as_bytes()) .unwrap() - .0 // todo: zerocopy: use-rest-of-range + .0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } @@ -2286,13 +2286,13 @@ pub struct HvX64TableRegister { impl From for HvRegisterValue { fn from(val: HvX64TableRegister) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range + Self::read_from_prefix(val.as_bytes()).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } impl From for HvX64TableRegister { fn from(val: HvRegisterValue) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range + Self::read_from_prefix(val.as_bytes()).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } @@ -2307,13 +2307,13 @@ pub struct HvX64SegmentRegister { impl From for HvRegisterValue { fn from(val: HvX64SegmentRegister) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range + Self::read_from_prefix(val.as_bytes()).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } impl From for HvX64SegmentRegister { fn from(val: HvRegisterValue) -> Self { - Self::read_from_prefix(val.as_bytes()).unwrap().0 // todo: zerocopy: use-rest-of-range + Self::read_from_prefix(val.as_bytes()).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } @@ -2334,7 +2334,7 @@ pub struct HvDeliverabilityNotificationsRegister { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvVtlEntryReason: u32 { /// This reason is reserved and is not used. RESERVED = 0, @@ -2415,7 +2415,7 @@ pub struct HvVpAssistPageActionSignalEvent { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvInterceptAccessType: u8 { READ = 0, WRITE = 1, @@ -2562,7 +2562,7 @@ pub struct HvArm64MemoryAccessInfo { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvCacheType: u32 { #![allow(non_upper_case_globals)] HvCacheTypeUncached = 0, @@ -2660,7 +2660,7 @@ pub struct HvX64InterruptionDeliverableMessage { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvX64PendingInterruptionType: u8 { HV_X64_PENDING_INTERRUPT = 0, HV_X64_PENDING_NMI = 2, @@ -2794,7 +2794,7 @@ pub struct HvArm64ResetInterceptMessage { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvArm64ResetType: u32 { POWER_OFF = 0, REBOOT = 1, @@ -2802,7 +2802,7 @@ open_enum! { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvInterruptType : u32 { #![allow(non_upper_case_globals)] HvArm64InterruptTypeFixed = 0x0000, @@ -3220,7 +3220,7 @@ pub struct HvInstructionEmulatorHintsRegister { } open_enum! { - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum HvAarch64PendingEventType: u8 { EXCEPTION = 0, SYNTHETIC_EXCEPTION = 1, diff --git a/vm/loader/igvmfilegen/src/file_loader.rs b/vm/loader/igvmfilegen/src/file_loader.rs index c9e2fd5f08..573e8cb758 100644 --- a/vm/loader/igvmfilegen/src/file_loader.rs +++ b/vm/loader/igvmfilegen/src/file_loader.rs @@ -834,7 +834,7 @@ impl IgvmLoader { gpa: page_base * PAGE_SIZE_4K, compatibility_mask: DEFAULT_COMPATIBILITY_MASK, vp_index: 0, - vmsa: Box::new(SevVmsa::read_from_bytes(data).expect("should be correct size")), // todo: zerocopy: map_err + vmsa: Box::new(SevVmsa::read_from_bytes(data).expect("should be correct size")), // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) }); } else { for page in page_base..page_base + page_count { diff --git a/vm/loader/igvmfilegen/src/main.rs b/vm/loader/igvmfilegen/src/main.rs index 9ae16ddcdc..0cccb019c8 100644 --- a/vm/loader/igvmfilegen/src/main.rs +++ b/vm/loader/igvmfilegen/src/main.rs @@ -93,7 +93,7 @@ fn main() -> anyhow::Result<()> { let image = fs_err::read(file_path).context("reading input file")?; let fixed_header = IGVM_FIXED_HEADER::read_from_prefix(image.as_bytes()) .expect("Invalid fixed header") - .0; // todo: zerocopy: use-rest-of-range + .0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let igvm_data = IgvmFile::new_from_binary(&image, None).expect("should be valid"); println!("Total file size: {} bytes\n", fixed_header.total_file_size); diff --git a/vm/loader/loader_defs/src/linux.rs b/vm/loader/loader_defs/src/linux.rs index 8e207f1335..49620e6139 100644 --- a/vm/loader/loader_defs/src/linux.rs +++ b/vm/loader/loader_defs/src/linux.rs @@ -155,7 +155,7 @@ pub struct setup_header { pub handover_offset: u32_ne, } -// TODO: zerocopy doesn't support const new methods, so define them as u32 for now. +// TODO: zerocopy doesn't support const new methods, so define them as u32 for now. (https://github.com/microsoft/openvmm/issues/759) pub const E820_RAM: u32 = 1; pub const E820_RESERVED: u32 = 2; pub const E820_ACPI: u32 = 3; diff --git a/vm/loader/loader_defs/src/paravisor.rs b/vm/loader/loader_defs/src/paravisor.rs index 640c6ff5af..f0502a6a6b 100644 --- a/vm/loader/loader_defs/src/paravisor.rs +++ b/vm/loader/loader_defs/src/paravisor.rs @@ -111,7 +111,7 @@ pub const PARAVISOR_LOCAL_MAP_SIZE: u64 = 0x200000; open_enum! { /// Underhill command line policy. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum CommandLinePolicy : u16 { /// Use the static command line encoded only. STATIC = 0, diff --git a/vm/loader/loader_defs/src/shim.rs b/vm/loader/loader_defs/src/shim.rs index 44c2610a58..67fbde8e86 100644 --- a/vm/loader/loader_defs/src/shim.rs +++ b/vm/loader/loader_defs/src/shim.rs @@ -57,7 +57,7 @@ pub struct ShimParamsRaw { open_enum! { /// Possible isolation types supported by the shim. - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum SupportedIsolationType: u32 { // Starting from 1 for consistency with None usually being 0, but // the IGVM file for None and Vbs will likely be the same, so None will diff --git a/vm/loader/src/uefi/mod.rs b/vm/loader/src/uefi/mod.rs index cc1fb98434..5c7cfa72dd 100644 --- a/vm/loader/src/uefi/mod.rs +++ b/vm/loader/src/uefi/mod.rs @@ -149,7 +149,7 @@ struct ImageDataDirectory { } fn pe_get_entry_point_offset(pe32_data: &[u8]) -> Option { - let dos_header = ImageDosHeader::read_from_prefix(pe32_data).ok()?.0; // todo: zerocopy: use-rest-of-range, option-to-error + let dos_header = ImageDosHeader::read_from_prefix(pe32_data).ok()?.0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) let nt_headers_offset = if dos_header.e_magic == IMAGE_DOS_SIGNATURE { // DOS image header is present, so read the PE header after the DOS image header. dos_header.e_lfanew as usize @@ -160,19 +160,19 @@ fn pe_get_entry_point_offset(pe32_data: &[u8]) -> Option { let signature = u32::read_from_prefix(&pe32_data[nt_headers_offset..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) // Calculate the entry point relative to the start of the image. // AddressOfEntryPoint is common for PE32 & PE32+ if signature as u16 == TE_IMAGE_HEADER_SIGNATURE { let te = TeImageHeader::read_from_prefix(&pe32_data[nt_headers_offset..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) Some(te.address_of_entry_point + size_of_val(&te) as u32 - te.stripped_size as u32) } else if signature == IMAGE_NT_SIGNATURE { let pe = ImageNtHeaders32::read_from_prefix(&pe32_data[nt_headers_offset..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) Some(pe.optional_header.address_of_entry_point) } else { None @@ -224,7 +224,7 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { // Expect a firmware volume header for SEC volume. let fvh = EFI_FIRMWARE_VOLUME_HEADER::read_from_prefix(&image[image_offset as usize..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if fvh.signature != EFI_FVH_SIGNATURE { return None; } @@ -243,7 +243,7 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { } let fh = EFI_FFS_FILE_HEADER::read_from_prefix(&image[image_offset as usize..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if fh.typ == EFI_FV_FILETYPE_SECURITY_CORE { sec_core_file_header = Some(fh); break; @@ -276,7 +276,7 @@ fn get_sec_entry_point_offset(image: &[u8]) -> Option { let sh = EFI_COMMON_SECTION_HEADER::read_from_prefix(&image[image_offset as usize..]) .ok()? - .0; // todo: zerocopy: use-rest-of-range, option-to-error + .0; // TODO: zerocopy: use-rest-of-range, option-to-error (https://github.com/microsoft/openvmm/issues/759) if sh.typ == EFI_SECTION_PE32 { let pe_offset = pe_get_entry_point_offset( &image[image_offset as usize + size_of::()..], diff --git a/vm/vmgs/vmgs/src/vmgs_impl.rs b/vm/vmgs/vmgs/src/vmgs_impl.rs index 8c3a3afa94..370af84b9e 100644 --- a/vm/vmgs/vmgs/src/vmgs_impl.rs +++ b/vm/vmgs/vmgs/src/vmgs_impl.rs @@ -231,7 +231,7 @@ impl Vmgs { let file_table = VmgsFileTable::ref_from_prefix(&file_table_buffer) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let file_control_blocks = initialize_file_metadata(file_table, version, storage.block_capacity())?; @@ -1067,7 +1067,7 @@ impl Vmgs { // Update the cached extended file table let extended_file_table = VmgsExtendedFileTable::read_from_prefix(extended_file_table_buffer.as_bytes()) - .map_err(|_| anyhow!("Invalid decrypted extended file table"))? // todo: zerocopy: use result + .map_err(|_| anyhow!("Invalid decrypted extended file table"))? // TODO: zerocopy: use result (https://github.com/microsoft/openvmm/issues/759) .0; for (file_id, fcb) in self.fcbs.iter_mut() { fcb.attributes = extended_file_table.entries[*file_id].attributes; @@ -1385,11 +1385,11 @@ async fn read_headers_inner(storage: &mut VmgsStorage) -> Result<(VmgsHeader, Vm .map_err(Error::ReadDisk)?; // first_two_blocks will contain enough bytes to read the first two headers - let header_1 = VmgsHeader::read_from_prefix(&first_two_blocks).unwrap().0; // todo: zerocopy: use-rest-of-range + let header_1 = VmgsHeader::read_from_prefix(&first_two_blocks).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let header_2 = VmgsHeader::read_from_prefix(&first_two_blocks[storage.aligned_header_size() as usize..]) .unwrap() - .0; // todo: zerocopy: from-prefix (read_from_prefix): use-rest-of-range + .0; // TODO: zerocopy: from-prefix (read_from_prefix): use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) Ok((header_1, header_2)) } diff --git a/vm/vmgs/vmgs_format/src/lib.rs b/vm/vmgs/vmgs_format/src/lib.rs index 47a5e9ef7e..88b07661ec 100644 --- a/vm/vmgs/vmgs_format/src/lib.rs +++ b/vm/vmgs/vmgs_format/src/lib.rs @@ -201,7 +201,7 @@ open_enum! { /// Encryption algorithm used to encrypt VMGS file #[cfg_attr(feature = "inspect", derive(Inspect))] #[cfg_attr(feature = "inspect", inspect(debug))] - #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, )] + #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] pub enum EncryptionAlgorithm: u16 { /// No encryption algorithm NONE = 0, diff --git a/vmm_core/virt/src/x86/vp.rs b/vmm_core/virt/src/x86/vp.rs index a190db8326..7c8b814e43 100644 --- a/vmm_core/virt/src/x86/vp.rs +++ b/vmm_core/virt/src/x86/vp.rs @@ -710,7 +710,7 @@ pub struct Xsave { impl Xsave { fn normalize(&mut self) { let (mut fxsave, data) = Ref::<_, Fxsave>::from_prefix(self.data.as_mut_bytes()).unwrap(); - let header = XsaveHeader::mut_from_prefix(data).unwrap().0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + let header = XsaveHeader::mut_from_prefix(data).unwrap().0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Clear the mxcsr mask since it's ignored in the restore process and // will only cause xsave comparisons to fail. @@ -779,7 +779,7 @@ impl Xsave { let header = XsaveHeader::mut_from_prefix(&mut this.data.as_mut_bytes()[XSAVE_LEGACY_LEN..]) .unwrap() - .0; // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0; // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) // Just enable supervisor states that were possible when the // hypervisor had the bug. Future ones will only be supported by @@ -866,7 +866,7 @@ impl Xsave { /// Since this does not include `xstate_bv`, fields for disabled features /// will be set to their default values. pub fn fxsave(&self) -> Fxsave { - let mut fxsave = Fxsave::read_from_prefix(self.data.as_bytes()).unwrap().0; // todo: zerocopy: use-rest-of-range + let mut fxsave = Fxsave::read_from_prefix(self.data.as_bytes()).unwrap().0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) let header = self.xsave_header(); if header.xstate_bv & XFEATURE_X87 == 0 { fxsave.fcw = INIT_FCW; @@ -880,7 +880,7 @@ impl Xsave { fn xsave_header(&self) -> &XsaveHeader { XsaveHeader::ref_from_prefix(&self.data.as_bytes()[XSAVE_LEGACY_LEN..]) .unwrap() - .0 // todo: zerocopy: ref-from-prefix: use-rest-of-range + .0 // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } } @@ -956,7 +956,7 @@ impl StateElement for Xsave { *XsaveHeader::mut_from_prefix(&mut data[XSAVE_LEGACY_LEN..]) .unwrap() .0 = XsaveHeader { - // todo: zerocopy: ref-from-prefix: use-rest-of-range + // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) xstate_bv: 0, xcomp_bv: XCOMP_COMPRESSED | caps.xsave.features | caps.xsave.supervisor_features, reserved: [0; 6], diff --git a/vmm_core/virt_whp/src/hypercalls.rs b/vmm_core/virt_whp/src/hypercalls.rs index 9a0c87e2d0..84c08833e4 100644 --- a/vmm_core/virt_whp/src/hypercalls.rs +++ b/vmm_core/virt_whp/src/hypercalls.rs @@ -1080,7 +1080,7 @@ mod x86 { &actions[offset..], ) { Ok((v, _)) => v, - Err(_) => break, // todo: zerocopy: err + Err(_) => break, // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) }; if let Err(err) = self.handle_action_signal_event(&signal_event) diff --git a/vmm_core/virt_whp/src/vp.rs b/vmm_core/virt_whp/src/vp.rs index c407de71e1..8c0ac82fff 100644 --- a/vmm_core/virt_whp/src/vp.rs +++ b/vmm_core/virt_whp/src/vp.rs @@ -1793,7 +1793,7 @@ mod aarch64 { | HvMessageType::HvMessageTypeGpaIntercept => { self.handle_memory_access( dev, - FromBytes::ref_from_prefix(message).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range + FromBytes::ref_from_prefix(message).unwrap().0, // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) exit, ) .await?; @@ -1802,21 +1802,21 @@ mod aarch64 { HvMessageType::HvMessageTypeSynicSintDeliverable => { self.handle_sint_deliverable( FromBytes::ref_from_prefix(message).unwrap().0, - ); // todo: zerocopy: ref-from-prefix: use-rest-of-range + ); // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) &mut self.state.exits.sint_deliverable } HvMessageType::HvMessageTypeHypercallIntercept => { crate::hypercalls::WhpHypercallExit::handle( self, dev, - FromBytes::ref_from_prefix(message).unwrap().0, // todo: zerocopy: ref-from-prefix: use-rest-of-range + FromBytes::ref_from_prefix(message).unwrap().0, // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) ); &mut self.state.exits.hypercall } HvMessageType::HvMessageTypeArm64ResetIntercept => { return Err( self.handle_reset(FromBytes::ref_from_prefix(message).unwrap().0) - ); // todo: zerocopy: ref-from-prefix: use-rest-of-range + ); // TODO: zerocopy: ref-from-prefix: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } reason => { return Err(VpHaltReason::Hypervisor(WhpRunVpError::UnknownExit(reason))); From 379d4e4ed9d077846efa1e1cd13f06d19ae50f97 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Fri, 31 Jan 2025 16:55:44 -0800 Subject: [PATCH 11/14] merge fixups --- vm/hv1/hvdef/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/hv1/hvdef/src/lib.rs b/vm/hv1/hvdef/src/lib.rs index 3d94361972..b394169353 100644 --- a/vm/hv1/hvdef/src/lib.rs +++ b/vm/hv1/hvdef/src/lib.rs @@ -403,7 +403,7 @@ impl Debug for HvStatus { // // DEVNOTE: use `NonZeroU16` to get a niche optimization, since 0 is reserved // for success. -#[derive(Copy, Clone, PartialEq, Eq, AsBytes)] +#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout)] #[repr(transparent)] pub struct HvError(core::num::NonZeroU16); From 08f1ba25d0f558bb5ee3f539b93146870f522b5e Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Tue, 4 Feb 2025 19:40:40 +0000 Subject: [PATCH 12/14] update fdt tests --- support/fdt/src/parser.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/support/fdt/src/parser.rs b/support/fdt/src/parser.rs index c32230367f..d78fc15469 100644 --- a/support/fdt/src/parser.rs +++ b/support/fdt/src/parser.rs @@ -773,6 +773,7 @@ mod test { use alloc::string::String; use alloc::vec; use alloc::vec::Vec; + use zerocopy::IntoBytes; #[derive(Debug, Clone, PartialEq, Eq)] enum DtProp { @@ -780,6 +781,7 @@ mod test { PropB(Vec), Reg(u32), SuperAwesomeProp(String), + PropList(Vec), } #[derive(Debug, PartialEq, Eq)] @@ -801,6 +803,7 @@ mod test { propb: StringId, reg: StringId, saprop: StringId, + proplist: StringId, } macro_rules! build_fdt_props { @@ -813,6 +816,26 @@ mod test { DtProp::PropB(val) => new_builder.add_prop_array($ids.propb, &[&val]).unwrap(), DtProp::Reg(val) => new_builder.add_u32($ids.reg, *val).unwrap(), DtProp::SuperAwesomeProp(val) => new_builder.add_str($ids.saprop, val).unwrap(), + DtProp::PropList(val) => { + // convert to BE first, since the underlying routines require BE data + let big_endians = val + .iter() + .map(|v| { + zerocopy::byteorder::U64::::new(*v) + }) + .collect::>(); + + new_builder + .add_prop_array( + $ids.proplist, + big_endians + .iter() + .map(|v| v.as_bytes()) + .collect::>() + .as_slice(), + ) + .unwrap() + } }; } @@ -839,6 +862,7 @@ mod test { propb: builder.add_string("test,prop-b").unwrap(), reg: builder.add_string("reg").unwrap(), saprop: builder.add_string("Awesome,super-prop").unwrap(), + proplist: builder.add_string("prop-list").unwrap(), }; // build root @@ -883,6 +907,13 @@ mod test { "Awesome,super-prop" => { DtProp::SuperAwesomeProp(prop.read_str().unwrap().into()) } + "prop-list" => { + let mut list = vec![]; + for val in prop.as_64_list().unwrap() { + list.push(val); + } + DtProp::PropList(list) + } _ => panic!("unexpected name {}", name), }; @@ -964,8 +995,11 @@ mod test { properties: vec![ DtProp::PropA(0x123456789abcdef), DtProp::PropB(vec![]), + DtProp::PropB(vec![1]), DtProp::Reg(0xabcdef), DtProp::SuperAwesomeProp("this is a string!".into()), + DtProp::PropList(vec![1, 2, 3, 4, 5]), + DtProp::PropA(0x223456789abcdef), ], }, memory_reservations: vec![ReserveEntry { From 989afa3f34f5ae4c60922254062b892b6a87319d Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Thu, 6 Feb 2025 04:21:50 +0000 Subject: [PATCH 13/14] Post-merge fixups --- openhcl/sidecar/src/arch/x86_64/vp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openhcl/sidecar/src/arch/x86_64/vp.rs b/openhcl/sidecar/src/arch/x86_64/vp.rs index 77046e71c0..a31fad6d30 100644 --- a/openhcl/sidecar/src/arch/x86_64/vp.rs +++ b/openhcl/sidecar/src/arch/x86_64/vp.rs @@ -518,7 +518,7 @@ fn translate_gva(command_page: &mut CommandPage) { let output = unsafe { &*addr_space::hypercall_output() }; FromBytes::read_from_prefix(output).unwrap().0 // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759) } else { - FromZeroes::new_zeroed() + FromZeros::new_zeroed() }; TranslateGvaResponse { From ea853987d1341f942f9cd81a98808edff6478ad7 Mon Sep 17 00:00:00 2001 From: Matt LaFayette Date: Thu, 6 Feb 2025 04:46:34 +0000 Subject: [PATCH 14/14] Review feedback --- openhcl/openhcl_boot/src/hypercall.rs | 1 - openhcl/underhill_crash/src/lib.rs | 1 - support/fdt/src/parser.rs | 1 - .../hcl_compat_uefi_nvram_storage/src/lib.rs | 1 - vm/hv1/hv1_hypercall/src/support.rs | 18 +++++++----------- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/openhcl/openhcl_boot/src/hypercall.rs b/openhcl/openhcl_boot/src/hypercall.rs index 6cb004e736..93d2f0d7bb 100644 --- a/openhcl/openhcl_boot/src/hypercall.rs +++ b/openhcl/openhcl_boot/src/hypercall.rs @@ -373,7 +373,6 @@ impl HvCall { ); let n = r.elements_processed(); - //TODO: zerocopy: review carefully! (https://github.com/microsoft/openvmm/issues/759) output.extend( <[u32]>::ref_from_bytes(&Self::output_page().buffer[..n * 4]) .unwrap() diff --git a/openhcl/underhill_crash/src/lib.rs b/openhcl/underhill_crash/src/lib.rs index 1d23be63ec..fe5ccc5f9e 100644 --- a/openhcl/underhill_crash/src/lib.rs +++ b/openhcl/underhill_crash/src/lib.rs @@ -528,7 +528,6 @@ impl<'a> DumpStreamer<'a> { let phnum = std::cmp::min(phnum_remaining, max); let phdrs_size = phnum * size_of::(); self.read(&mut buf[..phdrs_size], true).await; - // TODO: zerocopy: review carefully! (https://github.com/microsoft/openvmm/issues/759) let phdrs: &mut [Elf64_Phdr] = <[Elf64_Phdr]>::mut_from_bytes(&mut buf[..phdrs_size]).unwrap(); diff --git a/support/fdt/src/parser.rs b/support/fdt/src/parser.rs index d78fc15469..1cfda548dc 100644 --- a/support/fdt/src/parser.rs +++ b/support/fdt/src/parser.rs @@ -637,7 +637,6 @@ impl<'a> Property<'a> { // read types that are greater than 4 bytes, we must bound T to accept // unaligned types so LayoutVerified does not apply alignment and read // incorrect values. - // TODO: zerocopy: review carefully! (manual) (https://github.com/microsoft/openvmm/issues/759) <[T]>::ref_from_bytes(self.data) .map_err(|_| { // TODO: zerocopy: map_err (https://github.com/microsoft/openvmm/issues/759) diff --git a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs index 8bfbcce92d..60df2d7b30 100644 --- a/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs +++ b/vm/devices/firmware/hcl_compat_uefi_nvram_storage/src/lib.rs @@ -169,7 +169,6 @@ impl HclCompatNvram { self.nvram_buf = nvram_buf; let mut buf = self.nvram_buf.as_slice(); // TODO: zerocopy: error propagation (https://github.com/microsoft/openvmm/issues/759) - // TODO: zerocopy: review carefully! manual fixup (https://github.com/microsoft/openvmm/issues/759) while let Ok((header, _)) = format::NvramHeader::read_from_prefix(buf) { if buf.len() < header.length as usize { return Err(NvramStorageError::Load( diff --git a/vm/hv1/hv1_hypercall/src/support.rs b/vm/hv1/hv1_hypercall/src/support.rs index a1a5cf5ab8..e46b5883b3 100644 --- a/vm/hv1/hv1_hypercall/src/support.rs +++ b/vm/hv1/hv1_hypercall/src/support.rs @@ -485,8 +485,8 @@ where /// Parses the hypercall parameters to input and output types. pub fn parse(params: HypercallParameters<'_>) -> (&In, &mut Out) { ( - FromBytes::ref_from_prefix(params.input).unwrap().0, // TODO: zerocopy: ref-from-prefix: use-rest-of-range, err - FromBytes::mut_from_prefix(params.output).unwrap().0, // TODO: zerocopy: mut-from-prefix: use-rest-of-range, err + FromBytes::ref_from_prefix(params.input).unwrap().0, // TODO: zerocopy: ref-from-prefix: use-rest-of-range, err (https://github.com/microsoft/openvmm/issues/759) + FromBytes::mut_from_prefix(params.output).unwrap().0, // TODO: zerocopy: mut-from-prefix: use-rest-of-range, err (https://github.com/microsoft/openvmm/issues/759) ) } @@ -528,8 +528,8 @@ where let (input, rest) = Ref::<_, In>::from_prefix(params.input).unwrap(); ( Ref::into_ref(input), - <[u64]>::ref_from_bytes(rest).unwrap(), //TODO: zerocopy: err - Out::mut_from_prefix(params.output).unwrap().0, //TODO: zerocopy: err + <[u64]>::ref_from_bytes(rest).unwrap(), //TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) + Out::mut_from_prefix(params.output).unwrap().0, //TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) ) } @@ -579,15 +579,13 @@ where let input = if size_of::() == 0 { &[] } else { - // TODO: zerocopy: review carefully! - // TODO: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] }; let output = if size_of::() == 0 { &mut [] } else { - // TODO: zerocopy: review carefully! - // TODO: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) &mut <[Out]>::mut_from_prefix_with_elems( params.output, params.output.len() / size_of::(), @@ -648,13 +646,11 @@ where &[] } else { &<[In]>::ref_from_bytes(rest).unwrap()[params.control.rep_start()..] - // TODO: zerocopy: review carefully! }; let output = if size_of::() == 0 { &mut [] } else { - // TODO: zerocopy: review carefully! - // TODO: zerocopy: err + // TODO: zerocopy: err (https://github.com/microsoft/openvmm/issues/759) &mut <[Out]>::mut_from_prefix_with_elems( params.output, params.output.len() / size_of::(),