Xen patches

- Avoid mmap race involving Xen's mapcache
 - Fix xenforeignmemory_resource leak at exit
 - Fix xen-block to choose a driver for the disk image when created via
   xenstore.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEE+AwAYwjiLP2KkueYDPVXL9f7Va8FAmCZK+QACgkQDPVXL9f7
 Va+yrggA8vdfm2uRPZPKMrQ9asakyXabox9LGML7GeU5k8xVDuy38kEqWqCW4A78
 L7ubiamj91KR6viHaKNPi+tlpHgJAJNXqUIqqpZoU78J0MJm1dMD4lgAHC9b/FAH
 PVVHGLR5bSSon6qq+LECLlgvokLp7rCru3d/Fi3ISw8jckOPF5xhAEuX4Q8aqDsV
 bk2Sic5CAn2ocHjb2gYHsOH7QZXrJwLamFGpHZjwViJTdTmmNTnZze/dPlq+24hB
 QoVe1fIQOr+BUvzN1N8+1nEGMMTrY9ZVxAxuFMNejyuwyrQ5rvR+9oGiNnP1LNq/
 0tm4XsNOAVTa7TUXWCAm+n0ynZWp7A==
 =aOnW
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20210510' into staging

Xen patches

- Avoid mmap race involving Xen's mapcache
- Fix xenforeignmemory_resource leak at exit
- Fix xen-block to choose a driver for the disk image when created via
  xenstore.

# gpg: Signature made Mon 10 May 2021 13:49:40 BST
# gpg:                using RSA key F80C006308E22CFD8A92E7980CF5572FD7FB55AF
# gpg: Good signature from "Anthony PERARD <anthony.perard@gmail.com>" [unknown]
# gpg:                 aka "Anthony PERARD <anthony.perard@citrix.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 5379 2F71 024C 600F 778A  7161 D8D5 7199 DF83 42C8
#      Subkey fingerprint: F80C 0063 08E2 2CFD 8A92  E798 0CF5 572F D7FB 55AF

* remotes/aperard/tags/pull-xen-20210510:
  xen-block: Use specific blockdev driver
  xen: Free xenforeignmemory_resource at exit
  xen-mapcache: avoid a race on memory map while using MAP_FIXED

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-05-12 08:54:49 +01:00
commit 4f24f774ba
4 changed files with 39 additions and 5 deletions

View file

@ -728,6 +728,8 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
XenBlockDrive *drive = NULL;
QDict *file_layer;
QDict *driver_layer;
struct stat st;
int rc;
if (params) {
char **v = g_strsplit(params, ":", 2);
@ -761,7 +763,17 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
file_layer = qdict_new();
driver_layer = qdict_new();
qdict_put_str(file_layer, "driver", "file");
rc = stat(filename, &st);
if (rc) {
error_setg_errno(errp, errno, "Could not stat file '%s'", filename);
goto done;
}
if (S_ISBLK(st.st_mode)) {
qdict_put_str(file_layer, "driver", "host_device");
} else {
qdict_put_str(file_layer, "driver", "file");
}
qdict_put_str(file_layer, "filename", filename);
g_free(filename);

View file

@ -108,6 +108,7 @@ typedef struct XenIOState {
shared_iopage_t *shared_page;
shared_vmport_iopage_t *shared_vmport_page;
buffered_iopage_t *buffered_io_page;
xenforeignmemory_resource_handle *fres;
QEMUTimer *buffered_io_timer;
CPUState **cpu_by_vcpu_id;
/* the evtchn port for polling the notification, */
@ -1253,6 +1254,9 @@ static void xen_exit_notifier(Notifier *n, void *data)
XenIOState *state = container_of(n, XenIOState, exit);
xen_destroy_ioreq_server(xen_domid, state->ioservid);
if (state->fres != NULL) {
xenforeignmemory_unmap_resource(xen_fmem, state->fres);
}
xenevtchn_close(state->xce_handle);
xs_daemon_close(state->xenstore);
@ -1320,7 +1324,6 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data)
static int xen_map_ioreq_server(XenIOState *state)
{
void *addr = NULL;
xenforeignmemory_resource_handle *fres;
xen_pfn_t ioreq_pfn;
xen_pfn_t bufioreq_pfn;
evtchn_port_t bufioreq_evtchn;
@ -1332,12 +1335,12 @@ static int xen_map_ioreq_server(XenIOState *state)
*/
QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_bufioreq != 0);
QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_ioreq(0) != 1);
fres = xenforeignmemory_map_resource(xen_fmem, xen_domid,
state->fres = xenforeignmemory_map_resource(xen_fmem, xen_domid,
XENMEM_resource_ioreq_server,
state->ioservid, 0, 2,
&addr,
PROT_READ | PROT_WRITE, 0);
if (fres != NULL) {
if (state->fres != NULL) {
trace_xen_map_resource_ioreq(state->ioservid, addr);
state->buffered_io_page = addr;
state->shared_page = addr + TARGET_PAGE_SIZE;

View file

@ -171,7 +171,20 @@ static void xen_remap_bucket(MapCacheEntry *entry,
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
ram_block_notify_remove(entry->vaddr_base, entry->size);
}
if (munmap(entry->vaddr_base, entry->size) != 0) {
/*
* If an entry is being replaced by another mapping and we're using
* MAP_FIXED flag for it - there is possibility of a race for vaddr
* address with another thread doing an mmap call itself
* (see man 2 mmap). To avoid that we skip explicit unmapping here
* and allow the kernel to destroy the previous mappings by replacing
* them in mmap call later.
*
* Non-identical replacements are not allowed therefore.
*/
assert(!vaddr || (entry->vaddr_base == vaddr && entry->size == size));
if (!vaddr && munmap(entry->vaddr_base, entry->size) != 0) {
perror("unmap fails");
exit(-1);
}

View file

@ -134,6 +134,12 @@ static inline xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
return NULL;
}
static inline int xenforeignmemory_unmap_resource(
xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
{
return 0;
}
#endif /* CONFIG_XEN_CTRL_INTERFACE_VERSION < 41100 */
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000