git: 0f735657aa76 - main - bhyve: Remove vmctx member from struct vm_snapshot_meta.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Mar 2023 18:49:14 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=0f735657aa762e3b226087a9be6edf95868bc62d commit 0f735657aa762e3b226087a9be6edf95868bc62d Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2023-03-24 18:49:06 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2023-03-24 18:49:06 +0000 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 --- lib/libvmmapi/vmmapi.c | 4 ++-- lib/libvmmapi/vmmapi.h | 2 +- sys/amd64/include/vmm_snapshot.h | 23 ----------------------- sys/amd64/vmm/vmm_dev.c | 32 ++++++++++++++++++++++++++++++++ usr.sbin/bhyve/bhyverun.c | 2 +- usr.sbin/bhyve/pci_ahci.c | 11 ++++++----- usr.sbin/bhyve/pci_e82545.c | 12 +++++++----- usr.sbin/bhyve/pci_xhci.c | 25 +++++++++++++------------ usr.sbin/bhyve/snapshot.c | 36 +++++++++++++++--------------------- usr.sbin/bhyve/snapshot.h | 23 ++++++++++++++++++++++- usr.sbin/bhyve/virtio.c | 12 ++++++++---- 11 files changed, 107 insertions(+), 75 deletions(-) diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 2d0cc21aeb25..3cbc885b82db 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -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); diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index 322b47e4ee0e..459aad0fe1a3 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -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); /* diff --git a/sys/amd64/include/vmm_snapshot.h b/sys/amd64/include/vmm_snapshot.h index c4d7fc4d4371..a34684e9b671 100644 --- a/sys/amd64/include/vmm_snapshot.h +++ b/sys/amd64/include/vmm_snapshot.h @@ -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 { \ diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 2d8ff43a74dd..e7f7d24cecd2 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -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; diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index 57d8dd7aea60..d447a9ee60e4 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -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); } diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c index 9c023d93cab9..6b6a91325f72 100644 --- a/usr.sbin/bhyve/pci_ahci.c +++ b/usr.sbin/bhyve/pci_ahci.c @@ -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); diff --git a/usr.sbin/bhyve/pci_e82545.c b/usr.sbin/bhyve/pci_e82545.c index bec8edb17caf..646eb0ca0118 100644 --- a/usr.sbin/bhyve/pci_e82545.c +++ b/usr.sbin/bhyve/pci_e82545.c @@ -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); diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c index 0ac1423f0736..2c5f36eb130d 100644 --- a/usr.sbin/bhyve/pci_xhci.c +++ b/usr.sbin/bhyve/pci_xhci.c @@ -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) { diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c index 72b63c506c41..866fc265b8aa 100644 --- a/usr.sbin/bhyve/snapshot.c +++ b/usr.sbin/bhyve/snapshot.c @@ -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; } diff --git a/usr.sbin/bhyve/snapshot.h b/usr.sbin/bhyve/snapshot.h index e59c92f2326f..a125dddc1e71 100644 --- a/usr.sbin/bhyve/snapshot.h +++ b/usr.sbin/bhyve/snapshot.h @@ -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 diff --git a/usr.sbin/bhyve/virtio.c b/usr.sbin/bhyve/virtio.c index 68304f76dc49..12d5f9b147d0 100644 --- a/usr.sbin/bhyve/virtio.c +++ b/usr.sbin/bhyve/virtio.c @@ -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,