Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jan 2017 14:14:01 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r312382 - in stable/10: include lib/libkvm
Message-ID:  <201701181414.v0IEE1WF067085@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Wed Jan 18 14:14:00 2017
New Revision: 312382
URL: https://svnweb.freebsd.org/changeset/base/312382

Log:
  MFC r310630: libkvm: support access to vmm guest memory, allow writes to
  fwmem and vmm
  
  Sponsored by:	 Panzura

Modified:
  stable/10/include/paths.h
  stable/10/lib/libkvm/kvm.c
  stable/10/lib/libkvm/kvm_private.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/include/paths.h
==============================================================================
--- stable/10/include/paths.h	Wed Jan 18 14:13:28 2017	(r312381)
+++ stable/10/include/paths.h	Wed Jan 18 14:14:00 2017	(r312382)
@@ -98,6 +98,7 @@
 #define	_PATH_VARDB	"/var/db/"
 #define	_PATH_VARRUN	"/var/run/"
 #define	_PATH_VARTMP	"/var/tmp/"
+#define	_PATH_DEVVMM	"/dev/vmm/"
 #define	_PATH_YP	"/var/yp/"
 #define	_PATH_UUCPLOCK	"/var/spool/lock/"
 

Modified: stable/10/lib/libkvm/kvm.c
==============================================================================
--- stable/10/lib/libkvm/kvm.c	Wed Jan 18 14:13:28 2017	(r312381)
+++ stable/10/lib/libkvm/kvm.c	Wed Jan 18 14:14:00 2017	(r312382)
@@ -198,8 +198,10 @@ _kvm_open(kvm_t *kd, const char *uf, con
 			return (kd);
 		}
 	}
+
 	/*
-	 * This is a crash dump.
+	 * This is either a crash dump or a remote live system with its physical
+	 * memory fully accessible via a special device.
 	 * Initialize the virtual address translation machinery,
 	 * but first setup the namelist fd.
 	 */
@@ -207,8 +209,11 @@ _kvm_open(kvm_t *kd, const char *uf, con
 		_kvm_syserr(kd, kd->program, "%s", uf);
 		goto failed;
 	}
-	if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0)
+	if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0 ||
+	    strncmp(mf, _PATH_DEVVMM, strlen(_PATH_DEVVMM)) == 0) {
 		kd->rawdump = 1;
+		kd->writable = 1;
+	}
 	if (_kvm_initvtop(kd) < 0)
 		goto failed;
 	return (kd);
@@ -557,6 +562,15 @@ ssize_t
 kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len)
 {
 	int cc;
+	ssize_t cw;
+	off_t pa;
+	const char *cp;
+
+	if (!ISALIVE(kd) && !kd->writable) {
+		_kvm_err(kd, kd->program,
+		    "kvm_write not implemented for dead kernels");
+		return (-1);
+	}
 
 	if (ISALIVE(kd)) {
 		/*
@@ -574,10 +588,36 @@ kvm_write(kvm_t *kd, u_long kva, const v
 		} else if ((size_t)cc < len)
 			_kvm_err(kd, kd->program, "short write");
 		return (cc);
-	} else {
-		_kvm_err(kd, kd->program,
-		    "kvm_write not implemented for dead kernels");
-		return (-1);
 	}
-	/* NOTREACHED */
+
+	cp = buf;
+	while (len > 0) {
+		cc = _kvm_kvatop(kd, kva, &pa);
+		if (cc == 0)
+			return (-1);
+		if (cc > (ssize_t)len)
+			cc = len;
+		errno = 0;
+		if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) {
+			_kvm_syserr(kd, 0, _PATH_MEM);
+			break;
+		}
+		cw = write(kd->pmfd, cp, cc);
+		if (cw < 0) {
+			_kvm_syserr(kd, kd->program, "kvm_write");
+			break;
+		}
+		/*
+		 * If ka_kvatop returns a bogus value or our core file is
+		 * truncated, we might wind up seeking beyond the end of the
+		 * core file in which case the read will return 0 (EOF).
+		 */
+		if (cw == 0)
+			break;
+		cp += cw;
+		kva += cw;
+		len -= cw;
+	}
+
+	return (cp - (char *)buf);
 }

Modified: stable/10/lib/libkvm/kvm_private.h
==============================================================================
--- stable/10/lib/libkvm/kvm_private.h	Wed Jan 18 14:13:28 2017	(r312381)
+++ stable/10/lib/libkvm/kvm_private.h	Wed Jan 18 14:14:00 2017	(r312382)
@@ -62,6 +62,7 @@ struct __kvm {
 	 */
 	struct vmstate *vmst;
 	int	rawdump;	/* raw dump format */
+	int	writable;	/* physical memory is writable */
 
 	int		vnet_initialized;	/* vnet fields set up */
 	uintptr_t	vnet_start;	/* start of kernel's vnet region */



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