diff options
author | 2016-04-04 17:13:54 +0000 | |
---|---|---|
committer | 2016-04-04 17:13:54 +0000 | |
commit | 5d69b7aac31b27b308d4afc471d5f0f069ee195b (patch) | |
tree | 045ec8b346bf4e48720c6fdc046db3e12c3156fc | |
parent | Deallocate guest vm_map when the guest gets terminated. (diff) | |
download | wireguard-openbsd-5d69b7aac31b27b308d4afc471d5f0f069ee195b.tar.xz wireguard-openbsd-5d69b7aac31b27b308d4afc471d5f0f069ee195b.zip |
Directly use physical addresses from ELF header for kernel loading.
This allows us to remove the 'do_mask' parameters in read_mem and
write_mem as well as the address mask operaton itself.
ok mlarkin@
-rw-r--r-- | usr.sbin/vmd/loadfile_elf.c | 26 | ||||
-rw-r--r-- | usr.sbin/vmd/virtio.c | 44 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.h | 6 | ||||
-rw-r--r-- | usr.sbin/vmd/vmm.c | 28 |
4 files changed, 40 insertions, 64 deletions
diff --git a/usr.sbin/vmd/loadfile_elf.c b/usr.sbin/vmd/loadfile_elf.c index 2c51e199c03..10a5ad80d83 100644 --- a/usr.sbin/vmd/loadfile_elf.c +++ b/usr.sbin/vmd/loadfile_elf.c @@ -1,5 +1,5 @@ /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ -/* $OpenBSD: loadfile_elf.c,v 1.11 2016/03/13 13:11:47 stefan Exp $ */ +/* $OpenBSD: loadfile_elf.c,v 1.12 2016/04/04 17:13:54 stefan Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -191,7 +191,7 @@ push_gdt(void) setsegment(&sd[1], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 1, 1); setsegment(&sd[2], 0, 0xffffffff, SDT_MEMRWA, SEL_KPL, 1, 1); - write_mem(GDT_PAGE, gdtpage, PAGE_SIZE, 1); + write_mem(GDT_PAGE, gdtpage, PAGE_SIZE); } /* @@ -338,7 +338,7 @@ push_bootargs(bios_memmap_t *memmap, size_t n) ba[i + 2] = consdev_sz; memcpy(&ba[i + 3], &consdev, sizeof(bios_consdev_t)); - write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE, 1); + write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE); return (memmap_sz + consdev_sz); } @@ -386,7 +386,7 @@ push_stack(uint32_t bootargsz, uint32_t end) stack[--loc] = MAKEBOOTDEV(0x4, 0, 0, 0, 0); /* bootdev: sd0a */ stack[--loc] = 0x0; - write_mem(STACK_PAGE, &stack, PAGE_SIZE, 1); + write_mem(STACK_PAGE, &stack, PAGE_SIZE); return (1024 - (loc - 1)) * sizeof(uint32_t); } @@ -432,7 +432,7 @@ mread(int fd, paddr_t addr, size_t sz) } rd += ct; - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return (0); addr += ct; @@ -456,7 +456,7 @@ mread(int fd, paddr_t addr, size_t sz) } rd += ct; - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return (0); } @@ -493,7 +493,7 @@ marc4random_buf(paddr_t addr, int sz) arc4random_buf(buf, ct); - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return; addr += ct; @@ -508,7 +508,7 @@ marc4random_buf(paddr_t addr, int sz) arc4random_buf(buf, ct); - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return; } } @@ -541,7 +541,7 @@ mbzero(paddr_t addr, int sz) if (addr % PAGE_SIZE != 0) { ct = PAGE_SIZE - (addr % PAGE_SIZE); - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return; addr += ct; @@ -553,7 +553,7 @@ mbzero(paddr_t addr, int sz) else ct = PAGE_SIZE; - if (write_mem(addr, buf, ct, 1)) + if (write_mem(addr, buf, ct)) return; } } @@ -665,8 +665,7 @@ elf64_exec(int fd, Elf64_Ehdr *elf, u_long *marks, int flags) free(phdr); return 1; } - if (mread(fd, (phdr[i].p_paddr - - 0xffffffff80000000ULL), phdr[i].p_filesz) != + if (mread(fd, phdr[i].p_paddr, phdr[i].p_filesz) != phdr[i].p_filesz) { free(phdr); return 1; @@ -687,8 +686,7 @@ elf64_exec(int fd, Elf64_Ehdr *elf, u_long *marks, int flags) /* Zero out BSS. */ if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { - mbzero((phdr[i].p_paddr - - 0xffffffff80000000 + phdr[i].p_filesz), + mbzero((phdr[i].p_paddr + phdr[i].p_filesz), phdr[i].p_memsz - phdr[i].p_filesz); } if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c index 43a19777980..3164766866f 100644 --- a/usr.sbin/vmd/virtio.c +++ b/usr.sbin/vmd/virtio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio.c,v 1.10 2016/03/13 13:11:47 stefan Exp $ */ +/* $OpenBSD: virtio.c,v 1.11 2016/04/04 17:13:54 stefan Exp $ */ /* * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> @@ -172,7 +172,7 @@ viornd_notifyq(void) memset(buf, 0, vr_sz); - if (read_mem(q_gpa, buf, vr_sz, 0)) { + if (read_mem(q_gpa, buf, vr_sz)) { free(buf); return (0); } @@ -189,7 +189,7 @@ viornd_notifyq(void) if (rnd_data != NULL) { arc4random_buf(rnd_data, desc[avail->ring[avail->idx]].len); if (write_mem(desc[avail->ring[avail->idx]].addr, - rnd_data, desc[avail->ring[avail->idx]].len, 0)) { + rnd_data, desc[avail->ring[avail->idx]].len)) { log_warnx("viornd: can't write random data @ " "0x%llx", desc[avail->ring[avail->idx]].addr); @@ -203,7 +203,7 @@ viornd_notifyq(void) desc[avail->ring[avail->idx]].len; used->idx++; - if (write_mem(q_gpa, buf, vr_sz, 0)) { + if (write_mem(q_gpa, buf, vr_sz)) { log_warnx("viornd: error writing vio ring"); } } @@ -384,7 +384,7 @@ vioblk_notifyq(struct vioblk_dev *dev) memset(vr, 0, vr_sz); - if (read_mem(q_gpa, vr, vr_sz, 0)) { + if (read_mem(q_gpa, vr, vr_sz)) { log_warnx("error reading gpa 0x%llx", q_gpa); free(vr); return (0); @@ -417,7 +417,7 @@ vioblk_notifyq(struct vioblk_dev *dev) } /* Read command from descriptor ring */ - if (read_mem(cmd_desc->addr, &cmd, cmd_desc->len, 0)) { + if (read_mem(cmd_desc->addr, &cmd, cmd_desc->len)) { log_warnx("vioblk: command read_mem error @ 0x%llx", cmd_desc->addr); free(vr); @@ -454,7 +454,7 @@ vioblk_notifyq(struct vioblk_dev *dev) } if (write_mem(secdata_desc->addr, secdata, - secdata_desc->len, 0)) { + secdata_desc->len)) { log_warnx("can't write sector " "data to gpa @ 0x%llx", secdata_desc->addr); @@ -476,7 +476,7 @@ vioblk_notifyq(struct vioblk_dev *dev) ds_desc = secdata_desc; ds = VIRTIO_BLK_S_OK; - if (write_mem(ds_desc->addr, &ds, ds_desc->len, 0)) { + if (write_mem(ds_desc->addr, &ds, ds_desc->len)) { log_warnx("can't write device status data @ " "0x%llx", ds_desc->addr); dump_descriptor_chain(desc, cmd_desc_idx); @@ -494,7 +494,7 @@ vioblk_notifyq(struct vioblk_dev *dev) dev->vq[dev->cfg.queue_notify].last_avail = avail->idx & VIOBLK_QUEUE_MASK; - if (write_mem(q_gpa, vr, vr_sz, 0)) { + if (write_mem(q_gpa, vr, vr_sz)) { log_warnx("vioblk: error writing vio ring"); } break; @@ -520,7 +520,7 @@ vioblk_notifyq(struct vioblk_dev *dev) secbias = 0; do { if (read_mem(secdata_desc->addr, secdata, - secdata_desc->len, 0)) { + secdata_desc->len)) { log_warnx("wr vioblk: can't read " "sector data @ 0x%llx", secdata_desc->addr); @@ -551,7 +551,7 @@ vioblk_notifyq(struct vioblk_dev *dev) ds_desc = secdata_desc; ds = VIRTIO_BLK_S_OK; - if (write_mem(ds_desc->addr, &ds, ds_desc->len, 0)) { + if (write_mem(ds_desc->addr, &ds, ds_desc->len)) { log_warnx("wr vioblk: can't write device status " "data @ 0x%llx", ds_desc->addr); dump_descriptor_chain(desc, cmd_desc_idx); @@ -567,7 +567,7 @@ vioblk_notifyq(struct vioblk_dev *dev) dev->vq[dev->cfg.queue_notify].last_avail = avail->idx & VIOBLK_QUEUE_MASK; - if (write_mem(q_gpa, vr, vr_sz, 0)) + if (write_mem(q_gpa, vr, vr_sz)) log_warnx("wr vioblk: error writing vio ring"); break; case VIRTIO_BLK_T_FLUSH: @@ -576,7 +576,7 @@ vioblk_notifyq(struct vioblk_dev *dev) ds_desc = &desc[ds_desc_idx]; ds = VIRTIO_BLK_S_OK; - if (write_mem(ds_desc->addr, &ds, ds_desc->len, 0)) { + if (write_mem(ds_desc->addr, &ds, ds_desc->len)) { log_warnx("fl vioblk: can't write device status " "data @ 0x%llx", ds_desc->addr); dump_descriptor_chain(desc, cmd_desc_idx); @@ -592,7 +592,7 @@ vioblk_notifyq(struct vioblk_dev *dev) dev->vq[dev->cfg.queue_notify].last_avail = avail->idx & VIOBLK_QUEUE_MASK; - if (write_mem(q_gpa, vr, vr_sz, 0)) { + if (write_mem(q_gpa, vr, vr_sz)) { log_warnx("fl vioblk: error writing vio ring"); } break; @@ -804,7 +804,7 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc) memset(vr, 0, vr_sz); - if (read_mem(q_gpa, vr, vr_sz, 0)) { + if (read_mem(q_gpa, vr, vr_sz)) { log_warnx("rx enq: error reading gpa 0x%llx", q_gpa); free(vr); return (0); @@ -840,7 +840,7 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc) } /* Write packet to descriptor ring */ - if (write_mem(pkt_desc->addr, pkt, sz, 0)) { + if (write_mem(pkt_desc->addr, pkt, sz)) { log_warnx("vionet: rx enq packet write_mem error @ " "0x%llx", pkt_desc->addr); free(vr); @@ -854,7 +854,7 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc) used->idx++; dev->vq[0].last_avail = (dev->vq[0].last_avail + 1); *spc = avail->idx - dev->vq[0].last_avail; - if (write_mem(q_gpa, vr, vr_sz, 0)) { + if (write_mem(q_gpa, vr, vr_sz)) { log_warnx("vionet: error writing vio ring"); } @@ -930,7 +930,7 @@ vionet_notify_rx(struct vionet_dev *dev) memset(vr, 0, vr_sz); - if (read_mem(q_gpa, vr, vr_sz, 0)) { + if (read_mem(q_gpa, vr, vr_sz)) { log_warnx("error reading gpa 0x%llx", q_gpa); free(vr); return; @@ -991,7 +991,7 @@ vionet_notifyq(struct vionet_dev *dev) memset(vr, 0, vr_sz); - if (read_mem(q_gpa, vr, vr_sz, 0)) { + if (read_mem(q_gpa, vr, vr_sz)) { log_warnx("error reading gpa 0x%llx", q_gpa); goto out; } @@ -1053,7 +1053,7 @@ vionet_notifyq(struct vionet_dev *dev) /* Read packet from descriptor ring */ if (read_mem(pkt_desc->addr, pkt + ofs, - pkt_desc->len, 0)) { + pkt_desc->len)) { log_warnx("vionet: packet read_mem error " "@ 0x%llx", pkt_desc->addr); goto out; @@ -1073,7 +1073,7 @@ vionet_notifyq(struct vionet_dev *dev) /* Read packet from descriptor ring */ if (read_mem(pkt_desc->addr, pkt + ofs, - pkt_desc->len, 0)) { + pkt_desc->len)) { log_warnx("vionet: packet read_mem error @ " "0x%llx", pkt_desc->addr); goto out; @@ -1100,7 +1100,7 @@ vionet_notifyq(struct vionet_dev *dev) VIONET_QUEUE_MASK; } - if (write_mem(q_gpa, vr, vr_sz, 0)) { + if (write_mem(q_gpa, vr, vr_sz)) { log_warnx("vionet: tx error writing vio ring"); } diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h index 2d52ac87a44..9bb309b8ec7 100644 --- a/usr.sbin/vmd/vmd.h +++ b/usr.sbin/vmd/vmd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.h,v 1.19 2016/03/13 13:11:47 stefan Exp $ */ +/* $OpenBSD: vmd.h,v 1.20 2016/04/04 17:13:54 stefan Exp $ */ /* * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> @@ -114,8 +114,8 @@ char *get_string(uint8_t *, size_t); /* vmm.c */ pid_t vmm(struct privsep *, struct privsep_proc *); -int write_mem(paddr_t, void *buf, size_t, int); -int read_mem(paddr_t, void *buf, size_t, int); +int write_mem(paddr_t, void *buf, size_t); +int read_mem(paddr_t, void *buf, size_t); int opentap(void); /* control.c */ diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c index 3f1a3653e09..521a08beb7f 100644 --- a/usr.sbin/vmd/vmm.c +++ b/usr.sbin/vmd/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.23 2016/03/13 13:11:47 stefan Exp $ */ +/* $OpenBSD: vmm.c,v 1.24 2016/04/04 17:13:54 stefan Exp $ */ /* * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> @@ -1544,30 +1544,19 @@ vcpu_exit(struct vm_run_params *vrp) * in the guest's address space) * buf: data to push * len: size of 'buf' - * do_mask: 1 to mask the destination address (for kernel load), 0 to - * leave 'dst' unmasked * * Return values: * various return values from ioctl(VMM_IOC_WRITEPAGE), or 0 if no error * occurred. - * - * Note - this function only handles GPAs < 4GB. */ int -write_mem(paddr_t dst, void *buf, size_t len, int do_mask) +write_mem(paddr_t dst, void *buf, size_t len) { char *p = buf; size_t n, left; paddr_t gpa; struct vm_writepage_params vwp; - /* - * Mask kernel load addresses to avoid uint32_t -> uint64_t cast - * errors - */ - if (do_mask) - dst &= 0xFFFFFFF; - left = len; for (gpa = dst; gpa < dst + len; gpa = (gpa & ~PAGE_MASK) + PAGE_SIZE) { @@ -1603,30 +1592,19 @@ write_mem(paddr_t dst, void *buf, size_t len, int do_mask) * src: the source paddr_t in the guest VM to read from. * buf: destination (local) buffer * len: size of 'buf' - * do_mask: 1 to mask the source address (for kernel load), 0 to - * leave 'src' unmasked * * Return values: * various return values from ioctl(VMM_IOC_READPAGE), or 0 if no error * occurred. - * - * Note - this function only handles GPAs < 4GB. */ int -read_mem(paddr_t src, void *buf, size_t len, int do_mask) +read_mem(paddr_t src, void *buf, size_t len) { char *p = buf; size_t n, left; paddr_t gpa; struct vm_readpage_params vrp; - /* - * Mask kernel load addresses to avoid uint32_t -> uint64_t cast - * errors - */ - if (do_mask) - src &= 0xFFFFFFF; - left = len; for (gpa = src; gpa < src + len; gpa = (gpa & ~PAGE_MASK) + PAGE_SIZE) { |