From patchwork Mon Jul 10 22:40:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Druzhinin X-Patchwork-Id: 9833829 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 BB96960393 for ; Mon, 10 Jul 2017 22:42:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ACCBC26CFF for ; Mon, 10 Jul 2017 22:42:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A1314282EC; Mon, 10 Jul 2017 22:42:48 +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 EA11B26CFF for ; Mon, 10 Jul 2017 22:42:47 +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 1dUhM3-0007Br-IX; Mon, 10 Jul 2017 22:40:35 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dUhM2-0007BB-TM for xen-devel@lists.xenproject.org; Mon, 10 Jul 2017 22:40:34 +0000 Received: from [85.158.143.35] by server-10.bemta-6.messagelabs.com id E2/E2-03582-26204695; Mon, 10 Jul 2017 22:40:34 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrFIsWRWlGSWpSXmKPExsWyU9JRQjeRKSX S4N97SYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNePbrXaWgk6PimUNfUwNjCdNuhg5OSQE/CT+ LN7OCGKzCRhInNq0iAXEFhGwlZj9dypzFyMXB7PADEaJl08b2EASwgKeElva14LZLAKqEks+3 2QFsXmB4rP+9DNCDJWTuHmukxnE5hTwklgHVS8EVPP0/Q9GiHpBiZMzn4AtYxaQkDj44gUzRI 2axNGuXSwQc9Ik7p85zzyBkW8WkpZZSFoWMDKtYtQoTi0qSy3SNbLQSyrKTM8oyU3MzNE1NDD Ty00tLk5MT81JTCrWS87P3cQIDCsGINjBeH5t4CFGSQ4mJVHer/uTI4X4kvJTKjMSizPii0pz UosPMcpwcChJ8KYzpkQKCRalpqdWpGXmAAMcJi3BwaMkwrv8M1Arb3FBYm5xZjpE6hSjJceG1 eu/MHHM+b0DSL6a8P8bkxBLXn5eqpQ4bwTIPAGQhozSPLhxsCi8xCgrJczLCHSgEE9BalFuZg mq/CtGcQ5GJWFeTZApPJl5JXBbXwEdxAR0EFtdAshBJYkIKakGRv0r33IC559ZM9M0u9b1u0P NP94f9qtLgi7NO6z6o+OgxVmF/gvxNsrpRZ0P/l4Mu67XtePs/Kx1Qc8ltn/daXCiRWGusLbq 2qKAFxaMc5qf3J2b4sPJYvgw0fD8bIN0D5Eaw6diE+eKrm9v5r65eEl+r7q2t+iMqliZU91L9 Wd3eISZ2X80VGIpzkg01GIuKk4EAE7fKp29AgAA X-Env-Sender: prvs=357aabd99=igor.druzhinin@citrix.com X-Msg-Ref: server-9.tower-21.messagelabs.com!1499726433!72452438!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 9607 invoked from network); 10 Jul 2017 22:40:33 -0000 Received: from smtp.eu.citrix.com (HELO SMTP.EU.CITRIX.COM) (185.25.65.24) by server-9.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 10 Jul 2017 22:40:33 -0000 X-IronPort-AV: E=Sophos;i="5.40,342,1496102400"; d="scan'208";a="49102144" From: Igor Druzhinin To: , Date: Mon, 10 Jul 2017 23:40:02 +0100 Message-ID: <1499726403-10129-4-git-send-email-igor.druzhinin@citrix.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1499726403-10129-1-git-send-email-igor.druzhinin@citrix.com> References: <1499726403-10129-1-git-send-email-igor.druzhinin@citrix.com> MIME-Version: 1.0 X-ClientProxiedBy: FTLPEX02CAS03.citrite.net (10.13.99.94) To AMSPEX02CL01.citrite.net (10.69.22.125) Cc: anthony.perard@citrix.com, Igor Druzhinin , sstabellini@kernel.org, paul.durrant@citrix.com, pbonzini@redhat.com Subject: [Xen-devel] [PATCH v3 3/4] xen/mapcache: introduce xen_replace_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 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 Reviewed-by: Paul Durrant --- 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 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 39cb511..8bc63e0 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..b38962c 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) { } +uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, + hwaddr new_phys_addr, + hwaddr size) +{ + abort(); +} + #endif #endif /* XEN_MAPCACHE_H */