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.