svn commit: r253135 - in projects/bhyve_npt_pmap/sys/amd64: include vmm
Neel Natu
neel at FreeBSD.org
Wed Jul 10 07:12:56 UTC 2013
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;
More information about the svn-src-projects
mailing list