Index: pci_virtio_net.c =================================================================== --- pci_virtio_net.c (revision 247367) +++ pci_virtio_net.c (working copy) @@ -326,7 +326,7 @@ * Get a pointer to the rx header, and use the * data immediately following it for the packet buffer. */ - vrx = (struct virtio_net_rxhdr *)paddr_guest2host(vd->vd_addr); + vrx = paddr_guest2host(vd->vd_addr, vd->vd_len); buf = (uint8_t *)(vrx + 1); len = read(sc->vsc_tapfd, buf, @@ -434,7 +434,7 @@ for (i = 0, plen = 0; i < VTNET_MAXSEGS; i++, vd = &hq->hq_dtable[vd->vd_next]) { - iov[i].iov_base = paddr_guest2host(vd->vd_addr); + iov[i].iov_base = paddr_guest2host(vd->vd_addr, vd->vd_len); iov[i].iov_len = vd->vd_len; plen += vd->vd_len; tlen += vd->vd_len; @@ -517,7 +517,8 @@ hq = &sc->vsc_hq[qnum]; hq->hq_size = pci_vtnet_qsize(qnum); - hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN); + hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN, + vring_size(hq->hq_size)); hq->hq_avail_flags = (uint16_t *)(hq->hq_dtable + hq->hq_size); hq->hq_avail_idx = hq->hq_avail_flags + 1; hq->hq_avail_ring = hq->hq_avail_flags + 2; @@ -541,13 +542,6 @@ struct pci_vtnet_softc *sc; const char *env_msi; - /* - * Access to guest memory is required. Fail if - * memory not mapped - */ - if (paddr_guest2host(0) == NULL) - return (1); - sc = malloc(sizeof(struct pci_vtnet_softc)); memset(sc, 0, sizeof(struct pci_vtnet_softc)); Index: pci_virtio_block.c =================================================================== --- pci_virtio_block.c (revision 247367) +++ pci_virtio_block.c (working copy) @@ -222,13 +222,13 @@ assert(nsegs >= 3); assert(nsegs < VTBLK_MAXSEGS + 2); - vid = paddr_guest2host(vd->vd_addr); + vid = paddr_guest2host(vd->vd_addr, vd->vd_len); assert((vid->vd_flags & VRING_DESC_F_INDIRECT) == 0); /* * The first descriptor will be the read-only fixed header */ - vbh = paddr_guest2host(vid[0].vd_addr); + vbh = paddr_guest2host(vid[0].vd_addr, sizeof(struct virtio_blk_hdr)); assert(vid[0].vd_len == sizeof(struct virtio_blk_hdr)); assert(vid[0].vd_flags & VRING_DESC_F_NEXT); assert((vid[0].vd_flags & VRING_DESC_F_WRITE) == 0); @@ -247,7 +247,8 @@ * Build up the iovec based on the guest's data descriptors */ for (i = 1, iolen = 0; i < nsegs - 1; i++) { - iov[i-1].iov_base = paddr_guest2host(vid[i].vd_addr); + iov[i-1].iov_base = paddr_guest2host(vid[i].vd_addr, + vid[i].vd_len); iov[i-1].iov_len = vid[i].vd_len; iolen += vid[i].vd_len; @@ -265,7 +266,7 @@ } /* Lastly, get the address of the status byte */ - status = paddr_guest2host(vid[nsegs - 1].vd_addr); + status = paddr_guest2host(vid[nsegs - 1].vd_addr, 1); assert(vid[nsegs - 1].vd_len == 1); assert((vid[nsegs - 1].vd_flags & VRING_DESC_F_NEXT) == 0); assert(vid[nsegs - 1].vd_flags & VRING_DESC_F_WRITE); @@ -341,7 +342,8 @@ hq = &sc->vbsc_q; hq->hq_size = VTBLK_RINGSZ; - hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN); + hq->hq_dtable = paddr_guest2host(pfn << VRING_PFN, + vring_size(VTBLK_RINGSZ)); hq->hq_avail_flags = (uint16_t *)(hq->hq_dtable + hq->hq_size); hq->hq_avail_idx = hq->hq_avail_flags + 1; hq->hq_avail_ring = hq->hq_avail_flags + 2; @@ -372,13 +374,6 @@ } /* - * Access to guest memory is required. Fail if - * memory not mapped - */ - if (paddr_guest2host(0) == NULL) - return (1); - - /* * The supplied backing file has to exist */ fd = open(opts, O_RDWR); Index: acpi.c =================================================================== --- acpi.c (revision 247367) +++ acpi.c (working copy) @@ -683,13 +683,16 @@ basl_load(int fd, uint64_t off) { struct stat sb; + void *gaddr; int err; err = 0; - - if (fstat(fd, &sb) < 0 || - read(fd, paddr_guest2host(basl_acpi_base + off), sb.st_size) < 0) + gaddr = paddr_guest2host(basl_acpi_base + off, sb.st_size); + if (gaddr != NULL) { + if (fstat(fd, &sb) < 0 || read(fd, gaddr, sb.st_size) < 0) err = errno; + } else + err = EFAULT; return (err); } Index: virtio.h =================================================================== --- virtio.h (revision 247367) +++ virtio.h (working copy) @@ -85,4 +85,18 @@ #define VTCFG_R_CFG1 24 /* With MSI-X */ #define VTCFG_R_MSIX 20 +static inline u_int +vring_size(u_int qsz) +{ + u_int size; + + size = sizeof(struct virtio_desc) * qsz + sizeof(uint16_t) * (3 + qsz); + size = roundup2(size, VRING_ALIGN); + + size += sizeof(uint16_t) * 3 + sizeof(struct virtio_used) * qsz; + size = roundup2(size, VRING_ALIGN); + + return (size); +} + #endif /* _VIRTIO_H_ */ Index: bhyverun.c =================================================================== --- bhyverun.c (revision 247367) +++ bhyverun.c (working copy) @@ -157,17 +157,19 @@ } void * -paddr_guest2host(uintptr_t gaddr) +paddr_guest2host(uintptr_t gaddr, size_t len) { - if (lomem_sz == 0) - return (NULL); - if (gaddr < lomem_sz) { + if (gaddr < lomem_sz && gaddr + len <= lomem_sz) return ((void *)(lomem_addr + gaddr)); - } else if (gaddr >= 4*GB && gaddr < (4*GB + himem_sz)) { - return ((void *)(himem_addr + gaddr - 4*GB)); - } else - return (NULL); + + if (gaddr >= 4*GB) { + gaddr -= 4*GB; + if (gaddr < himem_sz && gaddr + len <= himem_sz) + return ((void *)(himem_addr + gaddr)); + } + + return (NULL); } int Index: bhyverun.h =================================================================== --- bhyverun.h (revision 247367) +++ bhyverun.h (working copy) @@ -43,7 +43,7 @@ extern u_long lomem_sz, himem_sz; -void *paddr_guest2host(uintptr_t); +void *paddr_guest2host(uintptr_t addr, size_t len); void fbsdrun_addcpu(struct vmctx *ctx, int cpu, uint64_t rip); int fbsdrun_muxed(void); Index: mptbl.c =================================================================== --- mptbl.c (revision 247367) +++ mptbl.c (working copy) @@ -41,6 +41,9 @@ #define MPTABLE_BASE 0xF0000 +/* floating pointer length + maximum length of configuration table */ +#define MPTABLE_MAX_LENGTH (65536 + 16) + #define LAPIC_PADDR 0xFEE00000 #define LAPIC_VERSION 16 @@ -346,13 +349,13 @@ char *curraddr; char *startaddr; - if (paddr_guest2host(0) == NULL) { + startaddr = paddr_guest2host(MPTABLE_BASE, MPTABLE_MAX_LENGTH); + if (startaddr == NULL) { printf("mptable requires mapped mem\n"); return (ENOMEM); } - startaddr = curraddr = paddr_guest2host(MPTABLE_BASE); - + curraddr = startaddr; mpfp = (mpfps_t)curraddr; mpt_build_mpfp(mpfp, MPTABLE_BASE); curraddr += sizeof(*mpfp);