summaryrefslogtreecommitdiff
path: root/sys/dev/pv/xen.c
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-04-19 14:19:45 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-04-19 14:19:45 +0000
commit5ea52cf3dc43392042126bdd7a1cd1097081a28f (patch)
treeac6dadafb80293e6d1c83fbcf18316b8817d14e5 /sys/dev/pv/xen.c
parent984e1d98a337bc7e4809cb61ebd60abfbf88b774 (diff)
Allow to grant memory access to domains other than dom0.
Extend xen_grant_table_enter to take an additional "domain" argument and extract it from the upper part of the bus_dmamap_load flags (sigh.) to be able to punch it into the grant table entry. Issue reported by Marco Peereboom who found that we wouldn't run under QubesOS that "chains" VMs. He also did the hard work getting the debug data out of the aforementioned system.
Diffstat (limited to 'sys/dev/pv/xen.c')
-rw-r--r--sys/dev/pv/xen.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c
index 6f57daa490a..117409a5163 100644
--- a/sys/dev/pv/xen.c
+++ b/sys/dev/pv/xen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xen.c,v 1.53 2016/04/19 13:55:19 mikeb Exp $ */
+/* $OpenBSD: xen.c,v 1.54 2016/04/19 14:19:44 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -66,7 +66,8 @@ struct xen_gntent *
xen_grant_table_grow(struct xen_softc *);
int xen_grant_table_alloc(struct xen_softc *, grant_ref_t *);
void xen_grant_table_free(struct xen_softc *, grant_ref_t);
-void xen_grant_table_enter(struct xen_softc *, grant_ref_t, paddr_t, int);
+void xen_grant_table_enter(struct xen_softc *, grant_ref_t, paddr_t,
+ int, int);
void xen_grant_table_remove(struct xen_softc *, grant_ref_t);
void xen_disable_emulated_devices(struct xen_softc *);
@@ -1039,7 +1040,7 @@ xen_grant_table_free(struct xen_softc *sc, grant_ref_t ref)
void
xen_grant_table_enter(struct xen_softc *sc, grant_ref_t ref, paddr_t pa,
- int flags)
+ int domain, int flags)
{
struct xen_gntent *ge;
@@ -1057,7 +1058,7 @@ xen_grant_table_enter(struct xen_softc *sc, grant_ref_t ref, paddr_t pa,
#endif
ref -= ge->ge_start;
ge->ge_table[ref].frame = atop(pa);
- ge->ge_table[ref].domid = 0;
+ ge->ge_table[ref].domid = domain;
virtio_membar_sync();
ge->ge_table[ref].flags = GTF_permit_access | flags;
virtio_membar_sync();
@@ -1160,14 +1161,16 @@ xen_bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
{
struct xen_softc *sc = t->_cookie;
struct xen_gntmap *gm = map->_dm_cookie;
- int i, error;
+ int i, domain, error;
+ domain = flags >> 16;
+ flags &= 0xffff;
error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
if (error)
return (error);
for (i = 0; i < map->dm_nsegs; i++) {
xen_grant_table_enter(sc, gm[i].gm_ref, map->dm_segs[i].ds_addr,
- flags & BUS_DMA_WRITE ? GTF_readonly : 0);
+ domain, flags & BUS_DMA_WRITE ? GTF_readonly : 0);
gm[i].gm_paddr = map->dm_segs[i].ds_addr;
map->dm_segs[i].ds_addr = gm[i].gm_ref;
}
@@ -1180,14 +1183,16 @@ xen_bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
{
struct xen_softc *sc = t->_cookie;
struct xen_gntmap *gm = map->_dm_cookie;
- int i, error;
+ int i, domain, error;
+ domain = flags >> 16;
+ flags &= 0xffff;
error = _bus_dmamap_load_mbuf(t, map, m0, flags);
if (error)
return (error);
for (i = 0; i < map->dm_nsegs; i++) {
xen_grant_table_enter(sc, gm[i].gm_ref, map->dm_segs[i].ds_addr,
- flags & BUS_DMA_WRITE ? GTF_readonly : 0);
+ domain, flags & BUS_DMA_WRITE ? GTF_readonly : 0);
gm[i].gm_paddr = map->dm_segs[i].ds_addr;
map->dm_segs[i].ds_addr = gm[i].gm_ref;
}