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