(
&self,
req_address: GuestAddress,
req_size: GuestUsize,
alignment: GuestUsize,
)
| 78 | } |
| 79 | |
| 80 | fn available_range( |
| 81 | &self, |
| 82 | req_address: GuestAddress, |
| 83 | req_size: GuestUsize, |
| 84 | alignment: GuestUsize, |
| 85 | ) -> Result<GuestAddress> { |
| 86 | let aligned_address = self.align_address(req_address, alignment); |
| 87 | |
| 88 | // The requested address should be aligned. |
| 89 | if aligned_address != req_address { |
| 90 | return Err(Error::UnalignedAddress); |
| 91 | } |
| 92 | |
| 93 | // The aligned address should be within the address space range. |
| 94 | if aligned_address >= self.end || aligned_address < self.base { |
| 95 | return Err(Error::Overflow); |
| 96 | } |
| 97 | |
| 98 | let mut prev_end_address = self.base; |
| 99 | for (address, size) in self.ranges.iter() { |
| 100 | if aligned_address <= *address { |
| 101 | // Do we overlap with the previous range? |
| 102 | if prev_end_address > aligned_address { |
| 103 | return Err(Error::Overlap); |
| 104 | } |
| 105 | |
| 106 | // Do we have enough space? |
| 107 | if address |
| 108 | .unchecked_sub(aligned_address.raw_value()) |
| 109 | .raw_value() |
| 110 | < req_size |
| 111 | { |
| 112 | return Err(Error::Overlap); |
| 113 | } |
| 114 | |
| 115 | return Ok(aligned_address); |
| 116 | } |
| 117 | |
| 118 | prev_end_address = address.unchecked_add(*size); |
| 119 | } |
| 120 | |
| 121 | // We have not found a range that starts after the requested address, |
| 122 | // despite having a marker at the end of our range. |
| 123 | Err(Error::Overflow) |
| 124 | } |
| 125 | |
| 126 | fn first_available_range( |
| 127 | &self, |
no test coverage detected