Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/vmm/vmm_dev.c
Show First 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | vmmdev_lookup2(struct cdev *cdev) | ||||
return (cdev->si_drv1); | return (cdev->si_drv1); | ||||
} | } | ||||
static int | static int | ||||
vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) | vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) | ||||
{ | { | ||||
int error, off, c, prot; | int error, off, c, prot; | ||||
vm_paddr_t gpa; | vm_paddr_t gpa, maxaddr; | ||||
void *hpa, *cookie; | void *hpa, *cookie; | ||||
struct vmmdev_softc *sc; | struct vmmdev_softc *sc; | ||||
sc = vmmdev_lookup2(cdev); | sc = vmmdev_lookup2(cdev); | ||||
if (sc == NULL) | if (sc == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
/* | /* | ||||
* Get a read lock on the guest memory map by freezing any vcpu. | * Get a read lock on the guest memory map by freezing any vcpu. | ||||
*/ | */ | ||||
error = vcpu_lock_one(sc, VM_MAXCPU - 1); | error = vcpu_lock_one(sc, VM_MAXCPU - 1); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ); | prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ); | ||||
maxaddr = vmm_sysmem_maxaddr(sc->vm); | |||||
while (uio->uio_resid > 0 && error == 0) { | while (uio->uio_resid > 0 && error == 0) { | ||||
gpa = uio->uio_offset; | gpa = uio->uio_offset; | ||||
off = gpa & PAGE_MASK; | off = gpa & PAGE_MASK; | ||||
c = min(uio->uio_resid, PAGE_SIZE - off); | c = min(uio->uio_resid, PAGE_SIZE - off); | ||||
/* | /* | ||||
* The VM has a hole in its physical memory map. If we want to | * The VM has a hole in its physical memory map. If we want to | ||||
* use 'dd' to inspect memory beyond the hole we need to | * use 'dd' to inspect memory beyond the hole we need to | ||||
* provide bogus data for memory that lies in the hole. | * provide bogus data for memory that lies in the hole. | ||||
* | * | ||||
* Since this device does not support lseek(2), dd(1) will | * Since this device does not support lseek(2), dd(1) will | ||||
* read(2) blocks of data to simulate the lseek(2). | * read(2) blocks of data to simulate the lseek(2). | ||||
*/ | */ | ||||
hpa = vm_gpa_hold(sc->vm, VM_MAXCPU - 1, gpa, c, prot, &cookie); | hpa = vm_gpa_hold(sc->vm, VM_MAXCPU - 1, gpa, c, prot, &cookie); | ||||
if (hpa == NULL) { | if (hpa == NULL) { | ||||
if (uio->uio_rw == UIO_READ) | if (uio->uio_rw == UIO_READ && gpa < maxaddr) | ||||
error = uiomove(__DECONST(void *, zero_region), | error = uiomove(__DECONST(void *, zero_region), | ||||
c, uio); | c, uio); | ||||
else | else | ||||
error = EFAULT; | error = EFAULT; | ||||
} else { | } else { | ||||
error = uiomove(hpa, c, uio); | error = uiomove(hpa, c, uio); | ||||
vm_gpa_release(cookie); | vm_gpa_release(cookie); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 877 Lines • Show Last 20 Lines |