Xen 2016/01/26 with Signed-off-by lines.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJWp6rMAAoJEIlPj0hw4a6Q4KAQAPi9W7kJFSRZxWyBgfdYZv8E
 WUZPPA91XCV7kqe7XrunKYldUCnlNs+TSzP3AGfMVHqF+uw82R4doDCwQqgK/Zx+
 1kXpwrpKhFm9F0Y3q0o5vNLZ+T3JPSHB9HRf6B1XqCOtWDWyowFjg/Iz7ky5H2ad
 +AXcsXjPHIDOuHoM/Lhu/aTb5xAI/EcV1UpDEoDP0guQ8uQDghCxN78B4wITwXXI
 Xy2pRoB1U/o4uHJcp46t1S0YXWdOGdOAhoObMll2XyUqWH2yvwdqpOeRAibF4Oek
 4BQImto9b7MVTc8Z7zMjqJWTSwVU+HmunaACkMOkWfAMWVw53yf84ZpAlv435U1A
 LcZNoS5xqzGgOBZUGVCwL/eL0B6kjWSbToOO9/DhjwFnQz7ODT802+JM2LfTwzFz
 kV9Dve7nloJE0pB3KdpqukA0+e1o5jPT/JvwqteOCxRXKG77W56DcNDJU0Z32R1s
 og1sSY+eVv6A5ET2ioSlP9hnBEVF6ug+QEPt5fuDc+wMxeCyrdArUB16+57wTsfL
 LienlrvZupZaCtypqoO8Px3zQaXWr5bz9x1kSWWy9GwMfs+g+XA/HcANZr7F+JWr
 6a1vbgPJ6y67gLE4pZq0Pmcm7kZtKV4TOsMTUTmpNuhtGbs3wQU+Pw7qch7CnbwQ
 v+yGlaqVuXxmxS5XfH8X
 =PRfJ
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20160126-2' into staging

Xen 2016/01/26 with Signed-off-by lines.

# gpg: Signature made Tue 26 Jan 2016 17:20:12 GMT using RSA key ID 70E1AE90
# gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>"

* remotes/sstabellini/tags/xen-20160126-2:
  xen: make it possible to build without the Xen PV domain builder
  xen: domainbuild: reopen libxenctrl interface after forking for domain watcher.
  xen: Use stable library interfaces when they are available.
  xen: Switch uses of xc_map_foreign_{pages,bulk} to use libxenforeignmemory API.
  xen: Switch uses of xc_map_foreign_range into xc_map_foreign_pages
  xen: Switch to libxengnttab interface for compat shims.
  xen: Switch to libxenevtchn interface for compat shims.
  xen_console: correctly cleanup primary console on teardown.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-01-26 17:25:11 +00:00
commit 39c36a0573
14 changed files with 314 additions and 134 deletions

70
configure vendored
View File

@ -250,6 +250,7 @@ vnc_jpeg=""
vnc_png=""
xen=""
xen_ctrl_version=""
xen_pv_domain_build="no"
xen_pci_passthrough=""
linux_aio=""
cap_ng=""
@ -927,6 +928,10 @@ for opt do
;;
--enable-xen-pci-passthrough) xen_pci_passthrough="yes"
;;
--disable-xen-pv-domain-build) xen_pv_domain_build="no"
;;
--enable-xen-pv-domain-build) xen_pv_domain_build="yes"
;;
--disable-brlapi) brlapi="no"
;;
--enable-brlapi) brlapi="yes"
@ -1938,6 +1943,7 @@ fi
if test "$xen" != "no" ; then
xen_libs="-lxenstore -lxenctrl -lxenguest"
xen_stable_libs="-lxenforeignmemory -lxengnttab -lxenevtchn"
# First we test whether Xen headers and libraries are available.
# If no, we are done and there is no Xen support.
@ -1960,6 +1966,57 @@ EOF
# Xen unstable
elif
cat > $TMPC <<EOF &&
/*
* If we have stable libs the we don't want the libxc compat
* layers, regardless of what CFLAGS we may have been given.
*/
#undef XC_WANT_COMPAT_EVTCHN_API
#undef XC_WANT_COMPAT_GNTTAB_API
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenctrl.h>
#include <xenstore.h>
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenforeignmemory.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
xc_interface *xc = NULL;
xenforeignmemory_handle *xfmem;
xenevtchn_handle *xe;
xengnttab_handle *xg;
xen_domain_handle_t handle;
xs_daemon_open();
xc = xc_interface_open(0, 0, 0);
xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL);
xc_domain_create(xc, 0, handle, 0, NULL, NULL);
xfmem = xenforeignmemory_open(0, 0);
xenforeignmemory_map(xfmem, 0, 0, 0, 0, 0);
xe = xenevtchn_open(0, 0);
xenevtchn_fd(xe);
xg = xengnttab_open(0, 0);
xengnttab_map_grant_ref(xg, 0, 0, 0);
return 0;
}
EOF
compile_prog "" "$xen_libs $xen_stable_libs"
then
xen_ctrl_version=471
xen=yes
elif
cat > $TMPC <<EOF &&
#include <xenctrl.h>
#include <stdint.h>
int main(void) {
@ -2153,6 +2210,9 @@ EOF
fi
if test "$xen" = yes; then
if test $xen_ctrl_version -ge 471 ; then
libs_softmmu="$xen_stable_libs $libs_softmmu"
fi
libs_softmmu="$xen_libs $libs_softmmu"
fi
fi
@ -2174,6 +2234,12 @@ if test "$xen_pci_passthrough" != "no"; then
fi
fi
if test "$xen_pv_domain_build" = "yes" &&
test "$xen" != "yes"; then
error_exit "User requested Xen PV domain builder support" \
"which requires Xen support."
fi
##########################################
# libtool probe
@ -4793,6 +4859,7 @@ fi
echo "xen support $xen"
if test "$xen" = "yes" ; then
echo "xen ctrl version $xen_ctrl_version"
echo "pv dom build $xen_pv_domain_build"
fi
echo "brlapi support $brlapi"
echo "bluez support $bluez"
@ -5164,6 +5231,9 @@ fi
if test "$xen" = "yes" ; then
echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
if test "$xen_pv_domain_build" = "yes" ; then
echo "CONFIG_XEN_PV_DOMAIN_BUILD=y" >> $config_host_mak
fi
fi
if test "$linux_aio" = "yes" ; then
echo "CONFIG_LINUX_AIO=y" >> $config_host_mak

View File

@ -161,11 +161,11 @@ static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
static void destroy_grant(gpointer pgnt)
{
PersistentGrant *grant = pgnt;
XenGnttab gnt = grant->blkdev->xendev.gnttabdev;
xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev;
if (xc_gnttab_munmap(gnt, grant->page, 1) != 0) {
if (xengnttab_unmap(gnt, grant->page, 1) != 0) {
xen_be_printf(&grant->blkdev->xendev, 0,
"xc_gnttab_munmap failed: %s\n",
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
grant->blkdev->persistent_gnt_count--;
@ -178,11 +178,11 @@ static void remove_persistent_region(gpointer data, gpointer dev)
{
PersistentRegion *region = data;
struct XenBlkDev *blkdev = dev;
XenGnttab gnt = blkdev->xendev.gnttabdev;
xengnttab_handle *gnt = blkdev->xendev.gnttabdev;
if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) {
if (xengnttab_unmap(gnt, region->addr, region->num) != 0) {
xen_be_printf(&blkdev->xendev, 0,
"xc_gnttab_munmap region %p failed: %s\n",
"xengnttab_unmap region %p failed: %s\n",
region->addr, strerror(errno));
}
xen_be_printf(&blkdev->xendev, 3,
@ -317,7 +317,7 @@ err:
static void ioreq_unmap(struct ioreq *ioreq)
{
XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
xengnttab_handle *gnt = ioreq->blkdev->xendev.gnttabdev;
int i;
if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
@ -327,8 +327,9 @@ static void ioreq_unmap(struct ioreq *ioreq)
if (!ioreq->pages) {
return;
}
if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
ioreq->blkdev->cnt_map -= ioreq->num_unmap;
@ -338,8 +339,9 @@ static void ioreq_unmap(struct ioreq *ioreq)
if (!ioreq->page[i]) {
continue;
}
if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0) {
xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
if (xengnttab_unmap(gnt, ioreq->page[i], 1) != 0) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
"xengnttab_unmap failed: %s\n",
strerror(errno));
}
ioreq->blkdev->cnt_map--;
@ -351,7 +353,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
static int ioreq_map(struct ioreq *ioreq)
{
XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
xengnttab_handle *gnt = ioreq->blkdev->xendev.gnttabdev;
uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@ -402,7 +404,7 @@ static int ioreq_map(struct ioreq *ioreq)
}
if (batch_maps && new_maps) {
ioreq->pages = xc_gnttab_map_grant_refs
ioreq->pages = xengnttab_map_grant_refs
(gnt, new_maps, domids, refs, ioreq->prot);
if (ioreq->pages == NULL) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
@ -418,7 +420,7 @@ static int ioreq_map(struct ioreq *ioreq)
ioreq->blkdev->cnt_map += new_maps;
} else if (new_maps) {
for (i = 0; i < new_maps; i++) {
ioreq->page[i] = xc_gnttab_map_grant_ref
ioreq->page[i] = xengnttab_map_grant_ref
(gnt, domids[i], refs[i], ioreq->prot);
if (ioreq->page[i] == NULL) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
@ -768,9 +770,9 @@ static void blk_alloc(struct XenDevice *xendev)
if (xen_mode != XEN_EMULATE) {
batch_maps = 1;
}
if (xc_gnttab_set_max_grants(xendev->gnttabdev,
if (xengnttab_set_max_grants(xendev->gnttabdev,
MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
xen_be_printf(xendev, 0, "xc_gnttab_set_max_grants failed: %s\n",
xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
strerror(errno));
}
}
@ -980,7 +982,7 @@ static int blk_connect(struct XenDevice *xendev)
}
}
blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
blkdev->sring = xengnttab_map_grant_ref(blkdev->xendev.gnttabdev,
blkdev->xendev.dom,
blkdev->ring_ref,
PROT_READ | PROT_WRITE);
@ -1045,7 +1047,7 @@ static void blk_disconnect(struct XenDevice *xendev)
xen_be_unbind_evtchn(&blkdev->xendev);
if (blkdev->sring) {
xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
blkdev->cnt_map--;
blkdev->sring = NULL;
}

View File

@ -228,12 +228,12 @@ static int con_initialise(struct XenDevice *xendev)
con->buffer.max_capacity = limit;
if (!xendev->dev) {
con->sring = xc_map_foreign_range(xen_xc, con->xendev.dom,
XC_PAGE_SIZE,
xen_pfn_t mfn = con->ring_ref;
con->sring = xenforeignmemory_map(xen_fmem, con->xendev.dom,
PROT_READ|PROT_WRITE,
con->ring_ref);
1, &mfn, NULL);
} else {
con->sring = xc_gnttab_map_grant_ref(xendev->gnttabdev, con->xendev.dom,
con->sring = xengnttab_map_grant_ref(xendev->gnttabdev, con->xendev.dom,
con->ring_ref,
PROT_READ|PROT_WRITE);
}
@ -265,9 +265,6 @@ static void con_disconnect(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
if (!xendev->dev) {
return;
}
if (con->chr) {
qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(con->chr);
@ -275,12 +272,12 @@ static void con_disconnect(struct XenDevice *xendev)
xen_be_unbind_evtchn(&con->xendev);
if (con->sring) {
if (!xendev->gnttabdev) {
munmap(con->sring, XC_PAGE_SIZE);
if (!xendev->dev) {
xenforeignmemory_unmap(xen_fmem, con->sring, 1);
} else {
xc_gnttab_munmap(xendev->gnttabdev, con->sring, 1);
xengnttab_unmap(xendev->gnttabdev, con->sring, 1);
}
con->sring = NULL;
con->sring = NULL;
}
}

View File

@ -95,23 +95,24 @@ struct XenFB {
static int common_bind(struct common *c)
{
uint64_t mfn;
uint64_t val;
xen_pfn_t mfn;
if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &mfn) == -1)
if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
return -1;
assert(mfn == (xen_pfn_t)mfn);
mfn = (xen_pfn_t)val;
assert(val == mfn);
if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
return -1;
c->page = xc_map_foreign_range(xen_xc, c->xendev.dom,
XC_PAGE_SIZE,
PROT_READ | PROT_WRITE, mfn);
c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
PROT_READ | PROT_WRITE, 1, &mfn, NULL);
if (c->page == NULL)
return -1;
xen_be_bind_evtchn(&c->xendev);
xen_be_printf(&c->xendev, 1, "ring mfn %"PRIx64", remote-port %d, local-port %d\n",
xen_be_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
mfn, c->xendev.remote_port, c->xendev.local_port);
return 0;
@ -121,7 +122,7 @@ static void common_unbind(struct common *c)
{
xen_be_unbind_evtchn(&c->xendev);
if (c->page) {
munmap(c->page, XC_PAGE_SIZE);
xenforeignmemory_unmap(xen_fmem, c->page, 1);
c->page = NULL;
}
}
@ -494,15 +495,15 @@ static int xenfb_map_fb(struct XenFB *xenfb)
fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);
xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
PROT_READ, pgmfns, n_fbdirs);
map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
PROT_READ, n_fbdirs, pgmfns, NULL);
if (map == NULL)
goto out;
xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
munmap(map, n_fbdirs * XC_PAGE_SIZE);
xenforeignmemory_unmap(xen_fmem, map, n_fbdirs);
xenfb->pixels = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
PROT_READ, fbmfns, xenfb->fbpages);
xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
PROT_READ, xenfb->fbpages, fbmfns, NULL);
if (xenfb->pixels == NULL)
goto out;
@ -912,6 +913,7 @@ static void fb_disconnect(struct XenDevice *xendev)
* Replacing the framebuffer with anonymous shared memory
* instead. This releases the guest pages and keeps qemu happy.
*/
xenforeignmemory_unmap(xen_fmem, fb->pixels, fb->fbpages);
fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
-1, 0);

View File

@ -168,7 +168,7 @@ static void net_tx_packets(struct XenNetDev *netdev)
(txreq.flags & NETTXF_more_data) ? " more_data" : "",
(txreq.flags & NETTXF_extra_info) ? " extra_info" : "");
page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
page = xengnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->xendev.dom,
txreq.gref, PROT_READ);
if (page == NULL) {
@ -190,7 +190,7 @@ static void net_tx_packets(struct XenNetDev *netdev)
qemu_send_packet(qemu_get_queue(netdev->nic),
page + txreq.offset, txreq.size);
}
xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
xengnttab_unmap(netdev->xendev.gnttabdev, page, 1);
net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
}
if (!netdev->tx_work) {
@ -260,7 +260,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
netdev->rx_ring.req_cons = ++rc;
page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
page = xengnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->xendev.dom,
rxreq.gref, PROT_WRITE);
if (page == NULL) {
@ -270,7 +270,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
return -1;
}
memcpy(page + NET_IP_ALIGN, buf, size);
xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
xengnttab_unmap(netdev->xendev.gnttabdev, page, 1);
net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
return size;
@ -342,19 +342,19 @@ static int net_connect(struct XenDevice *xendev)
return -1;
}
netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->txs = xengnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->xendev.dom,
netdev->tx_ring_ref,
PROT_READ | PROT_WRITE);
if (!netdev->txs) {
return -1;
}
netdev->rxs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->rxs = xengnttab_map_grant_ref(netdev->xendev.gnttabdev,
netdev->xendev.dom,
netdev->rx_ring_ref,
PROT_READ | PROT_WRITE);
if (!netdev->rxs) {
xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1);
netdev->txs = NULL;
return -1;
}
@ -379,11 +379,11 @@ static void net_disconnect(struct XenDevice *xendev)
xen_be_unbind_evtchn(&netdev->xendev);
if (netdev->txs) {
xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1);
netdev->txs = NULL;
}
if (netdev->rxs) {
xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
netdev->rxs = NULL;
}
}

View File

@ -45,6 +45,7 @@
/* public */
XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
xenforeignmemory_handle *xen_fmem = NULL;
struct xs_handle *xenstore = NULL;
const char *xen_protocol;
@ -243,24 +244,24 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
xendev->debug = debug;
xendev->local_port = -1;
xendev->evtchndev = xen_xc_evtchn_open(NULL, 0);
if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) {
xendev->evtchndev = xenevtchn_open(NULL, 0);
if (xendev->evtchndev == NULL) {
xen_be_printf(NULL, 0, "can't open evtchn device\n");
g_free(xendev);
return NULL;
}
fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
xendev->gnttabdev = xen_xc_gnttab_open(NULL, 0);
if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) {
xendev->gnttabdev = xengnttab_open(NULL, 0);
if (xendev->gnttabdev == NULL) {
xen_be_printf(NULL, 0, "can't open gnttab device\n");
xc_evtchn_close(xendev->evtchndev);
xenevtchn_close(xendev->evtchndev);
g_free(xendev);
return NULL;
}
} else {
xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE;
xendev->gnttabdev = NULL;
}
QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
@ -306,11 +307,11 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
g_free(xendev->fe);
}
if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) {
xc_evtchn_close(xendev->evtchndev);
if (xendev->evtchndev != NULL) {
xenevtchn_close(xendev->evtchndev);
}
if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) {
xc_gnttab_close(xendev->gnttabdev);
if (xendev->gnttabdev != NULL) {
xengnttab_close(xendev->gnttabdev);
}
QTAILQ_REMOVE(&xendevs, xendev, next);
@ -691,13 +692,14 @@ static void xen_be_evtchn_event(void *opaque)
struct XenDevice *xendev = opaque;
evtchn_port_t port;
port = xc_evtchn_pending(xendev->evtchndev);
port = xenevtchn_pending(xendev->evtchndev);
if (port != xendev->local_port) {
xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
xen_be_printf(xendev, 0,
"xenevtchn_pending returned %d (expected %d)\n",
port, xendev->local_port);
return;
}
xc_evtchn_unmask(xendev->evtchndev, port);
xenevtchn_unmask(xendev->evtchndev, port);
if (xendev->ops->event) {
xendev->ops->event(xendev);
@ -716,7 +718,7 @@ int xen_be_init(void)
qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
if (xen_xc == XC_HANDLER_INITIAL_VALUE || xen_fmem == NULL) {
/* Check if xen_init() have been called */
goto err;
}
@ -740,14 +742,14 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
if (xendev->local_port != -1) {
return 0;
}
xendev->local_port = xc_evtchn_bind_interdomain
xendev->local_port = xenevtchn_bind_interdomain
(xendev->evtchndev, xendev->dom, xendev->remote_port);
if (xendev->local_port == -1) {
xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n");
xen_be_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
return -1;
}
xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev),
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
xen_be_evtchn_event, NULL, xendev);
return 0;
}
@ -757,15 +759,15 @@ void xen_be_unbind_evtchn(struct XenDevice *xendev)
if (xendev->local_port == -1) {
return;
}
qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
xendev->local_port = -1;
}
int xen_be_send_notify(struct XenDevice *xendev)
{
return xc_evtchn_notify(xendev->evtchndev, xendev->local_port);
return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
}
/*

View File

@ -1,2 +1,4 @@
# Xen PV machine support
obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
obj-$(CONFIG_XEN) += xen_machine_pv.o
# Xen PV machine builder support
obj-$(CONFIG_XEN_PV_DOMAIN_BUILD) += xen_domainbuild.o

View File

@ -174,12 +174,15 @@ static int xen_domain_watcher(void)
for (i = 3; i < n; i++) {
if (i == fd[0])
continue;
if (i == xc_fd(xen_xc)) {
continue;
}
close(i);
}
/*
* Reopen xc interface, since the original is unsafe after fork
* and was closed above.
*/
xen_xc = xc_interface_open(0, 0, 0);
/* ignore term signals */
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);

View File

@ -30,9 +30,6 @@
static void xen_init_pv(MachineState *machine)
{
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
DriveInfo *dinfo;
int i;
@ -46,17 +43,27 @@ static void xen_init_pv(MachineState *machine)
case XEN_ATTACH:
/* nothing to do, xend handles everything */
break;
case XEN_CREATE:
#ifdef CONFIG_XEN_PV_DOMAIN_BUILD
case XEN_CREATE: {
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
if (xen_domain_build_pv(kernel_filename, initrd_filename,
kernel_cmdline) < 0) {
fprintf(stderr, "xen pv domain creation failed\n");
exit(1);
}
break;
}
#endif
case XEN_EMULATE:
fprintf(stderr, "xen emulation not implemented (yet)\n");
exit(1);
break;
default:
fprintf(stderr, "unhandled xen_mode %d\n", xen_mode);
exit(1);
break;
}
xen_be_register("console", &xen_console_ops);

View File

@ -46,8 +46,8 @@ struct XenDevice {
int remote_port;
int local_port;
XenEvtchn evtchndev;
XenGnttab gnttabdev;
xenevtchn_handle *evtchndev;
xengnttab_handle *gnttabdev;
struct XenDevOps *ops;
QTAILQ_ENTRY(XenDevice) next;
@ -57,6 +57,7 @@ struct XenDevice {
/* variables */
extern XenXC xen_xc;
extern xenforeignmemory_handle *xen_fmem;
extern struct xs_handle *xenstore;
extern const char *xen_protocol;

View File

@ -6,6 +6,15 @@
#include <stddef.h>
#include <inttypes.h>
/*
* If we have new enough libxenctrl then we do not want/need these compat
* interfaces, despite what the user supplied cflags might say. They
* must be undefined before including xenctrl.h
*/
#undef XC_WANT_COMPAT_EVTCHN_API
#undef XC_WANT_COMPAT_GNTTAB_API
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenctrl.h>
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 420
# include <xs.h>
@ -39,23 +48,65 @@ static inline void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
typedef int XenXC;
typedef int XenEvtchn;
typedef int XenGnttab;
typedef int xenevtchn_handle;
typedef int xengnttab_handle;
typedef int xenforeignmemory_handle;
# define XC_INTERFACE_FMT "%i"
# define XC_HANDLER_INITIAL_VALUE -1
static inline XenEvtchn xen_xc_evtchn_open(void *logger,
unsigned int open_flags)
static inline xenevtchn_handle *xenevtchn_open(void *logger,
unsigned int open_flags)
{
return xc_evtchn_open();
xenevtchn_handle *h = malloc(sizeof(*h));
if (!h) {
return NULL;
}
*h = xc_evtchn_open();
if (*h == -1) {
free(h);
h = NULL;
}
return h;
}
static inline int xenevtchn_close(xenevtchn_handle *h)
{
int rc = xc_evtchn_close(*h);
free(h);
return rc;
}
#define xenevtchn_fd(h) xc_evtchn_fd(*h)
#define xenevtchn_pending(h) xc_evtchn_pending(*h)
#define xenevtchn_notify(h, p) xc_evtchn_notify(*h, p)
#define xenevtchn_bind_interdomain(h, d, p) xc_evtchn_bind_interdomain(*h, d, p)
#define xenevtchn_unmask(h, p) xc_evtchn_unmask(*h, p)
#define xenevtchn_unbind(h, p) xc_evtchn_unmask(*h, p)
static inline XenGnttab xen_xc_gnttab_open(void *logger,
unsigned int open_flags)
static inline xengnttab_handle *xengnttab_open(void *logger,
unsigned int open_flags)
{
return xc_gnttab_open();
xengnttab_handle *h = malloc(sizeof(*h));
if (!h) {
return NULL;
}
*h = xc_gnttab_open();
if (*h == -1) {
free(h);
h = NULL;
}
return h;
}
static inline int xengnttab_close(xengnttab_handle *h)
{
int rc = xc_gnttab_close(*h);
free(h);
return rc;
}
#define xengnttab_set_max_grants(h, n) xc_gnttab_set_max_grants(*h, n)
#define xengnttab_map_grant_ref(h, d, r, p) xc_gnttab_map_grant_ref(*h, d, r, p)
#define xengnttab_map_grant_refs(h, c, d, r, p) \
xc_gnttab_map_grant_refs(*h, c, d, r, p)
#define xengnttab_unmap(h, a, n) xc_gnttab_munmap(*h, a, n)
static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger,
unsigned int open_flags)
@ -63,11 +114,7 @@ static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger,
return xc_interface_open();
}
static inline int xc_fd(int xen_xc)
{
return xen_xc;
}
/* See below for xenforeignmemory_* APIs */
static inline int xc_domain_populate_physmap_exact
(XenXC xc_handle, uint32_t domid, unsigned long nr_extents,
@ -104,27 +151,33 @@ static inline void xs_close(struct xs_handle *xsh)
}
/* Xen 4.1 */
#else
/* Xen 4.1 thru 4.6 */
#elif CONFIG_XEN_CTRL_INTERFACE_VERSION < 471
typedef xc_interface *XenXC;
typedef xc_evtchn *XenEvtchn;
typedef xc_gnttab *XenGnttab;
typedef xc_interface *xenforeignmemory_handle;
typedef xc_evtchn xenevtchn_handle;
typedef xc_gnttab xengnttab_handle;
# define XC_INTERFACE_FMT "%p"
# define XC_HANDLER_INITIAL_VALUE NULL
static inline XenEvtchn xen_xc_evtchn_open(void *logger,
unsigned int open_flags)
{
return xc_evtchn_open(logger, open_flags);
}
#define xenevtchn_open(l, f) xc_evtchn_open(l, f);
#define xenevtchn_close(h) xc_evtchn_close(h)
#define xenevtchn_fd(h) xc_evtchn_fd(h)
#define xenevtchn_pending(h) xc_evtchn_pending(h)
#define xenevtchn_notify(h, p) xc_evtchn_notify(h, p)
#define xenevtchn_bind_interdomain(h, d, p) xc_evtchn_bind_interdomain(h, d, p)
#define xenevtchn_unmask(h, p) xc_evtchn_unmask(h, p)
#define xenevtchn_unbind(h, p) xc_evtchn_unbind(h, p)
static inline XenGnttab xen_xc_gnttab_open(void *logger,
unsigned int open_flags)
{
return xc_gnttab_open(logger, open_flags);
}
#define xengnttab_open(l, f) xc_gnttab_open(l, f)
#define xengnttab_close(h) xc_gnttab_close(h)
#define xengnttab_set_max_grants(h, n) xc_gnttab_set_max_grants(h, n)
#define xengnttab_map_grant_ref(h, d, r, p) xc_gnttab_map_grant_ref(h, d, r, p)
#define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
#define xengnttab_map_grant_refs(h, c, d, r, p) \
xc_gnttab_map_grant_refs(h, c, d, r, p)
static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger,
unsigned int open_flags)
@ -132,10 +185,23 @@ static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger,
return xc_interface_open(logger, dombuild_logger, open_flags);
}
/* FIXME There is now way to have the xen fd */
static inline int xc_fd(xc_interface *xen_xc)
/* See below for xenforeignmemory_* APIs */
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 471 */
typedef xc_interface *XenXC;
# define XC_INTERFACE_FMT "%p"
# define XC_HANDLER_INITIAL_VALUE NULL
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenforeignmemory.h>
static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger,
unsigned int open_flags)
{
return -1;
return xc_interface_open(logger, dombuild_logger, open_flags);
}
#endif
@ -439,6 +505,7 @@ static inline int xen_xc_domain_add_to_physmap(XenXC xch, uint32_t domid,
}
#endif
#ifdef CONFIG_XEN_PV_DOMAIN_BUILD
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 470
static inline int xen_domain_create(XenXC xc, uint32_t ssidref,
xen_domain_handle_t handle, uint32_t flags,
@ -453,6 +520,26 @@ static inline int xen_domain_create(XenXC xc, uint32_t ssidref,
{
return xc_domain_create(xc, ssidref, handle, flags, pdomid, NULL);
}
#endif
#endif
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 471
#define xenforeignmemory_open(l, f) &xen_xc
static inline void *xenforeignmemory_map(XenXC *h, uint32_t dom,
int prot, size_t pages,
const xen_pfn_t arr[/*pages*/],
int err[/*pages*/])
{
if (err)
return xc_map_foreign_bulk(*h, dom, prot, arr, err, pages);
else
return xc_map_foreign_pages(*h, dom, prot, arr, pages);
}
#define xenforeignmemory_unmap(h, p, s) munmap(p, s * XC_PAGE_SIZE)
#endif
#endif /* QEMU_HW_XEN_COMMON_H */

View File

@ -118,6 +118,12 @@ static int xen_init(MachineState *ms)
xen_be_printf(NULL, 0, "can't open xen interface\n");
return -1;
}
xen_fmem = xenforeignmemory_open(0, 0);
if (xen_fmem == NULL) {
xen_be_printf(NULL, 0, "can't open xen fmem interface\n");
xc_interface_close(xen_xc);
return -1;
}
qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
global_state_set_optional();

View File

@ -110,7 +110,7 @@ typedef struct XenIOState {
/* evtchn local port for buffered io */
evtchn_port_t bufioreq_local_port;
/* the evtchn fd for polling */
XenEvtchn xce_handle;
xenevtchn_handle *xce_handle;
/* which vcpu we are serving */
int send_vcpu;
@ -717,7 +717,7 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state)
int i;
evtchn_port_t port;
port = xc_evtchn_pending(state->xce_handle);
port = xenevtchn_pending(state->xce_handle);
if (port == state->bufioreq_local_port) {
timer_mod(state->buffered_io_timer,
BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
@ -736,7 +736,7 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state)
}
/* unmask the wanted port again */
xc_evtchn_unmask(state->xce_handle, port);
xenevtchn_unmask(state->xce_handle, port);
/* get the io packet from shared memory */
state->send_vcpu = i;
@ -1043,7 +1043,7 @@ static void handle_buffered_io(void *opaque)
BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
} else {
timer_del(state->buffered_io_timer);
xc_evtchn_unmask(state->xce_handle, state->bufioreq_local_port);
xenevtchn_unmask(state->xce_handle, state->bufioreq_local_port);
}
}
@ -1087,7 +1087,8 @@ static void cpu_handle_ioreq(void *opaque)
}
req->state = STATE_IORESP_READY;
xc_evtchn_notify(state->xce_handle, state->ioreq_local_port[state->send_vcpu]);
xenevtchn_notify(state->xce_handle,
state->ioreq_local_port[state->send_vcpu]);
}
}
@ -1095,8 +1096,8 @@ static void xen_main_loop_prepare(XenIOState *state)
{
int evtchn_fd = -1;
if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) {
evtchn_fd = xc_evtchn_fd(state->xce_handle);
if (state->xce_handle != NULL) {
evtchn_fd = xenevtchn_fd(state->xce_handle);
}
state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io,
@ -1134,7 +1135,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
{
XenIOState *state = container_of(n, XenIOState, exit);
xc_evtchn_close(state->xce_handle);
xenevtchn_close(state->xce_handle);
xs_daemon_close(state->xenstore);
}
@ -1201,8 +1202,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
state = g_malloc0(sizeof (XenIOState));
state->xce_handle = xen_xc_evtchn_open(NULL, 0);
if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
state->xce_handle = xenevtchn_open(NULL, 0);
if (state->xce_handle == NULL) {
perror("xen: event channel open");
goto err;
}
@ -1241,8 +1242,9 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
PROT_READ|PROT_WRITE, ioreq_pfn);
state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
PROT_READ|PROT_WRITE,
1, &ioreq_pfn, NULL);
if (state->shared_page == NULL) {
error_report("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,
errno, xen_xc);
@ -1253,8 +1255,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
if (!rc) {
DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
state->shared_vmport_page =
xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
PROT_READ|PROT_WRITE, ioreq_pfn);
xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
1, &ioreq_pfn, NULL);
if (state->shared_vmport_page == NULL) {
error_report("map shared vmport IO page returned error %d handle="
XC_INTERFACE_FMT, errno, xen_xc);
@ -1266,10 +1268,9 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
goto err;
}
state->buffered_io_page = xc_map_foreign_range(xen_xc, xen_domid,
XC_PAGE_SIZE,
state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
PROT_READ|PROT_WRITE,
bufioreq_pfn);
1, &bufioreq_pfn, NULL);
if (state->buffered_io_page == NULL) {
error_report("map buffered IO page returned error %d", errno);
goto err;
@ -1289,7 +1290,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
/* FIXME: how about if we overflow the page here? */
for (i = 0; i < max_cpus; i++) {
rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
xen_vcpu_eport(state->shared_page, i));
if (rc == -1) {
error_report("shared evtchn %d bind error %d", i, errno);
@ -1298,7 +1299,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
state->ioreq_local_port[i] = rc;
}
rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
bufioreq_evtchn);
if (rc == -1) {
error_report("buffered evtchn bind error %d", errno);

View File

@ -176,10 +176,10 @@ static void xen_remap_bucket(MapCacheEntry *entry,
pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
}
vaddr_base = xc_map_foreign_bulk(xen_xc, xen_domid, PROT_READ|PROT_WRITE,
pfns, err, nb_pfn);
vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
nb_pfn, pfns, err);
if (vaddr_base == NULL) {
perror("xc_map_foreign_bulk");
perror("xenforeignmemory_map");
exit(-1);
}