Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Mar 2013 02:26:29 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r247523 - head/usr.sbin/bhyve
Message-ID:  <201303010226.r212QTG8048342@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Fri Mar  1 02:26:28 2013
New Revision: 247523
URL: http://svnweb.freebsd.org/changeset/base/247523

Log:
  Specify the length of the mapping requested from 'paddr_guest2host()'.
  
  This seems prudent to do in its own right but it also opens up the possibility
  of not having to mmap the entire guest address space in the 'bhyve' process
  context.
  
  Discussed with:	grehan
  Obtained from:	NetApp

Modified:
  head/usr.sbin/bhyve/acpi.c
  head/usr.sbin/bhyve/bhyverun.c
  head/usr.sbin/bhyve/bhyverun.h
  head/usr.sbin/bhyve/mptbl.c
  head/usr.sbin/bhyve/pci_virtio_block.c
  head/usr.sbin/bhyve/pci_virtio_net.c
  head/usr.sbin/bhyve/virtio.h

Modified: head/usr.sbin/bhyve/acpi.c
==============================================================================
--- head/usr.sbin/bhyve/acpi.c	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/acpi.c	Fri Mar  1 02:26:28 2013	(r247523)
@@ -683,13 +683,16 @@ static int
 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);
 }

Modified: head/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.c	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/bhyverun.c	Fri Mar  1 02:26:28 2013	(r247523)
@@ -157,17 +157,19 @@ usage(int code)
 }
 
 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

Modified: head/usr.sbin/bhyve/bhyverun.h
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.h	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/bhyverun.h	Fri Mar  1 02:26:28 2013	(r247523)
@@ -43,7 +43,7 @@ extern char *vmname;
 
 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);

Modified: head/usr.sbin/bhyve/mptbl.c
==============================================================================
--- head/usr.sbin/bhyve/mptbl.c	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/mptbl.c	Fri Mar  1 02:26:28 2013	(r247523)
@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
 
 #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 @@ mptable_build(struct vmctx *ctx, int ncp
 	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);

Modified: head/usr.sbin/bhyve/pci_virtio_block.c
==============================================================================
--- head/usr.sbin/bhyve/pci_virtio_block.c	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/pci_virtio_block.c	Fri Mar  1 02:26:28 2013	(r247523)
@@ -222,13 +222,13 @@ pci_vtblk_proc(struct pci_vtblk_softc *s
 	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 @@ pci_vtblk_proc(struct pci_vtblk_softc *s
 	 * 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 @@ pci_vtblk_proc(struct pci_vtblk_softc *s
 	}
 
 	/* 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 @@ pci_vtblk_ring_init(struct pci_vtblk_sof
 	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 @@ pci_vtblk_init(struct vmctx *ctx, struct
 	}
 
 	/*
-	 * 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);

Modified: head/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- head/usr.sbin/bhyve/pci_virtio_net.c	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/pci_virtio_net.c	Fri Mar  1 02:26:28 2013	(r247523)
@@ -326,7 +326,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc 
 		 * 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 @@ pci_vtnet_proctx(struct pci_vtnet_softc 
 	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 @@ pci_vtnet_ring_init(struct pci_vtnet_sof
 	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 @@ pci_vtnet_init(struct vmctx *ctx, struct
 	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));
 

Modified: head/usr.sbin/bhyve/virtio.h
==============================================================================
--- head/usr.sbin/bhyve/virtio.h	Fri Mar  1 02:09:06 2013	(r247522)
+++ head/usr.sbin/bhyve/virtio.h	Fri Mar  1 02:26:28 2013	(r247523)
@@ -85,4 +85,19 @@ struct virtio_used {
 #define VTCFG_R_CFG1		24	/* With MSI-X */
 #define VTCFG_R_MSIX		20
 
+/* From section 2.3, "Virtqueue Configuration", of the virtio specification */
+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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303010226.r212QTG8048342>