From cd1ba7de230b3a85fb4dba53bb681b7ea626b4eb Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Wed, 18 Jan 2012 12:21:38 +0000 Subject: xen mapcache: check if memory region has moved. This patch changes the xen_map_cache behavior. Before trying to map a guest addr, mapcache will look into the list of range of address that have been moved (physmap/set_memory). There is currently one memory space like this, the vram, "moved" from were it's allocated to were the guest will look into. This help to have a succefull migration. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini --- xen-mapcache.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'xen-mapcache.c') diff --git a/xen-mapcache.c b/xen-mapcache.c index 585b559..a456479 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -78,6 +78,9 @@ typedef struct MapCache { uint8_t *last_address_vaddr; unsigned long max_mcache_size; unsigned int mcache_bucket_shift; + + phys_offset_to_gaddr_t phys_offset_to_gaddr; + void *opaque; } MapCache; static MapCache *mapcache; @@ -91,13 +94,16 @@ static inline int test_bits(int nr, int size, const unsigned long *addr) return 0; } -void xen_map_cache_init(void) +void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque) { unsigned long size; struct rlimit rlimit_as; mapcache = g_malloc0(sizeof (MapCache)); + mapcache->phys_offset_to_gaddr = f; + mapcache->opaque = opaque; + QTAILQ_INIT(&mapcache->locked_entries); mapcache->last_address_index = -1; @@ -193,9 +199,14 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock) { MapCacheEntry *entry, *pentry = NULL; - target_phys_addr_t address_index = phys_addr >> MCACHE_BUCKET_SHIFT; - target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1); + target_phys_addr_t address_index; + target_phys_addr_t address_offset; target_phys_addr_t __size = size; + bool translated = false; + +tryagain: + address_index = phys_addr >> MCACHE_BUCKET_SHIFT; + address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1); trace_xen_map_cache(phys_addr); @@ -237,6 +248,11 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT, entry->valid_mapping)) { mapcache->last_address_index = -1; + if (!translated && mapcache->phys_offset_to_gaddr) { + phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque); + translated = true; + goto tryagain; + } trace_xen_map_cache_return(NULL); return NULL; } -- cgit v1.1