dbs_address_space/
layout.rs1use lazy_static::lazy_static;
5
6use crate::{AddressSpaceRegion, AddressSpaceRegionType};
7
8const PROC_READ_RETRY: u64 = 5;
10
11lazy_static! {
12 pub static ref USABLE_END: u64 = {
14 for _ in 0..PROC_READ_RETRY {
15 if let Ok(buf) = std::fs::read("/proc/meminfo") {
16 let content = String::from_utf8_lossy(&buf);
17 for line in content.lines() {
18 if line.starts_with("MemTotal:") {
19 if let Some(end) = line.find(" kB") {
20 if let Ok(size) = line[9..end].trim().parse::<u64>() {
21 return (size << 10) - 1;
22 }
23 }
24 }
25 }
26 }
27 }
28 panic!("Exceed max retry times. Cannot get total mem size from /proc/meminfo");
29 };
30}
31
32#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct AddressSpaceLayout {
38 pub phys_end: u64,
40 pub mem_start: u64,
42 pub mem_end: u64,
44 pub usable_end: u64,
46}
47
48impl AddressSpaceLayout {
49 pub fn new(phys_end: u64, mem_start: u64, mem_end: u64) -> Self {
51 AddressSpaceLayout {
52 phys_end,
53 mem_start,
54 mem_end,
55 usable_end: *USABLE_END,
56 }
57 }
58
59 pub fn is_region_valid(&self, region: &AddressSpaceRegion) -> bool {
61 let region_end = match region.base.0.checked_add(region.size) {
62 None => return false,
63 Some(v) => v,
64 };
65
66 match region.ty {
67 AddressSpaceRegionType::DefaultMemory => {
68 if region.base.0 < self.mem_start || region_end > self.mem_end {
69 return false;
70 }
71 }
72 AddressSpaceRegionType::DeviceMemory | AddressSpaceRegionType::DAXMemory => {
73 if region.base.0 < self.mem_end || region_end > self.phys_end {
74 return false;
75 }
76 }
77 }
78
79 true
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use vm_memory::GuestAddress;
87
88 #[test]
89 fn test_is_region_valid() {
90 let layout = AddressSpaceLayout::new(0x1_0000_0000, 0x1000_0000, 0x2000_0000);
91
92 let region = AddressSpaceRegion::new(
93 AddressSpaceRegionType::DefaultMemory,
94 GuestAddress(0x0),
95 0x1_0000,
96 );
97 assert!(!layout.is_region_valid(®ion));
98 let region = AddressSpaceRegion::new(
99 AddressSpaceRegionType::DefaultMemory,
100 GuestAddress(0x2000_0000),
101 0x1_0000,
102 );
103 assert!(!layout.is_region_valid(®ion));
104 let region = AddressSpaceRegion::new(
105 AddressSpaceRegionType::DefaultMemory,
106 GuestAddress(0x1_0000),
107 0x2000_0000,
108 );
109 assert!(!layout.is_region_valid(®ion));
110 let region = AddressSpaceRegion::new(
111 AddressSpaceRegionType::DefaultMemory,
112 GuestAddress(u64::MAX),
113 0x1_0000_0000,
114 );
115 assert!(!layout.is_region_valid(®ion));
116 let region = AddressSpaceRegion::new(
117 AddressSpaceRegionType::DefaultMemory,
118 GuestAddress(0x1000_0000),
119 0x1_0000,
120 );
121 assert!(layout.is_region_valid(®ion));
122
123 let region = AddressSpaceRegion::new(
124 AddressSpaceRegionType::DeviceMemory,
125 GuestAddress(0x1000_0000),
126 0x1_0000,
127 );
128 assert!(!layout.is_region_valid(®ion));
129 let region = AddressSpaceRegion::new(
130 AddressSpaceRegionType::DeviceMemory,
131 GuestAddress(0x1_0000_0000),
132 0x1_0000,
133 );
134 assert!(!layout.is_region_valid(®ion));
135 let region = AddressSpaceRegion::new(
136 AddressSpaceRegionType::DeviceMemory,
137 GuestAddress(0x1_0000),
138 0x1_0000_0000,
139 );
140 assert!(!layout.is_region_valid(®ion));
141 let region = AddressSpaceRegion::new(
142 AddressSpaceRegionType::DeviceMemory,
143 GuestAddress(u64::MAX),
144 0x1_0000_0000,
145 );
146 assert!(!layout.is_region_valid(®ion));
147 let region = AddressSpaceRegion::new(
148 AddressSpaceRegionType::DeviceMemory,
149 GuestAddress(0x8000_0000),
150 0x1_0000,
151 );
152 assert!(layout.is_region_valid(®ion));
153 }
154}