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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to