| 193 | } |
| 194 | |
| 195 | static int |
| 196 | vmmdev_rw(struct cdev *cdev, struct uio *uio, int flags) |
| 197 | { |
| 198 | int error, off, c, prot; |
| 199 | vm_paddr_t gpa, maxaddr; |
| 200 | void *hpa, *cookie; |
| 201 | struct vmmdev_softc *sc; |
| 202 | uint16_t lastcpu; |
| 203 | |
| 204 | error = vmm_priv_check(curthread->td_ucred); |
| 205 | if (error) |
| 206 | return (error); |
| 207 | |
| 208 | sc = vmmdev_lookup2(cdev); |
| 209 | if (sc == NULL) |
| 210 | return (ENXIO); |
| 211 | |
| 212 | /* |
| 213 | * Get a read lock on the guest memory map by freezing any vcpu. |
| 214 | */ |
| 215 | lastcpu = vm_get_maxcpus(sc->vm) - 1; |
| 216 | error = vcpu_lock_one(sc, lastcpu); |
| 217 | if (error) |
| 218 | return (error); |
| 219 | |
| 220 | prot = (uio->uio_rw == UIO_WRITE ? VM_PROT_WRITE : VM_PROT_READ); |
| 221 | maxaddr = vmm_sysmem_maxaddr(sc->vm); |
| 222 | while (uio->uio_resid > 0 && error == 0) { |
| 223 | gpa = uio->uio_offset; |
| 224 | off = gpa & PAGE_MASK; |
| 225 | c = min(uio->uio_resid, PAGE_SIZE - off); |
| 226 | |
| 227 | /* |
| 228 | * The VM has a hole in its physical memory map. If we want to |
| 229 | * use 'dd' to inspect memory beyond the hole we need to |
| 230 | * provide bogus data for memory that lies in the hole. |
| 231 | * |
| 232 | * Since this device does not support lseek(2), dd(1) will |
| 233 | * read(2) blocks of data to simulate the lseek(2). |
| 234 | */ |
| 235 | hpa = vm_gpa_hold(sc->vm, lastcpu, gpa, c, |
| 236 | prot, &cookie); |
| 237 | if (hpa == NULL) { |
| 238 | if (uio->uio_rw == UIO_READ && gpa < maxaddr) |
| 239 | error = uiomove(__DECONST(void *, zero_region), |
| 240 | c, uio); |
| 241 | else |
| 242 | error = EFAULT; |
| 243 | } else { |
| 244 | error = uiomove(hpa, c, uio); |
| 245 | vm_gpa_release(cookie); |
| 246 | } |
| 247 | } |
| 248 | vcpu_unlock_one(sc, lastcpu); |
| 249 | return (error); |
| 250 | } |
| 251 | |
| 252 | CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= VM_MAX_SUFFIXLEN + 1); |
nothing calls this directly
no test coverage detected