From owner-svn-src-projects@FreeBSD.ORG Sun Jul 7 01:52:07 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]) by hub.freebsd.org (Postfix) with ESMTP id 3FC7CF20; Sun, 7 Jul 2013 01:52:07 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 2297E1C7B; Sun, 7 Jul 2013 01:52:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r671q7Dw093316; Sun, 7 Jul 2013 01:52:07 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r671q6bV093311; Sun, 7 Jul 2013 01:52:06 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307070152.r671q6bV093311@svn.freebsd.org> From: Neel Natu Date: Sun, 7 Jul 2013 01:52:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r252908 - in projects/bhyve_npt_pmap/sys/amd64: include vmm 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: Sun, 07 Jul 2013 01:52:07 -0000 Author: neel Date: Sun Jul 7 01:52:05 2013 New Revision: 252908 URL: http://svnweb.freebsd.org/changeset/base/252908 Log: Allocate an object of type OBJT_DEFAULT for each memory segment created for the guest (i.e. guest memory is no longer wired). Use the 'd_mmap_single' entry point to return the object/offset underlying the mmap'ed region. Since we don't yet handle nested page faults in vmm.ko the guest will exit immediately on entry with an unhandled memory fault. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 01:32:52 2013 (r252907) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 01:52:05 2013 (r252908) @@ -40,6 +40,7 @@ struct vm_exit; struct vm_run; struct vlapic; struct vmspace; +struct vm_object; enum x2apic_state; @@ -101,6 +102,8 @@ int vm_unmap_mmio(struct vm *vm, vm_padd vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, struct vm_memory_segment *seg); +int vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, + vm_offset_t *offset, struct vm_object **object); int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); int vm_get_seg_desc(struct vm *vm, int vcpu, int reg, Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 01:32:52 2013 (r252907) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 01:52:05 2013 (r252908) @@ -39,11 +39,14 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include +#include +#include #include #include @@ -88,6 +91,11 @@ struct vcpu { #define vcpu_lock(v) mtx_lock_spin(&((v)->mtx)) #define vcpu_unlock(v) mtx_unlock_spin(&((v)->mtx)) +struct mem_seg { + vm_paddr_t gpa; + size_t len; + vm_object_t object; +}; #define VM_MAX_MEMORY_SEGMENTS 2 struct vm { @@ -96,7 +104,7 @@ struct vm { struct vmspace *vmspace; /* guest's address space */ struct vcpu vcpu[VM_MAXCPU]; int num_mem_segs; - struct vm_memory_segment mem_segs[VM_MAX_MEMORY_SEGMENTS]; + struct mem_seg mem_segs[VM_MAX_MEMORY_SEGMENTS]; char name[VM_MAX_NAMELEN]; /* @@ -304,42 +312,17 @@ vm_create(const char *name, struct vm ** return (0); } +/* + * XXX need to deal with iommu mappings + */ static void -vm_free_mem_seg(struct vm *vm, struct vm_memory_segment *seg) +vm_free_mem_seg(struct vm *vm, struct mem_seg *seg) { - size_t len; - vm_paddr_t hpa; - void *host_domain; - - host_domain = iommu_host_domain(); - - len = 0; - while (len < seg->len) { - hpa = vm_gpa2hpa(vm, seg->gpa + len, PAGE_SIZE); - if (hpa == (vm_paddr_t)-1) { - panic("vm_free_mem_segs: cannot free hpa " - "associated with gpa 0x%016lx", seg->gpa + len); - } - - /* - * Remove the 'gpa' to 'hpa' mapping in VMs domain. - * And resurrect the 1:1 mapping for 'hpa' in 'host_domain'. - */ - iommu_remove_mapping(vm->iommu, seg->gpa + len, PAGE_SIZE); - iommu_create_mapping(host_domain, hpa, hpa, PAGE_SIZE); - - vmm_mem_free(hpa, PAGE_SIZE); - - len += PAGE_SIZE; - } - /* - * Invalidate cached translations associated with 'vm->iommu' since - * we have now moved some pages from it. - */ - iommu_invalidate_tlb(vm->iommu); + if (seg->object != NULL) + vmm_mem_free(seg->object); - bzero(seg, sizeof(struct vm_memory_segment)); + bzero(seg, sizeof(*seg)); } void @@ -412,15 +395,16 @@ vm_gpa_available(struct vm *vm, vm_paddr return (TRUE); } +/* + * XXX need to deal with iommu + */ int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len) { - int error, available, allocated; - struct vm_memory_segment *seg; - vm_paddr_t g, hpa; - void *host_domain; - - const boolean_t spok = TRUE; /* superpage mappings are ok */ + int available, allocated; + struct mem_seg *seg; + vm_object_t object; + vm_paddr_t g; if ((gpa & PAGE_MASK) || (len & PAGE_MASK) || len == 0) return (EINVAL); @@ -453,45 +437,14 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, if (vm->num_mem_segs >= VM_MAX_MEMORY_SEGMENTS) return (E2BIG); - host_domain = iommu_host_domain(); - seg = &vm->mem_segs[vm->num_mem_segs]; - error = 0; - seg->gpa = gpa; - seg->len = 0; - while (seg->len < len) { - hpa = vmm_mem_alloc(PAGE_SIZE); - if (hpa == 0) { - error = ENOMEM; - break; - } - - error = VMMMAP_SET(vm->cookie, gpa + seg->len, hpa, PAGE_SIZE, - VM_MEMATTR_WRITE_BACK, VM_PROT_ALL, spok); - if (error) - break; - - /* - * Remove the 1:1 mapping for 'hpa' from the 'host_domain'. - * Add mapping for 'gpa + seg->len' to 'hpa' in the VMs domain. - */ - iommu_remove_mapping(host_domain, hpa, PAGE_SIZE); - iommu_create_mapping(vm->iommu, gpa + seg->len, hpa, PAGE_SIZE); - - seg->len += PAGE_SIZE; - } - - if (error) { - vm_free_mem_seg(vm, seg); - return (error); - } + if ((object = vmm_mem_alloc(len)) == NULL) + return (ENOMEM); - /* - * Invalidate cached translations associated with 'host_domain' since - * we have now moved some pages from it. - */ - iommu_invalidate_tlb(host_domain); + seg->gpa = gpa; + seg->len = len; + seg->object = object; vm->num_mem_segs++; @@ -518,7 +471,8 @@ vm_gpabase2memseg(struct vm *vm, vm_padd for (i = 0; i < vm->num_mem_segs; i++) { if (gpabase == vm->mem_segs[i].gpa) { - *seg = vm->mem_segs[i]; + seg->gpa = vm->mem_segs[i].gpa; + seg->len = vm->mem_segs[i].len; return (0); } } @@ -526,6 +480,33 @@ vm_gpabase2memseg(struct vm *vm, vm_padd } int +vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, + vm_offset_t *offset, struct vm_object **object) +{ + int i; + size_t seg_len; + vm_paddr_t seg_gpa; + vm_object_t seg_obj; + + for (i = 0; i < vm->num_mem_segs; i++) { + if ((seg_obj = vm->mem_segs[i].object) == NULL) + continue; + + seg_gpa = vm->mem_segs[i].gpa; + seg_len = vm->mem_segs[i].len; + + if (gpa >= seg_gpa && gpa < seg_gpa + seg_len) { + *offset = gpa - seg_gpa; + *object = seg_obj; + vm_object_reference(seg_obj); + return (0); + } + } + + return (EINVAL); +} + +int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval) { Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Sun Jul 7 01:32:52 2013 (r252907) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Sun Jul 7 01:52:05 2013 (r252908) @@ -365,21 +365,19 @@ done: } static int -vmmdev_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, - int nprot, vm_memattr_t *memattr) +vmmdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **object, int nprot) { int error; struct vmmdev_softc *sc; - error = -1; mtx_lock(&vmmdev_mtx); sc = vmmdev_lookup2(cdev); - if (sc != NULL && (nprot & PROT_EXEC) == 0) { - *paddr = vm_gpa2hpa(sc->vm, (vm_paddr_t)offset, PAGE_SIZE); - if (*paddr != (vm_paddr_t)-1) - error = 0; - } + if (sc != NULL && (nprot & PROT_EXEC) == 0) + error = vm_get_memobj(sc->vm, *offset, size, offset, object); + else + error = EINVAL; mtx_unlock(&vmmdev_mtx); @@ -446,7 +444,7 @@ static struct cdevsw vmmdevsw = { .d_name = "vmmdev", .d_version = D_VERSION, .d_ioctl = vmmdev_ioctl, - .d_mmap = vmmdev_mmap, + .d_mmap_single = vmmdev_mmap_single, .d_read = vmmdev_rw, .d_write = vmmdev_rw, }; Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c Sun Jul 7 01:32:52 2013 (r252907) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c Sun Jul 7 01:52:05 2013 (r252908) @@ -30,40 +30,15 @@ __FBSDID("$FreeBSD$"); #include -#include -#include -#include #include -#include -#include -#include #include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include "vmm_util.h" #include "vmm_mem.h" -SYSCTL_DECL(_hw_vmm); - -static u_long pages_allocated; -SYSCTL_ULONG(_hw_vmm, OID_AUTO, pages_allocated, CTLFLAG_RD, - &pages_allocated, 0, "4KB pages allocated"); - -static void -update_pages_allocated(int howmany) -{ - pages_allocated += howmany; /* XXX locking? */ -} - int vmm_mem_init(void) { @@ -71,60 +46,23 @@ vmm_mem_init(void) return (0); } -vm_paddr_t +vm_object_t vmm_mem_alloc(size_t size) { - int flags; - vm_page_t m; - vm_paddr_t pa; + vm_object_t obj; - if (size != PAGE_SIZE) + if (size & PAGE_MASK) panic("vmm_mem_alloc: invalid allocation size %lu", size); - flags = VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | - VM_ALLOC_ZERO; - - while (1) { - /* - * XXX need policy to determine when to back off the allocation - */ - m = vm_page_alloc(NULL, 0, flags); - if (m == NULL) - VM_WAIT; - else - break; - } - - pa = VM_PAGE_TO_PHYS(m); - - if ((m->flags & PG_ZERO) == 0) - pagezero((void *)PHYS_TO_DMAP(pa)); - m->valid = VM_PAGE_BITS_ALL; - - update_pages_allocated(1); - - return (pa); + obj = vm_object_allocate(OBJT_DEFAULT, size >> PAGE_SHIFT); + return (obj); } void -vmm_mem_free(vm_paddr_t base, size_t length) +vmm_mem_free(vm_object_t obj) { - vm_page_t m; - - if (base & PAGE_MASK) { - panic("vmm_mem_free: base 0x%0lx must be aligned on a " - "0x%0x boundary\n", base, PAGE_SIZE); - } - - if (length != PAGE_SIZE) - panic("vmm_mem_free: invalid length %lu", length); - - m = PHYS_TO_VM_PAGE(base); - m->wire_count--; - vm_page_free(m); - atomic_subtract_int(&cnt.v_wire_count, 1); - update_pages_allocated(-1); + vm_object_deallocate(obj); } vm_paddr_t Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Sun Jul 7 01:32:52 2013 (r252907) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Sun Jul 7 01:52:05 2013 (r252908) @@ -29,9 +29,11 @@ #ifndef _VMM_MEM_H_ #define _VMM_MEM_H_ +struct vm_object; + int vmm_mem_init(void); -vm_paddr_t vmm_mem_alloc(size_t size); -void vmm_mem_free(vm_paddr_t start, size_t size); +struct vm_object *vmm_mem_alloc(size_t size); +void vmm_mem_free(struct vm_object *obj); vm_paddr_t vmm_mem_maxaddr(void); #endif From owner-svn-src-projects@FreeBSD.ORG Sun Jul 7 02:17:51 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 025131C8; Sun, 7 Jul 2013 02:17:50 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id E795D1CDA; Sun, 7 Jul 2013 02:17:50 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r672HoIs000437; Sun, 7 Jul 2013 02:17:50 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r672HnB4000424; Sun, 7 Jul 2013 02:17:49 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307070217.r672HnB4000424@svn.freebsd.org> From: Neel Natu Date: Sun, 7 Jul 2013 02:17:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r252909 - in projects/bhyve_npt_pmap/sys/amd64: include vmm vmm/amd vmm/intel 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: Sun, 07 Jul 2013 02:17:51 -0000 Author: neel Date: Sun Jul 7 02:17:49 2013 New Revision: 252909 URL: http://svnweb.freebsd.org/changeset/base/252909 Log: The GPA to HPA mappings are now handled by the host's VM subsystem. Get rid of the processor-specific hooks to get and set mappings into the nested page tables. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 02:17:49 2013 (r252909) @@ -49,11 +49,6 @@ typedef int (*vmm_cleanup_func_t)(void); typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */ typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip); typedef void (*vmi_cleanup_func_t)(void *vmi); -typedef int (*vmi_mmap_set_func_t)(void *vmi, vm_paddr_t gpa, - vm_paddr_t hpa, size_t length, - vm_memattr_t attr, int prot, - boolean_t superpages_ok); -typedef vm_paddr_t (*vmi_mmap_get_func_t)(void *vmi, vm_paddr_t gpa); typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, uint64_t *retval); typedef int (*vmi_set_register_t)(void *vmi, int vcpu, int num, @@ -77,8 +72,6 @@ struct vmm_ops { vmi_init_func_t vminit; /* vm-specific initialization */ vmi_run_func_t vmrun; vmi_cleanup_func_t vmcleanup; - vmi_mmap_set_func_t vmmmap_set; - vmi_mmap_get_func_t vmmmap_get; vmi_get_register_t vmgetreg; vmi_set_register_t vmsetreg; vmi_get_desc_t vmgetdesc; Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c Sun Jul 7 02:17:49 2013 (r252909) @@ -78,23 +78,6 @@ amdv_vmcleanup(void *arg) } static int -amdv_vmmmap_set(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, - vm_memattr_t attr, int prot, boolean_t spok) -{ - - printf("amdv_vmmmap_set: not implemented\n"); - return (EINVAL); -} - -static vm_paddr_t -amdv_vmmmap_get(void *arg, vm_paddr_t gpa) -{ - - printf("amdv_vmmmap_get: not implemented\n"); - return (EINVAL); -} - -static int amdv_getreg(void *arg, int vcpu, int regnum, uint64_t *retval) { @@ -173,8 +156,6 @@ struct vmm_ops vmm_ops_amd = { amdv_vminit, amdv_vmrun, amdv_vmcleanup, - amdv_vmmmap_set, - amdv_vmmmap_get, amdv_getreg, amdv_setreg, amdv_getdesc, Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 7 02:17:49 2013 (r252909) @@ -151,128 +151,6 @@ ept_dump(uint64_t *ptp, int nlevels) } #endif -static size_t -ept_create_mapping(uint64_t *ptp, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, - vm_memattr_t attr, vm_prot_t prot, boolean_t spok) -{ - int spshift, ptpshift, ptpindex, nlevels; - - /* - * Compute the size of the mapping that we can accomodate. - * - * This is based on three factors: - * - super page sizes supported by the processor - * - alignment of the region starting at 'gpa' and 'hpa' - * - length of the region 'len' - */ - spshift = PAGE_SHIFT; - if (spok) - spshift += (EPT_PWLEVELS - 1) * 9; - while (spshift >= PAGE_SHIFT) { - uint64_t spsize = 1UL << spshift; - if ((page_sizes_mask & spsize) != 0 && - (gpa & (spsize - 1)) == 0 && - (hpa & (spsize - 1)) == 0 && - length >= spsize) { - break; - } - spshift -= 9; - } - - if (spshift < PAGE_SHIFT) { - panic("Invalid spshift for gpa 0x%016lx, hpa 0x%016lx, " - "length 0x%016lx, page_sizes_mask 0x%016lx", - gpa, hpa, length, page_sizes_mask); - } - - nlevels = EPT_PWLEVELS; - while (--nlevels >= 0) { - ptpshift = PAGE_SHIFT + nlevels * 9; - ptpindex = (gpa >> ptpshift) & 0x1FF; - - /* We have reached the leaf mapping */ - if (spshift >= ptpshift) - break; - - /* - * We are working on a non-leaf page table page. - * - * Create the next level page table page if necessary and point - * to it from the current page table. - */ - if (ptp[ptpindex] == 0) { - void *nlp = malloc(PAGE_SIZE, M_VMX, M_WAITOK | M_ZERO); - ptp[ptpindex] = vtophys(nlp); - ptp[ptpindex] |= EPT_PG_RD | EPT_PG_WR | EPT_PG_EX; - } - - /* Work our way down to the next level page table page */ - ptp = (uint64_t *)PHYS_TO_DMAP(ptp[ptpindex] & EPT_ADDR_MASK); - } - - if ((gpa & ((1UL << ptpshift) - 1)) != 0) { - panic("ept_create_mapping: gpa 0x%016lx and ptpshift %d " - "mismatch\n", gpa, ptpshift); - } - - if (prot != VM_PROT_NONE) { - /* Do the mapping */ - ptp[ptpindex] = hpa; - - /* Apply the access controls */ - if (prot & VM_PROT_READ) - ptp[ptpindex] |= EPT_PG_RD; - if (prot & VM_PROT_WRITE) - ptp[ptpindex] |= EPT_PG_WR; - if (prot & VM_PROT_EXECUTE) - ptp[ptpindex] |= EPT_PG_EX; - - /* - * XXX should we enforce this memory type by setting the - * ignore PAT bit to 1. - */ - ptp[ptpindex] |= EPT_PG_MEMORY_TYPE(attr); - - if (nlevels > 0) - ptp[ptpindex] |= EPT_PG_SUPERPAGE; - } else { - /* Remove the mapping */ - ptp[ptpindex] = 0; - } - - return (1UL << ptpshift); -} - -static vm_paddr_t -ept_lookup_mapping(uint64_t *ptp, vm_paddr_t gpa) -{ - int nlevels, ptpshift, ptpindex; - uint64_t ptpval, hpabase, pgmask; - - nlevels = EPT_PWLEVELS; - while (--nlevels >= 0) { - ptpshift = PAGE_SHIFT + nlevels * 9; - ptpindex = (gpa >> ptpshift) & 0x1FF; - - ptpval = ptp[ptpindex]; - - /* Cannot make progress beyond this point */ - if ((ptpval & (EPT_PG_RD | EPT_PG_WR | EPT_PG_EX)) == 0) - break; - - if (nlevels == 0 || (ptpval & EPT_PG_SUPERPAGE)) { - pgmask = (1UL << ptpshift) - 1; - hpabase = ptpval & ~pgmask; - return (hpabase | (gpa & pgmask)); - } - - /* Work our way down to the next level page table page */ - ptp = (uint64_t *)PHYS_TO_DMAP(ptpval & EPT_ADDR_MASK); - } - - return ((vm_paddr_t)-1); -} - static void ept_free_pt_entry(pt_entry_t pte) { @@ -346,35 +224,6 @@ ept_vmcleanup(struct vmx *vmx) ept_free_pml4_entry(vmx->pml4ept[i]); } -int -ept_vmmmap_set(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t len, - vm_memattr_t attr, int prot, boolean_t spok) -{ - size_t n; - struct vmx *vmx = arg; - - while (len > 0) { - n = ept_create_mapping(vmx->pml4ept, gpa, hpa, len, attr, - prot, spok); - len -= n; - gpa += n; - hpa += n; - } - - return (0); -} - -vm_paddr_t -ept_vmmmap_get(void *arg, vm_paddr_t gpa) -{ - vm_paddr_t hpa; - struct vmx *vmx; - - vmx = arg; - hpa = ept_lookup_mapping(vmx->pml4ept, gpa); - return (hpa); -} - static void invept_single_context(void *arg) { Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 7 02:17:49 2013 (r252909) @@ -35,9 +35,6 @@ struct vmx; #define EPTP(pml4) ((pml4) | (EPT_PWLEVELS - 1) << 3 | PAT_WRITE_BACK) int ept_init(void); -int ept_vmmmap_set(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, - vm_memattr_t attr, int prot, boolean_t allow_superpage_mappings); -vm_paddr_t ept_vmmmap_get(void *arg, vm_paddr_t gpa); void ept_invalidate_mappings(u_long ept_pml4); void ept_vmcleanup(struct vmx *vmx); struct vmspace *ept_vmspace_alloc(vm_offset_t min, vm_offset_t max); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 7 02:17:49 2013 (r252909) @@ -1859,8 +1859,6 @@ struct vmm_ops vmm_ops_intel = { vmx_vminit, vmx_run, vmx_vmcleanup, - ept_vmmmap_set, - ept_vmmmap_get, vmx_getreg, vmx_setreg, vmx_getdesc, Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 01:52:05 2013 (r252908) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 02:17:49 2013 (r252909) @@ -125,12 +125,6 @@ static struct vmm_ops *ops; #define VMRUN(vmi, vcpu, rip) \ (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip) : ENXIO) #define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL) -#define VMMMAP_SET(vmi, gpa, hpa, len, attr, prot, spm) \ - (ops != NULL ? \ - (*ops->vmmmap_set)(vmi, gpa, hpa, len, attr, prot, spm) : \ - ENXIO) -#define VMMMAP_GET(vmi, gpa) \ - (ops != NULL ? (*ops->vmmmap_get)(vmi, gpa) : ENXIO) #define VMSPACE_ALLOC(min, max) \ (ops != NULL ? (*ops->vmspace_alloc)(min, max) : NULL) #define VMSPACE_FREE(vmspace) \ @@ -358,19 +352,15 @@ vm_name(struct vm *vm) int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa) { - const boolean_t spok = TRUE; /* superpage mappings are ok */ - return (VMMMAP_SET(vm->cookie, gpa, hpa, len, VM_MEMATTR_UNCACHEABLE, - VM_PROT_RW, spok)); + return (ENXIO); /* XXX fixme */ } int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) { - const boolean_t spok = TRUE; /* superpage mappings are ok */ - return (VMMMAP_SET(vm->cookie, gpa, 0, len, 0, - VM_PROT_NONE, spok)); + return (ENXIO); /* XXX fixme */ } /* @@ -460,7 +450,7 @@ vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa if (len > nextpage - gpa) panic("vm_gpa2hpa: invalid gpa/len: 0x%016lx/%lu", gpa, len); - return (VMMMAP_GET(vm->cookie, gpa)); + return ((vm_paddr_t)-1); /* XXX fixme */ } int From owner-svn-src-projects@FreeBSD.ORG Sun Jul 7 02:49:50 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 035624ED; Sun, 7 Jul 2013 02:49:50 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D9B221D58; Sun, 7 Jul 2013 02:49:49 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r672nnC8008998; Sun, 7 Jul 2013 02:49:49 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r672nmYc008991; Sun, 7 Jul 2013 02:49:48 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307070249.r672nmYc008991@svn.freebsd.org> From: Neel Natu Date: Sun, 7 Jul 2013 02:49:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r252910 - in projects/bhyve_npt_pmap/sys/amd64: include vmm vmm/amd vmm/intel 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: Sun, 07 Jul 2013 02:49:50 -0000 Author: neel Date: Sun Jul 7 02:49:48 2013 New Revision: 252910 URL: http://svnweb.freebsd.org/changeset/base/252910 Log: The nested page tables are now maintained by the VM subsystem. Remove the redundant 'pml4ept[]' and point the EPT to the physical address of 'pm_pml4' instead. Also get rid of the 'ept_vmcleanup()' function since this is now done by 'pmap_release()'. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Sun Jul 7 02:49:48 2013 (r252910) @@ -41,12 +41,13 @@ struct vm_run; struct vlapic; struct vmspace; struct vm_object; +struct pmap; enum x2apic_state; typedef int (*vmm_init_func_t)(void); typedef int (*vmm_cleanup_func_t)(void); -typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */ +typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap); typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip); typedef void (*vmi_cleanup_func_t)(void *vmi); typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/amd/amdv.c Sun Jul 7 02:49:48 2013 (r252910) @@ -54,7 +54,7 @@ amdv_cleanup(void) } static void * -amdv_vminit(struct vm *vm) +amdv_vminit(struct vm *vm, struct pmap *pmap) { printf("amdv_vminit: not implemented\n"); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sun Jul 7 02:49:48 2013 (r252910) @@ -152,79 +152,6 @@ ept_dump(uint64_t *ptp, int nlevels) #endif static void -ept_free_pt_entry(pt_entry_t pte) -{ - if (pte == 0) - return; - - /* sanity check */ - if ((pte & EPT_PG_SUPERPAGE) != 0) - panic("ept_free_pt_entry: pte cannot have superpage bit"); - - return; -} - -static void -ept_free_pd_entry(pd_entry_t pde) -{ - pt_entry_t *pt; - int i; - - if (pde == 0) - return; - - if ((pde & EPT_PG_SUPERPAGE) == 0) { - pt = (pt_entry_t *)PHYS_TO_DMAP(pde & EPT_ADDR_MASK); - for (i = 0; i < NPTEPG; i++) - ept_free_pt_entry(pt[i]); - free(pt, M_VMX); /* free the page table page */ - } -} - -static void -ept_free_pdp_entry(pdp_entry_t pdpe) -{ - pd_entry_t *pd; - int i; - - if (pdpe == 0) - return; - - if ((pdpe & EPT_PG_SUPERPAGE) == 0) { - pd = (pd_entry_t *)PHYS_TO_DMAP(pdpe & EPT_ADDR_MASK); - for (i = 0; i < NPDEPG; i++) - ept_free_pd_entry(pd[i]); - free(pd, M_VMX); /* free the page directory page */ - } -} - -static void -ept_free_pml4_entry(pml4_entry_t pml4e) -{ - pdp_entry_t *pdp; - int i; - - if (pml4e == 0) - return; - - if ((pml4e & EPT_PG_SUPERPAGE) == 0) { - pdp = (pdp_entry_t *)PHYS_TO_DMAP(pml4e & EPT_ADDR_MASK); - for (i = 0; i < NPDPEPG; i++) - ept_free_pdp_entry(pdp[i]); - free(pdp, M_VMX); /* free the page directory ptr page */ - } -} - -void -ept_vmcleanup(struct vmx *vmx) -{ - int i; - - for (i = 0; i < NPML4EPG; i++) - ept_free_pml4_entry(vmx->pml4ept[i]); -} - -static void invept_single_context(void *arg) { struct invept_desc desc = *(struct invept_desc *)arg; Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.h Sun Jul 7 02:49:48 2013 (r252910) @@ -36,7 +36,6 @@ struct vmx; int ept_init(void); void ept_invalidate_mappings(u_long ept_pml4); -void ept_vmcleanup(struct vmx *vmx); struct vmspace *ept_vmspace_alloc(vm_offset_t min, vm_offset_t max); void ept_vmspace_free(struct vmspace *vmspace); #endif Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Sun Jul 7 02:49:48 2013 (r252910) @@ -681,7 +681,7 @@ vmx_setup_cr_shadow(int which, struct vm #define vmx_setup_cr4_shadow(vmcs) vmx_setup_cr_shadow(4, (vmcs)) static void * -vmx_vminit(struct vm *vm) +vmx_vminit(struct vm *vm, pmap_t pmap) { uint16_t vpid; int i, error, guest_msr_count; @@ -694,6 +694,8 @@ vmx_vminit(struct vm *vm) } vmx->vm = vm; + vmx->eptphys = vtophys((vm_offset_t)pmap->pm_pml4); + /* * Clean up EPTP-tagged guest physical and combined mappings * @@ -703,7 +705,7 @@ vmx_vminit(struct vm *vm) * * Combined mappings for this EP4TA are also invalidated for all VPIDs. */ - ept_invalidate_mappings(vtophys(vmx->pml4ept)); + ept_invalidate_mappings(vmx->eptphys); msr_bitmap_initialize(vmx->msr_bitmap); @@ -759,7 +761,7 @@ vmx_vminit(struct vm *vm) error = vmcs_set_defaults(&vmx->vmcs[i], (u_long)vmx_longjmp, (u_long)&vmx->ctx[i], - vtophys(vmx->pml4ept), + vmx->eptphys, pinbased_ctls, procbased_ctls, procbased_ctls2, @@ -1543,7 +1545,6 @@ vmx_vmcleanup(void *arg) if (error != 0) panic("vmx_vmcleanup: vmclear error %d on vcpu 0", error); - ept_vmcleanup(vmx); free(vmx, M_VMX); return; Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.h Sun Jul 7 02:49:48 2013 (r252910) @@ -82,16 +82,15 @@ struct vmxstate { /* virtual machine softc */ struct vmx { - pml4_entry_t pml4ept[NPML4EPG]; struct vmcs vmcs[VM_MAXCPU]; /* one vmcs per virtual cpu */ char msr_bitmap[PAGE_SIZE]; struct msr_entry guest_msrs[VM_MAXCPU][GUEST_MSR_MAX_ENTRIES]; struct vmxctx ctx[VM_MAXCPU]; struct vmxcap cap[VM_MAXCPU]; struct vmxstate state[VM_MAXCPU]; + vm_paddr_t eptphys; struct vm *vm; }; -CTASSERT((offsetof(struct vmx, pml4ept) & PAGE_MASK) == 0); CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0); CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0); CTASSERT((offsetof(struct vmx, guest_msrs) & 15) == 0); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 02:17:49 2013 (r252909) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 02:49:48 2013 (r252910) @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -121,7 +122,7 @@ static struct vmm_ops *ops; #define VMM_INIT() (ops != NULL ? (*ops->init)() : 0) #define VMM_CLEANUP() (ops != NULL ? (*ops->cleanup)() : 0) -#define VMINIT(vm) (ops != NULL ? (*ops->vminit)(vm): NULL) +#define VMINIT(vm, pmap) (ops != NULL ? (*ops->vminit)(vm, pmap): NULL) #define VMRUN(vmi, vcpu, rip) \ (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip) : ENXIO) #define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL) @@ -290,7 +291,7 @@ vm_create(const char *name, struct vm ** vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO); strcpy(vm->name, name); - vm->cookie = VMINIT(vm); + vm->cookie = VMINIT(vm, vmspace_pmap(vmspace)); for (i = 0; i < VM_MAXCPU; i++) { vcpu_init(vm, i); From owner-svn-src-projects@FreeBSD.ORG Sun Jul 7 04:16:32 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id DB1F4D91; Sun, 7 Jul 2013 04:16:32 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id BD6531018; Sun, 7 Jul 2013 04:16:32 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r674GWLH036184; Sun, 7 Jul 2013 04:16:32 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r674GW46036179; Sun, 7 Jul 2013 04:16:32 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307070416.r674GW46036179@svn.freebsd.org> From: Neel Natu Date: Sun, 7 Jul 2013 04:16:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r252911 - projects/bhyve_npt_pmap/sys/amd64/vmm 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: Sun, 07 Jul 2013 04:16:33 -0000 Author: neel Date: Sun Jul 7 04:16:31 2013 New Revision: 252911 URL: http://svnweb.freebsd.org/changeset/base/252911 Log: Add mappings to guest's vm_map at the same time as creating the vm_object that backs those mappings. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 02:49:48 2013 (r252910) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Sun Jul 7 04:16:31 2013 (r252911) @@ -315,7 +315,7 @@ vm_free_mem_seg(struct vm *vm, struct me { if (seg->object != NULL) - vmm_mem_free(seg->object); + vmm_mem_free(vm->vmspace, seg->gpa, seg->len); bzero(seg, sizeof(*seg)); } @@ -430,7 +430,7 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, seg = &vm->mem_segs[vm->num_mem_segs]; - if ((object = vmm_mem_alloc(len)) == NULL) + if ((object = vmm_mem_alloc(vm->vmspace, gpa, len)) == NULL) return (ENOMEM); seg->gpa = gpa; Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c Sun Jul 7 02:49:48 2013 (r252910) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.c Sun Jul 7 04:16:31 2013 (r252911) @@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include +#include #include #include @@ -47,22 +50,35 @@ vmm_mem_init(void) } vm_object_t -vmm_mem_alloc(size_t size) +vmm_mem_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) { + int error; vm_object_t obj; - if (size & PAGE_MASK) - panic("vmm_mem_alloc: invalid allocation size %lu", size); + if (gpa & PAGE_MASK) + panic("vmm_mem_alloc: invalid gpa %#lx", gpa); + + if (len == 0 || (len & PAGE_MASK) != 0) + panic("vmm_mem_alloc: invalid allocation size %lu", len); + + obj = vm_object_allocate(OBJT_DEFAULT, len >> PAGE_SHIFT); + if (obj != NULL) { + error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, + VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); + if (error != KERN_SUCCESS) { + vm_object_deallocate(obj); + obj = NULL; + } + } - obj = vm_object_allocate(OBJT_DEFAULT, size >> PAGE_SHIFT); return (obj); } void -vmm_mem_free(vm_object_t obj) +vmm_mem_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) { - vm_object_deallocate(obj); + vm_map_remove(&vmspace->vm_map, gpa, gpa + len); } vm_paddr_t Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Sun Jul 7 02:49:48 2013 (r252910) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_mem.h Sun Jul 7 04:16:31 2013 (r252911) @@ -29,11 +29,12 @@ #ifndef _VMM_MEM_H_ #define _VMM_MEM_H_ +struct vmspace; struct vm_object; int vmm_mem_init(void); -struct vm_object *vmm_mem_alloc(size_t size); -void vmm_mem_free(struct vm_object *obj); +struct vm_object *vmm_mem_alloc(struct vmspace *, vm_paddr_t gpa, size_t size); +void vmm_mem_free(struct vmspace *, vm_paddr_t gpa, size_t size); vm_paddr_t vmm_mem_maxaddr(void); #endif From owner-svn-src-projects@FreeBSD.ORG Mon Jul 8 00:36:43 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]) by hub.freebsd.org (Postfix) with ESMTP id 6E7511F1; Mon, 8 Jul 2013 00:36:43 +0000 (UTC) (envelope-from bryanv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 5DA281DAB; Mon, 8 Jul 2013 00:36:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r680ah4Z099463; Mon, 8 Jul 2013 00:36:43 GMT (envelope-from bryanv@svn.freebsd.org) Received: (from bryanv@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r680ahKV099461; Mon, 8 Jul 2013 00:36:43 GMT (envelope-from bryanv@svn.freebsd.org) Message-Id: <201307080036.r680ahKV099461@svn.freebsd.org> From: Bryan Venteicher Date: Mon, 8 Jul 2013 00:36:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253014 - in projects/vmxnet/sys: dev/vmware/vmxnet3 modules/vmware modules/vmware/vmxnet3 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: Mon, 08 Jul 2013 00:36:43 -0000 Author: bryanv Date: Mon Jul 8 00:36:42 2013 New Revision: 253014 URL: http://svnweb.freebsd.org/changeset/base/253014 Log: Initial port of the OpenBSD vmxnet3 driver Appears to have basic functionality, but a lot of work remains. Has only been tested on QEMU's vmxnet3 backend. Added: projects/vmxnet/sys/dev/vmware/vmxnet3/ projects/vmxnet/sys/dev/vmware/vmxnet3/if_vmx.c (contents, props changed) projects/vmxnet/sys/dev/vmware/vmxnet3/if_vmxreg.h (contents, props changed) projects/vmxnet/sys/dev/vmware/vmxnet3/if_vmxvar.h (contents, props changed) projects/vmxnet/sys/modules/vmware/vmxnet3/ projects/vmxnet/sys/modules/vmware/vmxnet3/Makefile (contents, props changed) Modified: projects/vmxnet/sys/modules/vmware/Makefile Added: projects/vmxnet/sys/dev/vmware/vmxnet3/if_vmx.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/vmxnet/sys/dev/vmware/vmxnet3/if_vmx.c Mon Jul 8 00:36:42 2013 (r253014) @@ -0,0 +1,2047 @@ +/*- + * Copyright (c) 2013 Tsubai Masanari + * Copyright (c) 2013 Bryan Venteicher + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $OpenBSD: src/sys/dev/pci/if_vmx.c,v 1.11 2013/06/22 00:28:10 uebayasi Exp $ + */ + +/* Driver for VMware vmxnet3 virtual ethernet devices. */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "if_vmxreg.h" +#include "if_vmxvar.h" + +static int vmxnet3_probe(device_t); +static int vmxnet3_attach(device_t); +static int vmxnet3_detach(device_t); +static int vmxnet3_shutdown(device_t); + +static int vmxnet3_alloc_resources(struct vmxnet3_softc *); +static void vmxnet3_free_resources(struct vmxnet3_softc *); +static int vmxnet3_query(struct vmxnet3_softc *); + +static int vmxnet3_alloc_shared_data(struct vmxnet3_softc *); +static void vmxnet3_free_shared_data(struct vmxnet3_softc *); +static int vmxnet3_alloc_txq_data(struct vmxnet3_softc *); +static void vmxnet3_free_txq_data(struct vmxnet3_softc *); +static int vmxnet3_alloc_rxq_data(struct vmxnet3_softc *); +static void vmxnet3_free_rxq_data(struct vmxnet3_softc *); +static int vmxnet3_alloc_queue_data(struct vmxnet3_softc *); +static void vmxnet3_free_queue_data(struct vmxnet3_softc *); +static int vmxnet3_alloc_mcast_table(struct vmxnet3_softc *); +static void vmxnet3_init_shared_data(struct vmxnet3_softc *); +static void vmxnet3_reinit_shared_data(struct vmxnet3_softc *); +static int vmxnet3_alloc_data(struct vmxnet3_softc *); +static void vmxnet3_free_data(struct vmxnet3_softc *); +static int vmxnet3_setup_interface(struct vmxnet3_softc *); + +static void vmxnet3_evintr(struct vmxnet3_softc *); +static void vmxnet3_txeof(struct vmxnet3_softc *, struct vmxnet3_txqueue *); +static void vmxnet3_rx_csum(struct vmxnet3_rxcompdesc *, struct mbuf *); +static int vmxnet3_newbuf(struct vmxnet3_softc *, struct vmxnet3_rxring *); +static void vmxnet3_rxeof(struct vmxnet3_softc *, struct vmxnet3_rxqueue *); +static void vmxnet3_intr(void *); + +static void vmxnet3_txstop(struct vmxnet3_softc *, struct vmxnet3_txqueue *); +static void vmxnet3_rxstop(struct vmxnet3_softc *, struct vmxnet3_rxqueue *); +static void vmxnet3_stop(struct vmxnet3_softc *); + +static void vmxnet3_txinit(struct vmxnet3_softc *, struct vmxnet3_txqueue *); +static int vmxnet3_rxinit(struct vmxnet3_softc *, struct vmxnet3_rxqueue *); +static int vmxnet3_reset_queues(struct vmxnet3_softc *); +static void vmxnet3_init_locked(struct vmxnet3_softc *); +static void vmxnet3_init(void *); + +static int vmxnet3_encap_offload_ctx(struct mbuf *, int *, int *, int *); +static int vmxnet3_encap_load_mbuf(struct vmxnet3_softc *, + struct vmxnet3_txring *, struct mbuf **, bus_dmamap_t, + bus_dma_segment_t [], int *); +static int vmxnet3_encap(struct vmxnet3_softc *, struct mbuf **); +static void vmxnet3_start_locked(struct ifnet *); +static void vmxnet3_start(struct ifnet *); + +static void vmxnet3_set_rxfilter(struct vmxnet3_softc *); +static int vmxnet3_change_mtu(struct vmxnet3_softc *, int); +static int vmxnet3_ioctl(struct ifnet *, u_long, caddr_t); + +static void vmxnet3_watchdog(struct vmxnet3_softc *); +static void vmxnet3_tick(void *); +static void vmxnet3_link_state(struct vmxnet3_softc *); +static void vmxnet3_media_status(struct ifnet *, struct ifmediareq *); +static int vmxnet3_media_change(struct ifnet *); +static void vmxnet3_set_lladdr(struct vmxnet3_softc *); +static void vmxnet3_get_lladdr(struct vmxnet3_softc *); + +static uint32_t vmxnet3_read_bar0(struct vmxnet3_softc *, bus_size_t); +static void vmxnet3_write_bar0(struct vmxnet3_softc *, bus_size_t, + uint32_t); +static uint32_t vmxnet3_read_bar1(struct vmxnet3_softc *, bus_size_t); +static void vmxnet3_write_bar1(struct vmxnet3_softc *, bus_size_t, + uint32_t); +static void vmxnet3_write_cmd(struct vmxnet3_softc *, uint32_t); +static uint32_t vmxnet3_read_cmd(struct vmxnet3_softc *, uint32_t); + +static void vmxnet3_enable_intr(struct vmxnet3_softc *, int); +static void vmxnet3_disable_intr(struct vmxnet3_softc *, int); +static void vmxnet3_enable_all_intrs(struct vmxnet3_softc *); +static void vmxnet3_disable_all_intrs(struct vmxnet3_softc *); + +static int vmxnet3_dma_malloc(struct vmxnet3_softc *, bus_size_t, + bus_size_t, struct vmxnet3_dma_alloc *); +static void vmxnet3_dma_free(struct vmxnet3_softc *, + struct vmxnet3_dma_alloc *); + +static device_method_t vmxnet3_methods[] = { + /* Device interface. */ + DEVMETHOD(device_probe, vmxnet3_probe), + DEVMETHOD(device_attach, vmxnet3_attach), + DEVMETHOD(device_detach, vmxnet3_detach), + DEVMETHOD(device_shutdown, vmxnet3_shutdown), + + DEVMETHOD_END +}; + +static driver_t vmxnet3_driver = { + "vmx", vmxnet3_methods, sizeof(struct vmxnet3_softc) +}; + +static devclass_t vmxnet3_devclass; +DRIVER_MODULE(vmx, pci, vmxnet3_driver, vmxnet3_devclass, 0, 0); + +MODULE_DEPEND(vmx, pci, 1, 1, 1); +MODULE_DEPEND(vmx, ether, 1, 1, 1); + +#define VMXNET3_VMWARE_VENDOR_ID 0x15AD +#define VMXNET3_VMWARE_DEVICE_ID 0x07B0 + +static int +vmxnet3_probe(device_t dev) +{ + + if (pci_get_vendor(dev) == VMXNET3_VMWARE_VENDOR_ID && + pci_get_device(dev) == VMXNET3_VMWARE_DEVICE_ID) { + device_set_desc(dev, "VMware VMXNET3 Ethernet Adapter"); + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +vmxnet3_attach(device_t dev) +{ + struct vmxnet3_softc *sc; + int error; + + sc = device_get_softc(dev); + sc->vmx_dev = dev; + + VMXNET3_CORE_LOCK_INIT(sc, device_get_nameunit(dev)); + VMXNET3_RX_LOCK_INIT(sc, device_get_nameunit(dev)); + VMXNET3_TX_LOCK_INIT(sc, device_get_nameunit(dev)); + callout_init_mtx(&sc->vmx_tick, &sc->vmx_mtx, 0); + + error = vmxnet3_alloc_resources(sc); + if (error) + goto fail; + + error = vmxnet3_query(sc); + if (error) + goto fail; + + error = vmxnet3_alloc_data(sc); + if (error) + goto fail; + + error = vmxnet3_setup_interface(sc); + if (error) + goto fail; + + error = bus_setup_intr(dev, sc->vmx_irq, INTR_TYPE_NET | INTR_MPSAFE, + NULL, vmxnet3_intr, sc, &sc->vmx_intrhand); + if (error) { + ether_ifdetach(sc->vmx_ifp); + device_printf(dev, "could not set up interrupt\n"); + goto fail; + } + + vmxnet3_link_state(sc); + +fail: + if (error) + vmxnet3_detach(dev); + + return (error); +} + +static int +vmxnet3_detach(device_t dev) +{ + struct vmxnet3_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + ifp = sc->vmx_ifp; + + if (device_is_attached(dev)) { + ether_ifdetach(ifp); + VMXNET3_CORE_LOCK(sc); + vmxnet3_stop(sc); + VMXNET3_CORE_UNLOCK(sc); + callout_drain(&sc->vmx_tick); + } + + if (sc->vmx_intrhand != NULL) { + bus_teardown_intr(dev, sc->vmx_irq, sc->vmx_intrhand); + sc->vmx_intrhand = NULL; + } + + if (ifp != NULL) { + if_free(ifp); + sc->vmx_ifp = NULL; + } + + if (sc->vmx_irq != NULL) { + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vmx_irq); + sc->vmx_irq = NULL; + } + + vmxnet3_free_data(sc); + vmxnet3_free_resources(sc); + + VMXNET3_CORE_LOCK_DESTROY(sc); + VMXNET3_TX_LOCK_DESTROY(sc); + VMXNET3_RX_LOCK_DESTROY(sc); + + return (0); +} + +static int +vmxnet3_shutdown(device_t dev) +{ + + return (0); +} + +static int +vmxnet3_alloc_resources(struct vmxnet3_softc *sc) +{ + device_t dev; + int rid; + + dev = sc->vmx_dev; + + rid = PCIR_BAR(0); + sc->vmx_res0 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->vmx_res0 == NULL) { + device_printf(dev, + "could not map BAR0 memory\n"); + return (ENXIO); + } + + sc->vmx_iot0 = rman_get_bustag(sc->vmx_res0); + sc->vmx_ioh0 = rman_get_bushandle(sc->vmx_res0); + + rid = PCIR_BAR(1); + sc->vmx_res1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->vmx_res1 == NULL) { + device_printf(dev, + "could not map BAR1 memory\n"); + return (ENXIO); + } + + sc->vmx_iot1 = rman_get_bustag(sc->vmx_res1); + sc->vmx_ioh1 = rman_get_bushandle(sc->vmx_res1); + + rid = 0; + sc->vmx_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (sc->vmx_irq == NULL) { + device_printf(dev, "could not allocate interrupt resource\n"); + return (ENXIO); + } + + return (0); +} + +static void +vmxnet3_free_resources(struct vmxnet3_softc *sc) +{ + device_t dev; + int rid; + + dev = sc->vmx_dev; + + if (sc->vmx_res0 != NULL) { + rid = PCIR_BAR(0); + bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->vmx_res0); + sc->vmx_res0 = NULL; + } + + if (sc->vmx_res1 != NULL) { + rid = PCIR_BAR(1); + bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->vmx_res1); + sc->vmx_res1 = NULL; + } +} + +static int +vmxnet3_query(struct vmxnet3_softc *sc) +{ + device_t dev; + uint32_t version; + + dev = sc->vmx_dev; + + version = vmxnet3_read_bar1(sc, VMXNET3_BAR1_VRRS); + if ((version & 0x01) == 0) { + device_printf(dev, "unsupported hardware version %#x\n", + version); + return (ENOTSUP); + } + vmxnet3_write_bar1(sc, VMXNET3_BAR1_VRRS, 1); + + version = vmxnet3_read_bar1(sc, VMXNET3_BAR1_UVRS); + if ((version & 0x01) == 0) { + device_printf(dev, "unsupported UPT version %#x\n", version); + return (ENOTSUP); + } + vmxnet3_write_bar1(sc, VMXNET3_BAR1_UVRS, 1); + + vmxnet3_get_lladdr(sc); + + return (0); +} + +static int +vmxnet3_alloc_shared_data(struct vmxnet3_softc *sc) +{ + device_t dev; + uint8_t *kva; + size_t size; + int i, error; + + dev = sc->vmx_dev; + + size = sizeof(struct vmxnet3_driver_shared); + error = vmxnet3_dma_malloc(sc, size, 1, &sc->vmx_ds_dma); + if (error) { + device_printf(dev, "cannot alloc shared memory\n"); + return (error); + } + sc->vmx_ds = (struct vmxnet3_driver_shared *) sc->vmx_ds_dma.dma_vaddr; + + size = VMXNET3_TX_QUEUES * sizeof(struct vmxnet3_txq_shared); + size += VMXNET3_RX_QUEUES * sizeof(struct vmxnet3_rxq_shared); + error = vmxnet3_dma_malloc(sc, size, 128, &sc->vmx_qs_dma); + if (error) { + device_printf(dev, "cannot alloc queue shared memory\n"); + return (error); + } + sc->vmx_qs = (void *) sc->vmx_qs_dma.dma_vaddr; + kva = sc->vmx_qs; + + for (i = 0; i < VMXNET3_TX_QUEUES; i++) { + sc->vmx_txq[i].vxtxq_ts = (struct vmxnet3_txq_shared *) kva; + kva += sizeof(struct vmxnet3_txq_shared); + } + for (i = 0; i < VMXNET3_RX_QUEUES; i++) { + sc->vmx_rxq[i].vxrxq_rs = (struct vmxnet3_rxq_shared *) kva; + kva += sizeof(struct vmxnet3_rxq_shared); + } + + return (0); +} + +static void +vmxnet3_free_shared_data(struct vmxnet3_softc *sc) +{ + + if (sc->vmx_qs != NULL) { + vmxnet3_dma_free(sc, &sc->vmx_qs_dma); + sc->vmx_qs = NULL; + } + + if (sc->vmx_ds != NULL) { + vmxnet3_dma_free(sc, &sc->vmx_ds_dma); + sc->vmx_ds = NULL; + } +} + +static int +vmxnet3_alloc_txq_data(struct vmxnet3_softc *sc) +{ + device_t dev; + struct vmxnet3_txqueue *txq; + struct vmxnet3_txring *txr; + struct vmxnet3_comp_ring *txc; + size_t descsz, compsz; + int i, q, error; + + dev = sc->vmx_dev; + descsz = VMXNET3_TX_NDESC * sizeof(struct vmxnet3_txdesc); + compsz = VMXNET3_TX_NCOMPDESC * sizeof(struct vmxnet3_txcompdesc); + + for (q = 0; q < VMXNET3_TX_QUEUES; q++) { + txq = &sc->vmx_txq[q]; + txr = &txq->vxtxq_cmd_ring; + txc = &txq->vxtxq_comp_ring; + + error = bus_dma_tag_create(bus_get_dma_tag(dev), + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + VMXNET3_TSO_MAXSIZE, /* maxsize */ + VMXNET3_TX_MAXSEGS, /* nsegments */ + PAGE_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &txr->vxtxr_txtag); + if (error) { + device_printf(dev, + "unable to create Tx buffer tag for queue %d\n", q); + return (error); + } + + error = vmxnet3_dma_malloc(sc, descsz, 512, &txr->vxtxr_dma); + if (error) { + device_printf(dev, "cannot alloc Tx descriptors for " + "queue %d error %d\n", q, error); + return (error); + } + txr->vxtxr_txd = + (struct vmxnet3_txdesc *) txr->vxtxr_dma.dma_vaddr; + + error = vmxnet3_dma_malloc(sc, compsz, 512, &txc->vxcr_dma); + if (error) { + device_printf(dev, "cannot alloc Tx comp descriptors " + "for queue %d error %d\n", q, error); + return (error); + } + txc->vxcr_u.txcd = + (struct vmxnet3_txcompdesc *) txc->vxcr_dma.dma_vaddr; + + for (i = 0; i < VMXNET3_TX_NDESC; i++) { + error = bus_dmamap_create(txr->vxtxr_txtag, 0, + &txr->vxtxr_dmap[i]); + if (error) { + device_printf(dev, "unable to create Tx buf " + "dmamap for queue %d idx %d\n", q, i); + return (error); + } + } + } + + return (0); +} + +static void +vmxnet3_free_txq_data(struct vmxnet3_softc *sc) +{ + device_t dev; + struct vmxnet3_txqueue *txq; + struct vmxnet3_txring *txr; + struct vmxnet3_comp_ring *txc; + int i, q; + + dev = sc->vmx_dev; + + for (q = 0; q < VMXNET3_TX_QUEUES; q++) { + txq = &sc->vmx_txq[q]; + txr = &txq->vxtxq_cmd_ring; + txc = &txq->vxtxq_comp_ring; + + for (i = 0; i < VMXNET3_TX_NDESC; i++) { + if (txr->vxtxr_dmap[i] != NULL) { + bus_dmamap_destroy(txr->vxtxr_txtag, + txr->vxtxr_dmap[i]); + txr->vxtxr_dmap[i] = NULL; + } + } + + if (txc->vxcr_u.txcd != NULL) { + vmxnet3_dma_free(sc, &txc->vxcr_dma); + txc->vxcr_u.txcd = NULL; + } + + if (txr->vxtxr_txd != NULL) { + vmxnet3_dma_free(sc, &txr->vxtxr_dma); + txr->vxtxr_txd = NULL; + } + + if (txr->vxtxr_txtag != NULL) { + bus_dma_tag_destroy(txr->vxtxr_txtag); + txr->vxtxr_txtag = NULL; + } + } +} + +static int +vmxnet3_alloc_rxq_data(struct vmxnet3_softc *sc) +{ + device_t dev; + struct vmxnet3_rxqueue *rxq; + struct vmxnet3_rxring *rxr; + struct vmxnet3_comp_ring *rxc; + int descsz, compsz; + int i, j, q, error; + + dev = sc->vmx_dev; + descsz = VMXNET3_RX_NDESC * sizeof(struct vmxnet3_rxdesc); + compsz = VMXNET3_RX_NCOMPDESC * sizeof(struct vmxnet3_rxcompdesc); + + for (q = 0; q < VMXNET3_RX_QUEUES; q++) { + rxq = &sc->vmx_rxq[q]; + rxc = &rxq->vxrxq_comp_ring; + + for (i = 0; i < 2; i++) { + rxr = &rxq->vxrxq_cmd_ring[i]; + + error = bus_dma_tag_create(bus_get_dma_tag(dev), + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MJUMPAGESIZE, /* maxsize */ + 1, /* nsegments */ + MJUMPAGESIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &rxr->vxrxr_rxtag); + if (error) { + device_printf(dev, + "unable to create Rx buffer tag for queue %d\n", q); + return (error); + } + + error = vmxnet3_dma_malloc(sc, descsz, 512, + &rxr->vxrxr_dma); + if (error) { + device_printf(dev, "cannot allocate Rx " + "descriptors for queue %d/%d error %d\n", + i, q, error); + return (error); + } + rxr->vxrxr_rxd = + (struct vmxnet3_rxdesc *) rxr->vxrxr_dma.dma_vaddr; + } + + error = vmxnet3_dma_malloc(sc, compsz, 512, &rxc->vxcr_dma); + if (error) { + device_printf(dev, "cannot alloc Rx comp descriptors " + "for queue %d error %d\n", q, error); + return (error); + } + rxc->vxcr_u.rxcd = + (struct vmxnet3_rxcompdesc *) rxc->vxcr_dma.dma_vaddr; + + for (i = 0; i < 2; i++) { + rxr = &rxq->vxrxq_cmd_ring[i]; + + error = bus_dmamap_create(rxr->vxrxr_rxtag, 0, + &rxr->vxrxr_spare_dmap); + if (error) { + device_printf(dev, "unable to create spare " + "dmamap for queue %d/%d error %d\n", + q, i, error); + return (error); + } + + for (j = 0; j < VMXNET3_RX_NDESC; j++) { + error = bus_dmamap_create(rxr->vxrxr_rxtag, 0, + &rxr->vxrxr_dmap[j]); + if (error) { + device_printf(dev, "unable to create " + "dmamap for queue %d/%d slot %d " + "error %d\n", + q, i, j, error); + return (error); + } + } + } + } + + return (0); +} + +static void +vmxnet3_free_rxq_data(struct vmxnet3_softc *sc) +{ + device_t dev; + struct vmxnet3_rxqueue *rxq; + struct vmxnet3_rxring *rxr; + struct vmxnet3_comp_ring *rxc; + int i, j, q; + + dev = sc->vmx_dev; + + for (q = 0; q < VMXNET3_RX_QUEUES; q++) { + rxq = &sc->vmx_rxq[q]; + rxc = &rxq->vxrxq_comp_ring; + + for (i = 0; i < 2; i++) { + rxr = &rxq->vxrxq_cmd_ring[i]; + + if (rxr->vxrxr_spare_dmap != NULL) { + bus_dmamap_destroy(rxr->vxrxr_rxtag, + rxr->vxrxr_spare_dmap); + rxr->vxrxr_spare_dmap = NULL; + } + + for (j = 0; j < VMXNET3_RX_NDESC; j++) { + if (rxr->vxrxr_dmap[j] != NULL) { + bus_dmamap_destroy(rxr->vxrxr_rxtag, + rxr->vxrxr_dmap[j]); + rxr->vxrxr_dmap[j] = NULL; + } + } + } + + if (rxc->vxcr_u.rxcd != NULL) { + vmxnet3_dma_free(sc, &rxc->vxcr_dma); + rxc->vxcr_u.rxcd = NULL; + } + + for (i = 0; i < 2; i++) { + rxr = &rxq->vxrxq_cmd_ring[i]; + + if (rxr->vxrxr_rxd != NULL) { + vmxnet3_dma_free(sc, &rxr->vxrxr_dma); + rxr->vxrxr_rxd = NULL; + } + + if (rxr->vxrxr_rxtag != NULL) { + bus_dma_tag_destroy(rxr->vxrxr_rxtag); + rxr->vxrxr_rxtag = NULL; + } + } + } +} + +static int +vmxnet3_alloc_queue_data(struct vmxnet3_softc *sc) +{ + int error; + + error = vmxnet3_alloc_txq_data(sc); + if (error) + return (error); + + error = vmxnet3_alloc_rxq_data(sc); + if (error) + return (error); + + return (0); +} + +static void +vmxnet3_free_queue_data(struct vmxnet3_softc *sc) +{ + + vmxnet3_free_rxq_data(sc); + vmxnet3_free_txq_data(sc); +} + +static int +vmxnet3_alloc_mcast_table(struct vmxnet3_softc *sc) +{ + int error; + + error = vmxnet3_dma_malloc(sc, VMXNET3_MULTICAST_MAX * ETHER_ADDR_LEN, + 32, &sc->vmx_mcast_dma); + if (error) + device_printf(sc->vmx_dev, "unable to alloc multicast table\n"); + else + sc->vmx_mcast = sc->vmx_mcast_dma.dma_vaddr; + + return (error); +} + +static void +vmxnet3_free_mcast_table(struct vmxnet3_softc *sc) +{ + + if (sc->vmx_mcast != NULL) { + vmxnet3_dma_free(sc, &sc->vmx_mcast_dma); + sc->vmx_mcast = NULL; + } +} + +static void +vmxnet3_init_shared_data(struct vmxnet3_softc *sc) +{ + struct vmxnet3_driver_shared *ds; + struct vmxnet3_txqueue *txq; + struct vmxnet3_txq_shared *txs; + struct vmxnet3_rxqueue *rxq; + struct vmxnet3_rxq_shared *rxs; + u_int major, minor, release_code, rev; + int i; + + ds = sc->vmx_ds; + ds->magic = VMXNET3_REV1_MAGIC; + ds->version = VMXNET3_DRIVER_VERSION; + + major = __FreeBSD_version / 100000; + minor = (__FreeBSD_version / 1000) % 100; + release_code = (__FreeBSD_version / 100) % 10; + rev = __FreeBSD_version % 100; + ds->guest = release_code << 30 | rev << 22 | major << 14 | minor << 6 | + VMXNET3_GOS_FREEBSD; +#ifdef __LP64__ + ds->guest |= VMXNET3_GOS_64BIT; +#else + ds->guest |= VMXNET3_GOS_32BIT; +#endif + + ds->vmxnet3_revision = 1; + ds->upt_version = 1; + ds->upt_features = UPT1_F_CSUM | UPT1_F_VLAN; + ds->driver_data = vtophys(sc); + ds->driver_data_len = sizeof(struct vmxnet3_softc); + ds->queue_shared = sc->vmx_qs_dma.dma_paddr; + ds->queue_shared_len = sc->vmx_qs_dma.dma_size; + ds->mtu = ETHERMTU; + ds->ntxqueue = VMXNET3_TX_QUEUES; + ds->nrxqueue = VMXNET3_RX_QUEUES; + ds->mcast_table = sc->vmx_mcast_dma.dma_paddr; + ds->mcast_tablelen = sc->vmx_mcast_dma.dma_size; + ds->automask = 1; + ds->nintr = VMXNET3_NINTR; + ds->evintr = 0; + ds->ictrl = VMXNET3_ICTRL_DISABLE_ALL; + for (i = 0; i < VMXNET3_NINTR; i++) + ds->modlevel[i] = UPT1_IMOD_ADAPTIVE; + + for (i = 0; i < VMXNET3_TX_QUEUES; i++) { + txq = &sc->vmx_txq[i]; + txs = txq->vxtxq_ts; + + txs->npending = 0; + txs->intr_threshold = 1; + txs->cmd_ring = txq->vxtxq_cmd_ring.vxtxr_dma.dma_paddr; + txs->cmd_ring_len = VMXNET3_TX_NDESC; + txs->comp_ring = txq->vxtxq_comp_ring.vxcr_dma.dma_paddr; + txs->comp_ring_len = VMXNET3_TX_NCOMPDESC; + txs->driver_data = vtophys(txq); + txs->driver_data_len = sizeof(struct vmxnet3_txqueue); + txs->intr_idx = 0; + txs->stopped = 1; + txs->error = 0; + } + + for (i = 0; i < VMXNET3_RX_QUEUES; i++) { + rxq = &sc->vmx_rxq[i]; + rxs = rxq->vxrxq_rs; + + rxs->cmd_ring[0] = rxq->vxrxq_cmd_ring[0].vxrxr_dma.dma_paddr; + rxs->cmd_ring_len[0] = VMXNET3_RX_NDESC; + rxs->cmd_ring[1] = rxq->vxrxq_cmd_ring[1].vxrxr_dma.dma_paddr; + rxs->cmd_ring_len[1] = VMXNET3_RX_NDESC; + rxs->comp_ring = rxq->vxrxq_comp_ring.vxcr_dma.dma_paddr; + rxs->comp_ring_len = VMXNET3_RX_NCOMPDESC; + rxs->driver_data = vtophys(rxq); + rxs->driver_data_len = sizeof(struct vmxnet3_rxqueue); + rxs->intr_idx = 0; + rxs->stopped = 1; + rxs->error = 0; + } + + vmxnet3_write_bar1(sc, VMXNET3_BAR1_DSL, sc->vmx_ds_dma.dma_paddr); + vmxnet3_write_bar1(sc, VMXNET3_BAR1_DSH, + sc->vmx_ds_dma.dma_paddr >> 32); +} + +static void +vmxnet3_reinit_shared_data(struct vmxnet3_softc *sc) +{ + + vmxnet3_write_bar1(sc, VMXNET3_BAR1_DSL, sc->vmx_ds_dma.dma_paddr); + vmxnet3_write_bar1(sc, VMXNET3_BAR1_DSH, + sc->vmx_ds_dma.dma_paddr >> 32); +} + +static int +vmxnet3_alloc_data(struct vmxnet3_softc *sc) +{ + int error; + + error = vmxnet3_alloc_shared_data(sc); + if (error) + return (error); + + error = vmxnet3_alloc_queue_data(sc); + if (error) + return (error); + + error = vmxnet3_alloc_mcast_table(sc); + if (error) + return (error); + + vmxnet3_init_shared_data(sc); + + return (0); +} + +static void +vmxnet3_free_data(struct vmxnet3_softc *sc) +{ + + vmxnet3_free_mcast_table(sc); + vmxnet3_free_queue_data(sc); + vmxnet3_free_shared_data(sc); +} + +static int +vmxnet3_setup_interface(struct vmxnet3_softc *sc) +{ + device_t dev; + struct ifnet *ifp; + + dev = sc->vmx_dev; + + ifp = sc->vmx_ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "cannot allocate ifnet structure\n"); + return (ENOSPC); + } + + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + if_initbaudrate(ifp, IF_Gbps(10)); /* Approx. */ + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = vmxnet3_init; + ifp->if_ioctl = vmxnet3_ioctl; + ifp->if_start = vmxnet3_start; + ifp->if_snd.ifq_drv_maxlen = VMXNET3_TX_NDESC - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, VMXNET3_TX_NDESC - 1); + IFQ_SET_READY(&ifp->if_snd); + + ether_ifattach(ifp, sc->vmx_lladdr); + + if (sc->vmx_ds->upt_features & UPT1_F_VLAN) + ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; + if (sc->vmx_ds->upt_features & UPT1_F_CSUM) { + ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_TXCSUM; + ifp->if_hwassist |= VMXNET3_CSUM_FEATURES; + } + + ifp->if_capenable = ifp->if_capabilities; + + ifmedia_init(&sc->vmx_media, 0, vmxnet3_media_change, + vmxnet3_media_status); + ifmedia_add(&sc->vmx_media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&sc->vmx_media, IFM_ETHER | IFM_AUTO); + + return (0); +} + +static void +vmxnet3_evintr(struct vmxnet3_softc *sc) +{ + device_t dev; + struct ifnet *ifp; + struct vmxnet3_txq_shared *ts; + struct vmxnet3_rxq_shared *rs; + uint32_t event; + int reset; + + dev = sc->vmx_dev; + ifp = sc->vmx_ifp; + event = sc->vmx_ds->event; + reset = 0; + + /* Clear events. */ + vmxnet3_write_bar1(sc, VMXNET3_BAR1_EVENT, event); + + if (event & VMXNET3_EVENT_LINK) + vmxnet3_link_state(sc); + + if (event & (VMXNET3_EVENT_TQERROR | VMXNET3_EVENT_RQERROR)) { + reset = 1; + vmxnet3_read_cmd(sc, VMXNET3_CMD_GET_STATUS); + ts = sc->vmx_txq[0].vxtxq_ts; + if (ts->stopped != 0) + device_printf(dev, "TX queue error %#x\n", ts->error); + rs = sc->vmx_rxq[0].vxrxq_rs; + if (rs->stopped != 0) + device_printf(dev, "RX queue error %#x\n", rs->error); + } + + if (event & VMXNET3_EVENT_DIC) + device_printf(dev, "device implementation change event\n"); + if (event & VMXNET3_EVENT_DEBUG) + device_printf(dev, "debug event\n"); + + if (reset != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + vmxnet3_init(sc); + } +} + +static void +vmxnet3_txeof(struct vmxnet3_softc *sc, struct vmxnet3_txqueue *txq) +{ + struct ifnet *ifp; + struct vmxnet3_txring *txr; + struct vmxnet3_comp_ring *txc; + struct vmxnet3_txcompdesc *txcd; + u_int sop; + + ifp = sc->vmx_ifp; + txr = &txq->vxtxq_cmd_ring; + txc = &txq->vxtxq_comp_ring; + + VMXNET3_TX_LOCK_ASSERT(sc); + + for (;;) { + txcd = &txc->vxcr_u.txcd[txc->vxcr_next]; + if (txcd->gen != txc->vxcr_gen) + break; + + if (++txc->vxcr_next == VMXNET3_TX_NCOMPDESC) { + txc->vxcr_next = 0; + txc->vxcr_gen ^= 1; + } + + sop = txr->vxtxr_next; + if (txr->vxtxr_m[sop] != NULL) { + bus_dmamap_sync(txr->vxtxr_txtag, txr->vxtxr_dmap[sop], + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->vxtxr_txtag, + txr->vxtxr_dmap[sop]); + + m_freem(txr->vxtxr_m[sop]); + txr->vxtxr_m[sop] = NULL; + + ifp->if_opackets++; + } + + txr->vxtxr_next = (txcd->eop_idx + 1) % VMXNET3_TX_NDESC; + } + + if (txr->vxtxr_head == txr->vxtxr_next) + sc->vmx_watchdog_timer = 0; +} + +static void +vmxnet3_rx_csum(struct vmxnet3_rxcompdesc *rxcd, struct mbuf *m) +{ + + if (rxcd->ipv4 && rxcd->ipcsum_ok) + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID; + if (rxcd->fragment) + return; + if (rxcd->csum_ok && (rxcd->tcp || rxcd->udp)) { + m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xFFFF; + } +} + +static int +vmxnet3_newbuf(struct vmxnet3_softc *sc, struct vmxnet3_rxring *rxr) +{ + struct ifnet *ifp; + struct mbuf *m; + struct vmxnet3_rxdesc *rxd; *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-projects@FreeBSD.ORG Mon Jul 8 06:20:03 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id CF7133C6 for ; Mon, 8 Jul 2013 06:20:03 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.freebsd.org (Postfix) with ESMTP id 462FF1A79 for ; Mon, 8 Jul 2013 06:20:02 +0000 (UTC) Received: (qmail 61007 invoked from network); 8 Jul 2013 07:11:12 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 8 Jul 2013 07:11:12 -0000 Message-ID: <51DA5A11.5090706@freebsd.org> Date: Mon, 08 Jul 2013 08:20:01 +0200 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 MIME-Version: 1.0 To: Bryan Venteicher Subject: Re: svn commit: r253014 - in projects/vmxnet/sys: dev/vmware/vmxnet3 modules/vmware modules/vmware/vmxnet3 References: <201307080036.r680ahKV099461@svn.freebsd.org> In-Reply-To: <201307080036.r680ahKV099461@svn.freebsd.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Mon, 08 Jul 2013 06:20:03 -0000 On 08.07.2013 02:36, Bryan Venteicher wrote: > Author: bryanv > Date: Mon Jul 8 00:36:42 2013 > New Revision: 253014 > URL: http://svnweb.freebsd.org/changeset/base/253014 > > Log: > Initial port of the OpenBSD vmxnet3 driver > > Appears to have basic functionality, but a lot of work remains. Has > only been tested on QEMU's vmxnet3 backend. For the curious could you give an overview on the various approaches to virtual network interfaces used by the different virtualization platforms? -- Andre From owner-svn-src-projects@FreeBSD.ORG Mon Jul 8 19:19:30 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]) by hub.freebsd.org (Postfix) with ESMTP id 2D7C5296; Mon, 8 Jul 2013 19:19:30 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 1FA141360; Mon, 8 Jul 2013 19:19:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r68JJTdK085319; Mon, 8 Jul 2013 19:19:29 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r68JJTPg085315; Mon, 8 Jul 2013 19:19:29 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307081919.r68JJTPg085315@svn.freebsd.org> From: Neel Natu Date: Mon, 8 Jul 2013 19:19:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253043 - in projects/bhyve_npt_pmap/sys/amd64: include vmm 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: Mon, 08 Jul 2013 19:19:30 -0000 Author: neel Date: Mon Jul 8 19:19:29 2013 New Revision: 253043 URL: http://svnweb.freebsd.org/changeset/base/253043 Log: Require that the 'struct vie' be initialized before fetching and decoding the instruction. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm_instruction_emul.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm_instruction_emul.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm_instruction_emul.h Mon Jul 8 17:57:11 2013 (r253042) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm_instruction_emul.h Mon Jul 8 19:19:29 2013 (r253043) @@ -102,11 +102,15 @@ int vmm_emulate_instruction(void *vm, in #ifdef _KERNEL /* * APIs to fetch and decode the instruction from nested page fault handler. + * + * 'vie' must be initialized before calling 'vmm_fetch_instruction()' */ int vmm_fetch_instruction(struct vm *vm, int cpuid, uint64_t rip, int inst_length, uint64_t cr3, struct vie *vie); +void vie_init(struct vie *vie); + /* * Decode the instruction fetched into 'vie' so it can be emulated. * Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Mon Jul 8 17:57:11 2013 (r253042) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Mon Jul 8 19:19:29 2013 (r253043) @@ -399,7 +399,7 @@ vmm_emulate_instruction(void *vm, int vc } #ifdef _KERNEL -static void +void vie_init(struct vie *vie) { @@ -474,8 +474,6 @@ vmm_fetch_instruction(struct vm *vm, int if (inst_length > VIE_INST_SIZE) panic("vmm_fetch_instruction: invalid length %d", inst_length); - vie_init(vie); - /* Copy the instruction into 'vie' */ while (vie->num_valid < inst_length) { err = gla2gpa(vm, rip, cr3, &gpa, &gpaend); From owner-svn-src-projects@FreeBSD.ORG Mon Jul 8 19:40:51 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]) by hub.freebsd.org (Postfix) with ESMTP id EE1748B4; Mon, 8 Jul 2013 19:40:51 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id DF5C815E6; Mon, 8 Jul 2013 19:40:51 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r68Jeplq092044; Mon, 8 Jul 2013 19:40:51 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r68Jep39091253; Mon, 8 Jul 2013 19:40:51 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307081940.r68Jep39091253@svn.freebsd.org> From: Neel Natu Date: Mon, 8 Jul 2013 19:40:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253044 - in projects/bhyve_npt_pmap: sys/amd64/include sys/amd64/vmm sys/amd64/vmm/intel usr.sbin/bhyve 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: Mon, 08 Jul 2013 19:40:52 -0000 Author: neel Date: Mon Jul 8 19:40:50 2013 New Revision: 253044 URL: http://svnweb.freebsd.org/changeset/base/253044 Log: Fault in guest memory in response to EPT faults. The EPT faults are distinguished as follows: - Faults that point to an address that is assigned to a "memory" region will be resolved using vm_fault() - All other EPT faults are resolved via instruction emulation under the assumption that they happened because of an instruction accessing MMIO. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Mon Jul 8 19:19:29 2013 (r253043) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Mon Jul 8 19:40:50 2013 (r253044) @@ -98,6 +98,7 @@ int vm_gpabase2memseg(struct vm *vm, vm_ struct vm_memory_segment *seg); int vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, vm_offset_t *offset, struct vm_object **object); +boolean_t vm_mem_allocated(struct vm *vm, vm_paddr_t gpa); int vm_get_register(struct vm *vm, int vcpu, int reg, uint64_t *retval); int vm_set_register(struct vm *vm, int vcpu, int reg, uint64_t val); int vm_get_seg_desc(struct vm *vm, int vcpu, int reg, @@ -269,6 +270,8 @@ struct vm_exit { struct { uint64_t gpa; struct vie vie; + int inst_emulation; + int fault_type; } paging; /* * VMX specific payload. Used when there is no "better" Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Mon Jul 8 19:19:29 2013 (r253043) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Mon Jul 8 19:40:50 2013 (r253044) @@ -1175,7 +1175,22 @@ vmx_emulate_cr_access(struct vmx *vmx, i } static int -vmx_ept_fault(struct vm *vm, int cpu, +ept_fault_type(uint64_t ept_qual) +{ + int fault_type = 0; + + if (ept_qual & EPT_VIOLATION_INST_FETCH) + fault_type |= VM_PROT_EXECUTE; + if (ept_qual & EPT_VIOLATION_DATA_READ) + fault_type |= VM_PROT_READ; + if (ept_qual & EPT_VIOLATION_DATA_WRITE) + fault_type |= VM_PROT_WRITE; + + return (fault_type); +} + +static int +vmx_inst_emul(struct vm *vm, int cpu, uint64_t gla, uint64_t gpa, uint64_t rip, int inst_length, uint64_t cr3, uint64_t ept_qual, struct vie *vie) { @@ -1223,7 +1238,7 @@ vmx_ept_fault(struct vm *vm, int cpu, static int vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) { - int error, handled; + int error, handled, emulation; struct vmcs *vmcs; struct vmxctx *vmxctx; uint32_t eax, ecx, edx; @@ -1334,15 +1349,30 @@ vmx_exit_process(struct vmx *vmx, int vc break; case EXIT_REASON_EPT_FAULT: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EPT_FAULT, 1); - gla = vmcs_gla(); + /* + * If 'gpa' lies within the address space allocated to + * memory then this must be a nested page fault otherwise + * this must be an instruction that accesses MMIO space. + */ gpa = vmcs_gpa(); - cr3 = vmcs_guest_cr3(); - handled = vmx_ept_fault(vmx->vm, vcpu, gla, gpa, - vmexit->rip, vmexit->inst_length, - cr3, qual, &vmexit->u.paging.vie); + if (vm_mem_allocated(vmx->vm, gpa)) { + handled = 0; + emulation = 0; + } else { + emulation = 1; + gla = vmcs_gla(); + cr3 = vmcs_guest_cr3(); + vie_init(&vmexit->u.paging.vie); + handled = vmx_inst_emul(vmx->vm, vcpu, gla, gpa, + vmexit->rip, vmexit->inst_length, + cr3, qual, &vmexit->u.paging.vie); + } + if (!handled) { vmexit->exitcode = VM_EXITCODE_PAGING; vmexit->u.paging.gpa = gpa; + vmexit->u.paging.inst_emulation = emulation; + vmexit->u.paging.fault_type = ept_fault_type(qual); } break; default: Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Mon Jul 8 19:19:29 2013 (r253043) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Mon Jul 8 19:40:50 2013 (r253044) @@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -364,26 +366,20 @@ vm_unmap_mmio(struct vm *vm, vm_paddr_t return (ENXIO); /* XXX fixme */ } -/* - * Returns TRUE if 'gpa' is available for allocation and FALSE otherwise - */ -static boolean_t -vm_gpa_available(struct vm *vm, vm_paddr_t gpa) +boolean_t +vm_mem_allocated(struct vm *vm, vm_paddr_t gpa) { int i; vm_paddr_t gpabase, gpalimit; - if (gpa & PAGE_MASK) - panic("vm_gpa_available: gpa (0x%016lx) not page aligned", gpa); - for (i = 0; i < vm->num_mem_segs; i++) { gpabase = vm->mem_segs[i].gpa; gpalimit = gpabase + vm->mem_segs[i].len; if (gpa >= gpabase && gpa < gpalimit) - return (FALSE); + return (TRUE); } - return (TRUE); + return (FALSE); } /* @@ -403,10 +399,10 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, available = allocated = 0; g = gpa; while (g < gpa + len) { - if (vm_gpa_available(vm, g)) - available++; - else + if (vm_mem_allocated(vm, g)) allocated++; + else + available++; g += PAGE_SIZE; } @@ -657,11 +653,14 @@ restart: critical_exit(); + if (error) + goto done; + /* * Oblige the guest's desire to 'hlt' by sleeping until the vcpu * is ready to run. */ - if (error == 0 && vme->exitcode == VM_EXITCODE_HLT) { + if (vme->exitcode == VM_EXITCODE_HLT) { vcpu_lock(vcpu); /* @@ -699,6 +698,39 @@ restart: goto restart; } + if (vme->exitcode == VM_EXITCODE_PAGING && + vme->u.paging.inst_emulation == 0) { + int rv; + struct thread *td; + struct proc *p; + struct vm_map *map; + vm_prot_t ftype; + + td = curthread; + p = td->td_proc; + map = &vm->vmspace->vm_map; + ftype = vme->u.paging.fault_type; + + PROC_LOCK(p); + p->p_lock++; + PROC_UNLOCK(p); + + rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL); + + PROC_LOCK(p); + p->p_lock--; + PROC_UNLOCK(p); + + if (rv == KERN_SUCCESS) { + rip = vme->rip; + goto restart; + } else { + /* XXX */ + vme->inst_length = 0; + } + } + +done: return (error); } Modified: projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c ============================================================================== --- projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c Mon Jul 8 19:19:29 2013 (r253043) +++ projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c Mon Jul 8 19:40:50 2013 (r253044) @@ -440,8 +440,11 @@ vmexit_paging(struct vmctx *ctx, struct int err; stats.vmexit_paging++; - err = emulate_mem(ctx, *pvcpu, vmexit->u.paging.gpa, - &vmexit->u.paging.vie); + if (vmexit->u.paging.inst_emulation) { + err = emulate_mem(ctx, *pvcpu, vmexit->u.paging.gpa, + &vmexit->u.paging.vie); + } else + err = ESRCH; if (err) { if (err == EINVAL) { From owner-svn-src-projects@FreeBSD.ORG Tue Jul 9 23:54:44 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]) by hub.freebsd.org (Postfix) with ESMTP id DA6E72F4; Tue, 9 Jul 2013 23:54:44 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id CD7F4177C; Tue, 9 Jul 2013 23:54:44 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r69NsiVp094493; Tue, 9 Jul 2013 23:54:44 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r69Nsi6S094490; Tue, 9 Jul 2013 23:54:44 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307092354.r69Nsi6S094490@svn.freebsd.org> From: Neel Natu Date: Tue, 9 Jul 2013 23:54:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253123 - in projects/bhyve_npt_pmap/sys/amd64: include vmm 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: Tue, 09 Jul 2013 23:54:44 -0000 Author: neel Date: Tue Jul 9 23:54:43 2013 New Revision: 253123 URL: http://svnweb.freebsd.org/changeset/base/253123 Log: Change the vcpu state handling in preparation for doing instruction emulation. The long story: Currently the instruction fetch, decode and emulation are done in the vmx run loop i.e. in a critical section from the point of view of the host. This is no longer feasible because the VM's memory is now pageable. Accessing the VM's address space now relies on 'vm_fault_hold()' to hold the 'vm_page' associated with the GPA and this cannot be done inside a critical section. However, as soon as we exit the critical section around VMRUN(), the VMCS is no longer "active" and thus the vcpu cannot be in the RUNNING state. We work around this by keeping the vcpu in the FROZEN state while it is outside the VMRUN critical section. A vcpu in this state may transition back into RUNNING state or may return to IDLE state on its way back to userland. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Tue Jul 9 23:47:28 2013 (r253122) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Tue Jul 9 23:54:43 2013 (r253123) @@ -133,8 +133,9 @@ void *vm_iommu_domain(struct vm *vm); enum vcpu_state { VCPU_IDLE, + VCPU_FROZEN, VCPU_RUNNING, - VCPU_CANNOT_RUN, + VCPU_SLEEPING, }; int vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Tue Jul 9 23:47:28 2013 (r253122) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Tue Jul 9 23:54:43 2013 (r253123) @@ -93,6 +93,7 @@ struct vcpu { #define vcpu_lock_init(v) mtx_init(&((v)->mtx), "vcpu lock", 0, MTX_SPIN) #define vcpu_lock(v) mtx_lock_spin(&((v)->mtx)) #define vcpu_unlock(v) mtx_unlock_spin(&((v)->mtx)) +#define vcpu_assert_locked(v) mtx_assert(&((v)->mtx), MA_OWNED) struct mem_seg { vm_paddr_t gpa; @@ -611,6 +612,59 @@ save_guest_fpustate(struct vcpu *vcpu) static VMM_STAT(VCPU_IDLE_TICKS, "number of ticks vcpu was idle"); +static int +vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate) +{ + int error; + + vcpu_assert_locked(vcpu); + + /* + * The following state transitions are allowed: + * IDLE -> FROZEN -> IDLE + * FROZEN -> RUNNING -> FROZEN + * FROZEN -> SLEEPING -> FROZEN + */ + switch (vcpu->state) { + case VCPU_IDLE: + case VCPU_RUNNING: + case VCPU_SLEEPING: + error = (newstate != VCPU_FROZEN); + break; + case VCPU_FROZEN: + error = (newstate == VCPU_FROZEN); + break; + default: + error = 1; + break; + } + + if (error == 0) + vcpu->state = newstate; + else + error = EBUSY; + + return (error); +} + +static void +vcpu_require_state(struct vm *vm, int vcpuid, enum vcpu_state newstate) +{ + int error; + + if ((error = vcpu_set_state(vm, vcpuid, newstate)) != 0) + panic("Error %d setting state to %d\n", error, newstate); +} + +static void +vcpu_require_state_locked(struct vcpu *vcpu, enum vcpu_state newstate) +{ + int error; + + if ((error = vcpu_set_state_locked(vcpu, newstate)) != 0) + panic("Error %d setting state to %d", error, newstate); +} + int vm_run(struct vm *vm, struct vm_run *vmrun) { @@ -639,9 +693,11 @@ restart: restore_guest_msrs(vm, vcpuid); restore_guest_fpustate(vcpu); + vcpu_require_state(vm, vcpuid, VCPU_RUNNING); vcpu->hostcpu = curcpu; error = VMRUN(vm->cookie, vcpuid, rip); vcpu->hostcpu = NOCPU; + vcpu_require_state(vm, vcpuid, VCPU_FROZEN); save_guest_fpustate(vcpu); restore_host_msrs(vm, vcpuid); @@ -688,7 +744,9 @@ restart: if (sleepticks <= 0) panic("invalid sleepticks %d", sleepticks); t = ticks; + vcpu_require_state_locked(vcpu, VCPU_SLEEPING); msleep_spin(vcpu, &vcpu->mtx, "vmidle", sleepticks); + vcpu_require_state_locked(vcpu, VCPU_FROZEN); vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t); } @@ -883,7 +941,7 @@ vm_iommu_domain(struct vm *vm) } int -vcpu_set_state(struct vm *vm, int vcpuid, enum vcpu_state state) +vcpu_set_state(struct vm *vm, int vcpuid, enum vcpu_state newstate) { int error; struct vcpu *vcpu; @@ -894,20 +952,7 @@ vcpu_set_state(struct vm *vm, int vcpuid vcpu = &vm->vcpu[vcpuid]; vcpu_lock(vcpu); - - /* - * The following state transitions are allowed: - * IDLE -> RUNNING -> IDLE - * IDLE -> CANNOT_RUN -> IDLE - */ - if ((vcpu->state == VCPU_IDLE && state != VCPU_IDLE) || - (vcpu->state != VCPU_IDLE && state == VCPU_IDLE)) { - error = 0; - vcpu->state = state; - } else { - error = EBUSY; - } - + error = vcpu_set_state_locked(vcpu, newstate); vcpu_unlock(vcpu); return (error); @@ -993,16 +1038,7 @@ vm_interrupt_hostcpu(struct vm *vm, int vcpu_lock(vcpu); hostcpu = vcpu->hostcpu; if (hostcpu == NOCPU) { - /* - * If the vcpu is 'RUNNING' but without a valid 'hostcpu' then - * the host thread must be sleeping waiting for an event to - * kick the vcpu out of 'hlt'. - * - * XXX this is racy because the condition exists right before - * and after calling VMRUN() in vm_run(). The wakeup() is - * benign in this case. - */ - if (vcpu->state == VCPU_RUNNING) + if (vcpu->state == VCPU_SLEEPING) wakeup_one(vcpu); } else { if (vcpu->state != VCPU_RUNNING) Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Tue Jul 9 23:47:28 2013 (r253122) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Tue Jul 9 23:54:43 2013 (r253123) @@ -139,7 +139,6 @@ vmmdev_ioctl(struct cdev *cdev, u_long c struct thread *td) { int error, vcpu, state_changed; - enum vcpu_state new_state; struct vmmdev_softc *sc; struct vm_memory_segment *seg; struct vm_register *vmreg; @@ -189,12 +188,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c goto done; } - if (cmd == VM_RUN) - new_state = VCPU_RUNNING; - else - new_state = VCPU_CANNOT_RUN; - - error = vcpu_set_state(sc->vm, vcpu, new_state); + error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN); if (error) goto done; @@ -211,7 +205,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c */ error = 0; for (vcpu = 0; vcpu < VM_MAXCPU; vcpu++) { - error = vcpu_set_state(sc->vm, vcpu, VCPU_CANNOT_RUN); + error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN); if (error) break; } From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 00:36:02 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]) by hub.freebsd.org (Postfix) with ESMTP id EAC53C4E; Wed, 10 Jul 2013 00:36:02 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id DEB3A1900; Wed, 10 Jul 2013 00:36:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6A0a2JL007042; Wed, 10 Jul 2013 00:36:02 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6A0a2w7007041; Wed, 10 Jul 2013 00:36:02 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307100036.r6A0a2w7007041@svn.freebsd.org> From: Neel Natu Date: Wed, 10 Jul 2013 00:36:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253125 - projects/bhyve_npt_pmap/sys/amd64/vmm 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: Wed, 10 Jul 2013 00:36:03 -0000 Author: neel Date: Wed Jul 10 00:36:02 2013 New Revision: 253125 URL: http://svnweb.freebsd.org/changeset/base/253125 Log: Delay copying the exitinfo into vm_run.vm_exit until we know that we are returning to userland. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 00:31:28 2013 (r253124) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 00:36:02 2013 (r253125) @@ -680,7 +680,7 @@ vm_run(struct vm *vm, struct vm_run *vmr return (EINVAL); vcpu = &vm->vcpu[vcpuid]; - vme = &vmrun->vm_exit; + vme = &vcpu->exitinfo; rip = vmrun->rip; restart: critical_enter(); @@ -704,9 +704,6 @@ restart: vmm_stat_incr(vm, vcpuid, VCPU_TOTAL_RUNTIME, rdtsc() - tscval); - /* copy the exit information */ - bcopy(&vcpu->exitinfo, vme, sizeof(struct vm_exit)); - critical_exit(); if (error) @@ -783,12 +780,15 @@ restart: rip = vme->rip; goto restart; } else { - /* XXX */ - vme->inst_length = 0; + error = EFAULT; + goto done; } } done: + /* copy the exit information */ + bcopy(vme, &vmrun->vm_exit, sizeof(struct vm_exit)); + return (error); } From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 04:59:10 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]) by hub.freebsd.org (Postfix) with ESMTP id F0DB34C7; Wed, 10 Jul 2013 04:59:10 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D233812C7; Wed, 10 Jul 2013 04:59:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6A4xA81088869; Wed, 10 Jul 2013 04:59:10 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6A4xA9k088868; Wed, 10 Jul 2013 04:59:10 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307100459.r6A4xA9k088868@svn.freebsd.org> From: Neel Natu Date: Wed, 10 Jul 2013 04:59:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253133 - projects/bhyve_npt_pmap/sys/amd64/vmm 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: Wed, 10 Jul 2013 04:59:11 -0000 Author: neel Date: Wed Jul 10 04:59:10 2013 New Revision: 253133 URL: http://svnweb.freebsd.org/changeset/base/253133 Log: Tidy up the vm_run() function by splitting the in-kernel handling of guest 'hlt' and 'paging' vm exits into separate functions. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 04:51:07 2013 (r253132) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 04:59:10 2013 (r253133) @@ -665,14 +665,106 @@ vcpu_require_state_locked(struct vcpu *v panic("Error %d setting state to %d", error, newstate); } +/* + * Emulate a guest 'hlt' by sleeping until the vcpu is ready to run. + */ +static int +vcpu_sleep(struct vm *vm, int vcpuid, boolean_t *retu) +{ + struct vcpu *vcpu; + int sleepticks, t; + + vcpu = &vm->vcpu[vcpuid]; + + vcpu_lock(vcpu); + + /* + * Figure out the number of host ticks until the next apic + * timer interrupt in the guest. + */ + sleepticks = lapic_timer_tick(vm, vcpuid); + + /* + * If the guest local apic timer is disabled then sleep for + * a long time but not forever. + */ + if (sleepticks < 0) + sleepticks = hz; + + /* + * Do a final check for pending NMI or interrupts before + * really putting this thread to sleep. + * + * These interrupts could have happened any time after we + * returned from VMRUN() and before we grabbed the vcpu lock. + */ + if (!vm_nmi_pending(vm, vcpuid) && lapic_pending_intr(vm, vcpuid) < 0) { + if (sleepticks <= 0) + panic("invalid sleepticks %d", sleepticks); + t = ticks; + vcpu_require_state_locked(vcpu, VCPU_SLEEPING); + msleep_spin(vcpu, &vcpu->mtx, "vmidle", sleepticks); + vcpu_require_state_locked(vcpu, VCPU_FROZEN); + vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t); + } + vcpu_unlock(vcpu); + + return (0); +} + +static int +vcpu_paging(struct vm *vm, int vcpuid, boolean_t *retu) +{ + int rv; + struct thread *td; + struct proc *p; + struct vm_map *map; + vm_prot_t ftype; + struct vcpu *vcpu; + struct vm_exit *vme; + + vcpu = &vm->vcpu[vcpuid]; + vme = &vcpu->exitinfo; + + /* Return to userspace to do the instruction emulation */ + if (vme->u.paging.inst_emulation) { + *retu = TRUE; + return (0); + } + + td = curthread; + p = td->td_proc; + map = &vm->vmspace->vm_map; + ftype = vme->u.paging.fault_type; + + PROC_LOCK(p); + p->p_lock++; + PROC_UNLOCK(p); + + rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL); + + PROC_LOCK(p); + p->p_lock--; + PROC_UNLOCK(p); + + if (rv != KERN_SUCCESS) + return (EFAULT); + + /* restart execution at the faulting instruction */ + vme->inst_length = 0; + + return (0); +} + int vm_run(struct vm *vm, struct vm_run *vmrun) { - int error, vcpuid, sleepticks, t; + int error, vcpuid; struct vcpu *vcpu; struct pcb *pcb; uint64_t tscval, rip; struct vm_exit *vme; + boolean_t retu; vcpuid = vmrun->cpuid; @@ -706,89 +798,28 @@ restart: critical_exit(); - if (error) - goto done; - - /* - * Oblige the guest's desire to 'hlt' by sleeping until the vcpu - * is ready to run. - */ - if (vme->exitcode == VM_EXITCODE_HLT) { - vcpu_lock(vcpu); - - /* - * Figure out the number of host ticks until the next apic - * timer interrupt in the guest. - */ - sleepticks = lapic_timer_tick(vm, vcpuid); - - /* - * If the guest local apic timer is disabled then sleep for - * a long time but not forever. - */ - if (sleepticks < 0) - sleepticks = hz; - - /* - * Do a final check for pending NMI or interrupts before - * really putting this thread to sleep. - * - * These interrupts could have happened any time after we - * returned from VMRUN() and before we grabbed the vcpu lock. - */ - if (!vm_nmi_pending(vm, vcpuid) && - lapic_pending_intr(vm, vcpuid) < 0) { - if (sleepticks <= 0) - panic("invalid sleepticks %d", sleepticks); - t = ticks; - vcpu_require_state_locked(vcpu, VCPU_SLEEPING); - msleep_spin(vcpu, &vcpu->mtx, "vmidle", sleepticks); - vcpu_require_state_locked(vcpu, VCPU_FROZEN); - vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t); + if (error == 0) { + retu = FALSE; + switch (vme->exitcode) { + case VM_EXITCODE_HLT: + error = vcpu_sleep(vm, vcpuid, &retu); + break; + case VM_EXITCODE_PAGING: + error = vcpu_paging(vm, vcpuid, &retu); + break; + default: + retu = TRUE; /* handled in userland */ + break; } + } - vcpu_unlock(vcpu); - + if (error == 0 && retu == FALSE) { rip = vme->rip + vme->inst_length; goto restart; } - if (vme->exitcode == VM_EXITCODE_PAGING && - vme->u.paging.inst_emulation == 0) { - int rv; - struct thread *td; - struct proc *p; - struct vm_map *map; - vm_prot_t ftype; - - td = curthread; - p = td->td_proc; - map = &vm->vmspace->vm_map; - ftype = vme->u.paging.fault_type; - - PROC_LOCK(p); - p->p_lock++; - PROC_UNLOCK(p); - - rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL); - - PROC_LOCK(p); - p->p_lock--; - PROC_UNLOCK(p); - - if (rv == KERN_SUCCESS) { - rip = vme->rip; - goto restart; - } else { - error = EFAULT; - goto done; - } - } - -done: /* copy the exit information */ bcopy(vme, &vmrun->vm_exit, sizeof(struct vm_exit)); - return (error); } From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 07:12:56 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]) by hub.freebsd.org (Postfix) with ESMTP id 8C32C6FD; Wed, 10 Jul 2013 07:12:56 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 7E62E18BA; Wed, 10 Jul 2013 07:12:56 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6A7CuHK031585; Wed, 10 Jul 2013 07:12:56 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6A7CtsB031581; Wed, 10 Jul 2013 07:12:55 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307100712.r6A7CtsB031581@svn.freebsd.org> From: Neel Natu Date: Wed, 10 Jul 2013 07:12:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm 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: Wed, 10 Jul 2013 07:12:56 -0000 Author: neel Date: Wed Jul 10 07:12:55 2013 New Revision: 253135 URL: http://svnweb.freebsd.org/changeset/base/253135 Log: Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gpa_release(). We guarantee that the vm_page backing the 'gpa' is not reclaimed by the page daemon until the caller indicates that they are done using it by calling 'vm_gpa_release()'. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06:46:46 2013 (r253134) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:12:55 2013 (r253135) @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, + void **cookie); +void vm_gpa_release(void *cookie); vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, struct vm_memory_segment *seg); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06:46:46 2013 (r253134) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:12:55 2013 (r253135) @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, return (0); } -vm_paddr_t -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) +void * +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, + void **cookie) { - vm_paddr_t nextpage; + int rv, pageoff; + vm_page_t m; + struct proc *p; + + pageoff = gpa & PAGE_MASK; + if (len > PAGE_SIZE - pageoff) + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len); + + p = curthread->td_proc; + + PROC_LOCK(p); + p->p_lock++; + PROC_UNLOCK(p); - nextpage = rounddown(gpa + PAGE_SIZE, PAGE_SIZE); - if (len > nextpage - gpa) - panic("vm_gpa2hpa: invalid gpa/len: 0x%016lx/%lu", gpa, len); + rv = vm_fault_hold(&vm->vmspace->vm_map, trunc_page(gpa), reqprot, + VM_FAULT_NORMAL, &m); + + PROC_LOCK(p); + p->p_lock--; + PROC_UNLOCK(p); + + if (rv == KERN_SUCCESS) { + *cookie = m; + return ((void *)(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)) + pageoff)); + } else { + *cookie = NULL; + return (NULL); + } +} + +void +vm_gpa_release(void *cookie) +{ + vm_page_t m = cookie; - return ((vm_paddr_t)-1); /* XXX fixme */ + vm_page_lock(m); + vm_page_unhold(m); + vm_page_unlock(m); } int Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Wed Jul 10 06:46:46 2013 (r253134) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Wed Jul 10 07:12:55 2013 (r253135) @@ -95,8 +95,9 @@ vmmdev_lookup2(struct cdev *cdev) static int vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) { - int error, off, c; - vm_paddr_t hpa, gpa; + int error, off, c, prot; + vm_paddr_t gpa; + void *hpa, *cookie; struct vmmdev_softc *sc; static char zerobuf[PAGE_SIZE]; @@ -107,6 +108,7 @@ vmmdev_rw(struct cdev *cdev, struct uio if (sc == NULL) error = ENXIO; + prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ); while (uio->uio_resid > 0 && error == 0) { gpa = uio->uio_offset; off = gpa & PAGE_MASK; @@ -120,14 +122,16 @@ vmmdev_rw(struct cdev *cdev, struct uio * Since this device does not support lseek(2), dd(1) will * read(2) blocks of data to simulate the lseek(2). */ - hpa = vm_gpa2hpa(sc->vm, gpa, c); - if (hpa == (vm_paddr_t)-1) { + hpa = vm_gpa_hold(sc->vm, gpa, c, prot, &cookie); + if (hpa == NULL) { if (uio->uio_rw == UIO_READ) error = uiomove(zerobuf, c, uio); else error = EFAULT; - } else - error = uiomove((void *)PHYS_TO_DMAP(hpa), c, uio); + } else { + error = uiomove(hpa, c, uio); + vm_gpa_release(cookie); + } } mtx_unlock(&vmmdev_mtx); Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Wed Jul 10 06:46:46 2013 (r253134) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c Wed Jul 10 07:12:55 2013 (r253135) @@ -413,9 +413,9 @@ static int gla2gpa(struct vm *vm, uint64_t gla, uint64_t ptpphys, uint64_t *gpa, uint64_t *gpaend) { - vm_paddr_t hpa; int nlevels, ptpshift, ptpindex; uint64_t *ptpbase, pte, pgsize; + void *cookie; /* * XXX assumes 64-bit guest with 4 page walk levels @@ -425,18 +425,19 @@ gla2gpa(struct vm *vm, uint64_t gla, uin /* Zero out the lower 12 bits and the upper 12 bits */ ptpphys >>= 12; ptpphys <<= 24; ptpphys >>= 12; - hpa = vm_gpa2hpa(vm, ptpphys, PAGE_SIZE); - if (hpa == -1) + ptpbase = vm_gpa_hold(vm, ptpphys, PAGE_SIZE, VM_PROT_READ, + &cookie); + if (ptpbase == NULL) goto error; - ptpbase = (uint64_t *)PHYS_TO_DMAP(hpa); - ptpshift = PAGE_SHIFT + nlevels * 9; ptpindex = (gla >> ptpshift) & 0x1FF; pgsize = 1UL << ptpshift; pte = ptpbase[ptpindex]; + vm_gpa_release(cookie); + if ((pte & PG_V) == 0) goto error; @@ -464,13 +465,15 @@ int vmm_fetch_instruction(struct vm *vm, int cpuid, uint64_t rip, int inst_length, uint64_t cr3, struct vie *vie) { - int n, err; - uint64_t hpa, gpa, gpaend, off; + int n, err, prot; + uint64_t gpa, gpaend, off; + void *hpa, *cookie; /* * XXX cache previously fetched instructions using 'rip' as the tag */ + prot = VM_PROT_READ | VM_PROT_EXECUTE; if (inst_length > VIE_INST_SIZE) panic("vmm_fetch_instruction: invalid length %d", inst_length); @@ -483,11 +486,12 @@ vmm_fetch_instruction(struct vm *vm, int off = gpa & PAGE_MASK; n = min(inst_length - vie->num_valid, PAGE_SIZE - off); - hpa = vm_gpa2hpa(vm, gpa, n); - if (hpa == -1) + if ((hpa = vm_gpa_hold(vm, gpa, n, prot, &cookie)) == NULL) break; - bcopy((void *)PHYS_TO_DMAP(hpa), &vie->inst[vie->num_valid], n); + bcopy(hpa, &vie->inst[vie->num_valid], n); + + vm_gpa_release(cookie); rip += n; vie->num_valid += n; From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 07:20:41 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id BF331BDA; Wed, 10 Jul 2013 07:20:41 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) by mx1.freebsd.org (Postfix) with ESMTP id 19E671900; Wed, 10 Jul 2013 07:20:40 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.7/8.14.7) with ESMTP id r6A7KaGc055601; Wed, 10 Jul 2013 10:20:36 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.8.3 kib.kiev.ua r6A7KaGc055601 Received: (from kostik@localhost) by tom.home (8.14.7/8.14.7/Submit) id r6A7KaNx055600; Wed, 10 Jul 2013 10:20:36 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Wed, 10 Jul 2013 10:20:36 +0300 From: Konstantin Belousov To: Neel Natu Subject: Re: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm Message-ID: <20130710072036.GY91021@kib.kiev.ua> References: <201307100712.r6A7CtsB031581@svn.freebsd.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="T0/aMKx8NezEC19d" Content-Disposition: inline In-Reply-To: <201307100712.r6A7CtsB031581@svn.freebsd.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on tom.home Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Wed, 10 Jul 2013 07:20:41 -0000 --T0/aMKx8NezEC19d Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jul 10, 2013 at 07:12:55AM +0000, Neel Natu wrote: > Author: neel > Date: Wed Jul 10 07:12:55 2013 > New Revision: 253135 > URL: http://svnweb.freebsd.org/changeset/base/253135 >=20 > Log: > Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gpa_rele= ase(). > =20 > We guarantee that the vm_page backing the 'gpa' is not reclaimed by > the page daemon until the caller indicates that they are done using it > by calling 'vm_gpa_release()'. >=20 > Modified: > projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c > projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c >=20 > Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06:46:46 2= 013 (r253134) > +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:12:55 2= 013 (r253135) > @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); > int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); > int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hp= a); > int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); > +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, > + void **cookie); > +void vm_gpa_release(void *cookie); > vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); > int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, > struct vm_memory_segment *seg); >=20 > Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06:46:46 2013 = (r253134) > +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:12:55 2013 = (r253135) > @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, > return (0); > } > =20 > -vm_paddr_t > -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) > +void * > +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, > + void **cookie) > { > - vm_paddr_t nextpage; > + int rv, pageoff; > + vm_page_t m; > + struct proc *p; > + > + pageoff =3D gpa & PAGE_MASK; > + if (len > PAGE_SIZE - pageoff) > + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len); > + > + p =3D curthread->td_proc; > + > + PROC_LOCK(p); > + p->p_lock++; > + PROC_UNLOCK(p); Why do you need to hold the process there ? I do not think that hold in the trap handler is really useful, probably the reverse. --T0/aMKx8NezEC19d Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (FreeBSD) iQIcBAEBAgAGBQJR3QtDAAoJEJDCuSvBvK1BuloP/0dFkk7/lexiOW4Mq8h3Y1u0 aELW5gmHqx/hO5Ws/qF0f9a115PhriZ2AlVaYSp4Kdv0oht7zac3XenJTec4+Cet KKrImqiOkvZbwt20kpd14QtPfp5mLlZcZ/1owu50SZBjHvypQuoeNPjkj61DpAgz RhZssGcIctOwVzjIvkcfO3U3U2CbHuv1buDftRzgcePKWRJSRIfb1OUuXVpenl+7 c7R2AB/9ZgC04Ra5I1oFryOyfz0W3Kkw0ArrXNjp544Z1+6YXvg1YggLfgh1rQ5S Vr2O1hM60ESuyJYt+Io+SrTSCbfbPdz80IK1Uvep6+9EoZGkl14B2iwGvMoLLTbj vLW9afwj8RWUN67P9esGb33hwKUGuqqDijWbJaWRq5s9+8Q1hNGqaUdW2MZoNcP7 X6V4byTv/uVfYb2q2rfrw5LysSEGgpTwRiXJkkk3s+GWwWtABupXybgTo562rUyg q0T6v5peWs7r4ItmdBCG25uIBFzpmfRBK2aCCW75QTiI20d2R/2WxKkhjh/8mlKg S5ywfCQvAWoSsJ526nuBTurg2o6hbtNT5jD1KKwpOsXtxq7nYfJx4uPoGoABD6yL LxpCY4n+iFHJqVM52ObbJ4YDbmBtXy80KIOQCIbF9eXzFGXjX9+JE++E24eMT3gh kMf/uL7/rxez1+uulp59 =S5jH -----END PGP SIGNATURE----- --T0/aMKx8NezEC19d-- From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 07:22:01 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 4AC8ACD8; Wed, 10 Jul 2013 07:22:01 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 2D8B61915; Wed, 10 Jul 2013 07:22:01 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6A7M18N034507; Wed, 10 Jul 2013 07:22:01 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6A7M0fi034494; Wed, 10 Jul 2013 07:22:00 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307100722.r6A7M0fi034494@svn.freebsd.org> From: Neel Natu Date: Wed, 10 Jul 2013 07:22:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253137 - in projects/bhyve_npt_pmap: sys/amd64/include sys/amd64/vmm sys/amd64/vmm/intel usr.sbin/bhyve 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: Wed, 10 Jul 2013 07:22:01 -0000 Author: neel Date: Wed Jul 10 07:21:59 2013 New Revision: 253137 URL: http://svnweb.freebsd.org/changeset/base/253137 Log: Move instruction emulation out of the critical section since it may need to sleep waiting for the underlying page to be swapped in. The processor-specific code now simply identifies the EPT fault as one triggered during instruction execution and fills in the collateral (e.g. gpa, gla, cr3). The instruction fetch, decode and emulation is then done in the vm_run loop. Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c 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/bhyve/bhyverun.c Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:15:39 2013 (r253136) +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:21:59 2013 (r253137) @@ -96,7 +96,6 @@ int vm_unmap_mmio(struct vm *vm, vm_padd void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, void **cookie); void vm_gpa_release(void *cookie); -vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, struct vm_memory_segment *seg); int vm_get_memobj(struct vm *vm, vm_paddr_t gpa, size_t len, @@ -254,6 +253,7 @@ enum vm_exitcode { VM_EXITCODE_MTRAP, VM_EXITCODE_PAUSE, VM_EXITCODE_PAGING, + VM_EXITCODE_INST_EMUL, VM_EXITCODE_SPINUP_AP, VM_EXITCODE_MAX }; @@ -273,10 +273,14 @@ struct vm_exit { } inout; struct { uint64_t gpa; - struct vie vie; - int inst_emulation; int fault_type; } paging; + struct { + uint64_t gpa; + uint64_t gla; + uint64_t cr3; + struct vie vie; + } inst_emul; /* * VMX specific payload. Used when there is no "better" * exitcode to represent the VM-exit. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Wed Jul 10 07:15:39 2013 (r253136) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Wed Jul 10 07:21:59 2013 (r253137) @@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include "vmm_host.h" #include "vmm_lapic.h" @@ -1189,22 +1187,20 @@ ept_fault_type(uint64_t ept_qual) return (fault_type); } -static int -vmx_inst_emul(struct vm *vm, int cpu, - uint64_t gla, uint64_t gpa, uint64_t rip, int inst_length, - uint64_t cr3, uint64_t ept_qual, struct vie *vie) +static boolean_t +ept_emulation_fault(uint64_t ept_qual) { - int read, write, error; + int read, write; - /* EPT violation on an instruction fetch doesn't make sense here */ + /* EPT fault on an instruction fetch doesn't make sense here */ if (ept_qual & EPT_VIOLATION_INST_FETCH) - return (UNHANDLED); + return (FALSE); - /* EPT violation must be a read fault or a write fault */ + /* EPT fault must be a read fault or a write fault */ read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0; write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0; if ((read | write) == 0) - return (UNHANDLED); + return (FALSE); /* * The EPT violation must have been caused by accessing a @@ -1213,36 +1209,20 @@ vmx_inst_emul(struct vm *vm, int cpu, */ if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 || (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) { - return (UNHANDLED); + return (FALSE); } - /* Fetch, decode and emulate the faulting instruction */ - if (vmm_fetch_instruction(vm, cpu, rip, inst_length, cr3, vie) != 0) - return (UNHANDLED); - - if (vmm_decode_instruction(vm, cpu, gla, vie) != 0) - return (UNHANDLED); - - /* - * Check if this is a local apic access - */ - if (gpa < DEFAULT_APIC_BASE || gpa >= DEFAULT_APIC_BASE + PAGE_SIZE) - return (UNHANDLED); - - error = vmm_emulate_instruction(vm, cpu, gpa, vie, - lapic_mmio_read, lapic_mmio_write, 0); - - return (error ? UNHANDLED : HANDLED); + return (TRUE); } static int vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) { - int error, handled, emulation; + int error, handled; struct vmcs *vmcs; struct vmxctx *vmxctx; uint32_t eax, ecx, edx; - uint64_t qual, gla, gpa, cr3, intr_info; + uint64_t qual, gpa, intr_info; handled = 0; vmcs = &vmx->vmcs[vcpu]; @@ -1356,23 +1336,14 @@ vmx_exit_process(struct vmx *vmx, int vc */ gpa = vmcs_gpa(); if (vm_mem_allocated(vmx->vm, gpa)) { - handled = 0; - emulation = 0; - } else { - emulation = 1; - gla = vmcs_gla(); - cr3 = vmcs_guest_cr3(); - vie_init(&vmexit->u.paging.vie); - handled = vmx_inst_emul(vmx->vm, vcpu, gla, gpa, - vmexit->rip, vmexit->inst_length, - cr3, qual, &vmexit->u.paging.vie); - } - - if (!handled) { vmexit->exitcode = VM_EXITCODE_PAGING; vmexit->u.paging.gpa = gpa; - vmexit->u.paging.inst_emulation = emulation; vmexit->u.paging.fault_type = ept_fault_type(qual); + } else if (ept_emulation_fault(qual)) { + vmexit->exitcode = VM_EXITCODE_INST_EMUL; + vmexit->u.inst_emul.gpa = gpa; + vmexit->u.inst_emul.gla = vmcs_gla(); + vmexit->u.inst_emul.cr3 = vmcs_guest_cr3(); } break; default: @@ -1394,14 +1365,6 @@ vmx_exit_process(struct vmx *vmx, int vc vm_exit_update_rip(vmexit); vmexit->rip += vmexit->inst_length; vmexit->inst_length = 0; - - /* - * Special case for spinning up an AP - exit to userspace to - * give the controlling process a chance to intercept and - * spin up a thread for the AP. - */ - if (vmexit->exitcode == VM_EXITCODE_SPINUP_AP) - handled = 0; } else { if (vmexit->exitcode == VM_EXITCODE_BOGUS) { /* Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:15:39 2013 (r253136) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:21:59 2013 (r253137) @@ -701,7 +701,7 @@ vcpu_require_state_locked(struct vcpu *v * Emulate a guest 'hlt' by sleeping until the vcpu is ready to run. */ static int -vcpu_sleep(struct vm *vm, int vcpuid, boolean_t *retu) +vm_handle_hlt(struct vm *vm, int vcpuid, boolean_t *retu) { struct vcpu *vcpu; int sleepticks, t; @@ -745,7 +745,7 @@ vcpu_sleep(struct vm *vm, int vcpuid, bo } static int -vcpu_paging(struct vm *vm, int vcpuid, boolean_t *retu) +vm_handle_paging(struct vm *vm, int vcpuid, boolean_t *retu) { int rv; struct thread *td; @@ -758,12 +758,6 @@ vcpu_paging(struct vm *vm, int vcpuid, b vcpu = &vm->vcpu[vcpuid]; vme = &vcpu->exitinfo; - /* Return to userspace to do the instruction emulation */ - if (vme->u.paging.inst_emulation) { - *retu = TRUE; - return (0); - } - td = curthread; p = td->td_proc; map = &vm->vmspace->vm_map; @@ -788,6 +782,52 @@ vcpu_paging(struct vm *vm, int vcpuid, b return (0); } + +static int +vm_handle_inst_emul(struct vm *vm, int vcpuid, boolean_t *retu) +{ + struct vie *vie; + struct vcpu *vcpu; + struct vm_exit *vme; + int error, inst_length; + uint64_t rip, gla, gpa, cr3; + + vcpu = &vm->vcpu[vcpuid]; + vme = &vcpu->exitinfo; + + rip = vme->rip; + inst_length = vme->inst_length; + + gla = vme->u.inst_emul.gla; + gpa = vme->u.inst_emul.gpa; + cr3 = vme->u.inst_emul.cr3; + vie = &vme->u.inst_emul.vie; + + vie_init(vie); + + /* Fetch, decode and emulate the faulting instruction */ + if (vmm_fetch_instruction(vm, vcpuid, rip, inst_length, cr3, vie) != 0) + return (EFAULT); + + if (vmm_decode_instruction(vm, vcpuid, gla, vie) != 0) + return (EFAULT); + + /* return to userland unless this is a local apic access */ + if (gpa < DEFAULT_APIC_BASE || gpa >= DEFAULT_APIC_BASE + PAGE_SIZE) { + *retu = TRUE; + return (0); + } + + error = vmm_emulate_instruction(vm, vcpuid, gpa, vie, + lapic_mmio_read, lapic_mmio_write, 0); + + /* return to userland to spin up the AP */ + if (error == 0 && vme->exitcode == VM_EXITCODE_SPINUP_AP) + *retu = TRUE; + + return (error); +} + int vm_run(struct vm *vm, struct vm_run *vmrun) { @@ -834,10 +874,13 @@ restart: retu = FALSE; switch (vme->exitcode) { case VM_EXITCODE_HLT: - error = vcpu_sleep(vm, vcpuid, &retu); + error = vm_handle_hlt(vm, vcpuid, &retu); break; case VM_EXITCODE_PAGING: - error = vcpu_paging(vm, vcpuid, &retu); + error = vm_handle_paging(vm, vcpuid, &retu); + break; + case VM_EXITCODE_INST_EMUL: + error = vm_handle_inst_emul(vm, vcpuid, &retu); break; default: retu = TRUE; /* handled in userland */ Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Wed Jul 10 07:15:39 2013 (r253136) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c Wed Jul 10 07:21:59 2013 (r253137) @@ -359,6 +359,8 @@ vmmdev_ioctl(struct cdev *cdev, u_long c } done: + /* Make sure that no handler returns a bogus value like ERESTART */ + KASSERT(error >= 0, ("vmmdev_ioctl: invalid error return %d", error)); return (error); } Modified: projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c ============================================================================== --- projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c Wed Jul 10 07:15:39 2013 (r253136) +++ projects/bhyve_npt_pmap/usr.sbin/bhyve/bhyverun.c Wed Jul 10 07:21:59 2013 (r253137) @@ -107,7 +107,7 @@ struct fbsdstats { uint64_t vmexit_hlt; uint64_t vmexit_pause; uint64_t vmexit_mtrap; - uint64_t vmexit_paging; + uint64_t vmexit_inst_emul; uint64_t cpu_switch_rotate; uint64_t cpu_switch_direct; int io_reset; @@ -435,16 +435,13 @@ vmexit_mtrap(struct vmctx *ctx, struct v } static int -vmexit_paging(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) { int err; - stats.vmexit_paging++; + stats.vmexit_inst_emul++; - if (vmexit->u.paging.inst_emulation) { - err = emulate_mem(ctx, *pvcpu, vmexit->u.paging.gpa, - &vmexit->u.paging.vie); - } else - err = ESRCH; + err = emulate_mem(ctx, *pvcpu, vmexit->u.inst_emul.gpa, + &vmexit->u.inst_emul.vie); if (err) { if (err == EINVAL) { @@ -453,7 +450,7 @@ vmexit_paging(struct vmctx *ctx, struct vmexit->rip); } else if (err == ESRCH) { fprintf(stderr, "Unhandled memory access to 0x%lx\n", - vmexit->u.paging.gpa); + vmexit->u.inst_emul.gpa); } return (VMEXIT_ABORT); @@ -502,7 +499,7 @@ static vmexit_handler_t handler[VM_EXITC [VM_EXITCODE_RDMSR] = vmexit_rdmsr, [VM_EXITCODE_WRMSR] = vmexit_wrmsr, [VM_EXITCODE_MTRAP] = vmexit_mtrap, - [VM_EXITCODE_PAGING] = vmexit_paging, + [VM_EXITCODE_INST_EMUL] = vmexit_inst_emul, [VM_EXITCODE_SPINUP_AP] = vmexit_spinup_ap, }; From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 07:36:39 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]) by hub.freebsd.org (Postfix) with ESMTP id 0A7CD123; Wed, 10 Jul 2013 07:36:39 +0000 (UTC) (envelope-from neelnatu@gmail.com) Received: from mail-ie0-x233.google.com (mail-ie0-x233.google.com [IPv6:2607:f8b0:4001:c03::233]) by mx1.freebsd.org (Postfix) with ESMTP id CBED319B9; Wed, 10 Jul 2013 07:36:38 +0000 (UTC) Received: by mail-ie0-f179.google.com with SMTP id c10so14679364ieb.38 for ; Wed, 10 Jul 2013 00:36:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=qwijZ6YKouwkfO+tc9E9LtADeH5Hm5oPgAHMwLkYIXs=; b=OSuZ4MOzpRtjsijzOLlErBcXC0geebBItBI5r33Hg/Tkkq9OnHIpqthLfdJ3UEeqq8 3qsXxbPIByPfweXDjt6gYtsvgc57hUPL++m+RsqbL+MUhRw30UPqcBey3IDhEsjlzGK6 OjZa5Gvll96J6aEgY4BumFY3My6RjbXGeK25jc7MzG+If9vjEbcoQbob7a5/kIKpPP38 D8x6xUcblMjSLqseQduCWyXy6jCuyN47RUyBw2XoWB8WviUka5YDgl0lLpuOJex4GzBT T3tQTy1Q7zIHOXMWdUMRWBc9Ko9wPenGuQ+QKvdnk40kc9XyVex6kCP5TdI99DjzQ2s/ gIfQ== MIME-Version: 1.0 X-Received: by 10.50.7.1 with SMTP id f1mr11283933iga.48.1373441798231; Wed, 10 Jul 2013 00:36:38 -0700 (PDT) Received: by 10.42.151.74 with HTTP; Wed, 10 Jul 2013 00:36:38 -0700 (PDT) In-Reply-To: <20130710072036.GY91021@kib.kiev.ua> References: <201307100712.r6A7CtsB031581@svn.freebsd.org> <20130710072036.GY91021@kib.kiev.ua> Date: Wed, 10 Jul 2013 00:36:38 -0700 Message-ID: Subject: Re: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm From: Neel Natu To: Konstantin Belousov Content-Type: text/plain; charset=ISO-8859-1 Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Wed, 10 Jul 2013 07:36:39 -0000 Hi Konstantin, On Wed, Jul 10, 2013 at 12:20 AM, Konstantin Belousov wrote: > On Wed, Jul 10, 2013 at 07:12:55AM +0000, Neel Natu wrote: >> Author: neel >> Date: Wed Jul 10 07:12:55 2013 >> New Revision: 253135 >> URL: http://svnweb.freebsd.org/changeset/base/253135 >> >> Log: >> Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gpa_release(). >> >> We guarantee that the vm_page backing the 'gpa' is not reclaimed by >> the page daemon until the caller indicates that they are done using it >> by calling 'vm_gpa_release()'. >> >> Modified: >> projects/bhyve_npt_pmap/sys/amd64/include/vmm.h >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h >> ============================================================================== >> --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06:46:46 2013 (r253134) >> +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:12:55 2013 (r253135) >> @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); >> int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); >> int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); >> int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); >> +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, >> + void **cookie); >> +void vm_gpa_release(void *cookie); >> vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); >> int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, >> struct vm_memory_segment *seg); >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c >> ============================================================================== >> --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06:46:46 2013 (r253134) >> +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:12:55 2013 (r253135) >> @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, >> return (0); >> } >> >> -vm_paddr_t >> -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) >> +void * >> +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, >> + void **cookie) >> { >> - vm_paddr_t nextpage; >> + int rv, pageoff; >> + vm_page_t m; >> + struct proc *p; >> + >> + pageoff = gpa & PAGE_MASK; >> + if (len > PAGE_SIZE - pageoff) >> + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len); >> + >> + p = curthread->td_proc; >> + >> + PROC_LOCK(p); >> + p->p_lock++; >> + PROC_UNLOCK(p); > Why do you need to hold the process there ? I was following the idiom in trap_pfault() - the comment in trap.c about swapout was enough to convince me :-) > I do not think that hold in the trap handler is really useful, probably > the reverse. I am happy to remove the lock if isn't needed. Could you explain a bit more on why it may be detrimental or point me in the right direction so I can look for myself. best Neel From owner-svn-src-projects@FreeBSD.ORG Wed Jul 10 07:48:48 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]) by hub.freebsd.org (Postfix) with ESMTP id BC5885EC; Wed, 10 Jul 2013 07:48:48 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) by mx1.freebsd.org (Postfix) with ESMTP id 2F8171A18; Wed, 10 Jul 2013 07:48:48 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.7/8.14.7) with ESMTP id r6A7mdPK061100; Wed, 10 Jul 2013 10:48:39 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.8.3 kib.kiev.ua r6A7mdPK061100 Received: (from kostik@localhost) by tom.home (8.14.7/8.14.7/Submit) id r6A7mdFm061099; Wed, 10 Jul 2013 10:48:39 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Wed, 10 Jul 2013 10:48:39 +0300 From: Konstantin Belousov To: Neel Natu Subject: Re: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm Message-ID: <20130710074839.GZ91021@kib.kiev.ua> References: <201307100712.r6A7CtsB031581@svn.freebsd.org> <20130710072036.GY91021@kib.kiev.ua> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="jZi48drba+QTPlSF" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on tom.home Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Wed, 10 Jul 2013 07:48:48 -0000 --jZi48drba+QTPlSF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jul 10, 2013 at 12:36:38AM -0700, Neel Natu wrote: > Hi Konstantin, >=20 > On Wed, Jul 10, 2013 at 12:20 AM, Konstantin Belousov > wrote: > > On Wed, Jul 10, 2013 at 07:12:55AM +0000, Neel Natu wrote: > >> Author: neel > >> Date: Wed Jul 10 07:12:55 2013 > >> New Revision: 253135 > >> URL: http://svnweb.freebsd.org/changeset/base/253135 > >> > >> Log: > >> Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gpa_r= elease(). > >> > >> We guarantee that the vm_page backing the 'gpa' is not reclaimed by > >> the page daemon until the caller indicates that they are done using = it > >> by calling 'vm_gpa_release()'. > >> > >> Modified: > >> projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c > >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c > >> > >> Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D > >> --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06:46= :46 2013 (r253134) > >> +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:12= :55 2013 (r253135) > >> @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); > >> int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); > >> int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t= hpa); > >> int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); > >> +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, > >> + void **cookie); > >> +void vm_gpa_release(void *cookie); > >> vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); > >> int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, > >> struct vm_memory_segment *seg); > >> > >> Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D > >> --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06:46= :46 2013 (r253134) > >> +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:12= :55 2013 (r253135) > >> @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, > >> return (0); > >> } > >> > >> -vm_paddr_t > >> -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) > >> +void * > >> +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, > >> + void **cookie) > >> { > >> - vm_paddr_t nextpage; > >> + int rv, pageoff; > >> + vm_page_t m; > >> + struct proc *p; > >> + > >> + pageoff =3D gpa & PAGE_MASK; > >> + if (len > PAGE_SIZE - pageoff) > >> + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa,= len); > >> + > >> + p =3D curthread->td_proc; > >> + > >> + PROC_LOCK(p); > >> + p->p_lock++; > >> + PROC_UNLOCK(p); > > Why do you need to hold the process there ? >=20 > I was following the idiom in trap_pfault() - the comment in trap.c > about swapout was enough to convince me :-) >=20 > > I do not think that hold in the trap handler is really useful, probably > > the reverse. >=20 > I am happy to remove the lock if isn't needed. >=20 > Could you explain a bit more on why it may be detrimental or point me > in the right direction so I can look for myself. The hold prevents the swap out of the process. This means that kernel stack is assured to be resident for all process threads, and the vm_pageout_map_deactivate_pages() is not called for the process. In other words, in the low memory condition, the VM choice of the pages to reuse is limited, which is probably esp. bad for the large address spaces like whole virtual machine. The swapped-out state of the process interacts correctly with the vm_fault_hold(), the synchronization of the access to map and objects would do the right thing. IMO the PHOLD() makes the page fault potentially faster to proceed by the cost of making the deadlock due to low memory condition more probable. --jZi48drba+QTPlSF Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (FreeBSD) iQIcBAEBAgAGBQJR3RHWAAoJEJDCuSvBvK1B4hgP/0nrOL0sdSB/M7Eg4J/aS1qq 7l19H4O64C/9SM7G06HRiS5IC9B5hdYJR4gfNOBN1Ro63m4McM2Alk7IQgrQrwnf aLtFPNNCCnLXqh2Dxgfa2xaMo74XTdFN4/iN0WtF7gRKgrMFF6P/6Y1r1pXsAkiA KoUnrFiEt5nji5XE5v15OLuZnBTD0+XYBMSejGbHQF8rv6mFnDcjkKYGeWg0F31M Tg6NrauM/BubVMEWjL+c4Q9KjZnR5FOvEnTuhcihlLsRmTu10xhZDtr2G1NoYZBj uf9/6NTVODhuujxXHDnTK91USiWhxzEOaMTWpNkSCVM2V2mVJ7RX1N3K2d/aqPgU MdBLjcPhzFgvwFs19rfDJfno2N89KrD+VVC1kfVN/2nGNNCUPepc0tHM8FXUX+zI QIGW/iNJi/nlPcjmmE0Oe6XcYtGI7xG1S+nvVb1povfBwkRrjlo9bnI2CKarRkPK vg2JNSPJw/Zk7mCZD1fBGHqJwDCMiz2Aoc5ltmhRBNMkYaPFGU6XNdTJ3h0llGcj n+geWTi5IFRpMgnHPhadKfHdAub24jxt5H06TeCOezNGvyuTo9DaWw6T1Ic1rIHH l9UxQ55AZrQUP0GAJuJyh9ZUdLo0MwuocVfAIkkswbLKk0mh8R/FJbXcVoA10CGp Syh0prFXXy2dG/3ptPaD =LY6l -----END PGP SIGNATURE----- --jZi48drba+QTPlSF-- From owner-svn-src-projects@FreeBSD.ORG Thu Jul 11 03:57:54 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 7F5FBC36; Thu, 11 Jul 2013 03:57:54 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 570FA1E8A; Thu, 11 Jul 2013 03:57:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6B3vs6w010042; Thu, 11 Jul 2013 03:57:54 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6B3vsvN010041; Thu, 11 Jul 2013 03:57:54 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307110357.r6B3vsvN010041@svn.freebsd.org> From: Neel Natu Date: Thu, 11 Jul 2013 03:57:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253182 - projects/bhyve_npt_pmap/sys/amd64/vmm 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: Thu, 11 Jul 2013 03:57:54 -0000 Author: neel Date: Thu Jul 11 03:57:53 2013 New Revision: 253182 URL: http://svnweb.freebsd.org/changeset/base/253182 Log: Don't prevent the process address space from being swapped out while it is trying to resolve a page fault. This could potentially aggravate an already low memory condition and lead to a deadlock. A more detailed explanation is here: http://lists.freebsd.org/pipermail/svn-src-projects/2013-July/007215.html Pointed out by: kib Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Thu Jul 11 03:54:35 2013 (r253181) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Thu Jul 11 03:57:53 2013 (r253182) @@ -445,25 +445,14 @@ vm_gpa_hold(struct vm *vm, vm_paddr_t gp { int rv, pageoff; vm_page_t m; - struct proc *p; pageoff = gpa & PAGE_MASK; if (len > PAGE_SIZE - pageoff) panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len); - p = curthread->td_proc; - - PROC_LOCK(p); - p->p_lock++; - PROC_UNLOCK(p); - rv = vm_fault_hold(&vm->vmspace->vm_map, trunc_page(gpa), reqprot, VM_FAULT_NORMAL, &m); - PROC_LOCK(p); - p->p_lock--; - PROC_UNLOCK(p); - if (rv == KERN_SUCCESS) { *cookie = m; return ((void *)(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)) + pageoff)); @@ -748,8 +737,6 @@ static int vm_handle_paging(struct vm *vm, int vcpuid, boolean_t *retu) { int rv; - struct thread *td; - struct proc *p; struct vm_map *map; vm_prot_t ftype; struct vcpu *vcpu; @@ -758,21 +745,11 @@ vm_handle_paging(struct vm *vm, int vcpu vcpu = &vm->vcpu[vcpuid]; vme = &vcpu->exitinfo; - td = curthread; - p = td->td_proc; map = &vm->vmspace->vm_map; ftype = vme->u.paging.fault_type; - PROC_LOCK(p); - p->p_lock++; - PROC_UNLOCK(p); - rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL); - PROC_LOCK(p); - p->p_lock--; - PROC_UNLOCK(p); - if (rv != KERN_SUCCESS) return (EFAULT); From owner-svn-src-projects@FreeBSD.ORG Thu Jul 11 04:05:03 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]) by hub.freebsd.org (Postfix) with ESMTP id 1F4F273; Thu, 11 Jul 2013 04:05:03 +0000 (UTC) (envelope-from neelnatu@gmail.com) Received: from mail-ie0-x22f.google.com (mail-ie0-x22f.google.com [IPv6:2607:f8b0:4001:c03::22f]) by mx1.freebsd.org (Postfix) with ESMTP id E13A61EC2; Thu, 11 Jul 2013 04:05:02 +0000 (UTC) Received: by mail-ie0-f175.google.com with SMTP id a11so9622664iee.6 for ; Wed, 10 Jul 2013 21:05:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=XkaduLBTqR9voYYFd3M+qD7C2l6PIrKUBWcBmYcR/sA=; b=p3Cf3LUZg4rYzDAL729mWaMiZG+Chsm50yGHqJiOurANXZbewj5Jzit7VXDjgBibhA AhqApyA1AQF8li5aMLS99Po6mw9NTatCgRqkc3wyFfo3W1VjjvchAjWw2sJ/s0U/PZPi xDtPufbvCAkVjmUecRiVh2w1zyNVf0CCV8BGDw6xVLMNymrYneR18mb6NR8s1m75OEFq ba1ohYeBhmtkpJNuDDeUsvnTBcKqJ/RzrJgqAIXfEY8elpILtDHOqzqGcGhZYEMUrTtq +EUE5Ut31IFOSxvVac6S/EK/FcuaNtJGoVmcWLWvqN0/ZpdV3v/yK0b+RvUJtaF+14H5 Xn3Q== MIME-Version: 1.0 X-Received: by 10.42.36.3 with SMTP id s3mr10931601icd.42.1373515502651; Wed, 10 Jul 2013 21:05:02 -0700 (PDT) Received: by 10.42.151.74 with HTTP; Wed, 10 Jul 2013 21:05:02 -0700 (PDT) In-Reply-To: <20130710074839.GZ91021@kib.kiev.ua> References: <201307100712.r6A7CtsB031581@svn.freebsd.org> <20130710072036.GY91021@kib.kiev.ua> <20130710074839.GZ91021@kib.kiev.ua> Date: Wed, 10 Jul 2013 21:05:02 -0700 Message-ID: Subject: Re: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm From: Neel Natu To: Konstantin Belousov Content-Type: text/plain; charset=ISO-8859-1 Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Thu, 11 Jul 2013 04:05:03 -0000 Hi Konstantin, On Wed, Jul 10, 2013 at 12:48 AM, Konstantin Belousov wrote: > On Wed, Jul 10, 2013 at 12:36:38AM -0700, Neel Natu wrote: >> Hi Konstantin, >> >> On Wed, Jul 10, 2013 at 12:20 AM, Konstantin Belousov >> wrote: >> > On Wed, Jul 10, 2013 at 07:12:55AM +0000, Neel Natu wrote: >> >> Author: neel >> >> Date: Wed Jul 10 07:12:55 2013 >> >> New Revision: 253135 >> >> URL: http://svnweb.freebsd.org/changeset/base/253135 >> >> >> >> Log: >> >> Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gpa_release(). >> >> >> >> We guarantee that the vm_page backing the 'gpa' is not reclaimed by >> >> the page daemon until the caller indicates that they are done using it >> >> by calling 'vm_gpa_release()'. >> >> >> >> Modified: >> >> projects/bhyve_npt_pmap/sys/amd64/include/vmm.h >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c >> >> >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h >> >> ============================================================================== >> >> --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06:46:46 2013 (r253134) >> >> +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07:12:55 2013 (r253135) >> >> @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); >> >> int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); >> >> int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); >> >> int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); >> >> +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, >> >> + void **cookie); >> >> +void vm_gpa_release(void *cookie); >> >> vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); >> >> int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, >> >> struct vm_memory_segment *seg); >> >> >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c >> >> ============================================================================== >> >> --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06:46:46 2013 (r253134) >> >> +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07:12:55 2013 (r253135) >> >> @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, >> >> return (0); >> >> } >> >> >> >> -vm_paddr_t >> >> -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) >> >> +void * >> >> +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, >> >> + void **cookie) >> >> { >> >> - vm_paddr_t nextpage; >> >> + int rv, pageoff; >> >> + vm_page_t m; >> >> + struct proc *p; >> >> + >> >> + pageoff = gpa & PAGE_MASK; >> >> + if (len > PAGE_SIZE - pageoff) >> >> + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", gpa, len); >> >> + >> >> + p = curthread->td_proc; >> >> + >> >> + PROC_LOCK(p); >> >> + p->p_lock++; >> >> + PROC_UNLOCK(p); >> > Why do you need to hold the process there ? >> >> I was following the idiom in trap_pfault() - the comment in trap.c >> about swapout was enough to convince me :-) >> >> > I do not think that hold in the trap handler is really useful, probably >> > the reverse. >> >> I am happy to remove the lock if isn't needed. >> >> Could you explain a bit more on why it may be detrimental or point me >> in the right direction so I can look for myself. > The hold prevents the swap out of the process. This means that kernel > stack is assured to be resident for all process threads, and the > vm_pageout_map_deactivate_pages() is not called for the process. In > other words, in the low memory condition, the VM choice of the pages > to reuse is limited, which is probably esp. bad for the large address > spaces like whole virtual machine. > > The swapped-out state of the process interacts correctly with the > vm_fault_hold(), the synchronization of the access to map and objects > would do the right thing. IMO the PHOLD() makes the page fault > potentially faster to proceed by the cost of making the deadlock due to > low memory condition more probable. Thanks for the explanation. I submitted a change to get rid of the 'p_lock'ing when resolving the guest fault. Would the same reasoning lead us to get rid of the 'p_lock' increment in 'trap_pfault()' as well? best Neel From owner-svn-src-projects@FreeBSD.ORG Thu Jul 11 05:01:35 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 0BF6FB3D; Thu, 11 Jul 2013 05:01:35 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) by mx1.freebsd.org (Postfix) with ESMTP id 761501051; Thu, 11 Jul 2013 05:01:34 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.7/8.14.7) with ESMTP id r6B51Tca024115; Thu, 11 Jul 2013 08:01:29 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.8.3 kib.kiev.ua r6B51Tca024115 Received: (from kostik@localhost) by tom.home (8.14.7/8.14.7/Submit) id r6B51TwB024114; Thu, 11 Jul 2013 08:01:29 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 11 Jul 2013 08:01:29 +0300 From: Konstantin Belousov To: Neel Natu Subject: Re: svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm Message-ID: <20130711050129.GJ91021@kib.kiev.ua> References: <201307100712.r6A7CtsB031581@svn.freebsd.org> <20130710072036.GY91021@kib.kiev.ua> <20130710074839.GZ91021@kib.kiev.ua> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="5JjwDxJV2lCoj2Nt" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on tom.home Cc: svn-src-projects@freebsd.org, src-committers@freebsd.org 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: Thu, 11 Jul 2013 05:01:35 -0000 --5JjwDxJV2lCoj2Nt Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jul 10, 2013 at 09:05:02PM -0700, Neel Natu wrote: > Hi Konstantin, >=20 > On Wed, Jul 10, 2013 at 12:48 AM, Konstantin Belousov > wrote: > > On Wed, Jul 10, 2013 at 12:36:38AM -0700, Neel Natu wrote: > >> Hi Konstantin, > >> > >> On Wed, Jul 10, 2013 at 12:20 AM, Konstantin Belousov > >> wrote: > >> > On Wed, Jul 10, 2013 at 07:12:55AM +0000, Neel Natu wrote: > >> >> Author: neel > >> >> Date: Wed Jul 10 07:12:55 2013 > >> >> New Revision: 253135 > >> >> URL: http://svnweb.freebsd.org/changeset/base/253135 > >> >> > >> >> Log: > >> >> Replace vm_gpa2hpa() with a pair of functions vm_gpa_hold()/vm_gp= a_release(). > >> >> > >> >> We guarantee that the vm_page backing the 'gpa' is not reclaimed = by > >> >> the page daemon until the caller indicates that they are done usi= ng it > >> >> by calling 'vm_gpa_release()'. > >> >> > >> >> Modified: > >> >> projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_dev.c > >> >> projects/bhyve_npt_pmap/sys/amd64/vmm/vmm_instruction_emul.c > >> >> > >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/include/vmm.h > >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > >> >> --- projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 06= :46:46 2013 (r253134) > >> >> +++ projects/bhyve_npt_pmap/sys/amd64/include/vmm.h Wed Jul 10 07= :12:55 2013 (r253135) > >> >> @@ -93,6 +93,9 @@ const char *vm_name(struct vm *vm); > >> >> int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); > >> >> int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_padd= r_t hpa); > >> >> int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); > >> >> +void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int pro= t, > >> >> + void **cookie); > >> >> +void vm_gpa_release(void *cookie); > >> >> vm_paddr_t vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t size); > >> >> int vm_gpabase2memseg(struct vm *vm, vm_paddr_t gpabase, > >> >> struct vm_memory_segment *seg); > >> >> > >> >> Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c > >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D > >> >> --- projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 06= :46:46 2013 (r253134) > >> >> +++ projects/bhyve_npt_pmap/sys/amd64/vmm/vmm.c Wed Jul 10 07= :12:55 2013 (r253135) > >> >> @@ -439,16 +439,48 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, > >> >> return (0); > >> >> } > >> >> > >> >> -vm_paddr_t > >> >> -vm_gpa2hpa(struct vm *vm, vm_paddr_t gpa, size_t len) > >> >> +void * > >> >> +vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot, > >> >> + void **cookie) > >> >> { > >> >> - vm_paddr_t nextpage; > >> >> + int rv, pageoff; > >> >> + vm_page_t m; > >> >> + struct proc *p; > >> >> + > >> >> + pageoff =3D gpa & PAGE_MASK; > >> >> + if (len > PAGE_SIZE - pageoff) > >> >> + panic("vm_gpa_hold: invalid gpa/len: 0x%016lx/%lu", g= pa, len); > >> >> + > >> >> + p =3D curthread->td_proc; > >> >> + > >> >> + PROC_LOCK(p); > >> >> + p->p_lock++; > >> >> + PROC_UNLOCK(p); > >> > Why do you need to hold the process there ? > >> > >> I was following the idiom in trap_pfault() - the comment in trap.c > >> about swapout was enough to convince me :-) > >> > >> > I do not think that hold in the trap handler is really useful, proba= bly > >> > the reverse. > >> > >> I am happy to remove the lock if isn't needed. > >> > >> Could you explain a bit more on why it may be detrimental or point me > >> in the right direction so I can look for myself. > > The hold prevents the swap out of the process. This means that kernel > > stack is assured to be resident for all process threads, and the > > vm_pageout_map_deactivate_pages() is not called for the process. In > > other words, in the low memory condition, the VM choice of the pages > > to reuse is limited, which is probably esp. bad for the large address > > spaces like whole virtual machine. > > > > The swapped-out state of the process interacts correctly with the > > vm_fault_hold(), the synchronization of the access to map and objects > > would do the right thing. IMO the PHOLD() makes the page fault > > potentially faster to proceed by the cost of making the deadlock due to > > low memory condition more probable. >=20 > Thanks for the explanation. I submitted a change to get rid of the > 'p_lock'ing when resolving the guest fault. >=20 > Would the same reasoning lead us to get rid of the 'p_lock' increment > in 'trap_pfault()' as well? Yes, I think so. At least, it would remove two pairs of process lock' lock and unlock on the trap path. IMO, the only useful applications of the PHOLD() is when we need to ensure that other process does not exit while we manipulate it, or when the process kstack has to be accessed, e.g. in ptrace(2) to manipulate the trapframe or pcb. For vm_fault() calls, this means that it is enough to use PHOLD to interlock the call to vmspace_acquire_ref(). Other uses are probably vestiges of the time when struct user was swappable. Curproc cannot exit while thread is executing. --5JjwDxJV2lCoj2Nt Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (FreeBSD) iQIcBAEBAgAGBQJR3jwoAAoJEJDCuSvBvK1BkNYQAKmJgtjz35X+s4UrKw6f9XNb OziUOnxbjZsD/07aKsBa+b5ndsvrqtXDwNldrXLjsBWqFFHcLpKvITUTilvZfunm uAAp+2oECzu/7z4xKt1ZjieAluKnzD0cymiLvlQdeZCjMYD/BJCTZN8HwTZvG0TS owm9a3cdQiM28Bl01IzgMKTI8Amm6CecfnN7uw+lU/hTprtMTrN+KR+71OyF5US2 XnQTKnVmB/5+g0DU3pv06a4b9gBV661VKMGlnkjMCz3U/ni1l/atsCnTRbQaNUSp FpM8K5AruiGa/KyxQxx1YVmejTe1mgkj2jEQP2HbAIgzXZ938yXbRCMQA5tnDnvd opDhZzMuqwRyPXWC3bsch6GXb3hkmA/r+mkvGG3FXY/fRArf8cLt7uLtqWDKZZxr fxvmXOh1Z0tcBO9lYU+SLq/v/VI6mjI3ivQUJekLFk905ITwsPRPssqnYxgI5KYR /0nEXpOT4T0icWZ8sx3qFRThBmwc0X/iCQbJpFVpEYEXTGIu+/fl11n6yEyjWxeU 8sMCdgKqE736cc1FzwDJJGXsQlBbMMfgViQCxOHJz17VEJYmt+qFhjRSUU5pl2vT wCMUc4J0DaV6rgAMvJYiBV9ubbttt5fstp78NH7N0gCBEy0JAwCjDVsY6ymDGMW7 pMtJEit2JcY2Py0E9vH7 =exh0 -----END PGP SIGNATURE----- --5JjwDxJV2lCoj2Nt-- From owner-svn-src-projects@FreeBSD.ORG Fri Jul 12 05:58:55 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 6E4BFA08; Fri, 12 Jul 2013 05:58:55 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 5FCF71BA0; Fri, 12 Jul 2013 05:58:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6C5wtTT079083; Fri, 12 Jul 2013 05:58:55 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6C5wt1R079082; Fri, 12 Jul 2013 05:58:55 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307120558.r6C5wt1R079082@svn.freebsd.org> From: Neel Natu Date: Fri, 12 Jul 2013 05:58:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253251 - projects/bhyve_npt_pmap/sys/amd64/vmm/intel 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, 12 Jul 2013 05:58:55 -0000 Author: neel Date: Fri Jul 12 05:58:54 2013 New Revision: 253251 URL: http://svnweb.freebsd.org/changeset/base/253251 Log: Get rid of unused cruft in ept.c. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Fri Jul 12 05:45:09 2013 (r253250) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Fri Jul 12 05:58:54 2013 (r253251) @@ -29,26 +29,19 @@ #include __FBSDID("$FreeBSD$"); +#include #include -#include #include -#include #include #include #include -#include #include -#include -#include -#include -#include - #include + #include "vmx_cpufunc.h" #include "vmx_msr.h" -#include "vmx.h" #include "ept.h" #define EPT_PWL4(cap) ((cap) & (1UL << 6)) @@ -66,17 +59,6 @@ __FBSDID("$FreeBSD$"); #define INVEPT_ALL_TYPES_SUPPORTED(cap) \ (((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK) -#define EPT_PG_RD (1 << 0) -#define EPT_PG_WR (1 << 1) -#define EPT_PG_EX (1 << 2) -#define EPT_PG_MEMORY_TYPE(x) ((x) << 3) -#define EPT_PG_IGNORE_PAT (1 << 6) -#define EPT_PG_SUPERPAGE (1 << 7) - -#define EPT_ADDR_MASK ((uint64_t)-1 << 12) - -MALLOC_DECLARE(M_VMX); - static uint64_t page_sizes_mask; int From owner-svn-src-projects@FreeBSD.ORG Sat Jul 13 01:24:17 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]) by hub.freebsd.org (Postfix) with ESMTP id B0D88265; Sat, 13 Jul 2013 01:24:17 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 9118F1B14; Sat, 13 Jul 2013 01:24:17 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6D1OHaQ025189; Sat, 13 Jul 2013 01:24:17 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6D1OHSR025186; Sat, 13 Jul 2013 01:24:17 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307130124.r6D1OHSR025186@svn.freebsd.org> From: Neel Natu Date: Sat, 13 Jul 2013 01:24:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253313 - in projects/bhyve_npt_pmap/sys/amd64: amd64 include vmm/intel 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: Sat, 13 Jul 2013 01:24:17 -0000 Author: neel Date: Sat Jul 13 01:24:16 2013 New Revision: 253313 URL: http://svnweb.freebsd.org/changeset/base/253313 Log: If the 'PMAP_PDE_SUPERPAGE' bit is not set in 'pm_flags' then the pmap does not support 2MB superpages. We don't allow superpage promotion within these pmaps. The X86 pmaps unconditionally set the PMAP_PDE_SUPERPAGE bit. The EPT pmaps set the PMAP_PDE_SUPERPAGE bit only if the processor advertises 2MB superpages in the EPT. Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c projects/bhyve_npt_pmap/sys/amd64/include/pmap.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 00:53:56 2013 (r253312) +++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 01:24:16 2013 (r253313) @@ -773,6 +773,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr) kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys); CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */ TAILQ_INIT(&kernel_pmap->pm_pvchunk); + kernel_pmap->pm_flags = PMAP_PDE_SUPERPAGE; /* * Initialize the global pv list lock. @@ -1087,6 +1088,16 @@ pmap_cache_mask(pmap_t pmap, boolean_t i return (mask); } +static __inline boolean_t +pmap_ps_enabled(pmap_t pmap) +{ + + if ((pmap->pm_flags & PMAP_PDE_SUPERPAGE) != 0) + return (TRUE); + else + return (FALSE); +} + static void pmap_update_pde_store(pmap_t pmap, pd_entry_t *pde, pd_entry_t newpde) { @@ -1969,6 +1980,7 @@ pmap_pinit0(pmap_t pmap) PCPU_SET(curpmap, pmap); TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + pmap->pm_flags = PMAP_PDE_SUPERPAGE; } /* @@ -1976,7 +1988,7 @@ pmap_pinit0(pmap_t pmap) * such as one in a vmspace structure. */ int -pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type) +pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags) { vm_page_t pml4pg; pt_entry_t PG_A, PG_M; @@ -2021,6 +2033,7 @@ pmap_pinit_type(pmap_t pmap, enum pmap_t CPU_ZERO(&pmap->pm_active); TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + pmap->pm_flags = flags; return (1); } @@ -2029,7 +2042,7 @@ int pmap_pinit(pmap_t pmap) { - return (pmap_pinit_type(pmap, PT_X86)); + return (pmap_pinit_type(pmap, PT_X86, PMAP_PDE_SUPERPAGE)); } /* @@ -3991,7 +4004,8 @@ unchanged: * populated, then attempt promotion. */ if ((mpte == NULL || mpte->wire_count == NPTEPG) && - pg_ps_enabled && (m->flags & PG_FICTITIOUS) == 0 && + pg_ps_enabled && pmap_ps_enabled(pmap) && + (m->flags & PG_FICTITIOUS) == 0 && vm_reserv_level_iffullpop(m) == 0) pmap_promote_pde(pmap, pde, va, &lock); @@ -4105,7 +4119,8 @@ pmap_enter_object(pmap_t pmap, vm_offset va = start + ptoa(diff); if ((va & PDRMASK) == 0 && va + NBPDR <= end && (VM_PAGE_TO_PHYS(m) & PDRMASK) == 0 && - pg_ps_enabled && vm_reserv_level_iffullpop(m) == 0 && + pg_ps_enabled && pmap_ps_enabled(pmap) && + vm_reserv_level_iffullpop(m) == 0 && pmap_enter_pde(pmap, va, m, prot, &lock)) m = &m[NBPDR / PAGE_SIZE - 1]; else @@ -4284,6 +4299,8 @@ pmap_object_init_pt(pmap_t pmap, vm_offs KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); if ((addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) { + if (!pmap_ps_enabled(pmap)) + return; if (!vm_object_populate(object, pindex, pindex + atop(size))) return; p = vm_page_lookup(object, pindex); Modified: projects/bhyve_npt_pmap/sys/amd64/include/pmap.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Sat Jul 13 00:53:56 2013 (r253312) +++ projects/bhyve_npt_pmap/sys/amd64/include/pmap.h Sat Jul 13 01:24:16 2013 (r253313) @@ -259,8 +259,12 @@ struct pmap { struct pmap_statistics pm_stats; /* pmap statistics */ struct vm_radix pm_root; /* spare page table pages */ long pm_eptgen; /* EPT pmap generation id */ + int pm_flags; }; +/* flags */ +#define PMAP_PDE_SUPERPAGE (1 << 0) /* supports 2MB superpages */ + typedef struct pmap *pmap_t; #ifdef _KERNEL @@ -278,7 +282,7 @@ extern struct pmap kernel_pmap_store; #define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx) #define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx) -int pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type); +int pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags); #endif /* Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sat Jul 13 00:53:56 2013 (r253312) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/ept.c Sat Jul 13 01:24:16 2013 (r253313) @@ -59,12 +59,11 @@ __FBSDID("$FreeBSD$"); #define INVEPT_ALL_TYPES_SUPPORTED(cap) \ (((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK) -static uint64_t page_sizes_mask; +static int ept_pmap_flags; int ept_init(void) { - int page_shift; uint64_t cap; cap = rdmsr(MSR_VMX_EPT_VPID_CAP); @@ -84,17 +83,8 @@ ept_init(void) !INVEPT_ALL_TYPES_SUPPORTED(cap)) return (EINVAL); - /* Set bits in 'page_sizes_mask' for each valid page size */ - page_shift = PAGE_SHIFT; - page_sizes_mask = 1UL << page_shift; /* 4KB page */ - - page_shift += 9; if (EPT_PDE_SUPERPAGE(cap)) - page_sizes_mask |= 1UL << page_shift; /* 2MB superpage */ - - page_shift += 9; - if (EPT_PDPTE_SUPERPAGE(cap)) - page_sizes_mask |= 1UL << page_shift; /* 1GB superpage */ + ept_pmap_flags |= PMAP_PDE_SUPERPAGE; /* 2MB superpage */ return (0); } @@ -155,7 +145,7 @@ static int ept_pinit(pmap_t pmap) { - return (pmap_pinit_type(pmap, PT_EPT)); + return (pmap_pinit_type(pmap, PT_EPT, ept_pmap_flags)); } struct vmspace * From owner-svn-src-projects@FreeBSD.ORG Sat Jul 13 07:22:52 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]) by hub.freebsd.org (Postfix) with ESMTP id 830079DD; Sat, 13 Jul 2013 07:22:52 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 757FC15C4; Sat, 13 Jul 2013 07:22:52 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6D7MqTC031478; Sat, 13 Jul 2013 07:22:52 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6D7Mq41031477; Sat, 13 Jul 2013 07:22:52 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201307130722.r6D7Mq41031477@svn.freebsd.org> From: Neel Natu Date: Sat, 13 Jul 2013 07:22:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253317 - projects/bhyve_npt_pmap/sys/amd64/amd64 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: Sat, 13 Jul 2013 07:22:52 -0000 Author: neel Date: Sat Jul 13 07:22:51 2013 New Revision: 253317 URL: http://svnweb.freebsd.org/changeset/base/253317 Log: Use the ternary if operator to simplify pmap_ps_enabled(). Submitted by: alc Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Modified: projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 07:17:18 2013 (r253316) +++ projects/bhyve_npt_pmap/sys/amd64/amd64/pmap.c Sat Jul 13 07:22:51 2013 (r253317) @@ -1092,10 +1092,7 @@ static __inline boolean_t pmap_ps_enabled(pmap_t pmap) { - if ((pmap->pm_flags & PMAP_PDE_SUPERPAGE) != 0) - return (TRUE); - else - return (FALSE); + return ((pmap->pm_flags & PMAP_PDE_SUPERPAGE) != 0); } static void From owner-svn-src-projects@FreeBSD.ORG Sat Jul 13 20:56:09 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id D1C24C42; Sat, 13 Jul 2013 20:56:09 +0000 (UTC) (envelope-from miwi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C2B231F9D; Sat, 13 Jul 2013 20:56:09 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6DKu9Zl064444; Sat, 13 Jul 2013 20:56:09 GMT (envelope-from miwi@svn.freebsd.org) Received: (from miwi@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6DKu9Za064443; Sat, 13 Jul 2013 20:56:09 GMT (envelope-from miwi@svn.freebsd.org) Message-Id: <201307132056.r6DKu9Za064443@svn.freebsd.org> From: Martin Wilke Date: Sat, 13 Jul 2013 20:56:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253329 - projects/portbuild/scripts 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: Sat, 13 Jul 2013 20:56:09 -0000 Author: miwi Date: Sat Jul 13 20:56:09 2013 New Revision: 253329 URL: http://svnweb.freebsd.org/changeset/base/253329 Log: - Replace dependents=$(pkg info -qOr $base) to dependents=$(pkg query "%ro" $base) Modified: projects/portbuild/scripts/buildscript (contents, props changed) Modified: projects/portbuild/scripts/buildscript ============================================================================== --- projects/portbuild/scripts/buildscript Sat Jul 13 19:42:52 2013 (r253328) +++ projects/portbuild/scripts/buildscript Sat Jul 13 20:56:09 2013 (r253329) @@ -1,5 +1,5 @@ #!/bin/sh -# $FreeBSD: ports/Tools/portbuild/scripts/buildscript,v 1.39 2010/06/30 14:51:47 linimon Exp $ +# $FreeBSD$ # client-side script to actually build a package. intended to be run in a jail. @@ -109,7 +109,7 @@ del_pkg() { dependents=$(cat /var/db/pkg/${base}/+REQUIRED_BY 2>/dev/null) pkg_cmd_check="cd /var/db/pkg && test -d" else - dependents=$(pkg info -qOr $base) + dependents=$(pkg query "%ro" $base) pkg_cmd_check="pkg info -qe" fi if [ -n "$dependents" ]; then