From fd0f2d826f9294d5d68d4578a3e678e24d812c6a Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Wed, 23 Oct 2024 00:22:03 -0700 Subject: [PATCH] fix: let align_up/align_down take number of bits It ensures that the alignment is always a power of 2. Signed-off-by: Changyuan Lyu --- alioth/src/firmware/dt/dtb.rs | 4 ++-- alioth/src/loader/xen/xen.rs | 7 ++++--- alioth/src/pci/bus.rs | 2 +- alioth/src/pci/cap.rs | 2 +- alioth/src/utils/utils.rs | 26 +++++++++----------------- alioth/src/vfio/pci.rs | 4 ++-- alioth/src/virtio/dev/fs.rs | 2 +- 7 files changed, 20 insertions(+), 27 deletions(-) diff --git a/alioth/src/firmware/dt/dtb.rs b/alioth/src/firmware/dt/dtb.rs index 6f60f1a..a205fef 100644 --- a/alioth/src/firmware/dt/dtb.rs +++ b/alioth/src/firmware/dt/dtb.rs @@ -33,14 +33,14 @@ pub const FDT_END: [u8; 4] = [0x00, 0x00, 0x00, 0x09]; fn push_string_align(data: &mut Vec, s: &str) { data.extend(s.as_bytes()); - let padding = align_up!(s.len() + 1, 4) - s.len(); + let padding = align_up!(s.len() + 1, 2) - s.len(); for _ in 0..padding { data.push(b'\0'); } } fn pad_data(data: &mut Vec) { - let padding = align_up!(data.len(), 4) - data.len(); + let padding = align_up!(data.len(), 2) - data.len(); for _ in 0..padding { data.push(b'\0'); } diff --git a/alioth/src/loader/xen/xen.rs b/alioth/src/loader/xen/xen.rs index f74c656..d59957a 100644 --- a/alioth/src/loader/xen/xen.rs +++ b/alioth/src/loader/xen/xen.rs @@ -57,19 +57,20 @@ fn search_pvh_note( size: u64, align: u64, ) -> std::io::Result> { + let align_bits = std::cmp::max(align, 1).trailing_zeros(); let mut pos = 0; while pos < size { file.seek(SeekFrom::Start(offset + pos))?; let mut header = Elf64Note::new_zeroed(); file.read_exact(header.as_mut_bytes())?; pos += size_of::() as u64; - pos += align_up!(header.desc_sz as u64, align); - pos += align_up!(header.name_sz as u64, align); + pos += align_up!(header.desc_sz as u64, align_bits); + pos += align_up!(header.name_sz as u64, align_bits); if header.type_ != XEN_ELFNOTE_PHYS32_ENTRY { continue; } file.seek(SeekFrom::Current( - align_up!(header.name_sz as u64, align) as i64 + align_up!(header.name_sz as u64, align_bits) as i64, ))?; match header.desc_sz { 4 => { diff --git a/alioth/src/pci/bus.rs b/alioth/src/pci/bus.rs index dac1631..ce6b17e 100644 --- a/alioth/src/pci/bus.rs +++ b/alioth/src/pci/bus.rs @@ -179,7 +179,7 @@ impl PciBus { for (bdf, dev, index, size) in bar_list { let config = dev.dev.config(); let mut header = config.get_header().data.write(); - let aligned_addr = align_up!(addr, size); + let aligned_addr = align_up!(addr, size.trailing_zeros()); if aligned_addr + size > *end { log::error!( "{bdf}: cannot map BAR {index} into address range {start:#x}..{end:#x}" diff --git a/alioth/src/pci/cap.rs b/alioth/src/pci/cap.rs index e9d3520..35d7ca7 100644 --- a/alioth/src/pci/cap.rs +++ b/alioth/src/pci/cap.rs @@ -203,7 +203,7 @@ impl TryFrom>> for PciCapList { let next = if index == num_caps - 1 { 0 } else { - align_up!(ptr + Mmio::size(&cap), 4) + align_up!(ptr + Mmio::size(&cap), 2) }; cap.set_next(next as u8); bus.add(ptr, cap)?; diff --git a/alioth/src/utils/utils.rs b/alioth/src/utils/utils.rs index 8a7ffe6..31d869b 100644 --- a/alioth/src/utils/utils.rs +++ b/alioth/src/utils/utils.rs @@ -20,18 +20,16 @@ pub mod ioctls; #[macro_export] macro_rules! align_up { - ($num:expr, $align:expr) => {{ - debug_assert_eq!(($align as u64).count_ones(), 1); - let mask = $align - 1; + ($num:expr, $bits:expr) => {{ + let mask = (1 << $bits) - 1; ($num.wrapping_add(mask)) & !mask }}; } #[macro_export] macro_rules! align_down { - ($num:expr, $align:expr) => {{ - debug_assert_eq!(($align as u64).count_ones(), 1); - let mask = $align - 1; + ($num:expr, $bits:expr) => {{ + let mask = (1 << $bits) - 1; $num & !mask }}; } @@ -176,17 +174,11 @@ macro_rules! c_enum { mod test { #[test] fn test_align_up() { - assert_eq!(align_up!(0u64, 4), 0); - assert_eq!(align_up!(1u64, 4), 4); - assert_eq!(align_up!(3u64, 4), 4); + assert_eq!(align_up!(0u64, 2), 0); + assert_eq!(align_up!(1u64, 2), 4); + assert_eq!(align_up!(3u64, 2), 4); - assert_eq!(align_up!(u64::MAX, 1), u64::MAX); - assert_eq!(align_up!(u64::MAX, 4), 0); - } - - #[test] - #[should_panic] - fn test_align_up_panic() { - let _ = align_up!(1u64, 3); + assert_eq!(align_up!(u64::MAX, 0), u64::MAX); + assert_eq!(align_up!(u64::MAX, 2), 0); } } diff --git a/alioth/src/vfio/pci.rs b/alioth/src/vfio/pci.rs index fd13c0a..626c6c6 100644 --- a/alioth/src/vfio/pci.rs +++ b/alioth/src/vfio/pci.rs @@ -48,7 +48,7 @@ use crate::vfio::{error, Result, VfioParam}; use crate::{align_down, align_up, assign_bits, mask_bits, mem}; fn round_up_range(range: Range) -> Range { - (align_down!(range.start, 0x1000))..(align_up!(range.end, 0x1000)) + (align_down!(range.start, 12))..(align_up!(range.end, 12)) } fn create_mapped_bar_pages( @@ -177,7 +177,7 @@ where let table_offset = msix_table_offset.0 as usize & !0b111; let pba_offset = msix_pba_offset.0 as usize & !0b111; let table_range = table_offset..(table_offset + size_of::() * num_msix_entries); - let pba_range = pba_offset..(pba_offset + (align_up!(num_msix_entries, 64) >> 3)); + let pba_range = pba_offset..(pba_offset + (align_up!(num_msix_entries, 6) >> 3)); if msix_table_offset.bar() == index && msix_pba_offset.bar() == index { create_splitted_bar_region( diff --git a/alioth/src/virtio/dev/fs.rs b/alioth/src/virtio/dev/fs.rs index 740e34e..2d8ce22 100644 --- a/alioth/src/virtio/dev/fs.rs +++ b/alioth/src/virtio/dev/fs.rs @@ -139,7 +139,7 @@ impl VuFs { }; let dax_region = if param.dax_window > 0 { vu_dev.setup_channel()?; - let size = align_up!(param.dax_window, 4 << 10); + let size = align_up!(param.dax_window, 12); Some(ArcMemPages::from_anonymous(size, Some(PROT_NONE), None)?) } else { None