master
  1/*-
  2 * SPDX-License-Identifier: BSD-2-Clause
  3 *
  4 * Copyright (c) 2016 Flavius Anton
  5 * Copyright (c) 2016 Mihai Tiganus
  6 * Copyright (c) 2016-2019 Mihai Carabas
  7 * Copyright (c) 2017-2019 Darius Mihai
  8 * Copyright (c) 2017-2019 Elena Mihailescu
  9 * Copyright (c) 2018-2019 Sergiu Weisz
 10 * All rights reserved.
 11 * The bhyve-snapshot feature was developed under sponsorships
 12 * from Matthew Grooms.
 13 *
 14 * Redistribution and use in source and binary forms, with or without
 15 * modification, are permitted provided that the following conditions
 16 * are met:
 17 * 1. Redistributions of source code must retain the above copyright
 18 *    notice, this list of conditions and the following disclaimer.
 19 * 2. Redistributions in binary form must reproduce the above copyright
 20 *    notice, this list of conditions and the following disclaimer in the
 21 *    documentation and/or other materials provided with the distribution.
 22 *
 23 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 26 * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 33 * SUCH DAMAGE.
 34 */
 35
 36#ifndef _VMM_SNAPSHOT_
 37#define _VMM_SNAPSHOT_
 38
 39#include <sys/errno.h>
 40#include <sys/types.h>
 41#ifndef _KERNEL
 42#include <stdbool.h>
 43#endif
 44
 45enum snapshot_req {
 46	STRUCT_VIOAPIC = 1,
 47	STRUCT_VM,
 48	STRUCT_VLAPIC,
 49	VM_MEM,
 50	STRUCT_VHPET,
 51	STRUCT_VMCX,
 52	STRUCT_VATPIC,
 53	STRUCT_VATPIT,
 54	STRUCT_VPMTMR,
 55	STRUCT_VRTC,
 56};
 57
 58struct vm_snapshot_buffer {
 59	/*
 60	 * R/O for device-specific functions;
 61	 * written by generic snapshot functions.
 62	 */
 63	uint8_t *const buf_start;
 64	const size_t buf_size;
 65
 66	/*
 67	 * R/W for device-specific functions used to keep track of buffer
 68	 * current position and remaining size.
 69	 */
 70	uint8_t *buf;
 71	size_t buf_rem;
 72
 73	/*
 74	 * Length of the snapshot is either determined as (buf_size - buf_rem)
 75	 * or (buf - buf_start) -- the second variation returns a signed value
 76	 * so it may not be appropriate.
 77	 *
 78	 * Use vm_get_snapshot_size(meta).
 79	 */
 80};
 81
 82enum vm_snapshot_op {
 83	VM_SNAPSHOT_SAVE,
 84	VM_SNAPSHOT_RESTORE,
 85};
 86
 87struct vm_snapshot_meta {
 88	void *dev_data;
 89	const char *dev_name;      /* identify userspace devices */
 90	enum snapshot_req dev_req; /* identify kernel structs */
 91
 92	struct vm_snapshot_buffer buffer;
 93
 94	enum vm_snapshot_op op;
 95};
 96
 97void vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op);
 98int vm_snapshot_buf(void *data, size_t data_size,
 99    struct vm_snapshot_meta *meta);
100size_t vm_get_snapshot_size(struct vm_snapshot_meta *meta);
101
102#define	SNAPSHOT_BUF_OR_LEAVE(DATA, LEN, META, RES, LABEL)			\
103do {										\
104	(RES) = vm_snapshot_buf((DATA), (LEN), (META));				\
105	if ((RES) != 0) {							\
106		vm_snapshot_buf_err(#DATA, (META)->op);				\
107		goto LABEL;							\
108	}									\
109} while (0)
110
111#define	SNAPSHOT_VAR_OR_LEAVE(DATA, META, RES, LABEL)				\
112	SNAPSHOT_BUF_OR_LEAVE(&(DATA), sizeof(DATA), (META), (RES), LABEL)
113
114#ifndef _KERNEL
115int vm_snapshot_buf_cmp(void *data, size_t data_size,
116    struct vm_snapshot_meta *meta);
117
118/* compare the value in the meta buffer with the data */
119#define	SNAPSHOT_BUF_CMP_OR_LEAVE(DATA, LEN, META, RES, LABEL)			\
120do {										\
121	(RES) = vm_snapshot_buf_cmp((DATA), (LEN), (META));			\
122	if ((RES) != 0) {							\
123		vm_snapshot_buf_err(#DATA, (META)->op);				\
124		goto LABEL;							\
125	}									\
126} while (0)
127
128#define	SNAPSHOT_VAR_CMP_OR_LEAVE(DATA, META, RES, LABEL)			\
129	SNAPSHOT_BUF_CMP_OR_LEAVE(&(DATA), sizeof(DATA), (META), (RES), LABEL)
130
131#endif	/* _KERNEL */
132#endif