1*483d953aSJohn Baldwin /*- 2*483d953aSJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*483d953aSJohn Baldwin * 4*483d953aSJohn Baldwin * Copyright (c) 2016 Flavius Anton 5*483d953aSJohn Baldwin * Copyright (c) 2016 Mihai Tiganus 6*483d953aSJohn Baldwin * Copyright (c) 2016-2019 Mihai Carabas 7*483d953aSJohn Baldwin * Copyright (c) 2017-2019 Darius Mihai 8*483d953aSJohn Baldwin * Copyright (c) 2017-2019 Elena Mihailescu 9*483d953aSJohn Baldwin * Copyright (c) 2018-2019 Sergiu Weisz 10*483d953aSJohn Baldwin * All rights reserved. 11*483d953aSJohn Baldwin * The bhyve-snapshot feature was developed under sponsorships 12*483d953aSJohn Baldwin * from Matthew Grooms. 13*483d953aSJohn Baldwin * 14*483d953aSJohn Baldwin * Redistribution and use in source and binary forms, with or without 15*483d953aSJohn Baldwin * modification, are permitted provided that the following conditions 16*483d953aSJohn Baldwin * are met: 17*483d953aSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 18*483d953aSJohn Baldwin * notice, this list of conditions and the following disclaimer. 19*483d953aSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 20*483d953aSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 21*483d953aSJohn Baldwin * documentation and/or other materials provided with the distribution. 22*483d953aSJohn Baldwin * 23*483d953aSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 24*483d953aSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25*483d953aSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26*483d953aSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 27*483d953aSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28*483d953aSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29*483d953aSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30*483d953aSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31*483d953aSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32*483d953aSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33*483d953aSJohn Baldwin * SUCH DAMAGE. 34*483d953aSJohn Baldwin */ 35*483d953aSJohn Baldwin 36*483d953aSJohn Baldwin #include <sys/cdefs.h> 37*483d953aSJohn Baldwin __FBSDID("$FreeBSD$"); 38*483d953aSJohn Baldwin 39*483d953aSJohn Baldwin #include <sys/types.h> 40*483d953aSJohn Baldwin #include <sys/systm.h> 41*483d953aSJohn Baldwin 42*483d953aSJohn Baldwin #include <machine/vmm_snapshot.h> 43*483d953aSJohn Baldwin 44*483d953aSJohn Baldwin void 45*483d953aSJohn Baldwin vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op) 46*483d953aSJohn Baldwin { 47*483d953aSJohn Baldwin const char *opstr; 48*483d953aSJohn Baldwin 49*483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) 50*483d953aSJohn Baldwin opstr = "save"; 51*483d953aSJohn Baldwin else if (op == VM_SNAPSHOT_RESTORE) 52*483d953aSJohn Baldwin opstr = "restore"; 53*483d953aSJohn Baldwin else 54*483d953aSJohn Baldwin opstr = "unknown"; 55*483d953aSJohn Baldwin 56*483d953aSJohn Baldwin printf("%s: snapshot-%s failed for %s\r\n", __func__, opstr, bufname); 57*483d953aSJohn Baldwin } 58*483d953aSJohn Baldwin 59*483d953aSJohn Baldwin int 60*483d953aSJohn Baldwin vm_snapshot_buf(volatile void *data, size_t data_size, 61*483d953aSJohn Baldwin struct vm_snapshot_meta *meta) 62*483d953aSJohn Baldwin { 63*483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 64*483d953aSJohn Baldwin int op; 65*483d953aSJohn Baldwin void *nv_data; 66*483d953aSJohn Baldwin 67*483d953aSJohn Baldwin nv_data = __DEVOLATILE(void *, data); 68*483d953aSJohn Baldwin buffer = &meta->buffer; 69*483d953aSJohn Baldwin op = meta->op; 70*483d953aSJohn Baldwin 71*483d953aSJohn Baldwin if (buffer->buf_rem < data_size) { 72*483d953aSJohn Baldwin printf("%s: buffer too small\r\n", __func__); 73*483d953aSJohn Baldwin return (E2BIG); 74*483d953aSJohn Baldwin } 75*483d953aSJohn Baldwin 76*483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) 77*483d953aSJohn Baldwin copyout(nv_data, buffer->buf, data_size); 78*483d953aSJohn Baldwin else if (op == VM_SNAPSHOT_RESTORE) 79*483d953aSJohn Baldwin copyin(buffer->buf, nv_data, data_size); 80*483d953aSJohn Baldwin else 81*483d953aSJohn Baldwin return (EINVAL); 82*483d953aSJohn Baldwin 83*483d953aSJohn Baldwin buffer->buf += data_size; 84*483d953aSJohn Baldwin buffer->buf_rem -= data_size; 85*483d953aSJohn Baldwin 86*483d953aSJohn Baldwin return (0); 87*483d953aSJohn Baldwin } 88*483d953aSJohn Baldwin 89*483d953aSJohn Baldwin size_t 90*483d953aSJohn Baldwin vm_get_snapshot_size(struct vm_snapshot_meta *meta) 91*483d953aSJohn Baldwin { 92*483d953aSJohn Baldwin size_t length; 93*483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 94*483d953aSJohn Baldwin 95*483d953aSJohn Baldwin buffer = &meta->buffer; 96*483d953aSJohn Baldwin 97*483d953aSJohn Baldwin if (buffer->buf_size < buffer->buf_rem) { 98*483d953aSJohn Baldwin printf("%s: Invalid buffer: size = %zu, rem = %zu\r\n", 99*483d953aSJohn Baldwin __func__, buffer->buf_size, buffer->buf_rem); 100*483d953aSJohn Baldwin length = 0; 101*483d953aSJohn Baldwin } else { 102*483d953aSJohn Baldwin length = buffer->buf_size - buffer->buf_rem; 103*483d953aSJohn Baldwin } 104*483d953aSJohn Baldwin 105*483d953aSJohn Baldwin return (length); 106*483d953aSJohn Baldwin } 107*483d953aSJohn Baldwin 108*483d953aSJohn Baldwin int 109*483d953aSJohn Baldwin vm_snapshot_buf_cmp(volatile void *data, size_t data_size, 110*483d953aSJohn Baldwin struct vm_snapshot_meta *meta) 111*483d953aSJohn Baldwin { 112*483d953aSJohn Baldwin struct vm_snapshot_buffer *buffer; 113*483d953aSJohn Baldwin int op; 114*483d953aSJohn Baldwin int ret; 115*483d953aSJohn Baldwin void *_data = *(void **)(void *)&data; 116*483d953aSJohn Baldwin 117*483d953aSJohn Baldwin buffer = &meta->buffer; 118*483d953aSJohn Baldwin op = meta->op; 119*483d953aSJohn Baldwin 120*483d953aSJohn Baldwin if (buffer->buf_rem < data_size) { 121*483d953aSJohn Baldwin printf("%s: buffer too small\r\n", __func__); 122*483d953aSJohn Baldwin ret = E2BIG; 123*483d953aSJohn Baldwin goto done; 124*483d953aSJohn Baldwin } 125*483d953aSJohn Baldwin 126*483d953aSJohn Baldwin if (op == VM_SNAPSHOT_SAVE) { 127*483d953aSJohn Baldwin ret = 0; 128*483d953aSJohn Baldwin copyout(_data, buffer->buf, data_size); 129*483d953aSJohn Baldwin } else if (op == VM_SNAPSHOT_RESTORE) { 130*483d953aSJohn Baldwin ret = memcmp(_data, buffer->buf, data_size); 131*483d953aSJohn Baldwin } else { 132*483d953aSJohn Baldwin ret = EINVAL; 133*483d953aSJohn Baldwin goto done; 134*483d953aSJohn Baldwin } 135*483d953aSJohn Baldwin 136*483d953aSJohn Baldwin buffer->buf += data_size; 137*483d953aSJohn Baldwin buffer->buf_rem -= data_size; 138*483d953aSJohn Baldwin 139*483d953aSJohn Baldwin done: 140*483d953aSJohn Baldwin return (ret); 141*483d953aSJohn Baldwin } 142