From patchwork Thu Jan 12 14:58:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 9513355 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 9BF9460476 for ; Thu, 12 Jan 2017 15:01:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8DDBE286D3 for ; Thu, 12 Jan 2017 15:01:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8287F286DF; Thu, 12 Jan 2017 15:01:27 +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 931DB286D3 for ; Thu, 12 Jan 2017 15:01:26 +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 1cRgq4-0005W9-C5; Thu, 12 Jan 2017 14:58:52 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cRgq3-0005Ui-6O for xen-devel@lists.xenproject.org; Thu, 12 Jan 2017 14:58:51 +0000 Received: from [193.109.254.147] by server-8.bemta-6.messagelabs.com id A1/FF-21675-AA997785; Thu, 12 Jan 2017 14:58:50 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprIIsWRWlGSWpSXmKPExsXitHRDpO7KmeU RBnc+61p83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBk33+5jLZiaVbH0WydbA+O7wC5GTg4JAX+J L3M3sYPYbAI6ElOfXmLtYuTgEBFQkbi916CLkYuDWWASk0TrqzusIDXCArYSP59sZQKxWQRUJ W7cuM0CYvMKuEms+vGcGWKmnMT54z/BbE4Bd4l/c3aDzRcCqjm19AOUrSKxfuosNoheQYmTM5 +AzWEWkJA4+OIF8wRG3llIUrOQpBYwMq1i1ChOLSpLLdI1NNVLKspMzyjJTczM0TU0MNPLTS0 uTkxPzUlMKtZLzs/dxAgMHgYg2MH4bVnAIUZJDiYlUd5VHuURQnxJ+SmVGYnFGfFFpTmpxYcY ZTg4lCR4Z80AygkWpaanVqRl5gDDGCYtwcGjJML7GiTNW1yQmFucmQ6ROsWoy3HqxumXTEIse fl5qVLivEtAigRAijJK8+BGwGLqEqOslDAvI9BRQjwFqUW5mSWo8q8YxTkYlYR534JM4cnMK4 Hb9AroCCagIy7agB1RkoiQkmpgLImL3+V0IuljWVvFi133uJ5m7l1/4619+xcP73q2VVsMVyq uYGQv1xJauG7ntDnfd7y+XrV3qllPi3igiA6HTqJQm59G34QkmX/lL4ra+5cyPvDP6I4/ofJ/ 39X5N67If7/kEu5tmPdtnrD0IiW5l2axB0od3wQ3iTlIRqwNO3FyvZEdA7OSEktxRqKhFnNRc SIAZgdD66QCAAA= X-Env-Sender: prvs=1786f58dd=Paul.Durrant@citrix.com X-Msg-Ref: server-13.tower-27.messagelabs.com!1484233124!72103285!4 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 56944 invoked from network); 12 Jan 2017 14:58:49 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-13.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 12 Jan 2017 14:58:49 -0000 X-IronPort-AV: E=Sophos;i="5.33,349,1477958400"; d="scan'208";a="399471540" From: Paul Durrant To: Date: Thu, 12 Jan 2017 14:58:35 +0000 Message-ID: <1484233120-2015-4-git-send-email-paul.durrant@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1484233120-2015-1-git-send-email-paul.durrant@citrix.com> References: <1484233120-2015-1-git-send-email-paul.durrant@citrix.com> MIME-Version: 1.0 Cc: George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Paul Durrant , Jan Beulich , Daniel De Graaf Subject: [Xen-devel] [PATCH v3 3/8] dm_op: convert HVMOP_track_dirty_vram 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 The handle type passed to the underlying shadow and hap functions is changed for compatibility with the new hypercall buffer. NOTE: This patch also modifies the type of the 'nr' parameter of xc_hvm_track_dirty_vram() from uint64_t to uint32_t. In practice the value passed was always truncated to 32 bits. Suggested-by: Jan Beulich Signed-off-by: Paul Durrant Reviewed-by: Jan Beulich Acked-by: Tim Deegan Acked-by: George Dunlap --- Cc: Jan Beulich Cc: Daniel De Graaf Cc: Ian Jackson Acked-by: Wei Liu Cc: Andrew Cooper Cc: George Dunlap Cc: Tim Deegan v3: - Check d->max_vcpus rather than d->vcpu, as requested by Jan. - The handle type changes (from uint8 to void) are still necessary, hence omitting Jan's R-b until this is confirmed to be acceptable. v2: - Addressed several comments from Jan. --- tools/flask/policy/modules/xen.if | 4 ++-- tools/libxc/include/xenctrl.h | 2 +- tools/libxc/xc_misc.c | 32 +++++++++----------------- xen/arch/x86/hvm/dm.c | 45 +++++++++++++++++++++++++++++++++++++ xen/arch/x86/hvm/hvm.c | 41 --------------------------------- xen/arch/x86/mm/hap/hap.c | 2 +- xen/arch/x86/mm/shadow/common.c | 2 +- xen/include/asm-x86/hap.h | 2 +- xen/include/asm-x86/shadow.h | 2 +- xen/include/public/hvm/dm_op.h | 18 +++++++++++++++ xen/include/public/hvm/hvm_op.h | 16 ------------- xen/xsm/flask/hooks.c | 3 --- xen/xsm/flask/policy/access_vectors | 2 -- 13 files changed, 80 insertions(+), 91 deletions(-) diff --git a/tools/flask/policy/modules/xen.if b/tools/flask/policy/modules/xen.if index f9254c2..45e5b5f 100644 --- a/tools/flask/policy/modules/xen.if +++ b/tools/flask/policy/modules/xen.if @@ -58,7 +58,7 @@ define(`create_domain_common', ` allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp }; allow $1 $2:grant setup; allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc - setparam pcilevel trackdirtyvram nested altp2mhvm altp2mhvm_op send_irq }; + setparam pcilevel nested altp2mhvm altp2mhvm_op send_irq }; ') # create_domain(priv, target) @@ -151,7 +151,7 @@ define(`device_model', ` allow $1 $2_target:domain { getdomaininfo shutdown }; allow $1 $2_target:mmu { map_read map_write adjust physmap target_hack }; - allow $1 $2_target:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute pcilevel cacheattr send_irq dm }; + allow $1 $2_target:hvm { getparam setparam hvmctl irqlevel pciroute pcilevel cacheattr send_irq dm }; ') # make_device_model(priv, dm_dom, hvm_dom) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 2ba46d7..c7ee412 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -1620,7 +1620,7 @@ int xc_hvm_inject_msi( */ int xc_hvm_track_dirty_vram( xc_interface *xch, domid_t dom, - uint64_t first_pfn, uint64_t nr, + uint64_t first_pfn, uint32_t nr, unsigned long *bitmap); /* diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 06e90de..4c41d41 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -581,34 +581,22 @@ int xc_hvm_inject_msi( int xc_hvm_track_dirty_vram( xc_interface *xch, domid_t dom, - uint64_t first_pfn, uint64_t nr, + uint64_t first_pfn, uint32_t nr, unsigned long *dirty_bitmap) { - DECLARE_HYPERCALL_BOUNCE(dirty_bitmap, (nr+7) / 8, XC_HYPERCALL_BUFFER_BOUNCE_OUT); - DECLARE_HYPERCALL_BUFFER(struct xen_hvm_track_dirty_vram, arg); - int rc; + struct xen_dm_op op; + struct xen_dm_op_track_dirty_vram *data; - arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); - if ( arg == NULL || xc_hypercall_bounce_pre(xch, dirty_bitmap) ) - { - PERROR("Could not bounce memory for xc_hvm_track_dirty_vram hypercall"); - rc = -1; - goto out; - } + memset(&op, 0, sizeof(op)); - arg->domid = dom; - arg->first_pfn = first_pfn; - arg->nr = nr; - set_xen_guest_handle(arg->dirty_bitmap, dirty_bitmap); + op.op = XEN_DMOP_track_dirty_vram; + data = &op.u.track_dirty_vram; - rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, - HVMOP_track_dirty_vram, - HYPERCALL_BUFFER_AS_ARG(arg)); + data->first_pfn = first_pfn; + data->nr = nr; -out: - xc_hypercall_buffer_free(xch, arg); - xc_hypercall_bounce_post(xch, dirty_bitmap); - return rc; + return do_dm_op(xch, dom, 2, &op, sizeof(op), + dirty_bitmap, (nr + 7) / 8); } int xc_hvm_modified_memory( diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c index 4b94d85..d501d56 100644 --- a/xen/arch/x86/hvm/dm.c +++ b/xen/arch/x86/hvm/dm.c @@ -18,7 +18,9 @@ #include #include +#include #include +#include #include @@ -68,6 +70,35 @@ static int copy_buf_to_guest(XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs, return copy_to_guest(buf.h, src, size) ? -EFAULT : 0; } +static int track_dirty_vram(struct domain *d, + unsigned int nr_bufs, + XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs, + xen_pfn_t first_pfn, unsigned int nr) +{ + struct xen_dm_op_buf buf; + int rc; + + if ( nr > (GB(1) >> PAGE_SHIFT) ) + return -EINVAL; + + if ( d->is_dying ) + return -ESRCH; + + if ( !d->max_vcpus || !d->vcpu[0] ) + return -EINVAL; + + rc = get_buf(bufs, nr_bufs, 1, &buf); + if ( rc ) + return rc; + + if ( ((nr + 7) / 8) > buf.size ) + return -EINVAL; + + return shadow_mode_enabled(d) ? + shadow_track_dirty_vram(d, first_pfn, nr, buf.h) : + hap_track_dirty_vram(d, first_pfn, nr, buf.h); +} + long do_dm_op(domid_t domid, unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs) @@ -182,6 +213,20 @@ long do_dm_op(domid_t domid, break; } + case XEN_DMOP_track_dirty_vram: + { + const struct xen_dm_op_track_dirty_vram *data = + &op.u.track_dirty_vram; + + rc = -EINVAL; + if ( data->pad ) + break; + + rc = track_dirty_vram(d, nr_bufs, bufs, data->first_pfn, + data->nr); + break; + } + default: rc = -EOPNOTSUPP; break; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 138cb46..80d1ad6 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -5516,47 +5516,6 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) rc = guest_handle_is_null(arg) ? hvmop_flush_tlb_all() : -EINVAL; break; - case HVMOP_track_dirty_vram: - { - struct xen_hvm_track_dirty_vram a; - struct domain *d; - - if ( copy_from_guest(&a, arg, 1) ) - return -EFAULT; - - rc = rcu_lock_remote_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; - - rc = -EINVAL; - if ( !is_hvm_domain(d) ) - goto tdv_fail; - - if ( a.nr > GB(1) >> PAGE_SHIFT ) - goto tdv_fail; - - rc = xsm_hvm_control(XSM_DM_PRIV, d, op); - if ( rc ) - goto tdv_fail; - - rc = -ESRCH; - if ( d->is_dying ) - goto tdv_fail; - - rc = -EINVAL; - if ( d->vcpu == NULL || d->vcpu[0] == NULL ) - goto tdv_fail; - - if ( shadow_mode_enabled(d) ) - rc = shadow_track_dirty_vram(d, a.first_pfn, a.nr, a.dirty_bitmap); - else - rc = hap_track_dirty_vram(d, a.first_pfn, a.nr, a.dirty_bitmap); - - tdv_fail: - rcu_unlock_domain(d); - break; - } - case HVMOP_modified_memory: { struct xen_hvm_modified_memory a; diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c index e6dc088..6dbb3cc 100644 --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -68,7 +68,7 @@ int hap_track_dirty_vram(struct domain *d, unsigned long begin_pfn, unsigned long nr, - XEN_GUEST_HANDLE_64(uint8) guest_dirty_bitmap) + XEN_GUEST_HANDLE_PARAM(void) guest_dirty_bitmap) { long rc = 0; struct sh_dirty_vram *dirty_vram; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 4113351..0079238 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3604,7 +3604,7 @@ static void sh_clean_dirty_bitmap(struct domain *d) int shadow_track_dirty_vram(struct domain *d, unsigned long begin_pfn, unsigned long nr, - XEN_GUEST_HANDLE_64(uint8) guest_dirty_bitmap) + XEN_GUEST_HANDLE_PARAM(void) guest_dirty_bitmap) { int rc = 0; unsigned long end_pfn = begin_pfn + nr; diff --git a/xen/include/asm-x86/hap.h b/xen/include/asm-x86/hap.h index dedb4b1..88587c4 100644 --- a/xen/include/asm-x86/hap.h +++ b/xen/include/asm-x86/hap.h @@ -43,7 +43,7 @@ void hap_vcpu_init(struct vcpu *v); int hap_track_dirty_vram(struct domain *d, unsigned long begin_pfn, unsigned long nr, - XEN_GUEST_HANDLE_64(uint8) dirty_bitmap); + XEN_GUEST_HANDLE_PARAM(void) dirty_bitmap); extern const struct paging_mode *hap_paging_get_mode(struct vcpu *); int hap_set_allocation(struct domain *d, unsigned int pages, bool *preempted); diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index bac952f..7e1ed3b 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -63,7 +63,7 @@ int shadow_enable(struct domain *d, u32 mode); int shadow_track_dirty_vram(struct domain *d, unsigned long first_pfn, unsigned long nr, - XEN_GUEST_HANDLE_64(uint8) dirty_bitmap); + XEN_GUEST_HANDLE_PARAM(void) dirty_bitmap); /* Handler for shadow control ops: operations from user-space to enable * and disable ephemeral shadow modes (test mode and log-dirty mode) and diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h index b5c7c29..fb9cf17 100644 --- a/xen/include/public/hvm/dm_op.h +++ b/xen/include/public/hvm/dm_op.h @@ -174,6 +174,23 @@ struct xen_dm_op_destroy_ioreq_server { uint16_t pad; }; +/* + * XEN_DMOP_track_dirty_vram: Track modifications to the specified pfn + * range. + * + * NOTE: The bitmap passed back to the caller is passed in a + * secondary buffer. + */ +#define XEN_DMOP_track_dirty_vram 7 + +struct xen_dm_op_track_dirty_vram { + /* IN - number of pages to be tracked */ + uint32_t nr; + uint32_t pad; + /* IN - first pfn to track */ + uint64_aligned_t first_pfn; +}; + struct xen_dm_op { uint32_t op; uint32_t pad; @@ -184,6 +201,7 @@ struct xen_dm_op { struct xen_dm_op_ioreq_server_range unmap_io_range_from_ioreq_server; struct xen_dm_op_set_ioreq_server_state set_ioreq_server_state; struct xen_dm_op_destroy_ioreq_server destroy_ioreq_server; + struct xen_dm_op_track_dirty_vram track_dirty_vram; } u; }; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index 6fcd86d..47e836c 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -95,22 +95,6 @@ typedef enum { /* Following tools-only interfaces may change in future. */ #if defined(__XEN__) || defined(__XEN_TOOLS__) -/* Track dirty VRAM. */ -#define HVMOP_track_dirty_vram 6 -struct xen_hvm_track_dirty_vram { - /* Domain to be tracked. */ - domid_t domid; - /* Number of pages to track. */ - uint32_t nr; - /* First pfn to track. */ - uint64_aligned_t first_pfn; - /* OUT variable. */ - /* Dirty bitmap buffer. */ - XEN_GUEST_HANDLE_64(uint8) dirty_bitmap; -}; -typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t); - /* Notify that some pages got modified by the Device Model. */ #define HVMOP_modified_memory 7 struct xen_hvm_modified_memory { diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 1ce8a36..a4272d7 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1180,9 +1180,6 @@ static int flask_hvm_param(struct domain *d, unsigned long op) case HVMOP_get_param: perm = HVM__GETPARAM; break; - case HVMOP_track_dirty_vram: - perm = HVM__TRACKDIRTYVRAM; - break; default: perm = HVM__HVMCTL; } diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 92e6da9..47ce589 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -268,8 +268,6 @@ class hvm bind_irq # XEN_DOMCTL_pin_mem_cacheattr cacheattr -# HVMOP_track_dirty_vram - trackdirtyvram # HVMOP_modified_memory, HVMOP_get_mem_type, HVMOP_set_mem_type, # HVMOP_set_mem_access, HVMOP_get_mem_access, HVMOP_pagetable_dying, # HVMOP_inject_trap