From owner-svn-src-projects@FreeBSD.ORG Fri Aug 2 06:31:12 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 09C66ACE; Fri, 2 Aug 2013 06:31:12 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E9B47269B; Fri, 2 Aug 2013 06:31:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r726VBUD014463; Fri, 2 Aug 2013 06:31:11 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r726VADS014454; Fri, 2 Aug 2013 06:31:10 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201308020631.r726VADS014454@svn.freebsd.org> From: Neel Natu Date: Fri, 2 Aug 2013 06:31:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253884 - in projects/bhyve_npt_pmap: lib/libvmmapi sys/amd64/amd64 sys/amd64/include sys/amd64/vmm usr.sbin/bhyvectl X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Aug 2013 06:31:12 -0000 Author: neel Date: Fri Aug 2 06:31:09 2013 New Revision: 253884 URL: http://svnweb.freebsd.org/changeset/base/253884 Log: Add a debugging aid to get the page table entries that map a guest physical address to a host physical address. The option "--get-gpa-pmap " for /usr/sbin/bhyvectl can be used to inspect the mapping from the command line. Modified: projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.c projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.h projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c projects/bhyve_npt_pmap/sys/amd64/include/pmap.h projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/include/vmm_dev.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c projects/bhyve_npt_pmap/usr.sbin/bhyvectl/bhyvectl.c Modified: projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.c ============================================================================== --- projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.c Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.c Fri Aug 2 06:31:09 2013 (r253884) @@ -741,3 +741,23 @@ vcpu_reset(struct vmctx *vmctx, int vcpu done: return (error); } + +int +vm_get_gpa_pmap(struct vmctx *ctx, uint64_t gpa, uint64_t *pte, int *num) +{ + int error, i; + struct vm_gpa_pte gpapte; + + bzero(&gpapte, sizeof(gpapte)); + gpapte.gpa = gpa; + + error = ioctl(ctx->fd, VM_GET_GPA_PMAP, &gpapte); + + if (error == 0) { + *num = gpapte.ptenum; + for (i = 0; i < gpapte.ptenum; i++) + pte[i] = gpapte.pte[i]; + } + + return (error); +} Modified: projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.h ============================================================================== --- projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.h Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/lib/libvmmapi/vmmapi.h Fri Aug 2 06:31:09 2013 (r253884) @@ -48,6 +48,7 @@ void vm_destroy(struct vmctx *ctx); int vm_get_memory_seg(struct vmctx *ctx, vm_paddr_t gpa, size_t *ret_len); int vm_setup_memory(struct vmctx *ctx, size_t len, enum vm_mmap_style s); void *vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len); +int vm_get_gpa_pmap(struct vmctx *, uint64_t gpa, uint64_t *pte, int *num); uint32_t vm_get_lowmem_limit(struct vmctx *ctx); void vm_set_lowmem_limit(struct vmctx *ctx, uint32_t limit); int vm_set_desc(struct vmctx *ctx, int vcpu, int reg, Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Fri Aug 2 06:31:09 2013 (r253884) @@ -5921,6 +5921,41 @@ pmap_align_superpage(vm_object_t object, *addr = ((*addr + PDRMASK) & ~PDRMASK) + superpage_offset; } +void +pmap_get_mapping(pmap_t pmap, vm_offset_t va, uint64_t *ptr, int *num) +{ + pml4_entry_t *pml4; + pdp_entry_t *pdp; + pd_entry_t *pde; + pt_entry_t *pte; + int idx; + + idx = 0; + PMAP_LOCK(pmap); + + pml4 = pmap_pml4e(pmap, va); + ptr[idx++] = *pml4; + if ((*pml4 & PG_V) == 0) + goto done; + + pdp = pmap_pml4e_to_pdpe(pml4, va); + ptr[idx++] = *pdp; + if ((*pdp & PG_V) == 0 || (*pdp & PG_PS) != 0) + goto done; + + pde = pmap_pdpe_to_pde(pdp, va); + ptr[idx++] = *pde; + if ((*pde & PG_V) == 0 || (*pde & PG_PS) != 0) + goto done; + + pte = pmap_pde_to_pte(pde, va); + ptr[idx++] = *pte; + +done: + PMAP_UNLOCK(pmap); + *num = idx; +} + #include "opt_ddb.h" #ifdef DDB #include Modified: projects/bhyve_npt_pmap/sys/amd64/include/pmap.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Fri Aug 2 06:31:09 2013 (r253884) @@ -341,7 +341,7 @@ void pmap_invalidate_all(pmap_t); void pmap_invalidate_cache(void); void pmap_invalidate_cache_pages(vm_page_t *pages, int count); void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); - +void pmap_get_mapping(pmap_t pmap, vm_offset_t va, uint64_t *ptr, int *num); #endif /* _KERNEL */ #endif /* !LOCORE */ Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Fri Aug 2 06:31:09 2013 (r253884) @@ -152,7 +152,7 @@ vcpu_is_running(struct vm *vm, int vcpu, void *vcpu_stats(struct vm *vm, int vcpu); void vm_interrupt_hostcpu(struct vm *vm, int vcpu); - +struct vmspace *vm_get_vmspace(struct vm *vm); #endif /* KERNEL */ #include Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm_dev.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm_dev.h Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm_dev.h Fri Aug 2 06:31:09 2013 (r253884) @@ -135,6 +135,12 @@ struct vm_x2apic { enum x2apic_state state; }; +struct vm_gpa_pte { + uint64_t gpa; /* in */ + uint64_t pte[4]; /* out */ + int ptenum; +}; + enum { IOCNUM_RUN, IOCNUM_MAP_MEMORY, @@ -157,6 +163,7 @@ enum { IOCNUM_VM_STAT_DESC, IOCNUM_SET_X2APIC_STATE, IOCNUM_GET_X2APIC_STATE, + IOCNUM_GET_GPA_PMAP, }; #define VM_RUN \ @@ -201,4 +208,6 @@ enum { _IOW('v', IOCNUM_SET_X2APIC_STATE, struct vm_x2apic) #define VM_GET_X2APIC_STATE \ _IOWR('v', IOCNUM_GET_X2APIC_STATE, struct vm_x2apic) +#define VM_GET_GPA_PMAP \ + _IOWR('v', IOCNUM_GET_GPA_PMAP, struct vm_gpa_pte) #endif Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Fri Aug 2 06:31:09 2013 (r253884) @@ -1135,3 +1135,10 @@ vm_interrupt_hostcpu(struct vm *vm, int } vcpu_unlock(vcpu); } + +struct vmspace * +vm_get_vmspace(struct vm *vm) +{ + + return (vm->vmspace); +} Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Fri Aug 2 06:31:09 2013 (r253884) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -159,6 +160,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c struct vm_stats *vmstats; struct vm_stat_desc *statdesc; struct vm_x2apic *x2apic; + struct vm_gpa_pte *gpapte; sc = vmmdev_lookup2(cdev); if (sc == NULL) @@ -346,6 +348,12 @@ vmmdev_ioctl(struct cdev *cdev, u_long c error = vm_get_x2apic_state(sc->vm, x2apic->cpuid, &x2apic->state); break; + case VM_GET_GPA_PMAP: + gpapte = (struct vm_gpa_pte *)data; + pmap_get_mapping(vmspace_pmap(vm_get_vmspace(sc->vm)), + gpapte->gpa, gpapte->pte, &gpapte->ptenum); + error = 0; + break; default: error = ENOTTY; break; Modified: projects/bhyve_npt_pmap/usr.sbin/bhyvectl/bhyvectl.c ============================================================================== --- projects/bhyve_npt_pmap/usr.sbin/bhyvectl/bhyvectl.c Fri Aug 2 06:25:28 2013 (r253883) +++ projects/bhyve_npt_pmap/usr.sbin/bhyvectl/bhyvectl.c Fri Aug 2 06:31:09 2013 (r253884) @@ -188,12 +188,13 @@ usage(void) " [--unassign-pptdev=]\n" " [--set-mem=]\n" " [--get-lowmem]\n" - " [--get-highmem]\n", + " [--get-highmem]\n" + " [--get-gpa-pmap]\n", progname); exit(1); } -static int get_stats, getcap, setcap, capval; +static int get_stats, getcap, setcap, capval, get_gpa_pmap; static const char *capname; static int create, destroy, get_lowmem, get_highmem; static uint64_t memsize; @@ -377,17 +378,18 @@ enum { SET_CAP, CAPNAME, UNASSIGN_PPTDEV, + GET_GPA_PMAP, }; int main(int argc, char *argv[]) { char *vmname; - int error, ch, vcpu; - vm_paddr_t gpa; + int error, ch, vcpu, ptenum; + vm_paddr_t gpa, gpa_pmap; size_t len; struct vm_exit vmexit; - uint64_t ctl, eptp, bm, addr, u64; + uint64_t ctl, eptp, bm, addr, u64, pteval[4], *pte; struct vmctx *ctx; uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat; @@ -427,6 +429,7 @@ main(int argc, char *argv[]) { "capname", REQ_ARG, 0, CAPNAME }, { "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV }, { "setcap", REQ_ARG, 0, SET_CAP }, + { "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP }, { "getcap", NO_ARG, &getcap, 1 }, { "get-stats", NO_ARG, &get_stats, 1 }, { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, @@ -666,6 +669,10 @@ main(int argc, char *argv[]) capval = strtoul(optarg, NULL, 0); setcap = 1; break; + case GET_GPA_PMAP: + gpa_pmap = strtoul(optarg, NULL, 0); + get_gpa_pmap = 1; + break; case CAPNAME: capname = optarg; break; @@ -1457,6 +1464,17 @@ main(int argc, char *argv[]) printf("Capability \"%s\" is not available\n", capname); } + if (!error && get_gpa_pmap) { + error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum); + if (error == 0) { + printf("gpa %#lx:", gpa_pmap); + pte = &pteval[0]; + while (ptenum-- > 0) + printf(" %#lx", *pte++); + printf("\n"); + } + } + if (!error && (getcap || get_all)) { int captype, val, getcaptype;