bhyve: Remove vmctx member from struct vm_snapshot_meta.
This is a userland-only pointer that isn't relevant to the kernel and doesn't belong in the ioctl structure shared between userland and the kernel. For the kernel, the old structure for the ioctl is still supported under COMPAT_FREEBSD13. This changes vm_snapshot_req() in libvmmapi to accept an explicit vmctx argument. It also changes vm_snapshot_guest2host_addr to take an explicit vmctx argument. As part of this change, move the declaration for this function and its wrapper macro from vmm_snapshot.h to snapshot.h as it is a userland-only API. Reviewed by: corvink, markj Differential Revision: https://reviews.freebsd.org/D38125
This commit is contained in:
parent
7d9ef309bd
commit
0f735657aa
@ -1712,10 +1712,10 @@ vm_restart_instruction(struct vcpu *vcpu)
|
||||
}
|
||||
|
||||
int
|
||||
vm_snapshot_req(struct vm_snapshot_meta *meta)
|
||||
vm_snapshot_req(struct vmctx *ctx, struct vm_snapshot_meta *meta)
|
||||
{
|
||||
|
||||
if (ioctl(meta->ctx->fd, VM_SNAPSHOT_REQ, meta) == -1) {
|
||||
if (ioctl(ctx->fd, VM_SNAPSHOT_REQ, meta) == -1) {
|
||||
#ifdef SNAPSHOT_DEBUG
|
||||
fprintf(stderr, "%s: snapshot failed for %s: %d\r\n",
|
||||
__func__, meta->dev_name, errno);
|
||||
|
@ -265,7 +265,7 @@ void vm_setup_freebsd_gdt(uint64_t *gdtr);
|
||||
/*
|
||||
* Save and restore
|
||||
*/
|
||||
int vm_snapshot_req(struct vm_snapshot_meta *meta);
|
||||
int vm_snapshot_req(struct vmctx *ctx, struct vm_snapshot_meta *meta);
|
||||
int vm_restore_time(struct vmctx *ctx);
|
||||
|
||||
/*
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
struct vmctx;
|
||||
|
||||
enum snapshot_req {
|
||||
STRUCT_VIOAPIC = 1,
|
||||
STRUCT_VM,
|
||||
@ -89,7 +87,6 @@ enum vm_snapshot_op {
|
||||
};
|
||||
|
||||
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 */
|
||||
@ -103,8 +100,6 @@ void vm_snapshot_buf_err(const char *bufname, const enum vm_snapshot_op op);
|
||||
int vm_snapshot_buf(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(void *data, size_t data_size,
|
||||
struct vm_snapshot_meta *meta);
|
||||
|
||||
@ -120,24 +115,6 @@ do { \
|
||||
#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 { \
|
||||
|
@ -79,6 +79,20 @@ struct vm_stats_old {
|
||||
|
||||
#define VM_STATS_OLD \
|
||||
_IOWR('v', IOCNUM_VM_STATS, struct vm_stats_old)
|
||||
|
||||
struct vm_snapshot_meta_old {
|
||||
void *ctx; /* unused */
|
||||
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;
|
||||
};
|
||||
|
||||
#define VM_SNAPSHOT_REQ_OLD \
|
||||
_IOWR('v', IOCNUM_SNAPSHOT_REQ, struct vm_snapshot_meta_old)
|
||||
#endif
|
||||
|
||||
struct devmem_softc {
|
||||
@ -416,6 +430,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
bool memsegs_locked;
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
struct vm_snapshot_meta *snapshot_meta;
|
||||
#ifdef COMPAT_FREEBSD13
|
||||
struct vm_snapshot_meta_old *snapshot_old;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
error = vmm_priv_check(curthread->td_ucred);
|
||||
@ -495,6 +512,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
case VM_UNMAP_PPTDEV_MMIO:
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
case VM_SNAPSHOT_REQ:
|
||||
#ifdef COMPAT_FREEBSD13
|
||||
case VM_SNAPSHOT_REQ_OLD:
|
||||
#endif
|
||||
case VM_RESTORE_TIME:
|
||||
#endif
|
||||
/*
|
||||
@ -951,6 +971,18 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
snapshot_meta = (struct vm_snapshot_meta *)data;
|
||||
error = vm_snapshot_req(sc->vm, snapshot_meta);
|
||||
break;
|
||||
#ifdef COMPAT_FREEBSD13
|
||||
case VM_SNAPSHOT_REQ_OLD:
|
||||
/*
|
||||
* The old structure just has an additional pointer at
|
||||
* the start that is ignored.
|
||||
*/
|
||||
snapshot_old = (struct vm_snapshot_meta_old *)data;
|
||||
snapshot_meta =
|
||||
(struct vm_snapshot_meta *)&snapshot_old->dev_data;
|
||||
error = vm_snapshot_req(sc->vm, snapshot_meta);
|
||||
break;
|
||||
#endif
|
||||
case VM_RESTORE_TIME:
|
||||
error = vm_restore_time(sc->vm);
|
||||
break;
|
||||
|
@ -1534,7 +1534,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
fprintf(stdout, "Restoring pci devs...\r\n");
|
||||
if (vm_restore_user_devs(ctx, &rstate) != 0) {
|
||||
if (vm_restore_user_devs(&rstate) != 0) {
|
||||
fprintf(stderr, "Failed to restore PCI device state.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ata.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#include <machine/vmm_snapshot.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -61,6 +59,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "pci_emul.h"
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
#include "snapshot.h"
|
||||
#endif
|
||||
#include "ahci.h"
|
||||
#include "block_if.h"
|
||||
|
||||
@ -2623,10 +2624,10 @@ pci_ahci_snapshot(struct vm_snapshot_meta *meta)
|
||||
goto done;
|
||||
}
|
||||
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(port->cmd_lst,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, port->cmd_lst,
|
||||
AHCI_CL_SIZE * AHCI_MAX_SLOTS, false, meta, ret, done);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(port->rfis, 256, false, meta,
|
||||
ret, done);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, port->rfis, 256,
|
||||
false, meta, ret, done);
|
||||
|
||||
SNAPSHOT_VAR_OR_LEAVE(port->ata_ident, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(port->atapi, meta, ret, done);
|
||||
|
@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
|
||||
#ifndef WITHOUT_CAPSICUM
|
||||
#include <capsicum_helpers.h>
|
||||
#endif
|
||||
#include <machine/vmm_snapshot.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
@ -68,6 +67,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "pci_emul.h"
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
#include "snapshot.h"
|
||||
#endif
|
||||
#include "mevent.h"
|
||||
#include "net_utils.h"
|
||||
#include "net_backends.h"
|
||||
@ -2436,8 +2438,8 @@ e82545_snapshot(struct vm_snapshot_meta *meta)
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TADV, meta, ret, done);
|
||||
|
||||
/* Has dependency on esc_TDLEN; reoreder of fields from struct. */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->esc_txdesc, sc->esc_TDLEN,
|
||||
true, meta, ret, done);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->esc_txdesc,
|
||||
sc->esc_TDLEN, true, meta, ret, done);
|
||||
|
||||
/* L2 frame acceptance */
|
||||
for (i = 0; i < (int)nitems(sc->esc_uni); i++) {
|
||||
@ -2471,8 +2473,8 @@ e82545_snapshot(struct vm_snapshot_meta *meta)
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RXCSUM, meta, ret, done);
|
||||
|
||||
/* Has dependency on esc_RDLEN; reoreder of fields from struct. */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->esc_rxdesc, sc->esc_TDLEN,
|
||||
true, meta, ret, done);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->esc_rxdesc,
|
||||
sc->esc_TDLEN, true, meta, ret, done);
|
||||
|
||||
/* IO Port register access */
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->io_addr, meta, ret, done);
|
||||
|
@ -48,8 +48,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <machine/vmm_snapshot.h>
|
||||
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usb_freebsd.h>
|
||||
@ -60,6 +58,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include "debug.h"
|
||||
#include "pci_emul.h"
|
||||
#include "pci_xhci.h"
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
#include "snapshot.h"
|
||||
#endif
|
||||
#include "usb_emul.h"
|
||||
|
||||
|
||||
@ -2965,8 +2966,8 @@ pci_xhci_map_devs_slots(struct pci_xhci_softc *sc, int maps[])
|
||||
}
|
||||
|
||||
static int
|
||||
pci_xhci_snapshot_ep(struct pci_xhci_softc *sc __unused,
|
||||
struct pci_xhci_dev_emu *dev, int idx, struct vm_snapshot_meta *meta)
|
||||
pci_xhci_snapshot_ep(struct pci_xhci_softc *sc, struct pci_xhci_dev_emu *dev,
|
||||
int idx, struct vm_snapshot_meta *meta)
|
||||
{
|
||||
int k;
|
||||
int ret;
|
||||
@ -2992,9 +2993,9 @@ pci_xhci_snapshot_ep(struct pci_xhci_softc *sc __unused,
|
||||
for (k = 0; k < USB_MAX_XFER_BLOCKS; k++) {
|
||||
xfer_block = &xfer->data[k];
|
||||
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(xfer_block->buf,
|
||||
XHCI_GADDR_SIZE(xfer_block->buf), true, meta, ret,
|
||||
done);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->xsc_pi->pi_vmctx,
|
||||
xfer_block->buf, XHCI_GADDR_SIZE(xfer_block->buf), true,
|
||||
meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(xfer_block->blen, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(xfer_block->bdone, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(xfer_block->processed, meta, ret, done);
|
||||
@ -3059,11 +3060,11 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta)
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->opregs.config, meta, ret, done);
|
||||
|
||||
/* opregs.cr_p */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->opregs.cr_p,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->opregs.cr_p,
|
||||
XHCI_GADDR_SIZE(sc->opregs.cr_p), true, meta, ret, done);
|
||||
|
||||
/* opregs.dcbaa_p */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->opregs.dcbaa_p,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->opregs.dcbaa_p,
|
||||
XHCI_GADDR_SIZE(sc->opregs.dcbaa_p), true, meta, ret, done);
|
||||
|
||||
/* rtsregs */
|
||||
@ -3078,11 +3079,11 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta)
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->rtsregs.intrreg.erdp, meta, ret, done);
|
||||
|
||||
/* rtsregs.erstba_p */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->rtsregs.erstba_p,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->rtsregs.erstba_p,
|
||||
XHCI_GADDR_SIZE(sc->rtsregs.erstba_p), true, meta, ret, done);
|
||||
|
||||
/* rtsregs.erst_p */
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->rtsregs.erst_p,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->rtsregs.erst_p,
|
||||
XHCI_GADDR_SIZE(sc->rtsregs.erst_p), true, meta, ret, done);
|
||||
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->rtsregs.er_deq_seg, meta, ret, done);
|
||||
@ -3168,7 +3169,7 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta)
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(dev->dev_ctx,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, dev->dev_ctx,
|
||||
XHCI_GADDR_SIZE(dev->dev_ctx), true, meta, ret, done);
|
||||
|
||||
if (dev->dev_ctx != NULL) {
|
||||
|
@ -886,7 +886,6 @@ vm_restore_kern_struct(struct vmctx *ctx, struct restore_state *rstate,
|
||||
}
|
||||
|
||||
meta = &(struct vm_snapshot_meta) {
|
||||
.ctx = ctx,
|
||||
.dev_name = info->struct_name,
|
||||
.dev_req = info->req,
|
||||
|
||||
@ -899,7 +898,7 @@ vm_restore_kern_struct(struct vmctx *ctx, struct restore_state *rstate,
|
||||
.op = VM_SNAPSHOT_RESTORE,
|
||||
};
|
||||
|
||||
ret = vm_snapshot_req(meta);
|
||||
ret = vm_snapshot_req(ctx, meta);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s: Failed to restore struct: %s\r\n",
|
||||
__func__, info->struct_name);
|
||||
@ -927,7 +926,7 @@ vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate)
|
||||
}
|
||||
|
||||
static int
|
||||
vm_restore_user_dev(struct vmctx *ctx, struct restore_state *rstate,
|
||||
vm_restore_user_dev(struct restore_state *rstate,
|
||||
const struct vm_snapshot_dev_info *info)
|
||||
{
|
||||
void *dev_ptr;
|
||||
@ -950,7 +949,6 @@ vm_restore_user_dev(struct vmctx *ctx, struct restore_state *rstate,
|
||||
}
|
||||
|
||||
meta = &(struct vm_snapshot_meta) {
|
||||
.ctx = ctx,
|
||||
.dev_name = info->dev_name,
|
||||
|
||||
.buffer.buf_start = dev_ptr,
|
||||
@ -974,13 +972,13 @@ vm_restore_user_dev(struct vmctx *ctx, struct restore_state *rstate,
|
||||
|
||||
|
||||
int
|
||||
vm_restore_user_devs(struct vmctx *ctx, struct restore_state *rstate)
|
||||
vm_restore_user_devs(struct restore_state *rstate)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < nitems(snapshot_devs); i++) {
|
||||
ret = vm_restore_user_dev(ctx, rstate, &snapshot_devs[i]);
|
||||
ret = vm_restore_user_dev(rstate, &snapshot_devs[i]);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
}
|
||||
@ -1029,14 +1027,14 @@ vm_resume_user_devs(void)
|
||||
}
|
||||
|
||||
static int
|
||||
vm_snapshot_kern_struct(int data_fd, xo_handle_t *xop, const char *array_key,
|
||||
struct vm_snapshot_meta *meta, off_t *offset)
|
||||
vm_snapshot_kern_struct(struct vmctx *ctx, int data_fd, xo_handle_t *xop,
|
||||
const char *array_key, struct vm_snapshot_meta *meta, off_t *offset)
|
||||
{
|
||||
int ret;
|
||||
size_t data_size;
|
||||
ssize_t write_cnt;
|
||||
|
||||
ret = vm_snapshot_req(meta);
|
||||
ret = vm_snapshot_req(ctx, meta);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s: Failed to snapshot struct %s\r\n",
|
||||
__func__, meta->dev_name);
|
||||
@ -1089,8 +1087,6 @@ vm_snapshot_kern_structs(struct vmctx *ctx, int data_fd, xo_handle_t *xop)
|
||||
}
|
||||
|
||||
meta = &(struct vm_snapshot_meta) {
|
||||
.ctx = ctx,
|
||||
|
||||
.buffer.buf_start = buffer,
|
||||
.buffer.buf_size = buf_size,
|
||||
|
||||
@ -1106,8 +1102,8 @@ vm_snapshot_kern_structs(struct vmctx *ctx, int data_fd, xo_handle_t *xop)
|
||||
meta->buffer.buf = meta->buffer.buf_start;
|
||||
meta->buffer.buf_rem = meta->buffer.buf_size;
|
||||
|
||||
ret = vm_snapshot_kern_struct(data_fd, xop, JSON_DEV_ARR_KEY,
|
||||
meta, &offset);
|
||||
ret = vm_snapshot_kern_struct(ctx, data_fd, xop,
|
||||
JSON_DEV_ARR_KEY, meta, &offset);
|
||||
if (ret != 0) {
|
||||
error = -1;
|
||||
goto err_vm_snapshot_kern_data;
|
||||
@ -1186,7 +1182,7 @@ vm_snapshot_user_dev(const struct vm_snapshot_dev_info *info,
|
||||
}
|
||||
|
||||
static int
|
||||
vm_snapshot_user_devs(struct vmctx *ctx, int data_fd, xo_handle_t *xop)
|
||||
vm_snapshot_user_devs(int data_fd, xo_handle_t *xop)
|
||||
{
|
||||
int ret;
|
||||
off_t offset;
|
||||
@ -1210,8 +1206,6 @@ vm_snapshot_user_devs(struct vmctx *ctx, int data_fd, xo_handle_t *xop)
|
||||
}
|
||||
|
||||
meta = &(struct vm_snapshot_meta) {
|
||||
.ctx = ctx,
|
||||
|
||||
.buffer.buf_start = buffer,
|
||||
.buffer.buf_size = buf_size,
|
||||
|
||||
@ -1395,7 +1389,7 @@ vm_checkpoint(struct vmctx *ctx, const char *checkpoint_file, bool stop_vm)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = vm_snapshot_user_devs(ctx, kdata_fd, xop);
|
||||
ret = vm_snapshot_user_devs(kdata_fd, xop);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to snapshot device state.\n");
|
||||
error = -1;
|
||||
@ -1639,14 +1633,14 @@ 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)
|
||||
vm_snapshot_guest2host_addr(struct vmctx *ctx, void **addrp, size_t len,
|
||||
bool restore_null, struct vm_snapshot_meta *meta)
|
||||
{
|
||||
int ret;
|
||||
vm_paddr_t gaddr;
|
||||
|
||||
if (meta->op == VM_SNAPSHOT_SAVE) {
|
||||
gaddr = paddr_host2guest(meta->ctx, *addrp);
|
||||
gaddr = paddr_host2guest(ctx, *addrp);
|
||||
if (gaddr == (vm_paddr_t) -1) {
|
||||
if (!restore_null ||
|
||||
(restore_null && (*addrp != NULL))) {
|
||||
@ -1665,7 +1659,7 @@ vm_snapshot_guest2host_addr(void **addrp, size_t len, bool restore_null,
|
||||
}
|
||||
}
|
||||
|
||||
*addrp = paddr_guest2host(meta->ctx, gaddr, len);
|
||||
*addrp = paddr_guest2host(ctx, gaddr, len);
|
||||
} else {
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ void checkpoint_cpu_suspend(int vcpu);
|
||||
int restore_vm_mem(struct vmctx *ctx, struct restore_state *rstate);
|
||||
int vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate);
|
||||
|
||||
int vm_restore_user_devs(struct vmctx *ctx, struct restore_state *rstate);
|
||||
int vm_restore_user_devs(struct restore_state *rstate);
|
||||
int vm_pause_user_devs(void);
|
||||
int vm_resume_user_devs(void);
|
||||
|
||||
@ -106,4 +106,25 @@ void init_snapshot(void);
|
||||
|
||||
int load_restore_file(const char *filename, struct restore_state *rstate);
|
||||
|
||||
int vm_snapshot_guest2host_addr(struct vmctx *ctx, void **addrp, size_t len,
|
||||
bool restore_null, struct vm_snapshot_meta *meta);
|
||||
|
||||
/*
|
||||
* 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(CTX, ADDR, LEN, RNULL, META, RES, LABEL) \
|
||||
do { \
|
||||
(RES) = vm_snapshot_guest2host_addr((CTX), (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)
|
||||
|
||||
#endif
|
||||
|
@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/vmm_snapshot.h>
|
||||
|
||||
#include <dev/virtio/pci/virtio_pci_legacy_var.h>
|
||||
|
||||
@ -47,6 +46,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include "bhyverun.h"
|
||||
#include "debug.h"
|
||||
#include "pci_emul.h"
|
||||
#ifdef BHYVE_SNAPSHOT
|
||||
#include "snapshot.h"
|
||||
#endif
|
||||
#include "virtio.h"
|
||||
|
||||
/*
|
||||
@ -880,8 +882,10 @@ vi_pci_snapshot_queues(struct virtio_softc *vs, struct vm_snapshot_meta *meta)
|
||||
int ret;
|
||||
struct virtio_consts *vc;
|
||||
struct vqueue_info *vq;
|
||||
struct vmctx *ctx;
|
||||
uint64_t addr_size;
|
||||
|
||||
ctx = vs->vs_pi->pi_vmctx;
|
||||
vc = vs->vs_vc;
|
||||
|
||||
/* Save virtio queue info */
|
||||
@ -903,15 +907,15 @@ vi_pci_snapshot_queues(struct virtio_softc *vs, struct vm_snapshot_meta *meta)
|
||||
continue;
|
||||
|
||||
addr_size = vq->vq_qsize * sizeof(struct vring_desc);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(vq->vq_desc, addr_size,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(ctx, vq->vq_desc, addr_size,
|
||||
false, meta, ret, done);
|
||||
|
||||
addr_size = (2 + vq->vq_qsize + 1) * sizeof(uint16_t);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(vq->vq_avail, addr_size,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(ctx, vq->vq_avail, addr_size,
|
||||
false, meta, ret, done);
|
||||
|
||||
addr_size = (2 + 2 * vq->vq_qsize + 1) * sizeof(uint16_t);
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(vq->vq_used, addr_size,
|
||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(ctx, vq->vq_used, addr_size,
|
||||
false, meta, ret, done);
|
||||
|
||||
SNAPSHOT_BUF_OR_LEAVE(vq->vq_desc,
|
||||
|
Loading…
Reference in New Issue
Block a user