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