From patchwork Fri Jun 30 16:07:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Druzhinin X-Patchwork-Id: 9819997 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EC78F60224 for ; Fri, 30 Jun 2017 16:09:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E71B2285EB for ; Fri, 30 Jun 2017 16:09:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DBB9D28676; Fri, 30 Jun 2017 16:09:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 28405285EB for ; Fri, 30 Jun 2017 16:09:29 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dQySZ-0003l2-4n; Fri, 30 Jun 2017 16:07:55 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dQySY-0003ki-AP for xen-devel@lists.xenproject.org; Fri, 30 Jun 2017 16:07:54 +0000 Received: from [85.158.139.211] by server-13.bemta-5.messagelabs.com id 8B/BD-01732-95776595; Fri, 30 Jun 2017 16:07:53 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrFIsWRWlGSWpSXmKPExsWyU9JRQjeiPCz SYOsZC4vvWyYzOTB6HP5whSWAMYo1My8pvyKBNWN3RwNLwUmHivf/P7A1MH4w6GLk5JAQ8JOY 9XI6O4jNJmAgcWrTIhYQW0TAVmL236nMXYxcHMwCMxglXj5tYANJCAu4SCzZ/4cRxGYRUJWYv PsKmM0r4CnR27uMBWKonMTNc53MIDangJfEjIM/wHqFgGq2Nc2AqheUODnzCVg9s4CExMEXL5 ghatQkjnbtgpqTJtF+/xrrBEa+WUhaZiFpWcDItIpRozi1qCy1SNfQWC+pKDM9oyQ3MTNH19D AVC83tbg4MT01JzGpWC85P3cTIzCsGIBgB+O/bZ6HGCU5mJREeVdeC40U4kvKT6nMSCzOiC8q zUktPsQow8GhJMHLXRYWKSRYlJqeWpGWmQMMcJi0BAePkgivbBBQmre4IDG3ODMdInWK0ZJjw +r1X5g45vzeASRfTfj/jUmIJS8/L1VKnHdHKVCDAEhDRmke3DhYFF5ilJUS5mUEOlCIpyC1KD ezBFX+FaM4B6OSMK8gyFU8mXklcFtfAR3EBHSQ8IwQkINKEhFSUg2MzDuMvsxlFq9ztPntJPa 6M4A3l5cl96V2l+jSrioDsboiqTe77VM1Lk2t/GaXwSycdsXh9rVYr6v/vd+c8Eraxv985TKD 1u5vXK6rRRsZZ/K5MekVzmJVVhJ5sq5G85i5xMupW1e0bS+8uOWEzkbnnyI6q/Ni/v0z9l/08 vH+MJvrmx7sqKtVYinOSDTUYi4qTgQA5Qpuxb0CAAA= X-Env-Sender: prvs=3478c7289=igor.druzhinin@citrix.com X-Msg-Ref: server-5.tower-206.messagelabs.com!1498838872!99237906!1 X-Originating-IP: [185.25.65.24] X-SpamReason: No, hits=0.0 required=7.0 tests=received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 50293 invoked from network); 30 Jun 2017 16:07:52 -0000 Received: from smtp.eu.citrix.com (HELO SMTP.EU.CITRIX.COM) (185.25.65.24) by server-5.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 30 Jun 2017 16:07:52 -0000 X-IronPort-AV: E=Sophos;i="5.40,287,1496102400"; d="scan'208";a="48683293" From: Igor Druzhinin To: , Date: Fri, 30 Jun 2017 17:07:04 +0100 Message-ID: <1498838825-23701-4-git-send-email-igor.druzhinin@citrix.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1498838825-23701-1-git-send-email-igor.druzhinin@citrix.com> References: <1498838825-23701-1-git-send-email-igor.druzhinin@citrix.com> MIME-Version: 1.0 X-ClientProxiedBy: FTLPEX02CAS03.citrite.net (10.13.99.94) To AMSPEX02CL03.citrite.net (10.69.22.127) Cc: anthony.perard@citrix.com, Igor Druzhinin , sstabellini@kernel.org, paul.durrant@citrix.com, pbonzini@redhat.com Subject: [Xen-devel] [PATCH 3/4] xen/mapcache: introduce xen_remap_cache_entry() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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, tries to translate the address and maps again at the same place. If the mapping is dummy this call will make it real. This function makes use of a new xenforeignmemory_map2() call with 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 --- configure | 18 ++++++++ hw/i386/xen/xen-mapcache.c | 105 +++++++++++++++++++++++++++++++++++++++--- include/hw/xen/xen_common.h | 7 +++ include/sysemu/xen-mapcache.h | 6 +++ 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/configure b/configure index c571ad1..ad6156b 100755 --- a/configure +++ b/configure @@ -2021,6 +2021,24 @@ EOF # Xen unstable elif cat > $TMPC < +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 < diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c index 05050de..5d8d990 100644 --- a/hw/i386/xen/xen-mapcache.c +++ b/hw/i386/xen/xen-mapcache.c @@ -149,6 +149,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) @@ -179,11 +180,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 { @@ -191,7 +192,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"); @@ -278,14 +279,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); } } @@ -482,3 +483,95 @@ void xen_invalidate_map_cache(void) mapcache_unlock(); } + +static uint8_t *xen_remap_cache_entry_unlocked(hwaddr phys_addr, hwaddr size) +{ + MapCacheEntry *entry, *pentry = NULL; + hwaddr address_index; + hwaddr address_offset; + hwaddr cache_size = size; + hwaddr test_bit_size; + void *vaddr = NULL; + uint8_t lock; + + address_index = phys_addr >> MCACHE_BUCKET_SHIFT; + address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1); + + /* test_bit_size is always a multiple of XC_PAGE_SIZE */ + if (size) { + test_bit_size = size + (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); + } + } else { + test_bit_size = XC_PAGE_SIZE; + cache_size = MCACHE_BUCKET_SIZE; + } + + /* Search for the requested map cache entry to invalidate */ + entry = &mapcache->entry[address_index % mapcache->nr_buckets]; + while (entry && !(entry->paddr_index == address_index && entry->size == cache_size)) { + pentry = entry; + entry = entry->next; + } + if (!entry) { + DPRINTF("Trying to update an entry for %lx that is not in the mapcache!\n", phys_addr); + return NULL; + } + + vaddr = entry->vaddr_base; + lock = entry->lock; + if (entry->vaddr_base) { + ram_block_notify_remove(entry->vaddr_base, entry->size); + if (munmap(entry->vaddr_base, entry->size) != 0) { + perror("unmap fails"); + exit(-1); + } + } + entry->vaddr_base = NULL; + entry->lock = 0; + + if (mapcache->phys_offset_to_gaddr) { + phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque); + + address_index = phys_addr >> MCACHE_BUCKET_SHIFT; + address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1); + } + + /* Address may have changed so we need to repeat the search */ + entry = &mapcache->entry[address_index % mapcache->nr_buckets]; + while (entry && entry->lock && entry->vaddr_base) { + pentry = entry; + entry = entry->next; + } + if (!entry) { + entry = g_malloc0(sizeof (MapCacheEntry)); + pentry->next = entry; + } + + entry->lock = 0; + xen_remap_bucket(entry, vaddr, 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 an entry for %lx in the mapcache!\n", phys_addr); + return NULL; + } + + entry->lock = lock; + return entry->vaddr_base + address_offset; +} + +uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size) +{ + uint8_t *p; + + mapcache_lock(); + p = xen_remap_cache_entry_unlocked(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..70a5cad 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -78,6 +78,13 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom, extern xenforeignmemory_handle *xen_fmem; +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000 + +#define xenforeignmemory_map2(h, d, a, p, f, ps, ar, e) \ + xenforeignmemory_map(h, d, p, ps, ar, e) + +#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..8c140d0 100644 --- a/include/sysemu/xen-mapcache.h +++ b/include/sysemu/xen-mapcache.h @@ -21,6 +21,7 @@ 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_remap_cache_entry(hwaddr phys_addr, hwaddr size); #else @@ -50,6 +51,11 @@ static inline void xen_invalidate_map_cache(void) { } +static inline uint8_t *xen_remap_cache_entry(hwaddr phys_addr, hwaddr size) +{ + abort(); +} + #endif #endif /* XEN_MAPCACHE_H */