1 // Copyright © 2020 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 use crate::{MigratableError, VersionMapped}; 7 use std::io::{Read, Write}; 8 use versionize::{VersionMap, Versionize, VersionizeResult}; 9 use versionize_derive::Versionize; 10 use vm_memory::ByteValued; 11 12 // Migration protocol 13 // 1: Source establishes communication with destination (file socket or TCP connection.) 14 // (The establishment is out of scope.) 15 // 2: Source -> Dest : send "start command" 16 // 3: Dest -> Source : sends "ok response" when read to accept state data 17 // 4: Source -> Dest : sends "config command" followed by config data, length 18 // in command is length of config data 19 // 5: Dest -> Source : sends "ok response" when ready to accept memory data 20 // 6: Source -> Dest : send "memory command" followed by table of u64 pairs (GPA, size) 21 // followed by the memory described in those pairs. 22 // !! length is size of table i.e. 16 * number of ranges !! 23 // 7: Dest -> Source : sends "ok response" when ready to accept more memory data 24 // 8..(n-4): Repeat steps 6 and 7 until source has no more memory to send 25 // (n-3): Source -> Dest : sends "state command" followed by state data, length 26 // in command is length of config data 27 // (n-2): Dest -> Source : sends "ok response" 28 // (n-1): Source -> Dest : send "complete command" 29 // n: Dest -> Source: sends "ok response" 30 // 31 // "Local version": (Handing FDs across socket for memory) 32 // 1: Source establishes communication with destination (file socket or TCP connection.) 33 // (The establishment is out of scope.) 34 // 2: Source -> Dest : send "start command" 35 // 3: Dest -> Source : sends "ok response" when read to accept state data 36 // 4: Source -> Dest : sends "config command" followed by config data, length 37 // in command is length of config data 38 // 5: Dest -> Source : sends "ok response" when ready to accept memory data 39 // 6: Source -> Dest : send "memory fd command" followed by u16 slot ID and FD for memory 40 // 7: Dest -> Source : sends "ok response" when received 41 // 8..(n-4): Repeat steps 6 and 7 until source has no more memory to send 42 // (n-3): Source -> Dest : sends "state command" followed by state data, length 43 // in command is length of config data 44 // (n-2): Dest -> Source : sends "ok response" 45 // (n-1): Source -> Dest : send "complete command" 46 // n: Dest -> Source: sends "ok response" 47 // 48 // The destination can at any time send an "error response" to cancel 49 // The source can at any time send an "abandon request" to cancel 50 51 #[repr(u16)] 52 #[derive(Copy, Clone)] 53 pub enum Command { 54 Invalid, 55 Start, 56 Config, 57 State, 58 Memory, 59 Complete, 60 Abandon, 61 MemoryFd, 62 } 63 64 impl Default for Command { 65 fn default() -> Self { 66 Self::Invalid 67 } 68 } 69 70 #[repr(C)] 71 #[derive(Default, Copy, Clone)] 72 pub struct Request { 73 command: Command, 74 padding: [u8; 6], 75 length: u64, // Length of payload for command excluding the Request struct 76 } 77 78 // SAFETY: Request contains a series of integers with no implicit padding 79 unsafe impl ByteValued for Request {} 80 81 impl Request { 82 pub fn new(command: Command, length: u64) -> Self { 83 Self { 84 command, 85 length, 86 ..Default::default() 87 } 88 } 89 90 pub fn start() -> Self { 91 Self::new(Command::Start, 0) 92 } 93 94 pub fn state(length: u64) -> Self { 95 Self::new(Command::State, length) 96 } 97 98 pub fn config(length: u64) -> Self { 99 Self::new(Command::Config, length) 100 } 101 102 pub fn memory(length: u64) -> Self { 103 Self::new(Command::Memory, length) 104 } 105 106 pub fn memory_fd(length: u64) -> Self { 107 Self::new(Command::MemoryFd, length) 108 } 109 110 pub fn complete() -> Self { 111 Self::new(Command::Complete, 0) 112 } 113 114 pub fn abandon() -> Self { 115 Self::new(Command::Abandon, 0) 116 } 117 118 pub fn command(&self) -> Command { 119 self.command 120 } 121 122 pub fn length(&self) -> u64 { 123 self.length 124 } 125 126 pub fn read_from(fd: &mut dyn Read) -> Result<Request, MigratableError> { 127 let mut request = Request::default(); 128 fd.read_exact(Self::as_mut_slice(&mut request)) 129 .map_err(MigratableError::MigrateSocket)?; 130 131 Ok(request) 132 } 133 134 pub fn write_to(&self, fd: &mut dyn Write) -> Result<(), MigratableError> { 135 fd.write_all(Self::as_slice(self)) 136 .map_err(MigratableError::MigrateSocket) 137 } 138 } 139 140 #[repr(u16)] 141 #[derive(Copy, Clone, PartialEq)] 142 pub enum Status { 143 Invalid, 144 Ok, 145 Error, 146 } 147 148 impl Default for Status { 149 fn default() -> Self { 150 Self::Invalid 151 } 152 } 153 154 #[repr(C)] 155 #[derive(Default, Copy, Clone)] 156 pub struct Response { 157 status: Status, 158 padding: [u8; 6], 159 length: u64, // Length of payload for command excluding the Response struct 160 } 161 162 // SAFETY: Response contains a series of integers with no implicit padding 163 unsafe impl ByteValued for Response {} 164 165 impl Response { 166 pub fn new(status: Status, length: u64) -> Self { 167 Self { 168 status, 169 length, 170 ..Default::default() 171 } 172 } 173 174 pub fn ok() -> Self { 175 Self::new(Status::Ok, 0) 176 } 177 178 pub fn error() -> Self { 179 Self::new(Status::Error, 0) 180 } 181 182 pub fn status(&self) -> Status { 183 self.status 184 } 185 186 pub fn read_from(fd: &mut dyn Read) -> Result<Response, MigratableError> { 187 let mut response = Response::default(); 188 fd.read_exact(Self::as_mut_slice(&mut response)) 189 .map_err(MigratableError::MigrateSocket)?; 190 191 Ok(response) 192 } 193 194 pub fn write_to(&self, fd: &mut dyn Write) -> Result<(), MigratableError> { 195 fd.write_all(Self::as_slice(self)) 196 .map_err(MigratableError::MigrateSocket) 197 } 198 } 199 200 #[repr(C)] 201 #[derive(Clone, Default, Serialize, Deserialize, Versionize)] 202 pub struct MemoryRange { 203 pub gpa: u64, 204 pub length: u64, 205 } 206 207 #[derive(Clone, Default, Serialize, Deserialize, Versionize)] 208 pub struct MemoryRangeTable { 209 data: Vec<MemoryRange>, 210 } 211 212 impl VersionMapped for MemoryRangeTable {} 213 214 impl MemoryRangeTable { 215 pub fn from_bitmap(bitmap: Vec<u64>, start_addr: u64, page_size: u64) -> Self { 216 let mut table = MemoryRangeTable::default(); 217 let mut entry: Option<MemoryRange> = None; 218 for (i, block) in bitmap.iter().enumerate() { 219 for j in 0..64 { 220 let is_page_dirty = ((block >> j) & 1u64) != 0u64; 221 let page_offset = ((i * 64) + j) as u64 * page_size; 222 if is_page_dirty { 223 if let Some(entry) = &mut entry { 224 entry.length += page_size; 225 } else { 226 entry = Some(MemoryRange { 227 gpa: start_addr + page_offset, 228 length: page_size, 229 }); 230 } 231 } else if let Some(entry) = entry.take() { 232 table.push(entry); 233 } 234 } 235 } 236 if let Some(entry) = entry.take() { 237 table.push(entry); 238 } 239 240 table 241 } 242 243 pub fn regions(&self) -> &[MemoryRange] { 244 &self.data 245 } 246 247 pub fn push(&mut self, range: MemoryRange) { 248 self.data.push(range) 249 } 250 251 pub fn read_from(fd: &mut dyn Read, length: u64) -> Result<MemoryRangeTable, MigratableError> { 252 assert!(length as usize % std::mem::size_of::<MemoryRange>() == 0); 253 254 let mut data: Vec<MemoryRange> = Vec::new(); 255 data.resize_with( 256 length as usize / (std::mem::size_of::<MemoryRange>()), 257 Default::default, 258 ); 259 fd.read_exact(unsafe { 260 std::slice::from_raw_parts_mut( 261 data.as_ptr() as *mut MemoryRange as *mut u8, 262 length as usize, 263 ) 264 }) 265 .map_err(MigratableError::MigrateSocket)?; 266 267 Ok(Self { data }) 268 } 269 270 pub fn length(&self) -> u64 { 271 (std::mem::size_of::<MemoryRange>() * self.data.len()) as u64 272 } 273 274 pub fn write_to(&self, fd: &mut dyn Write) -> Result<(), MigratableError> { 275 fd.write_all(unsafe { 276 std::slice::from_raw_parts( 277 self.data.as_ptr() as *const MemoryRange as *const u8, 278 self.length() as usize, 279 ) 280 }) 281 .map_err(MigratableError::MigrateSocket) 282 } 283 284 pub fn is_empty(&self) -> bool { 285 self.data.is_empty() 286 } 287 288 pub fn extend(&mut self, table: Self) { 289 self.data.extend(table.data) 290 } 291 292 pub fn new_from_tables(tables: Vec<Self>) -> Self { 293 let mut data = Vec::new(); 294 for table in tables { 295 data.extend(table.data); 296 } 297 Self { data } 298 } 299 } 300