* [PULL for-2.10 2/7] xen_pt_msi.c: Check for xen_host_pci_get_* failures in xen_pt_msix_init()
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 3/7] xen-platform: separate unplugging of NVMe disks Stefano Stabellini
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: anthony.perard, xen-devel, sstabellini, qemu-devel, stefanha
From: Peter Maydell <peter.maydell@linaro.org>
Check the return status of the xen_host_pci_get_* functions we call in
xen_pt_msix_init(), and fail device init if the reads failed rather than
ploughing ahead. (Spotted by Coverity: CID 777338.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
hw/xen/xen_pt_msi.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index 62add06..ff9a79f 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -535,7 +535,11 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
return -1;
}
- xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);
+ rc = xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);
+ if (rc) {
+ XEN_PT_ERR(d, "Failed to read PCI_MSIX_FLAGS field\n");
+ return rc;
+ }
total_entries = control & PCI_MSIX_FLAGS_QSIZE;
total_entries += 1;
@@ -554,7 +558,11 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
+ XC_PAGE_SIZE - 1)
& XC_PAGE_MASK);
- xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
+ rc = xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
+ if (rc) {
+ XEN_PT_ERR(d, "Failed to read PCI_MSIX_TABLE field\n");
+ goto error_out;
+ }
bar_index = msix->bar_index = table_off & PCI_MSIX_FLAGS_BIRMASK;
table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;
msix->table_base = s->real_device.io_regions[bar_index].base_addr;
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PULL for-2.10 3/7] xen-platform: separate unplugging of NVMe disks
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 2/7] xen_pt_msi.c: Check for xen_host_pci_get_* failures in xen_pt_msix_init() Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 4/7] xen: move physmap saving into a separate function Stefano Stabellini
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: sstabellini, qemu-devel, Paul Durrant, stefanha, anthony.perard,
xen-devel
Commit 090fa1c8 "add support for unplugging NVMe disks..." extended the
existing disk unplug flag to cover NVMe disks as well as IDE and SCSI.
The recent thread on the xen-devel mailing list [1] has highlighted that
this is not desirable behaviour: PV frontends should be able to distinguish
NVMe disks from other types of disk and should have separate control over
whether they are unplugged.
This patch defines a new bit in the unplug mask for this purpose (see Xen
commit [2]) and also tidies up the definitions of, and improves the
comments regarding, the previously exiting bits in the protocol.
[1] https://lists.xen.org/archives/html/xen-devel/2017-03/msg02924.html
[2] http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=1096aa02
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
hw/i386/xen/xen_platform.c | 47 ++++++++++++++++++++++++++++++++++------------
1 file changed, 35 insertions(+), 12 deletions(-)
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index f231558..9ba7474 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -87,10 +87,30 @@ static void log_writeb(PCIXenPlatformState *s, char val)
}
}
-/* Xen Platform, Fixed IOPort */
-#define UNPLUG_ALL_DISKS 1
-#define UNPLUG_ALL_NICS 2
-#define UNPLUG_AUX_IDE_DISKS 4
+/*
+ * Unplug device flags.
+ *
+ * The logic got a little confused at some point in the past but this is
+ * what they do now.
+ *
+ * bit 0: Unplug all IDE and SCSI disks.
+ * bit 1: Unplug all NICs.
+ * bit 2: Unplug IDE disks except primary master. This is overridden if
+ * bit 0 is also present in the mask.
+ * bit 3: Unplug all NVMe disks.
+ *
+ */
+#define _UNPLUG_IDE_SCSI_DISKS 0
+#define UNPLUG_IDE_SCSI_DISKS (1u << _UNPLUG_IDE_SCSI_DISKS)
+
+#define _UNPLUG_ALL_NICS 1
+#define UNPLUG_ALL_NICS (1u << _UNPLUG_ALL_NICS)
+
+#define _UNPLUG_AUX_IDE_DISKS 2
+#define UNPLUG_AUX_IDE_DISKS (1u << _UNPLUG_AUX_IDE_DISKS)
+
+#define _UNPLUG_NVME_DISKS 3
+#define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS)
static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
{
@@ -122,7 +142,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
{
uint32_t flags = *(uint32_t *)opaque;
bool aux = (flags & UNPLUG_AUX_IDE_DISKS) &&
- !(flags & UNPLUG_ALL_DISKS);
+ !(flags & UNPLUG_IDE_SCSI_DISKS);
/* We have to ignore passthrough devices */
if (!strcmp(d->name, "xen-pci-passthrough")) {
@@ -135,12 +155,16 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
break;
case PCI_CLASS_STORAGE_SCSI:
- case PCI_CLASS_STORAGE_EXPRESS:
if (!aux) {
object_unparent(OBJECT(d));
}
break;
+ case PCI_CLASS_STORAGE_EXPRESS:
+ if (flags & UNPLUG_NVME_DISKS) {
+ object_unparent(OBJECT(d));
+ }
+
default:
break;
}
@@ -158,10 +182,9 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
switch (addr) {
case 0: {
PCIDevice *pci_dev = PCI_DEVICE(s);
- /* Unplug devices. Value is a bitmask of which devices to
- unplug, with bit 0 the disk devices, bit 1 the network
- devices, and bit 2 the non-primary-master IDE devices. */
- if (val & (UNPLUG_ALL_DISKS | UNPLUG_AUX_IDE_DISKS)) {
+ /* Unplug devices. See comment above flag definitions */
+ if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
+ UNPLUG_NVME_DISKS)) {
DPRINTF("unplug disks\n");
pci_unplug_disks(pci_dev->bus, val);
}
@@ -349,14 +372,14 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
* If VMDP was to control both disk and LAN it would use 4.
* If it controlled just disk or just LAN, it would use 8 below.
*/
- pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS);
+ pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
pci_unplug_nics(pci_dev->bus);
}
break;
case 8:
switch (val) {
case 1:
- pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS);
+ pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
break;
case 2:
pci_unplug_nics(pci_dev->bus);
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PULL for-2.10 4/7] xen: move physmap saving into a separate function
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 2/7] xen_pt_msi.c: Check for xen_host_pci_get_* failures in xen_pt_msix_init() Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 3/7] xen-platform: separate unplugging of NVMe disks Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 5/7] xen/mapcache: add an ability to create dummy mappings Stefano Stabellini
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: Igor Druzhinin, sstabellini, qemu-devel, stefanha, anthony.perard,
xen-devel
From: Igor Druzhinin <igor.druzhinin@citrix.com>
Non-functional change.
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
---
hw/i386/xen/xen-hvm.c | 57 ++++++++++++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 26 deletions(-)
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 3d951a3..277919e 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -304,6 +304,36 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
return start_addr;
}
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+ char path[80], value[17];
+
+ snprintf(path, sizeof(path),
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+ xen_domid, (uint64_t)physmap->phys_offset);
+ snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
+ if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+ return -1;
+ }
+ snprintf(path, sizeof(path),
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+ xen_domid, (uint64_t)physmap->phys_offset);
+ snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
+ if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+ return -1;
+ }
+ if (physmap->name) {
+ snprintf(path, sizeof(path),
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+ xen_domid, (uint64_t)physmap->phys_offset);
+ if (!xs_write(state->xenstore, 0, path,
+ physmap->name, strlen(physmap->name))) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
static int xen_add_to_physmap(XenIOState *state,
hwaddr start_addr,
ram_addr_t size,
@@ -315,7 +345,6 @@ static int xen_add_to_physmap(XenIOState *state,
XenPhysmap *physmap = NULL;
hwaddr pfn, start_gpfn;
hwaddr phys_offset = memory_region_get_ram_addr(mr);
- char path[80], value[17];
const char *mr_name;
if (get_physmapping(state, start_addr, size)) {
@@ -367,31 +396,7 @@ go_physmap:
start_addr >> TARGET_PAGE_BITS,
(start_addr + size - 1) >> TARGET_PAGE_BITS,
XEN_DOMCTL_MEM_CACHEATTR_WB);
-
- snprintf(path, sizeof(path),
- "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
- xen_domid, (uint64_t)phys_offset);
- snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
- if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
- return -1;
- }
- snprintf(path, sizeof(path),
- "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
- xen_domid, (uint64_t)phys_offset);
- snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
- if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
- return -1;
- }
- if (mr_name) {
- snprintf(path, sizeof(path),
- "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
- xen_domid, (uint64_t)phys_offset);
- if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
- return -1;
- }
- }
-
- return 0;
+ return xen_save_physmap(state, physmap);
}
static int xen_remove_from_physmap(XenIOState *state,
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PULL for-2.10 5/7] xen/mapcache: add an ability to create dummy mappings
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
` (2 preceding siblings ...)
2017-07-18 22:22 ` [PULL for-2.10 4/7] xen: move physmap saving into a separate function Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry() Stefano Stabellini
2017-07-18 22:22 ` [PULL for-2.10 7/7] xen: don't use xenstore to save/restore physmap anymore Stefano Stabellini
5 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: Igor Druzhinin, sstabellini, qemu-devel, stefanha, anthony.perard,
xen-devel
From: Igor Druzhinin <igor.druzhinin@citrix.com>
Dummys are simple anonymous mappings that are placed instead
of regular foreign mappings in certain situations when we need
to postpone the actual mapping but still have to give a
memory region to QEMU to play with.
This is planned to be used for restore on Xen.
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
hw/i386/xen/xen-mapcache.c | 44 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index e60156c..39cb511 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
uint8_t *vaddr_base;
unsigned long *valid_mapping;
uint8_t lock;
+#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+ uint8_t flags;
hwaddr size;
struct MapCacheEntry *next;
} MapCacheEntry;
@@ -150,7 +152,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
static void xen_remap_bucket(MapCacheEntry *entry,
hwaddr size,
- hwaddr address_index)
+ hwaddr address_index,
+ bool dummy)
{
uint8_t *vaddr_base;
xen_pfn_t *pfns;
@@ -177,11 +180,25 @@ static void xen_remap_bucket(MapCacheEntry *entry,
pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
}
- vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
- nb_pfn, pfns, err);
- if (vaddr_base == NULL) {
- perror("xenforeignmemory_map");
- exit(-1);
+ if (!dummy) {
+ vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
+ PROT_READ | PROT_WRITE,
+ nb_pfn, pfns, err);
+ if (vaddr_base == NULL) {
+ perror("xenforeignmemory_map");
+ exit(-1);
+ }
+ } else {
+ /*
+ * We create dummy mappings where we are unable to create a foreign
+ * mapping immediately due to certain circumstances (i.e. on resume now)
+ */
+ vaddr_base = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0);
+ if (vaddr_base == NULL) {
+ perror("mmap");
+ exit(-1);
+ }
}
entry->vaddr_base = vaddr_base;
@@ -190,6 +207,12 @@ static void xen_remap_bucket(MapCacheEntry *entry,
entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
+ if (dummy) {
+ entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
+ } else {
+ entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
+ }
+
ram_block_notify_add(entry->vaddr_base, entry->size);
bitmap_zero(entry->valid_mapping, nb_pfn);
for (i = 0; i < nb_pfn; i++) {
@@ -211,6 +234,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
hwaddr cache_size = size;
hwaddr test_bit_size;
bool translated = false;
+ bool dummy = false;
tryagain:
address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
@@ -262,14 +286,14 @@ tryagain:
if (!entry) {
entry = g_malloc0(sizeof (MapCacheEntry));
pentry->next = entry;
- xen_remap_bucket(entry, cache_size, address_index);
+ xen_remap_bucket(entry, cache_size, address_index, dummy);
} else if (!entry->lock) {
if (!entry->vaddr_base || entry->paddr_index != address_index ||
entry->size != cache_size ||
!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- xen_remap_bucket(entry, cache_size, address_index);
+ xen_remap_bucket(entry, cache_size, address_index, dummy);
}
}
@@ -282,6 +306,10 @@ tryagain:
translated = true;
goto tryagain;
}
+ if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
+ dummy = true;
+ goto tryagain;
+ }
trace_xen_map_cache_return(NULL);
return NULL;
}
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry()
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
` (3 preceding siblings ...)
2017-07-18 22:22 ` [PULL for-2.10 5/7] xen/mapcache: add an ability to create dummy mappings Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
2017-07-21 13:50 ` Anthony PERARD
2017-07-18 22:22 ` [PULL for-2.10 7/7] xen: don't use xenstore to save/restore physmap anymore Stefano Stabellini
5 siblings, 1 reply; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: Igor Druzhinin, sstabellini, qemu-devel, stefanha, anthony.perard,
xen-devel
From: Igor Druzhinin <igor.druzhinin@citrix.com>
This new call is trying to update a requested map cache entry
according to the changes in the physmap. The call is searching
for the entry, unmaps it and maps again at the same place using
a new guest address. If the mapping is dummy this call will
make it real.
This function makes use of a new xenforeignmemory_map2() call
with an extended interface that was recently introduced in
libxenforeignmemory [1].
[1] https://www.mail-archive.com/xen-devel@lists.xen.org/msg113007.html
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
configure | 18 +++++++++
hw/i386/xen/xen-mapcache.c | 85 +++++++++++++++++++++++++++++++++++++++----
include/hw/xen/xen_common.h | 14 +++++++
include/sysemu/xen-mapcache.h | 11 +++++-
4 files changed, 119 insertions(+), 9 deletions(-)
diff --git a/configure b/configure
index e8798ce..bad50f5 100755
--- a/configure
+++ b/configure
@@ -2107,6 +2107,24 @@ EOF
# Xen unstable
elif
cat > $TMPC <<EOF &&
+#undef XC_WANT_COMPAT_MAP_FOREIGN_API
+#include <xenforeignmemory.h>
+int main(void) {
+ xenforeignmemory_handle *xfmem;
+
+ xfmem = xenforeignmemory_open(0, 0);
+ xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
+
+ return 0;
+}
+EOF
+ compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
+ then
+ xen_stable_libs="-lxendevicemodel $xen_stable_libs"
+ xen_ctrl_version=41000
+ xen=yes
+ elif
+ cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_DEVICEMODEL_API
#define __XEN_TOOLS__
#include <xendevicemodel.h>
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 39cb511..56986db 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -151,6 +151,7 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
}
static void xen_remap_bucket(MapCacheEntry *entry,
+ void *vaddr,
hwaddr size,
hwaddr address_index,
bool dummy)
@@ -167,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
err = g_malloc0(nb_pfn * sizeof (int));
if (entry->vaddr_base != NULL) {
- ram_block_notify_remove(entry->vaddr_base, entry->size);
+ if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
+ ram_block_notify_remove(entry->vaddr_base, entry->size);
+ }
if (munmap(entry->vaddr_base, entry->size) != 0) {
perror("unmap fails");
exit(-1);
@@ -181,11 +184,11 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
if (!dummy) {
- vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid,
- PROT_READ | PROT_WRITE,
+ vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
+ PROT_READ | PROT_WRITE, 0,
nb_pfn, pfns, err);
if (vaddr_base == NULL) {
- perror("xenforeignmemory_map");
+ perror("xenforeignmemory_map2");
exit(-1);
}
} else {
@@ -193,7 +196,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
* We create dummy mappings where we are unable to create a foreign
* mapping immediately due to certain circumstances (i.e. on resume now)
*/
- vaddr_base = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_SHARED, -1, 0);
if (vaddr_base == NULL) {
perror("mmap");
@@ -201,6 +204,10 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
}
+ if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
+ ram_block_notify_add(vaddr_base, size);
+ }
+
entry->vaddr_base = vaddr_base;
entry->paddr_index = address_index;
entry->size = size;
@@ -213,7 +220,6 @@ static void xen_remap_bucket(MapCacheEntry *entry,
entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
}
- ram_block_notify_add(entry->vaddr_base, entry->size);
bitmap_zero(entry->valid_mapping, nb_pfn);
for (i = 0; i < nb_pfn; i++) {
if (!err[i]) {
@@ -286,14 +292,14 @@ tryagain:
if (!entry) {
entry = g_malloc0(sizeof (MapCacheEntry));
pentry->next = entry;
- xen_remap_bucket(entry, cache_size, address_index, dummy);
+ xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
} else if (!entry->lock) {
if (!entry->vaddr_base || entry->paddr_index != address_index ||
entry->size != cache_size ||
!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- xen_remap_bucket(entry, cache_size, address_index, dummy);
+ xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
}
}
@@ -490,3 +496,66 @@ void xen_invalidate_map_cache(void)
mapcache_unlock();
}
+
+static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size)
+{
+ MapCacheEntry *entry;
+ hwaddr address_index, address_offset;
+ hwaddr test_bit_size, cache_size = size;
+
+ address_index = old_phys_addr >> MCACHE_BUCKET_SHIFT;
+ address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+ assert(size);
+ /* test_bit_size is always a multiple of XC_PAGE_SIZE */
+ test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
+ if (test_bit_size % XC_PAGE_SIZE) {
+ test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
+ }
+ cache_size = size + address_offset;
+ if (cache_size % MCACHE_BUCKET_SIZE) {
+ cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
+ }
+
+ entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+ while (entry && !(entry->paddr_index == address_index &&
+ entry->size == cache_size)) {
+ entry = entry->next;
+ }
+ if (!entry) {
+ DPRINTF("Trying to update an entry for %lx " \
+ "that is not in the mapcache!\n", old_phys_addr);
+ return NULL;
+ }
+
+ address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
+ address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+ fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
+ old_phys_addr, new_phys_addr);
+
+ xen_remap_bucket(entry, entry->vaddr_base,
+ cache_size, address_index, false);
+ if (!test_bits(address_offset >> XC_PAGE_SHIFT,
+ test_bit_size >> XC_PAGE_SHIFT,
+ entry->valid_mapping)) {
+ DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
+ return NULL;
+ }
+
+ return entry->vaddr_base + address_offset;
+}
+
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size)
+{
+ uint8_t *p;
+
+ mapcache_lock();
+ p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, size);
+ mapcache_unlock();
+ return p;
+}
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index e00ddd7..e28ed48 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -78,6 +78,20 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
extern xenforeignmemory_handle *xen_fmem;
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
+
+static inline void *xenforeignmemory_map2(xenforeignmemory_handle *h,
+ uint32_t dom, void *addr,
+ int prot, int flags, size_t pages,
+ const xen_pfn_t arr[/*pages*/],
+ int err[/*pages*/])
+{
+ assert(addr == NULL && flags == 0);
+ return xenforeignmemory_map(h, dom, prot, pages, arr, err);
+}
+
+#endif
+
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40900
typedef xc_interface xendevicemodel_handle;
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 01daaad..bd4d49e 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -21,7 +21,9 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
void xen_invalidate_map_cache_entry(uint8_t *buffer);
void xen_invalidate_map_cache(void);
-
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size);
#else
static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
@@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
{
}
+static inline uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size)
+{
+ abort();
+}
+
#endif
#endif /* XEN_MAPCACHE_H */
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry()
2017-07-18 22:22 ` [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry() Stefano Stabellini
@ 2017-07-21 13:50 ` Anthony PERARD
2017-07-21 18:35 ` Igor Druzhinin
0 siblings, 1 reply; 12+ messages in thread
From: Anthony PERARD @ 2017-07-21 13:50 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: xen-devel, qemu-devel, Igor Druzhinin
On Tue, Jul 18, 2017 at 03:22:41PM -0700, Stefano Stabellini wrote:
> From: Igor Druzhinin <igor.druzhinin@citrix.com>
...
> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
> + hwaddr new_phys_addr,
> + hwaddr size)
> +{
> + MapCacheEntry *entry;
> + hwaddr address_index, address_offset;
> + hwaddr test_bit_size, cache_size = size;
> +
> + address_index = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> + address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> + assert(size);
> + /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> + test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
> + if (test_bit_size % XC_PAGE_SIZE) {
> + test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
> + }
> + cache_size = size + address_offset;
> + if (cache_size % MCACHE_BUCKET_SIZE) {
> + cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
> + }
> +
> + entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> + while (entry && !(entry->paddr_index == address_index &&
> + entry->size == cache_size)) {
> + entry = entry->next;
> + }
> + if (!entry) {
> + DPRINTF("Trying to update an entry for %lx " \
> + "that is not in the mapcache!\n", old_phys_addr);
> + return NULL;
> + }
> +
> + address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> + address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> +
> + fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
> + old_phys_addr, new_phys_addr);
Looks likes this does not build on 32bits.
in: http://logs.test-lab.xenproject.org/osstest/logs/112041/build-i386/6.ts-xen-build.log
/home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c: In function 'xen_replace_cache_entry_unlocked':
/home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' [-Werror=format=]
old_phys_addr, new_phys_addr);
^
/home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13: error: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'hwaddr' [-Werror=format=]
cc1: all warnings being treated as errors
CC i386-softmmu/target/i386/gdbstub.o
/home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/rules.mak:66: recipe for target 'hw/i386/xen/xen-mapcache.o' failed
> +
> + xen_remap_bucket(entry, entry->vaddr_base,
> + cache_size, address_index, false);
> + if (!test_bits(address_offset >> XC_PAGE_SHIFT,
> + test_bit_size >> XC_PAGE_SHIFT,
> + entry->valid_mapping)) {
> + DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
> + return NULL;
> + }
> +
> + return entry->vaddr_base + address_offset;
> +}
> +
--
Anthony PERARD
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry()
2017-07-21 13:50 ` Anthony PERARD
@ 2017-07-21 18:35 ` Igor Druzhinin
2017-07-22 0:28 ` Stefano Stabellini
0 siblings, 1 reply; 12+ messages in thread
From: Igor Druzhinin @ 2017-07-21 18:35 UTC (permalink / raw)
To: Anthony PERARD, Stefano Stabellini; +Cc: xen-devel, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 3344 bytes --]
On 21/07/17 14:50, Anthony PERARD wrote:
> On Tue, Jul 18, 2017 at 03:22:41PM -0700, Stefano Stabellini wrote:
>> From: Igor Druzhinin <igor.druzhinin@citrix.com>
>
> ...
>
>> +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
>> + hwaddr new_phys_addr,
>> + hwaddr size)
>> +{
>> + MapCacheEntry *entry;
>> + hwaddr address_index, address_offset;
>> + hwaddr test_bit_size, cache_size = size;
>> +
>> + address_index = old_phys_addr >> MCACHE_BUCKET_SHIFT;
>> + address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> + assert(size);
>> + /* test_bit_size is always a multiple of XC_PAGE_SIZE */
>> + test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
>> + if (test_bit_size % XC_PAGE_SIZE) {
>> + test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
>> + }
>> + cache_size = size + address_offset;
>> + if (cache_size % MCACHE_BUCKET_SIZE) {
>> + cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
>> + }
>> +
>> + entry = &mapcache->entry[address_index % mapcache->nr_buckets];
>> + while (entry && !(entry->paddr_index == address_index &&
>> + entry->size == cache_size)) {
>> + entry = entry->next;
>> + }
>> + if (!entry) {
>> + DPRINTF("Trying to update an entry for %lx " \
>> + "that is not in the mapcache!\n", old_phys_addr);
>> + return NULL;
>> + }
>> +
>> + address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
>> + address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
>> +
>> + fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
>> + old_phys_addr, new_phys_addr);
>
> Looks likes this does not build on 32bits.
> in: http://logs.test-lab.xenproject.org/osstest/logs/112041/build-i386/6.ts-xen-build.log
>
> /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c: In function 'xen_replace_cache_entry_unlocked':
> /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' [-Werror=format=]
> old_phys_addr, new_phys_addr);
> ^
> /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13: error: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'hwaddr' [-Werror=format=]
> cc1: all warnings being treated as errors
> CC i386-softmmu/target/i386/gdbstub.o
> /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/rules.mak:66: recipe for target 'hw/i386/xen/xen-mapcache.o' failed
>
>> +
>> + xen_remap_bucket(entry, entry->vaddr_base,
>> + cache_size, address_index, false);
>> + if (!test_bits(address_offset >> XC_PAGE_SHIFT,
>> + test_bit_size >> XC_PAGE_SHIFT,
>> + entry->valid_mapping)) {
>> + DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
>> + return NULL;
>> + }
>> +
>> + return entry->vaddr_base + address_offset;
>> +}
>> +
>
Please, accept the attached patch to fix the issue.
Igor
[-- Attachment #2: 0001-xen-fix-compilation-on-32-bit-hosts.patch --]
[-- Type: text/x-patch, Size: 1870 bytes --]
>From 69a3afa453e283e92ddfd76109b203a20a02524c Mon Sep 17 00:00:00 2001
From: Igor Druzhinin <igor.druzhinin@citrix.com>
Date: Fri, 21 Jul 2017 19:27:41 +0100
Subject: [PATCH] xen: fix compilation on 32-bit hosts
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
---
hw/i386/xen/xen-mapcache.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 84cc4a2..540406a 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -529,7 +529,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
entry = entry->next;
}
if (!entry) {
- DPRINTF("Trying to update an entry for %lx " \
+ DPRINTF("Trying to update an entry for "TARGET_FMT_plx \
"that is not in the mapcache!\n", old_phys_addr);
return NULL;
}
@@ -537,15 +537,16 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
- fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
- old_phys_addr, new_phys_addr);
+ fprintf(stderr, "Replacing a dummy mapcache entry for "TARGET_FMT_plx \
+ " with "TARGET_FMT_plx"\n", old_phys_addr, new_phys_addr);
xen_remap_bucket(entry, entry->vaddr_base,
cache_size, address_index, false);
if(!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
+ DPRINTF("Unable to update a mapcache entry for "TARGET_FMT_plx"!\n",
+ old_phys_addr);
return NULL;
}
--
2.7.4
[-- Attachment #3: Type: text/plain, Size: 127 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry()
2017-07-21 18:35 ` Igor Druzhinin
@ 2017-07-22 0:28 ` Stefano Stabellini
0 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-22 0:28 UTC (permalink / raw)
To: Igor Druzhinin; +Cc: Anthony PERARD, xen-devel, Stefano Stabellini, qemu-devel
On Fri, 21 Jul 2017, Igor Druzhinin wrote:
> On 21/07/17 14:50, Anthony PERARD wrote:
> > On Tue, Jul 18, 2017 at 03:22:41PM -0700, Stefano Stabellini wrote:
> > > From: Igor Druzhinin <igor.druzhinin@citrix.com>
> >
> > ...
> >
> > > +static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
> > > + hwaddr new_phys_addr,
> > > + hwaddr size)
> > > +{
> > > + MapCacheEntry *entry;
> > > + hwaddr address_index, address_offset;
> > > + hwaddr test_bit_size, cache_size = size;
> > > +
> > > + address_index = old_phys_addr >> MCACHE_BUCKET_SHIFT;
> > > + address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > > +
> > > + assert(size);
> > > + /* test_bit_size is always a multiple of XC_PAGE_SIZE */
> > > + test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
> > > + if (test_bit_size % XC_PAGE_SIZE) {
> > > + test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
> > > + }
> > > + cache_size = size + address_offset;
> > > + if (cache_size % MCACHE_BUCKET_SIZE) {
> > > + cache_size += MCACHE_BUCKET_SIZE - (cache_size %
> > > MCACHE_BUCKET_SIZE);
> > > + }
> > > +
> > > + entry = &mapcache->entry[address_index % mapcache->nr_buckets];
> > > + while (entry && !(entry->paddr_index == address_index &&
> > > + entry->size == cache_size)) {
> > > + entry = entry->next;
> > > + }
> > > + if (!entry) {
> > > + DPRINTF("Trying to update an entry for %lx " \
> > > + "that is not in the mapcache!\n", old_phys_addr);
> > > + return NULL;
> > > + }
> > > +
> > > + address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
> > > + address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
> > > +
> > > + fprintf(stderr, "Replacing a dummy mapcache entry for %lx with
> > > %lx\n",
> > > + old_phys_addr, new_phys_addr);
> >
> > Looks likes this does not build on 32bits.
> > in:
> > http://logs.test-lab.xenproject.org/osstest/logs/112041/build-i386/6.ts-xen-build.log
> >
> > /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:
> > In function 'xen_replace_cache_entry_unlocked':
> > /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13:
> > error: format '%lx' expects argument of type 'long unsigned int', but
> > argument 3 has type 'hwaddr' [-Werror=format=]
> > old_phys_addr, new_phys_addr);
> > ^
> > /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/hw/i386/xen/xen-mapcache.c:539:13:
> > error: format '%lx' expects argument of type 'long unsigned int', but
> > argument 4 has type 'hwaddr' [-Werror=format=]
> > cc1: all warnings being treated as errors
> > CC i386-softmmu/target/i386/gdbstub.o
> > /home/osstest/build.112041.build-i386/xen/tools/qemu-xen-dir/rules.mak:66:
> > recipe for target 'hw/i386/xen/xen-mapcache.o' failed
> >
> > > +
> > > + xen_remap_bucket(entry, entry->vaddr_base,
> > > + cache_size, address_index, false);
> > > + if (!test_bits(address_offset >> XC_PAGE_SHIFT,
> > > + test_bit_size >> XC_PAGE_SHIFT,
> > > + entry->valid_mapping)) {
> > > + DPRINTF("Unable to update a mapcache entry for %lx!\n",
> > > old_phys_addr);
> > > + return NULL;
> > > + }
> > > +
> > > + return entry->vaddr_base + address_offset;
> > > +}
> > > +
> >
>
> Please, accept the attached patch to fix the issue.
The patch looks good to me. I'll send it upstream.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL for-2.10 7/7] xen: don't use xenstore to save/restore physmap anymore
2017-07-18 22:22 ` [PULL for-2.10 1/7] hw/xen: Set emu_mask for igd_opregion register Stefano Stabellini
` (4 preceding siblings ...)
2017-07-18 22:22 ` [PULL for-2.10 6/7] xen/mapcache: introduce xen_replace_cache_entry() Stefano Stabellini
@ 2017-07-18 22:22 ` Stefano Stabellini
5 siblings, 0 replies; 12+ messages in thread
From: Stefano Stabellini @ 2017-07-18 22:22 UTC (permalink / raw)
To: peter.maydell, stefanha
Cc: Igor Druzhinin, sstabellini, qemu-devel, stefanha, anthony.perard,
xen-devel
From: Igor Druzhinin <igor.druzhinin@citrix.com>
If we have a system with xenforeignmemory_map2() implemented
we don't need to save/restore physmap on suspend/restore
anymore. In case we resume a VM without physmap - try to
recreate the physmap during memory region restore phase and
remap map cache entries accordingly. The old code is left
for compatibility reasons.
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
---
hw/i386/xen/xen-hvm.c | 48 ++++++++++++++++++++++++++++++++++-----------
hw/i386/xen/xen-mapcache.c | 4 +++-
include/hw/xen/xen_common.h | 1 +
3 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 277919e..d9ccd5d 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -288,6 +288,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
return NULL;
}
+#ifdef XEN_COMPAT_PHYSMAP
static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
ram_addr_t size, void *opaque)
{
@@ -333,6 +334,12 @@ static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
}
return 0;
}
+#else
+static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
+{
+ return 0;
+}
+#endif
static int xen_add_to_physmap(XenIOState *state,
hwaddr start_addr,
@@ -367,6 +374,26 @@ go_physmap:
DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
start_addr, start_addr + size);
+ mr_name = memory_region_name(mr);
+
+ physmap = g_malloc(sizeof(XenPhysmap));
+
+ physmap->start_addr = start_addr;
+ physmap->size = size;
+ physmap->name = mr_name;
+ physmap->phys_offset = phys_offset;
+
+ QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+
+ if (runstate_check(RUN_STATE_INMIGRATE)) {
+ /* Now when we have a physmap entry we can replace a dummy mapping with
+ * a real one of guest foreign memory. */
+ uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
+ assert(p && p == memory_region_get_ram_ptr(mr));
+
+ return 0;
+ }
+
pfn = phys_offset >> TARGET_PAGE_BITS;
start_gpfn = start_addr >> TARGET_PAGE_BITS;
for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
@@ -381,17 +408,6 @@ go_physmap:
}
}
- mr_name = memory_region_name(mr);
-
- physmap = g_malloc(sizeof (XenPhysmap));
-
- physmap->start_addr = start_addr;
- physmap->size = size;
- physmap->name = mr_name;
- physmap->phys_offset = phys_offset;
-
- QLIST_INSERT_HEAD(&state->physmap, physmap, list);
-
xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
start_addr >> TARGET_PAGE_BITS,
(start_addr + size - 1) >> TARGET_PAGE_BITS,
@@ -1157,6 +1173,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
xs_daemon_close(state->xenstore);
}
+#ifdef XEN_COMPAT_PHYSMAP
static void xen_read_physmap(XenIOState *state)
{
XenPhysmap *physmap = NULL;
@@ -1204,6 +1221,11 @@ static void xen_read_physmap(XenIOState *state)
}
free(entries);
}
+#else
+static void xen_read_physmap(XenIOState *state)
+{
+}
+#endif
static void xen_wakeup_notifier(Notifier *notifier, void *data)
{
@@ -1330,7 +1352,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
state->bufioreq_local_port = rc;
/* Init RAM management */
+#ifdef XEN_COMPAT_PHYSMAP
xen_map_cache_init(xen_phys_offset_to_gaddr, state);
+#else
+ xen_map_cache_init(NULL, state);
+#endif
xen_ram_init(pcms, ram_size, ram_memory);
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 56986db..2a1fbd1 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -239,7 +239,7 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
hwaddr address_offset;
hwaddr cache_size = size;
hwaddr test_bit_size;
- bool translated = false;
+ bool translated G_GNUC_UNUSED = false;
bool dummy = false;
tryagain:
@@ -307,11 +307,13 @@ tryagain:
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
mapcache->last_entry = NULL;
+#ifdef XEN_COMPAT_PHYSMAP
if (!translated && mapcache->phys_offset_to_gaddr) {
phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
translated = true;
goto tryagain;
}
+#endif
if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
dummy = true;
goto tryagain;
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index e28ed48..86c7f26 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -80,6 +80,7 @@ extern xenforeignmemory_handle *xen_fmem;
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
+#define XEN_COMPAT_PHYSMAP
static inline void *xenforeignmemory_map2(xenforeignmemory_handle *h,
uint32_t dom, void *addr,
int prot, int flags, size_t pages,
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread