summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstefan <stefan@openbsd.org>2016-04-04 17:13:54 +0000
committerstefan <stefan@openbsd.org>2016-04-04 17:13:54 +0000
commit5d69b7aac31b27b308d4afc471d5f0f069ee195b (patch)
tree045ec8b346bf4e48720c6fdc046db3e12c3156fc
parentDeallocate guest vm_map when the guest gets terminated. (diff)
downloadwireguard-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.c26
-rw-r--r--usr.sbin/vmd/virtio.c44
-rw-r--r--usr.sbin/vmd/vmd.h6
-rw-r--r--usr.sbin/vmd/vmm.c28
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) {