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>