Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/include/vmm_snapshot.h
- This file was added.
/*- | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 2016 Flavius Anton | |||||
* Copyright (c) 2016 Mihai Tiganus | |||||
* Copyright (c) 2016-2019 Mihai Carabas | |||||
* Copyright (c) 2017-2019 Darius Mihai | |||||
* Copyright (c) 2017-2019 Elena Mihailescu | |||||
* Copyright (c) 2018-2019 Sergiu Weisz | |||||
* All rights reserved. | |||||
* The bhyve-snapshot feature was developed under sponsorships | |||||
* from Matthew Grooms. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* | |||||
* $FreeBSD$ | |||||
*/ | |||||
#ifndef _VMM_SNAPSHOT_ | |||||
#define _VMM_SNAPSHOT_ | |||||
dab: Perhaps there should be a function to determine the snapshot length rather than leaving it up… | |||||
Not Done Inline ActionsThere is a function called vm_get_snapshot_size - not that you mention it, I realize that the information in the comment should have mentioned "snapshot size" - that computes the size (or length) of the snapshot data darius.mihaim_gmail.com: There is a function called `vm_get_snapshot_size` - not that you mention it, I realize that the… | |||||
Done Inline ActionsAh, missed that. Thanks. dab: Ah, missed that. Thanks. | |||||
#include <sys/errno.h> | |||||
#include <sys/types.h> | |||||
Not Done Inline ActionsIt looks like this line could be deleted. dab: It looks like this line could be deleted. | |||||
Not Done Inline ActionsIt was left there to point that there wasn't a need for an explicit field. I may remove this line and the comment above if people agree that they shouldn't really be there. darius.mihaim_gmail.com: It was left there to point that there wasn't a need for an explicit field. I may remove this… | |||||
Done Inline ActionsMaybe just mention vm_get_snapshot_size() in the comment. dab: Maybe just mention `vm_get_snapshot_size()` in the comment. | |||||
#ifndef _KERNEL | |||||
#include <stdbool.h> | |||||
#endif | |||||
struct vmctx; | |||||
enum snapshot_req { | |||||
STRUCT_VMX, | |||||
STRUCT_VIOAPIC, | |||||
STRUCT_VM, | |||||
STRUCT_VLAPIC, | |||||
VM_MEM, | |||||
STRUCT_VHPET, | |||||
STRUCT_VMCX, | |||||
STRUCT_VATPIC, | |||||
STRUCT_VATPIT, | |||||
STRUCT_VPMTMR, | |||||
STRUCT_VRTC, | |||||
}; | |||||
struct vm_snapshot_buffer { | |||||
/* | |||||
* R/O for device-specific functions; | |||||
* written by generic snapshot functions. | |||||
*/ | |||||
uint8_t *const buf_start; | |||||
const size_t buf_size; | |||||
/* | |||||
* R/W for device-specific functions used to keep track of buffer | |||||
* current position and remaining size. | |||||
*/ | |||||
uint8_t *buf; | |||||
size_t buf_rem; | |||||
/* | |||||
* Length of the snapshot is either determined as (buf_size - buf_rem) | |||||
* or (buf - buf_start) -- the second variation returns a signed value | |||||
* so it may not be appropriate. | |||||
* | |||||
* Use vm_get_snapshot_size(meta). | |||||
*/ | |||||
}; | |||||
Done Inline Actionss/in stead/instead/ dab: s/in stead/instead/ | |||||
enum vm_snapshot_op { | |||||
VM_SNAPSHOT_SAVE, | |||||
VM_SNAPSHOT_RESTORE, | |||||
}; | |||||
struct vm_snapshot_meta { | |||||
struct vmctx *ctx; | |||||
void *dev_data; | |||||
const char *dev_name; /* identify userspace devices */ | |||||
enum snapshot_req dev_req; /* identify kernel structs */ | |||||
struct vm_snapshot_buffer buffer; | |||||
enum vm_snapshot_op op; | |||||
}; | |||||
void vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op); | |||||
int vm_snapshot_buf(volatile void *data, size_t data_size, | |||||
struct vm_snapshot_meta *meta); | |||||
size_t vm_get_snapshot_size(struct vm_snapshot_meta *meta); | |||||
int vm_snapshot_guest2host_addr(void **addrp, size_t len, bool restore_null, | |||||
struct vm_snapshot_meta *meta); | |||||
int vm_snapshot_buf_cmp(volatile void *data, size_t data_size, | |||||
struct vm_snapshot_meta *meta); | |||||
#define SNAPSHOT_BUF_OR_LEAVE(DATA, LEN, META, RES, LABEL) \ | |||||
do { \ | |||||
(RES) = vm_snapshot_buf((DATA), (LEN), (META)); \ | |||||
if ((RES) != 0) { \ | |||||
vm_snapshot_buf_err(#DATA, (META)->op); \ | |||||
goto LABEL; \ | |||||
} \ | |||||
} while (0) | |||||
#define SNAPSHOT_VAR_OR_LEAVE(DATA, META, RES, LABEL) \ | |||||
SNAPSHOT_BUF_OR_LEAVE(&(DATA), sizeof(DATA), (META), (RES), LABEL) | |||||
/* | |||||
* Address variables are pointers to guest memory. | |||||
* | |||||
* When RNULL != 0, do not enforce invalid address checks; instead, make the | |||||
* pointer NULL at restore time. | |||||
*/ | |||||
#define SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(ADDR, LEN, RNULL, META, RES, LABEL) \ | |||||
do { \ | |||||
(RES) = vm_snapshot_guest2host_addr((void **)&(ADDR), (LEN), (RNULL), \ | |||||
(META)); \ | |||||
if ((RES) != 0) { \ | |||||
if ((RES) == EFAULT) \ | |||||
fprintf(stderr, "%s: invalid address: %s\r\n", \ | |||||
__func__, #ADDR); \ | |||||
goto LABEL; \ | |||||
} \ | |||||
} while (0) | |||||
/* compare the value in the meta buffer with the data */ | |||||
#define SNAPSHOT_BUF_CMP_OR_LEAVE(DATA, LEN, META, RES, LABEL) \ | |||||
do { \ | |||||
(RES) = vm_snapshot_buf_cmp((DATA), (LEN), (META)); \ | |||||
if ((RES) != 0) { \ | |||||
vm_snapshot_buf_err(#DATA, (META)->op); \ | |||||
goto LABEL; \ | |||||
} \ | |||||
} while (0) | |||||
#define SNAPSHOT_VAR_CMP_OR_LEAVE(DATA, META, RES, LABEL) \ | |||||
SNAPSHOT_BUF_CMP_OR_LEAVE(&(DATA), sizeof(DATA), (META), (RES), LABEL) | |||||
#endif |
Perhaps there should be a function to determine the snapshot length rather than leaving it up to someone to interpret this comment and reach in to the struct components to calculate it.