From patchwork Tue Sep 22 18:24:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792953 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 530286CB for ; Tue, 22 Sep 2020 18:26:36 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 24947239D4 for ; Tue, 22 Sep 2020 18:26:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="hYCmON/z" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 24947239D4 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyp-00005F-ML; Tue, 22 Sep 2020 18:25:31 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyo-0008V0-8B for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:30 +0000 X-Inumbo-ID: c7901009-ebb4-44f8-b1cf-cae236d7e6f0 Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id c7901009-ebb4-44f8-b1cf-cae236d7e6f0; Tue, 22 Sep 2020 18:25:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799130; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PemkBKNb12MmUWwvMUvbxamV4GWuBXt6jS2JXhDGXTk=; b=hYCmON/zDE6l+ByI/2O7yFcVHlZhZaDKqrl/BASrxffZxK1HOtP3QPxl ajAT9A5R3z9pTCIE1K7d3shS/W+XQPPlEcQIxIHgzUXZpw6PPABauH4CD zWrjC0U/c9LSVOOw+rjiOl9aZlr2zA++3qDyhzMvYNrwGchbHZjFDyJuw Y=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: 61Ih/vUJm8RMzRKh9tGGFkyDlwBvALt8VM8HwJ25XC0I2Mfj/iGvmvCvdSzK6qEyRpmFGxLKvu APpU7qvVFNJg9qv3boln7BCSwMDx2BRVCCBJgXJo2xxMw+NVSzoYC6BamfTz/FCM845vDUkDu6 FnhoSi7oz05nzCK6+sMpVrDOY5HpcjI4ddoIOJvgbcmEBlVmxpmfDf64oYx1QY5HXDpBmQiLt1 YQDlwkIAWvmqEIY3+y8qeY3Ne0WQOi7O8tLyQPT6FSxzhXcVZWt98qForqhGinjmog9rIinaW0 Pwk= X-SBRS: 2.7 X-MesageID: 27631639 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27631639" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Wei Liu , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , "Stefano Stabellini" , Volodymyr Babchuk , =?utf-8?q?Micha=C5=82_Leszc?= =?utf-8?q?zy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 01/11] xen/memory: Introduce CONFIG_ARCH_ACQUIRE_RESOURCE Date: Tue, 22 Sep 2020 19:24:34 +0100 Message-ID: <20200922182444.12350-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" New architectures shouldn't be forced to implement no-op stubs for unused functionality. Introduce CONFIG_ARCH_ACQUIRE_RESOURCE which can be opted in to, and provide compatibility logic in xen/mm.h No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich Reviewed-by: Paul Durrant Acked-by: Julien Grall --- CC: Wei Liu CC: Roger Pau Monné CC: Stefano Stabellini CC: Volodymyr Babchuk CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/arch/x86/Kconfig | 1 + xen/common/Kconfig | 3 +++ xen/include/asm-arm/mm.h | 8 -------- xen/include/xen/mm.h | 9 +++++++++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index a636a4bb1e..e7644a0a9d 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -6,6 +6,7 @@ config X86 select ACPI select ACPI_LEGACY_TABLES_LOOKUP select ARCH_SUPPORTS_INT128 + select ARCH_ACQUIRE_RESOURCE select COMPAT select CORE_PARKING select HAS_ALTERNATIVE diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 15e3b79ff5..593459ea6e 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -22,6 +22,9 @@ config GRANT_TABLE If unsure, say Y. +config ARCH_ACQUIRE_RESOURCE + bool + config HAS_ALTERNATIVE bool diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index f8ba49b118..0b7de3102e 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -358,14 +358,6 @@ static inline void put_page_and_type(struct page_info *page) void clear_and_clean_page(struct page_info *page); -static inline -int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id, - unsigned long frame, unsigned int nr_frames, - xen_pfn_t mfn_list[]) -{ - return -EOPNOTSUPP; -} - unsigned int arch_get_dma_bitsize(void); #endif /* __ARCH_ARM_MM__ */ diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 4536a62940..26a4a3d350 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -685,4 +685,13 @@ static inline void put_page_alloc_ref(struct page_info *page) } } +#ifndef CONFIG_ARCH_ACQUIRE_RESOURCE +static inline int arch_acquire_resource( + struct domain *d, unsigned int type, unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]) +{ + return -EOPNOTSUPP; +} +#endif /* !CONFIG_ARCH_ACQUIRE_RESOURCE */ + #endif /* __XEN_MM_H__ */ From patchwork Tue Sep 22 18:24:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792943 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C7606CB for ; Tue, 22 Sep 2020 18:25:59 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0A2EF2085B for ; Tue, 22 Sep 2020 18:25:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="EFwciUQY" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0A2EF2085B Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyQ-0008GW-0k; Tue, 22 Sep 2020 18:25:06 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyP-0008GC-15 for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:05 +0000 X-Inumbo-ID: 5abe9782-d070-44d8-9f0e-6dd95fd55647 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 5abe9782-d070-44d8-9f0e-6dd95fd55647; Tue, 22 Sep 2020 18:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799104; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DIebahfK17iSM+wvw7c9wbKbOGEtBVrBQ2p8g+TwCC8=; b=EFwciUQYjWLt5I8QMzUA+7muXidcOWbYPcBqtsPriG0LWT/OS10hcCcy 2Zk1fI0gjoyyOsEXlPkWD0B3k2NX0lQl9S6xH889zL7VTlwGOPoVjdgo6 6xAH/YkkIqGC30DVI8xs+WWdHJoi5OMxNwYSWnNBnF0us/j/uBe0jaJq+ E=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: CIL0SFbCI+H2x0JROLZfnhW7ogjL/419mywgnwHWUhqo70XbyD5lqwkQzAifcWkdZKBA0aRKQN ZnPWEeo+eSOu1fB0iARKQyy9at2fRG5KrW3bVNqEhYNequfG4ldtbc2hmFobazDteDrQefO4Hf EbudCO5bx/cN0oKIkuR7vk5ChNZTHR1Rum07O8yUbj4cxVJuOgS1Ylhji1OgYAes/HbDbtmmbW ScKRHZi7ACw3OTpvtpZ4dh+9TUL6wSf8MCc+ZaAfxfoNTXikx0QFShD6RlXhLISajIvPZF7oZs WFM= X-SBRS: 2.7 X-MesageID: 27300354 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27300354" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 02/11] xen/gnttab: Rework resource acquisition Date: Tue, 22 Sep 2020 19:24:35 +0100 Message-ID: <20200922182444.12350-3-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The existing logic doesn't function in the general case for mapping a guests grant table, due to arbitrary 32 frame limit, and the default grant table limit being 64. In order to start addressing this, rework the existing grant table logic by implementing a single gnttab_acquire_resource(). This is far more efficient than the previous acquire_grant_table() in memory.c because it doesn't take the grant table write lock, and attempt to grow the table, for every single frame. The new gnttab_acquire_resource() function subsumes the previous two gnttab_get_{shared,status}_frame() helpers. No functional change. Signed-off-by: Andrew Cooper --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel v2: * Fix CentOS 6 build by initialising vaddrs to NULL * Add ASSERT_UNREACHABLE() and gt->status typecheck --- xen/common/grant_table.c | 102 +++++++++++++++++++++++++++++++----------- xen/common/memory.c | 42 +---------------- xen/include/xen/grant_table.h | 19 +++----- 3 files changed, 84 insertions(+), 79 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index a5d3ed8bda..912f07be47 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -4013,6 +4013,81 @@ static int gnttab_get_shared_frame_mfn(struct domain *d, return 0; } +int gnttab_acquire_resource( + struct domain *d, unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]) +{ + struct grant_table *gt = d->grant_table; + unsigned int i = nr_frames, tot_frames; + mfn_t tmp; + void **vaddrs = NULL; + int rc; + + /* Input sanity. */ + if ( !nr_frames ) + return -EINVAL; + + /* Overflow checks */ + if ( frame + nr_frames < frame ) + return -EINVAL; + + tot_frames = frame + nr_frames; + if ( tot_frames != frame + nr_frames ) + return -EINVAL; + + /* Grow table if necessary. */ + grant_write_lock(gt); + switch ( id ) + { + case XENMEM_resource_grant_table_id_shared: + rc = gnttab_get_shared_frame_mfn(d, tot_frames - 1, &tmp); + break; + + case XENMEM_resource_grant_table_id_status: + if ( gt->gt_version != 2 ) + { + default: + rc = -EINVAL; + break; + } + rc = gnttab_get_status_frame_mfn(d, tot_frames - 1, &tmp); + break; + } + + /* Any errors from growing the table? */ + if ( rc ) + goto out; + + switch ( id ) + { + case XENMEM_resource_grant_table_id_shared: + vaddrs = gt->shared_raw; + break; + + case XENMEM_resource_grant_table_id_status: + /* Check that void ** is a suitable representation for gt->status. */ + BUILD_BUG_ON(!__builtin_types_compatible_p( + typeof(gt->status), grant_status_t **)); + vaddrs = (void **)gt->status; + break; + } + + if ( !vaddrs ) + { + ASSERT_UNREACHABLE(); + rc = -EINVAL; + goto out; + } + + for ( i = 0; i < nr_frames; ++i ) + mfn_list[i] = virt_to_mfn(vaddrs[frame + i]); + + out: + grant_write_unlock(gt); + + return rc; +} + int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn) { int rc = 0; @@ -4047,33 +4122,6 @@ int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn) return rc; } -int gnttab_get_shared_frame(struct domain *d, unsigned long idx, - mfn_t *mfn) -{ - struct grant_table *gt = d->grant_table; - int rc; - - grant_write_lock(gt); - rc = gnttab_get_shared_frame_mfn(d, idx, mfn); - grant_write_unlock(gt); - - return rc; -} - -int gnttab_get_status_frame(struct domain *d, unsigned long idx, - mfn_t *mfn) -{ - struct grant_table *gt = d->grant_table; - int rc; - - grant_write_lock(gt); - rc = (gt->gt_version == 2) ? - gnttab_get_status_frame_mfn(d, idx, mfn) : -EINVAL; - grant_write_unlock(gt); - - return rc; -} - static void gnttab_usage_print(struct domain *rd) { int first = 1; diff --git a/xen/common/memory.c b/xen/common/memory.c index 1bab0e80c2..177fc378d9 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1007,44 +1007,6 @@ static long xatp_permission_check(struct domain *d, unsigned int space) return xsm_add_to_physmap(XSM_TARGET, current->domain, d); } -static int acquire_grant_table(struct domain *d, unsigned int id, - unsigned long frame, - unsigned int nr_frames, - xen_pfn_t mfn_list[]) -{ - unsigned int i = nr_frames; - - /* Iterate backwards in case table needs to grow */ - while ( i-- != 0 ) - { - mfn_t mfn = INVALID_MFN; - int rc; - - switch ( id ) - { - case XENMEM_resource_grant_table_id_shared: - rc = gnttab_get_shared_frame(d, frame + i, &mfn); - break; - - case XENMEM_resource_grant_table_id_status: - rc = gnttab_get_status_frame(d, frame + i, &mfn); - break; - - default: - rc = -EINVAL; - break; - } - - if ( rc ) - return rc; - - ASSERT(!mfn_eq(mfn, INVALID_MFN)); - mfn_list[i] = mfn_x(mfn); - } - - return 0; -} - static int acquire_resource( XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg) { @@ -1099,8 +1061,8 @@ static int acquire_resource( switch ( xmar.type ) { case XENMEM_resource_grant_table: - rc = acquire_grant_table(d, xmar.id, xmar.frame, xmar.nr_frames, - mfn_list); + rc = gnttab_acquire_resource(d, xmar.id, xmar.frame, xmar.nr_frames, + mfn_list); break; default: diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 98603604b8..5a2c75b880 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -56,10 +56,10 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, grant_ref_t ref, int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn); -int gnttab_get_shared_frame(struct domain *d, unsigned long idx, - mfn_t *mfn); -int gnttab_get_status_frame(struct domain *d, unsigned long idx, - mfn_t *mfn); + +int gnttab_acquire_resource( + struct domain *d, unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]); #else @@ -93,14 +93,9 @@ static inline int gnttab_map_frame(struct domain *d, unsigned long idx, return -EINVAL; } -static inline int gnttab_get_shared_frame(struct domain *d, unsigned long idx, - mfn_t *mfn) -{ - return -EINVAL; -} - -static inline int gnttab_get_status_frame(struct domain *d, unsigned long idx, - mfn_t *mfn) +static inline int gnttab_acquire_resource( + struct domain *d, unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]) { return -EINVAL; } From patchwork Tue Sep 22 18:24:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792951 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 968EE6CB for ; Tue, 22 Sep 2020 18:26:32 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 66ADA239D2 for ; Tue, 22 Sep 2020 18:26:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="SXcxF+gp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 66ADA239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyf-0008Py-4R; Tue, 22 Sep 2020 18:25:21 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmye-0008GI-7X for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:20 +0000 X-Inumbo-ID: 635d8d12-cb4f-4e0b-b442-646c3906e749 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 635d8d12-cb4f-4e0b-b442-646c3906e749; Tue, 22 Sep 2020 18:25:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799106; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pLAgF35adw/kn3WeOYhIg/xCYIoVFVCDELdjZDtTL0c=; b=SXcxF+gpotR8smdrO71mdzRkyIo3SzotYiMka0xg9Iu7thE4W10qRejz vvPd1cQnWNfrdNZlC2lyHQhBAWqTjuObaI8CNWM56U64gu9PAhepR45Ou jfY2j2SkzOVXXCXW05L5e3CJiGKjXAviR83+IVhjZ1FrbruYRcuaR5Frn Y=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: x4JzTL0cF8XRaqd3vLFHV5fhhcs+rcRu+VvL6j4BG7OCXCwhi8G360HAexdBGRZ7paMNOP8BEt 9qqW1tS6lR97zQLU+4ZUBxhjzrZYN/iUX2jL/1ckImYIRFGX0wawTKjQ2jsjdMI5GM2KOvY+FE G5hZSt6ERK/t0ZqM6q0L4A8glTCxviyHUFRgUReKTYnVJR7czj2HIcwq1eJ4kwIdIY8mK0DUC+ eV4Lf35mbVRgxhnp81exSMSck5l+S115dXw/HOnwRRN5FjdkL98cxHFacy3jUIJdEmRPQhiOn8 b88= X-SBRS: 2.7 X-MesageID: 28290908 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="28290908" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , =?utf-8?q?Micha=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 03/11] xen/memory: Fix compat XENMEM_acquire_resource for size requests Date: Tue, 22 Sep 2020 19:24:36 +0100 Message-ID: <20200922182444.12350-4-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Copy the nr_frames from the structure which actually has the correct value, so the caller doesn't unconditionally receive 0. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/common/compat/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index 3851f756c7..ed92e05b08 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -599,7 +599,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) if ( __copy_field_to_guest( guest_handle_cast(compat, compat_mem_acquire_resource_t), - &cmp.mar, nr_frames) ) + nat.mar, nr_frames) ) return -EFAULT; } else From patchwork Tue Sep 22 18:24:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792941 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD14F139A for ; Tue, 22 Sep 2020 18:25:36 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8F06C2085B for ; Tue, 22 Sep 2020 18:25:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="FutK5heh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F06C2085B Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmya-0008MQ-BT; Tue, 22 Sep 2020 18:25:16 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyY-0008GC-Vo for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:15 +0000 X-Inumbo-ID: 66495c64-27dd-4231-8881-6ceacd5bb973 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 66495c64-27dd-4231-8881-6ceacd5bb973; Tue, 22 Sep 2020 18:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799105; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OuR4rl0T07fCn2F5T8U3Qe+EIRHDfpOiju296cMpCPk=; b=FutK5hehDy7VsIYH4lvSHV9HymyDT5x+d8qf4IUfT0ZYYb+Tel/fUY6Z lDy1YM93bNRGDf72aC5rNc0RbZ9U2JkNwId4imOkYEim0H9avLqtSagIn qNnQXRAXJ75vnU71glmQuCsiuPEaYq6mul8nAT7HUvmYYxHOVuskPDtlr U=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: Lho6xcsGRtCB8Anv/OIHYGk5B1SKYJ/od3/Q02hzEGZefEHhpRxfJr6PiFSRRlkoL5GI+OwCOU ovoyiWaG3nkqTTzmvzotQix3thglJqJfw5HHX0sgIEnpSdhVDICM9FJx6vThirvdwY/TjIB41T OTs+62QRnZ2zEJpXzCqqs2wa/B/U8ZOkIeAcNL1fkPTQ7JiNL6sIqPr+EBnAWhVRFEhq/6SqbF xyProNbNxUXPV+076XnCynLOCZ60kf1EsB4i3ZfyNr5xBUZp0fXG7Z477Y4FYKSOeFw60fnJ6N EzU= X-SBRS: 2.7 X-MesageID: 28290900 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="28290900" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 04/11] xen/memory: Fix acquire_resource size semantics Date: Tue, 22 Sep 2020 19:24:37 +0100 Message-ID: <20200922182444.12350-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Calling XENMEM_acquire_resource with a NULL frame_list is a request for the size of the resource, but the returned 32 is bogus. If someone tries to follow it for XENMEM_resource_ioreq_server, the acquire call will fail as IOREQ servers currently top out at 2 frames, and it is only half the size of the default grant table limit for guests. Also, no users actually request a resource size, because it was never wired up in the sole implementaion of resource acquisition in Linux. Introduce a new resource_max_frames() to calculate the size of a resource, and implement it the IOREQ and grant subsystems. It is impossible to guarantee that a mapping call following a successful size call will succeed (e.g. The target IOREQ server gets destroyed, or the domain switches from grant v2 to v1). Document the restriction, and use the flexibility to simplify the paths to be lockless. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant Reviewed-by: Jan Beulich --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel v2: * Spelling fixes * Add more local variables. * Don't return any status frames on ARM where v2 support is compiled out. --- xen/arch/x86/mm.c | 20 ++++++++++++++++ xen/common/grant_table.c | 23 ++++++++++++++++++ xen/common/memory.c | 55 +++++++++++++++++++++++++++++++++---------- xen/include/asm-x86/mm.h | 3 +++ xen/include/public/memory.h | 16 +++++++++---- xen/include/xen/grant_table.h | 8 +++++++ xen/include/xen/mm.h | 6 +++++ 7 files changed, 114 insertions(+), 17 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index d1cfc8fb4a..e82307bdae 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4591,6 +4591,26 @@ int xenmem_add_to_physmap_one( return rc; } +unsigned int arch_resource_max_frames( + struct domain *d, unsigned int type, unsigned int id) +{ + unsigned int nr = 0; + + switch ( type ) + { +#ifdef CONFIG_HVM + case XENMEM_resource_ioreq_server: + if ( !is_hvm_domain(d) ) + break; + /* One frame for the buf-ioreq ring, and one frame per 128 vcpus. */ + nr = 1 + DIV_ROUND_UP(d->max_vcpus * sizeof(struct ioreq), PAGE_SIZE); + break; +#endif + } + + return nr; +} + int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 912f07be47..8c401a5540 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -4013,6 +4013,29 @@ static int gnttab_get_shared_frame_mfn(struct domain *d, return 0; } +unsigned int gnttab_resource_max_frames(struct domain *d, unsigned int id) +{ + const struct grant_table *gt = d->grant_table; + unsigned int nr = 0; + + /* Don't need the grant lock. This limit is fixed at domain create time. */ + switch ( id ) + { + case XENMEM_resource_grant_table_id_shared: + nr = gt->max_grant_frames; + break; + + case XENMEM_resource_grant_table_id_status: + if ( GNTTAB_MAX_VERSION < 2 ) + break; + + nr = grant_to_status_frames(gt->max_grant_frames); + break; + } + + return nr; +} + int gnttab_acquire_resource( struct domain *d, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) diff --git a/xen/common/memory.c b/xen/common/memory.c index 177fc378d9..c559935732 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1007,6 +1007,26 @@ static long xatp_permission_check(struct domain *d, unsigned int space) return xsm_add_to_physmap(XSM_TARGET, current->domain, d); } +/* + * Return 0 on any kind of error. Caller converts to -EINVAL. + * + * All nonzero values should be repeatable (i.e. derived from some fixed + * property of the domain), and describe the full resource (i.e. mapping the + * result of this call will be the entire resource). + */ +static unsigned int resource_max_frames(struct domain *d, + unsigned int type, unsigned int id) +{ + switch ( type ) + { + case XENMEM_resource_grant_table: + return gnttab_resource_max_frames(d, id); + + default: + return arch_resource_max_frames(d, type, id); + } +} + static int acquire_resource( XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg) { @@ -1018,6 +1038,7 @@ static int acquire_resource( * use-cases then per-CPU arrays or heap allocations may be required. */ xen_pfn_t mfn_list[32]; + unsigned int max_frames; int rc; /* @@ -1034,19 +1055,6 @@ static int acquire_resource( if ( xmar.pad != 0 ) return -EINVAL; - if ( guest_handle_is_null(xmar.frame_list) ) - { - if ( xmar.nr_frames ) - return -EINVAL; - - xmar.nr_frames = ARRAY_SIZE(mfn_list); - - if ( __copy_field_to_guest(arg, &xmar, nr_frames) ) - return -EFAULT; - - return 0; - } - if ( xmar.nr_frames > ARRAY_SIZE(mfn_list) ) return -E2BIG; @@ -1058,6 +1066,27 @@ static int acquire_resource( if ( rc ) goto out; + max_frames = resource_max_frames(d, xmar.type, xmar.id); + + rc = -EINVAL; + if ( !max_frames ) + goto out; + + if ( guest_handle_is_null(xmar.frame_list) ) + { + if ( xmar.nr_frames ) + goto out; + + xmar.nr_frames = max_frames; + + rc = -EFAULT; + if ( __copy_field_to_guest(arg, &xmar, nr_frames) ) + goto out; + + rc = 0; + goto out; + } + switch ( xmar.type ) { case XENMEM_resource_grant_table: diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index deeba75a1c..13977652a8 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -639,6 +639,9 @@ static inline bool arch_mfn_in_directmap(unsigned long mfn) return mfn <= (virt_to_mfn(eva - 1) + 1); } +unsigned int arch_resource_max_frames(struct domain *d, + unsigned int type, unsigned int id); + int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]); diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 21d483298e..d7eb34f167 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -639,10 +639,18 @@ struct xen_mem_acquire_resource { #define XENMEM_resource_grant_table_id_status 1 /* - * IN/OUT - As an IN parameter number of frames of the resource - * to be mapped. However, if the specified value is 0 and - * frame_list is NULL then this field will be set to the - * maximum value supported by the implementation on return. + * IN/OUT + * + * As an IN parameter number of frames of the resource to be mapped. + * + * When frame_list is NULL and nr_frames is 0, this is interpreted as a + * request for the size of the resource, which shall be returned in the + * nr_frames field. + * + * The size of a resource will never be zero, but a nonzero result doesn't + * guarantee that a subsequent mapping request will be successful. There + * are further type/id specific constraints which may change between the + * two calls. */ uint32_t nr_frames; uint32_t pad; diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 5a2c75b880..bae4d79623 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -57,6 +57,8 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, grant_ref_t ref, int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn); +unsigned int gnttab_resource_max_frames(struct domain *d, unsigned int id); + int gnttab_acquire_resource( struct domain *d, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]); @@ -93,6 +95,12 @@ static inline int gnttab_map_frame(struct domain *d, unsigned long idx, return -EINVAL; } +static inline unsigned int gnttab_resource_max_frames( + struct domain *d, unsigned int id) +{ + return 0; +} + static inline int gnttab_acquire_resource( struct domain *d, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 26a4a3d350..d686876b0e 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -686,6 +686,12 @@ static inline void put_page_alloc_ref(struct page_info *page) } #ifndef CONFIG_ARCH_ACQUIRE_RESOURCE +static inline unsigned int arch_resource_max_frames( + struct domain *d, unsigned int type, unsigned int id) +{ + return 0; +} + static inline int arch_acquire_resource( struct domain *d, unsigned int type, unsigned int id, unsigned long frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) From patchwork Tue Sep 22 18:24:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792955 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6EDF46CB for ; Tue, 22 Sep 2020 18:26:40 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3D0EE239D2 for ; Tue, 22 Sep 2020 18:26:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="WM7GOp3n" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3D0EE239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyV-0008JJ-0z; Tue, 22 Sep 2020 18:25:11 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyU-0008GI-76 for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:10 +0000 X-Inumbo-ID: 819e2044-916c-4164-8bb1-604b2425e6e5 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 819e2044-916c-4164-8bb1-604b2425e6e5; Tue, 22 Sep 2020 18:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799105; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Z1BzBbvoR0pCwu+iHfP1GCSjSw2toLzM4t1P0GPcqKs=; b=WM7GOp3nASJEHzrCtsc7G8Y9vIhnTlli4ck2UNzgY0WpH+/gnnRL34YN gQANPSEq8kbpOBgrL9LtxGjsZS2LLy9BiUtDic6uEYG8dUJ0Mau0uRiSH HWPJ5dJgL6ipNH2IkGo7n7UQ4ljqpWl5A4Xy/tAsX0qlvVpCnhZhlUb39 I=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: YH3FrCHwpp0y+LUFn1op1z8FGYh+origAhEFIzdvSqAXzibCrInD8ce1rZ5mgSBQsfg/C6RGD/ hRD7t56+h0F3rwmheB+jkp7EgT5J7cnKfiL39UcxWnScRZ3/3GmRKQQKVeZvlwrdHXtqS3zNC8 TmskwGUiiD0HApnr3IeZ2B/1p4T8/bTkeF6OSJTHQRVLSRsFHjFT9927ClyruPwZ9hzQhyNsCU mVLEzcAeXeXkuszncFu6Tn5wFhZ3QufoRKyBBd1qlwGrNN/elLXZuGuwyL+0dFP1Nce/e/pu0E Ebk= X-SBRS: 2.7 X-MesageID: 28290897 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="28290897" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Ian Jackson , =?utf-8?q?Micha=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 05/11] tools/foreignmem: Support querying the size of a resource Date: Tue, 22 Sep 2020 19:24:38 +0100 Message-ID: <20200922182444.12350-6-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" With the Xen side of this interface fixed to return real sizes, userspace needs to be able to make the query. Introduce xenforeignmemory_resource_size() for the purpose, bumping the library minor version and providing compatibility for the non-Linux builds. Its not possible to reuse the IOCTL_PRIVCMD_MMAP_RESOURCE infrastructure, because it depends on having already mmap()'d a suitably sized region before it will make an XENMEM_acquire_resource hypercall to Xen. Instead, open a xencall handle and make an XENMEM_acquire_resource hypercall directly. Signed-off-by: Andrew Cooper Acked-by: Wei Liu Reviewed-by: Paul Durrant Signed-off-by: Roger Pau Monné Tested-by: Andrew Cooper --- CC: Ian Jackson CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel v2: * Fix build in some environments. Extend the rubric for making foreignmem depend on call * Rebase over Juergens library changes. * Spelling fixes. --- tools/libs/foreignmemory/Makefile | 2 +- tools/libs/foreignmemory/core.c | 14 +++++++++ .../libs/foreignmemory/include/xenforeignmemory.h | 15 +++++++++ tools/libs/foreignmemory/libxenforeignmemory.map | 4 +++ tools/libs/foreignmemory/linux.c | 36 ++++++++++++++++++++++ tools/libs/foreignmemory/private.h | 14 +++++++++ tools/libs/uselibs.mk | 2 +- 7 files changed, 85 insertions(+), 2 deletions(-) diff --git a/tools/libs/foreignmemory/Makefile b/tools/libs/foreignmemory/Makefile index cf444d3c1a..0ed93edac2 100644 --- a/tools/libs/foreignmemory/Makefile +++ b/tools/libs/foreignmemory/Makefile @@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk MAJOR = 1 -MINOR = 3 +MINOR = 4 SRCS-y += core.c SRCS-$(CONFIG_Linux) += linux.c diff --git a/tools/libs/foreignmemory/core.c b/tools/libs/foreignmemory/core.c index 63f12e2450..5d95c59c48 100644 --- a/tools/libs/foreignmemory/core.c +++ b/tools/libs/foreignmemory/core.c @@ -53,6 +53,10 @@ xenforeignmemory_handle *xenforeignmemory_open(xentoollog_logger *logger, if (!fmem->logger) goto err; } + fmem->xcall = xencall_open(fmem->logger, 0); + if ( !fmem->xcall ) + goto err; + rc = osdep_xenforeignmemory_open(fmem); if ( rc < 0 ) goto err; @@ -61,6 +65,7 @@ xenforeignmemory_handle *xenforeignmemory_open(xentoollog_logger *logger, err: xentoolcore__deregister_active_handle(&fmem->tc_ah); osdep_xenforeignmemory_close(fmem); + xencall_close(fmem->xcall); xtl_logger_destroy(fmem->logger_tofree); free(fmem); return NULL; @@ -75,6 +80,7 @@ int xenforeignmemory_close(xenforeignmemory_handle *fmem) xentoolcore__deregister_active_handle(&fmem->tc_ah); rc = osdep_xenforeignmemory_close(fmem); + xencall_close(fmem->xcall); xtl_logger_destroy(fmem->logger_tofree); free(fmem); return rc; @@ -188,6 +194,14 @@ int xenforeignmemory_unmap_resource( return rc; } +int xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, unsigned long *nr_frames) +{ + return osdep_xenforeignmemory_resource_size(fmem, domid, type, + id, nr_frames); +} + /* * Local variables: * mode: C diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h b/tools/libs/foreignmemory/include/xenforeignmemory.h index d594be8df0..1ba2f5316b 100644 --- a/tools/libs/foreignmemory/include/xenforeignmemory.h +++ b/tools/libs/foreignmemory/include/xenforeignmemory.h @@ -179,6 +179,21 @@ xenforeignmemory_resource_handle *xenforeignmemory_map_resource( int xenforeignmemory_unmap_resource( xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres); +/** + * Determine the maximum size of a specific resource. + * + * @parm fmem handle to the open foreignmemory interface + * @parm domid the domain id + * @parm type the resource type + * @parm id the type-specific resource identifier + * + * Return 0 on success and fills in *nr_frames. Sets errno and return -1 on + * error. + */ +int xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, unsigned long *nr_frames); + #endif /* diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map b/tools/libs/foreignmemory/libxenforeignmemory.map index d5323c87d9..8aca341b99 100644 --- a/tools/libs/foreignmemory/libxenforeignmemory.map +++ b/tools/libs/foreignmemory/libxenforeignmemory.map @@ -19,3 +19,7 @@ VERS_1.3 { xenforeignmemory_map_resource; xenforeignmemory_unmap_resource; } VERS_1.2; +VERS_1.4 { + global: + xenforeignmemory_resource_size; +} VERS_1.3; diff --git a/tools/libs/foreignmemory/linux.c b/tools/libs/foreignmemory/linux.c index fe73d5ab72..eec089e232 100644 --- a/tools/libs/foreignmemory/linux.c +++ b/tools/libs/foreignmemory/linux.c @@ -21,12 +21,15 @@ #include #include #include +#include #include #include #include #include +#include + #include "private.h" #ifndef O_CLOEXEC @@ -339,6 +342,39 @@ int osdep_xenforeignmemory_map_resource( return 0; } +int osdep_xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, unsigned long *nr_frames) +{ + int rc; + struct xen_mem_acquire_resource *xmar = + xencall_alloc_buffer(fmem->xcall, sizeof(*xmar)); + + if ( !xmar ) + { + PERROR("Could not bounce memory for acquire_resource hypercall"); + return -1; + } + + *xmar = (struct xen_mem_acquire_resource){ + .domid = domid, + .type = type, + .id = id, + }; + + rc = xencall2(fmem->xcall, __HYPERVISOR_memory_op, + XENMEM_acquire_resource, (uintptr_t)xmar); + if ( rc ) + goto out; + + *nr_frames = xmar->nr_frames; + + out: + xencall_free_buffer(fmem->xcall, xmar); + + return rc; +} + /* * Local variables: * mode: C diff --git a/tools/libs/foreignmemory/private.h b/tools/libs/foreignmemory/private.h index 8f1bf081ed..1a6b685f45 100644 --- a/tools/libs/foreignmemory/private.h +++ b/tools/libs/foreignmemory/private.h @@ -4,6 +4,7 @@ #include #include +#include #include @@ -20,6 +21,7 @@ struct xenforeignmemory_handle { xentoollog_logger *logger, *logger_tofree; + xencall_handle *xcall; unsigned flags; int fd; Xentoolcore__Active_Handle tc_ah; @@ -74,6 +76,15 @@ static inline int osdep_xenforeignmemory_unmap_resource( { return 0; } + +static inline int osdep_xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, unsigned long *nr_frames) +{ + errno = EOPNOTSUPP; + return -1; +} + #else int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem, domid_t domid); @@ -81,6 +92,9 @@ int osdep_xenforeignmemory_map_resource( xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres); int osdep_xenforeignmemory_unmap_resource( xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres); +int osdep_xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, unsigned long *nr_frames); #endif #define PERROR(_f...) \ diff --git a/tools/libs/uselibs.mk b/tools/libs/uselibs.mk index a9dc2ce994..cb09e54de5 100644 --- a/tools/libs/uselibs.mk +++ b/tools/libs/uselibs.mk @@ -11,7 +11,7 @@ USELIBS_gnttab := toollog toolcore LIBS_LIBS += call USELIBS_call := toollog toolcore LIBS_LIBS += foreignmemory -USELIBS_foreignmemory := toollog toolcore +USELIBS_foreignmemory := toollog toolcore call LIBS_LIBS += devicemodel USELIBS_devicemodel := toollog toolcore call LIBS_LIBS += hypfs From patchwork Tue Sep 22 18:24:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792957 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC8CB6CB for ; Tue, 22 Sep 2020 18:26:41 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC1A6239D2 for ; Tue, 22 Sep 2020 18:26:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="cfjkELq5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AC1A6239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyo-0008Vj-DE; Tue, 22 Sep 2020 18:25:30 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyn-0008V0-BZ for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:29 +0000 X-Inumbo-ID: 9f7a1f4a-4c4b-44a5-ab12-d566d463e613 Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 9f7a1f4a-4c4b-44a5-ab12-d566d463e613; Tue, 22 Sep 2020 18:25:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799129; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QzVikzTXIrENnpKWbynQkJyOfWkh2lkxwYpfijKtf/0=; b=cfjkELq5Zs9EdqDmWRjmYe2SNkMvVWFebo+RwWbto6CccjvHexeo1bTr oo5I7Y4fVMFSwNvFdcxbiF5dviTQmfSvuMGI0zy9TCvS1OgRkVUwhN35L sFFu1AiedZw7DepUxzDwE/ajRGb6lWjT2dWBz0KKZ8zi35drH0KSztbZo 8=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: ox9Ky0uJZEa6RYONNB1dq0u6kg1zwZNt18Av1jD72N6oKG/HKDzpiS+q5FifRsFQzp+Y9+gB2B ygZIbhM0Ewo6WGqcimUaPBgcm96whm1DxbR/Q734qaKJSgf9BpjIjVRXMxoMIpYdnXjBHTnlY4 wct78+xVFlGg7pDfp9tAIFgx7nTZ6mcFPg2eERqFt4Qt/duSHB+Q6Xj1yGxtEjGUXspB51J9u9 AHM21dRrJAt6U3gXfMberzhBKwl08OcLehxKq21h+XacFmqpcp4Kssl8NRNicr4JqdM5Zsooxk VAw= X-SBRS: 2.7 X-MesageID: 27631635 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27631635" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 06/11] xen/memory: Clarify the XENMEM_acquire_resource ABI description Date: Tue, 22 Sep 2020 19:24:39 +0100 Message-ID: <20200922182444.12350-7-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" This is how similar operations already operate, compatible with the sole implementation (in Linux), and explicitly gives us some flexibility. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/include/public/memory.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index d7eb34f167..c4c47a0b38 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -642,6 +642,7 @@ struct xen_mem_acquire_resource { * IN/OUT * * As an IN parameter number of frames of the resource to be mapped. + * This value may be updated during the course of the operation. * * When frame_list is NULL and nr_frames is 0, this is interpreted as a * request for the size of the resource, which shall be returned in the @@ -656,7 +657,8 @@ struct xen_mem_acquire_resource { uint32_t pad; /* * IN - the index of the initial frame to be mapped. This parameter - * is ignored if nr_frames is 0. + * is ignored if nr_frames is 0. This value may be updated + * during the course of the operation. */ uint64_t frame; @@ -672,7 +674,8 @@ struct xen_mem_acquire_resource { * If -EIO is returned then the frame_list has only been * partially mapped and it is up to the caller to unmap all * the GFNs. - * This parameter may be NULL if nr_frames is 0. + * This parameter may be NULL if nr_frames is 0. This + * value may be updated during the course of the operation. */ XEN_GUEST_HANDLE(xen_pfn_t) frame_list; }; From patchwork Tue Sep 22 18:24:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792945 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2CDE56CB for ; Tue, 22 Sep 2020 18:26:04 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EFFF8239D2 for ; Tue, 22 Sep 2020 18:26:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="FWWzFI87" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EFFF8239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmya-0008Mp-Kx; Tue, 22 Sep 2020 18:25:16 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyZ-0008GI-7I for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:15 +0000 X-Inumbo-ID: e493f973-a6de-481c-b043-9d8af8e6b720 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id e493f973-a6de-481c-b043-9d8af8e6b720; Tue, 22 Sep 2020 18:25:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799106; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rU4T0b1gOrbQM5IJxlzUlr+qKaU/UBRT7s0tSb1goJY=; b=FWWzFI87tOVq1tJXsTAj/C6PfnaWdfmLVaMf09HzNtAeXZ6ZaRtbt3UP TTX2jONv+6y0k8m84KI7pAEJYQolFVTnXwy+PJzfnXEm3njP1mCZQSNzq 6swKhkpctxyGopmEYM1Wcs0Oo+lRpATpr+31efqcljldLycaQtmArbxxD k=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: BtEeTIYmEEE0eUHoxJvEe4cCTaaj1CJ0jl3J84aIM+PyauCZuJkj7WWbhF5rosbBTNuFhLB5PU mlpSVoO+WxmRnfol5bW5ToCVpD0WIm7W+a7U/xGC0jGw5YkZkqmH7lCyCHPSh9uwy0rCIME9E+ Avx+J/DTUMcDaSqi5CS01DF4HZMujpWqMgSEFFhsYkW6XEipYLdTOZHbZBQDK40dpVj2ZRCwAG qX5M6jvHU5C8BA0kPNZPzOJRDqZz41av37xpQ90ScgeSiE3G9CL8LJFIhuzKbXF36VQfvNTknt u1c= X-SBRS: 2.7 X-MesageID: 28290906 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="28290906" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 07/11] xen/memory: Improve compat XENMEM_acquire_resource handling Date: Tue, 22 Sep 2020 19:24:40 +0100 Message-ID: <20200922182444.12350-8-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The frame_list is an input, or an output, depending on whether the calling domain is translated or not. The array does not need marshalling in both directions. Furthermore, the copy-in loop was very inefficient, copying 4 bytes at at time. Rewrite it to copy in all nr_frames at once, and then expand compat_pfn_t to xen_pfn_t in place. Re-position the copy-in loop to simplify continuation support in a future patch, and reduce the scope of certain variables. No change in guest observed behaviour. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/common/compat/memory.c | 65 ++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index ed92e05b08..834c5e19d1 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -55,6 +55,8 @@ static int get_reserved_device_memory(xen_pfn_t start, xen_ulong_t nr, int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) { + struct vcpu *curr = current; + struct domain *currd = curr->domain; int split, op = cmd & MEMOP_CMD_MASK; long rc; unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; @@ -399,7 +401,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) case XENMEM_acquire_resource: { - xen_pfn_t *xen_frame_list; + xen_pfn_t *xen_frame_list = NULL; unsigned int max_nr_frames; if ( copy_from_guest(&cmp.mar, compat, 1) ) @@ -417,28 +419,10 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) if ( cmp.mar.nr_frames > max_nr_frames ) return -E2BIG; - if ( compat_handle_is_null(cmp.mar.frame_list) ) - xen_frame_list = NULL; - else - { + /* Marshal the frame list in the remainder of the xlat space. */ + if ( !compat_handle_is_null(cmp.mar.frame_list) ) xen_frame_list = (xen_pfn_t *)(nat.mar + 1); - if ( !compat_handle_okay(cmp.mar.frame_list, - cmp.mar.nr_frames) ) - return -EFAULT; - - for ( i = 0; i < cmp.mar.nr_frames; i++ ) - { - compat_pfn_t frame; - - if ( __copy_from_compat_offset( - &frame, cmp.mar.frame_list, i, 1) ) - return -EFAULT; - - xen_frame_list[i] = frame; - } - } - #define XLAT_mem_acquire_resource_HNDL_frame_list(_d_, _s_) \ set_xen_guest_handle((_d_)->frame_list, xen_frame_list) @@ -446,6 +430,31 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) #undef XLAT_mem_acquire_resource_HNDL_frame_list + if ( xen_frame_list && cmp.mar.nr_frames ) + { + /* + * frame_list is an input for translated guests, and an output + * for untranslated guests. Only copy in for translated guests. + */ + if ( paging_mode_translate(currd) ) + { + compat_pfn_t *compat_frame_list = (void *)xen_frame_list; + + if ( !compat_handle_okay(cmp.mar.frame_list, + cmp.mar.nr_frames) || + __copy_from_compat_offset( + compat_frame_list, cmp.mar.frame_list, + 0, cmp.mar.nr_frames) ) + return -EFAULT; + + /* + * Iterate backwards over compat_frame_list[] expanding + * compat_pfn_t to xen_pfn_t in place. + */ + for ( int x = cmp.mar.nr_frames - 1; x >= 0; --x ) + xen_frame_list[x] = compat_frame_list[x]; + } + } break; } default: @@ -590,8 +599,6 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) case XENMEM_acquire_resource: { - const xen_pfn_t *xen_frame_list = (xen_pfn_t *)(nat.mar + 1); - compat_pfn_t *compat_frame_list = (compat_pfn_t *)(nat.mar + 1); DEFINE_XEN_GUEST_HANDLE(compat_mem_acquire_resource_t); if ( compat_handle_is_null(cmp.mar.frame_list) ) @@ -601,9 +608,18 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) compat_mem_acquire_resource_t), nat.mar, nr_frames) ) return -EFAULT; + break; } - else + + /* + * frame_list is an input for translated guests, and an output for + * untranslated guests. Only copy out for untranslated guests. + */ + if ( !paging_mode_translate(currd) ) { + const xen_pfn_t *xen_frame_list = (xen_pfn_t *)(nat.mar + 1); + compat_pfn_t *compat_frame_list = (compat_pfn_t *)(nat.mar + 1); + /* * NOTE: the smaller compat array overwrites the native * array. @@ -625,7 +641,6 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) cmp.mar.nr_frames) ) return -EFAULT; } - break; } From patchwork Tue Sep 22 18:24:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792949 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1E83D139A for ; Tue, 22 Sep 2020 18:26:17 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E4968239D2 for ; Tue, 22 Sep 2020 18:26:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="QsGwBhxV" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E4968239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyU-0008Iv-NG; Tue, 22 Sep 2020 18:25:10 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyT-0008GC-Vo for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:10 +0000 X-Inumbo-ID: 14f5c2a9-ff66-451f-8133-86acca0362d2 Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 14f5c2a9-ff66-451f-8133-86acca0362d2; Tue, 22 Sep 2020 18:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799104; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VX5HKcJ42GTdKN2aMeeGpC6A33K0f3RBxZiuzBNTlmw=; b=QsGwBhxVOY+k9LzkID4g/t49ovXcbQ16WfIioFAnGJNE2P/gMREm1S6j MwCSoJHNxEz1jdjA/CbXB6dYsKIdZg8y0wPY9dE7j2BPGbFkpsNkZx68W VhpwNAnZtLcHI+AkhRAo9lmbhOSE2ydJjqXcuUvSw0XJ6Jwhh6Ew9THC7 M=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: tf2mZ/0twZBgK3V8kEmLi+CzQrtKTFxADKvq2XSj6uKVvcHAR+K1tcVaBtpozVfDlHPgq1Y9DQ 0PNC+yVds4MrwjMw/u2T6IaSIDzxI1qiLCRWBTN3uZ0Dg/70t0wBV8NYkt2NH7wyA9tBoWEfjs gbvCj9kA83rIZud3e0cA/H8oSGbn6W3/FLFT57BwnOehape1Fyua8Z9Nlu0BlMckFiBs8QpTPN fxiiwiTSdrEePuuqO1Azvz6jXBLM8UO0J0GZmRa5OsIQcHc80v7CoUijTLseQy97Tx4tk2SVC/ Szk= X-SBRS: 2.7 X-MesageID: 27631631 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27631631" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 08/11] xen/memory: Indent part of acquire_resource() Date: Tue, 22 Sep 2020 19:24:41 +0100 Message-ID: <20200922182444.12350-9-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Indent the middle of acquire_resource() inside a do {} while ( 0 ) loop. This is broken out specifically to make the following change readable. No functional change. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/common/memory.c | 66 +++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/xen/common/memory.c b/xen/common/memory.c index c559935732..369154b7c0 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1087,44 +1087,46 @@ static int acquire_resource( goto out; } - switch ( xmar.type ) - { - case XENMEM_resource_grant_table: - rc = gnttab_acquire_resource(d, xmar.id, xmar.frame, xmar.nr_frames, - mfn_list); - break; + do { + switch ( xmar.type ) + { + case XENMEM_resource_grant_table: + rc = gnttab_acquire_resource(d, xmar.id, xmar.frame, xmar.nr_frames, + mfn_list); + break; - default: - rc = arch_acquire_resource(d, xmar.type, xmar.id, xmar.frame, - xmar.nr_frames, mfn_list); - break; - } + default: + rc = arch_acquire_resource(d, xmar.type, xmar.id, xmar.frame, + xmar.nr_frames, mfn_list); + break; + } - if ( rc ) - goto out; + if ( rc ) + goto out; - if ( !paging_mode_translate(currd) ) - { - if ( copy_to_guest(xmar.frame_list, mfn_list, xmar.nr_frames) ) - rc = -EFAULT; - } - else - { - xen_pfn_t gfn_list[ARRAY_SIZE(mfn_list)]; - unsigned int i; + if ( !paging_mode_translate(currd) ) + { + if ( copy_to_guest(xmar.frame_list, mfn_list, xmar.nr_frames) ) + rc = -EFAULT; + } + else + { + xen_pfn_t gfn_list[ARRAY_SIZE(mfn_list)]; + unsigned int i; - if ( copy_from_guest(gfn_list, xmar.frame_list, xmar.nr_frames) ) - rc = -EFAULT; + if ( copy_from_guest(gfn_list, xmar.frame_list, xmar.nr_frames) ) + rc = -EFAULT; - for ( i = 0; !rc && i < xmar.nr_frames; i++ ) - { - rc = set_foreign_p2m_entry(currd, gfn_list[i], - _mfn(mfn_list[i])); - /* rc should be -EIO for any iteration other than the first */ - if ( rc && i ) - rc = -EIO; + for ( i = 0; !rc && i < xmar.nr_frames; i++ ) + { + rc = set_foreign_p2m_entry(currd, gfn_list[i], + _mfn(mfn_list[i])); + /* rc should be -EIO for any iteration other than the first */ + if ( rc && i ) + rc = -EIO; + } } - } + } while ( 0 ); out: rcu_unlock_domain(d); From patchwork Tue Sep 22 18:24:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792947 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49B0B6CB for ; Tue, 22 Sep 2020 18:26:06 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 12600239D2 for ; Tue, 22 Sep 2020 18:26:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="TnRYwCkT" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 12600239D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyQ-0008Gc-9H; Tue, 22 Sep 2020 18:25:06 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKmyP-0008GI-8I for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:25:05 +0000 X-Inumbo-ID: 6421078c-fe93-4655-8de5-36e2dcb6c77c Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 6421078c-fe93-4655-8de5-36e2dcb6c77c; Tue, 22 Sep 2020 18:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799103; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Hrj8h40RescwEXHVafFxUYIEwVRDZ7FpsOywCH2ubf0=; b=TnRYwCkT92d3MuCOPqHCne6RzH6UHZwGPXjaeiju5ie2KSBpBLi2VMr0 vrQwl83ra2V0uGZE5JWwml9yfVCd2M+ovWjIF2GcYpq0wIm6RBeateKKw rOEGhtNr8ykGK00EQZ4JAOfAqs9Zo4KoKnuWNuu6xYtfPQAjJXvzkblRf 0=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: De6Xx1fr/xVk9Efu3GIyaQHkOxaNv3c7W2nX55xm2L5ZzLyEBj5qEHGr+7JQWVcGXnLAnDwq/A fhFxWbAIw37pJCHUNLdUaCwy+Bc9T4oj47PQ/2wao/vaBbWuMeNz4jmQ4sTHqj5LcuCSsnyhku CcICprmLG7LnugGD0O6kPrUtVNu+GBlGYVMlyhLolFDi4aUovUAJzY6HtoeCqgzw3qFfpgWHwl snbwoieLUTJfuGQvHcrqmU3QJS6/HG8KSnqIshVEIY5tD9DmOuTvhpwo8QqMfdDzU2F55yW60S 29w= X-SBRS: 2.7 X-MesageID: 28290895 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="28290895" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Stefano Stabellini , Wei Liu , Julien Grall , Paul Durrant , =?utf-8?q?Micha?= =?utf-8?q?=C5=82_Leszczy=C5=84ski?= , Hubert Jasudowicz , Tamas K Lengyel Subject: [PATCH v2 09/11] xen/memory: Fix mapping grant tables with XENMEM_acquire_resource Date: Tue, 22 Sep 2020 19:24:42 +0100 Message-ID: <20200922182444.12350-10-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" A guests default number of grant frames is 64, and XENMEM_acquire_resource will reject an attempt to map more than 32 frames. This limit is caused by the size of mfn_list[] on the stack. Fix mapping of arbitrary size requests by looping over batches of 32 in acquire_resource(), and using hypercall continuations when necessary. To start with, break _acquire_resource() out of acquire_resource() to cope with type-specific dispatching, and update the return semantics to indicate the number of mfns returned. Update gnttab_acquire_resource() and x86's arch_acquire_resource() to match these new semantics. Have do_memory_op() pass start_extent into acquire_resource() so it can pick up where it left off after a continuation, and loop over batches of 32 until all the work is done, or a continuation needs to occur. compat_memory_op() is a bit more complicated, because it also has to marshal frame_list in the XLAT buffer. Have it account for continuation information itself and hide details from the upper layer, so it can marshal the buffer in chunks if necessary. With these fixes in place, it is now possible to map the whole grant table for a guest. Signed-off-by: Andrew Cooper --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Paul Durrant CC: Michał Leszczyński CC: Hubert Jasudowicz CC: Tamas K Lengyel --- xen/arch/x86/mm.c | 4 +- xen/common/compat/memory.c | 96 ++++++++++++++++++++++++++++++-------- xen/common/grant_table.c | 3 ++ xen/common/memory.c | 114 ++++++++++++++++++++++++++++++++++----------- 4 files changed, 168 insertions(+), 49 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index e82307bdae..8628f51402 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4632,7 +4632,6 @@ int arch_acquire_resource(struct domain *d, unsigned int type, if ( id != (unsigned int)ioservid ) break; - rc = 0; for ( i = 0; i < nr_frames; i++ ) { mfn_t mfn; @@ -4643,6 +4642,9 @@ int arch_acquire_resource(struct domain *d, unsigned int type, mfn_list[i] = mfn_x(mfn); } + if ( i == nr_frames ) + /* Success. Passed nr_frames back to the caller. */ + rc = nr_frames; break; } #endif diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index 834c5e19d1..17619f26ed 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -402,23 +402,10 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) case XENMEM_acquire_resource: { xen_pfn_t *xen_frame_list = NULL; - unsigned int max_nr_frames; if ( copy_from_guest(&cmp.mar, compat, 1) ) return -EFAULT; - /* - * The number of frames handled is currently limited to a - * small number by the underlying implementation, so the - * scratch space should be sufficient for bouncing the - * frame addresses. - */ - max_nr_frames = (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.mar)) / - sizeof(*xen_frame_list); - - if ( cmp.mar.nr_frames > max_nr_frames ) - return -E2BIG; - /* Marshal the frame list in the remainder of the xlat space. */ if ( !compat_handle_is_null(cmp.mar.frame_list) ) xen_frame_list = (xen_pfn_t *)(nat.mar + 1); @@ -432,6 +419,28 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) if ( xen_frame_list && cmp.mar.nr_frames ) { + unsigned int xlat_max_frames = + (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.mar)) / + sizeof(*xen_frame_list); + + if ( start_extent >= nat.mar->nr_frames ) + return -EINVAL; + + /* + * Adjust nat to account for work done on previous + * continuations, leaving cmp pristine. Hide the continaution + * from the native code to prevent double accounting. + */ + nat.mar->nr_frames -= start_extent; + nat.mar->frame += start_extent; + cmd &= MEMOP_CMD_MASK; + + /* + * If there are two many frames to fit within the xlat buffer, + * we'll need to loop to marshal them all. + */ + nat.mar->nr_frames = min(nat.mar->nr_frames, xlat_max_frames); + /* * frame_list is an input for translated guests, and an output * for untranslated guests. Only copy in for translated guests. @@ -444,14 +453,14 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) cmp.mar.nr_frames) || __copy_from_compat_offset( compat_frame_list, cmp.mar.frame_list, - 0, cmp.mar.nr_frames) ) + start_extent, nat.mar->nr_frames) ) return -EFAULT; /* * Iterate backwards over compat_frame_list[] expanding * compat_pfn_t to xen_pfn_t in place. */ - for ( int x = cmp.mar.nr_frames - 1; x >= 0; --x ) + for ( int x = nat.mar->nr_frames - 1; x >= 0; --x ) xen_frame_list[x] = compat_frame_list[x]; } } @@ -600,9 +609,11 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) case XENMEM_acquire_resource: { DEFINE_XEN_GUEST_HANDLE(compat_mem_acquire_resource_t); + unsigned int done; if ( compat_handle_is_null(cmp.mar.frame_list) ) { + ASSERT(split == 0 && rc == 0); if ( __copy_field_to_guest( guest_handle_cast(compat, compat_mem_acquire_resource_t), @@ -611,6 +622,21 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) break; } + if ( split < 0 ) + { + /* Contintuation occured. */ + ASSERT(rc != XENMEM_acquire_resource); + done = cmd >> MEMOP_EXTENT_SHIFT; + } + else + { + /* No continuation. */ + ASSERT(rc == 0); + done = nat.mar->nr_frames; + } + + ASSERT(done <= nat.mar->nr_frames); + /* * frame_list is an input for translated guests, and an output for * untranslated guests. Only copy out for untranslated guests. @@ -626,7 +652,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) */ BUILD_BUG_ON(sizeof(compat_pfn_t) > sizeof(xen_pfn_t)); - for ( i = 0; i < cmp.mar.nr_frames; i++ ) + for ( i = 0; i < done; i++ ) { compat_pfn_t frame = xen_frame_list[i]; @@ -636,15 +662,45 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) compat_frame_list[i] = frame; } - if ( __copy_to_compat_offset(cmp.mar.frame_list, 0, - compat_frame_list, - cmp.mar.nr_frames) ) + if ( __copy_to_compat_offset( + cmp.mar.frame_list, start_extent, + compat_frame_list, done) ) return -EFAULT; } - break; + + start_extent += done; + + /* Completely done. */ + if ( start_extent == cmp.mar.nr_frames ) + break; + + /* + * Done a "full" batch, but we were limited by space in the xlat + * area. Go around the loop again without necesserily returning + * to guest context. + */ + if ( done == nat.mar->nr_frames ) + { + split = 1; + break; + } + + /* Explicit continuation request from a higher level. */ + if ( done < nat.mar->nr_frames ) + return hypercall_create_continuation( + __HYPERVISOR_memory_op, "ih", + op | (start_extent << MEMOP_EXTENT_SHIFT), compat); + + /* + * Well... Somethings gone wrong with the two levels of chunking. + * My condolences to whomever next has to debug this mess. + */ + ASSERT_UNREACHABLE(); + goto crash; } default: + crash: domain_crash(current->domain); split = 0; break; diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 8c401a5540..81db47f8fd 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -4105,6 +4105,9 @@ int gnttab_acquire_resource( for ( i = 0; i < nr_frames; ++i ) mfn_list[i] = virt_to_mfn(vaddrs[frame + i]); + /* Success. Passed nr_frames back to the caller. */ + rc = nr_frames; + out: grant_write_unlock(gt); diff --git a/xen/common/memory.c b/xen/common/memory.c index 369154b7c0..ec276cb9b1 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1027,17 +1027,31 @@ static unsigned int resource_max_frames(struct domain *d, } } +/* + * Returns -errno on error, or positive in the range [1, nr_frames] on + * success. Returning less than nr_frames contitutes a request for a + * continuation. + */ +static int _acquire_resource( + struct domain *d, unsigned int type, unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]) +{ + switch ( type ) + { + case XENMEM_resource_grant_table: + return gnttab_acquire_resource(d, id, frame, nr_frames, mfn_list); + + default: + return arch_acquire_resource(d, type, id, frame, nr_frames, mfn_list); + } +} + static int acquire_resource( - XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg) + XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg, + unsigned long start_extent) { struct domain *d, *currd = current->domain; xen_mem_acquire_resource_t xmar; - /* - * The mfn_list and gfn_list (below) arrays are ok on stack for the - * moment since they are small, but if they need to grow in future - * use-cases then per-CPU arrays or heap allocations may be required. - */ - xen_pfn_t mfn_list[32]; unsigned int max_frames; int rc; @@ -1055,9 +1069,6 @@ static int acquire_resource( if ( xmar.pad != 0 ) return -EINVAL; - if ( xmar.nr_frames > ARRAY_SIZE(mfn_list) ) - return -E2BIG; - rc = rcu_lock_remote_domain_by_id(xmar.domid, &d); if ( rc ) return rc; @@ -1074,7 +1085,7 @@ static int acquire_resource( if ( guest_handle_is_null(xmar.frame_list) ) { - if ( xmar.nr_frames ) + if ( xmar.nr_frames || start_extent ) goto out; xmar.nr_frames = max_frames; @@ -1087,26 +1098,47 @@ static int acquire_resource( goto out; } + /* + * Limiting nr_frames at (UINT_MAX >> MEMOP_EXTENT_SHIFT) isn't ideal. If + * it ever becomes a practical problem, we can switch to mutating + * xmar.{frame,nr_frames,frame_list} in guest memory. + */ + rc = -EINVAL; + if ( start_extent >= xmar.nr_frames || + xmar.nr_frames > (UINT_MAX >> MEMOP_EXTENT_SHIFT) ) + goto out; + + /* Adjust for work done on previous continuations. */ + xmar.nr_frames -= start_extent; + xmar.frame += start_extent; + guest_handle_add_offset(xmar.frame_list, start_extent); + do { - switch ( xmar.type ) - { - case XENMEM_resource_grant_table: - rc = gnttab_acquire_resource(d, xmar.id, xmar.frame, xmar.nr_frames, - mfn_list); - break; + /* + * Arbitrary size. Not too much stack space, and a reasonable stride + * for continutation checks. + */ + xen_pfn_t mfn_list[32]; + unsigned int todo = MIN(ARRAY_SIZE(mfn_list), xmar.nr_frames), done; - default: - rc = arch_acquire_resource(d, xmar.type, xmar.id, xmar.frame, - xmar.nr_frames, mfn_list); - break; - } + rc = _acquire_resource(d, xmar.type, xmar.id, xmar.frame, + todo, mfn_list); + if ( rc < 0 ) + goto out; - if ( rc ) + done = rc; + rc = 0; + if ( done == 0 || done > todo ) + { + ASSERT_UNREACHABLE(); + rc = -EINVAL; goto out; + } + /* Adjust guest frame_list appropriately. */ if ( !paging_mode_translate(currd) ) { - if ( copy_to_guest(xmar.frame_list, mfn_list, xmar.nr_frames) ) + if ( copy_to_guest(xmar.frame_list, mfn_list, done) ) rc = -EFAULT; } else @@ -1114,10 +1146,10 @@ static int acquire_resource( xen_pfn_t gfn_list[ARRAY_SIZE(mfn_list)]; unsigned int i; - if ( copy_from_guest(gfn_list, xmar.frame_list, xmar.nr_frames) ) + if ( copy_from_guest(gfn_list, xmar.frame_list, done) ) rc = -EFAULT; - for ( i = 0; !rc && i < xmar.nr_frames; i++ ) + for ( i = 0; !rc && i < done; i++ ) { rc = set_foreign_p2m_entry(currd, gfn_list[i], _mfn(mfn_list[i])); @@ -1126,7 +1158,32 @@ static int acquire_resource( rc = -EIO; } } - } while ( 0 ); + + if ( rc ) + goto out; + + xmar.nr_frames -= done; + xmar.frame += done; + guest_handle_add_offset(xmar.frame_list, done); + start_extent += done; + + /* + * Explicit contination request from _acquire_resource(), or we've + * still got work to do other work is pending. + */ + if ( done < todo || + (xmar.nr_frames && hypercall_preempt_check()) ) + { + rc = hypercall_create_continuation( + __HYPERVISOR_memory_op, "lh", + XENMEM_acquire_resource | (start_extent << MEMOP_EXTENT_SHIFT), + arg); + goto out; + } + + } while ( xmar.nr_frames ); + + rc = 0; out: rcu_unlock_domain(d); @@ -1593,7 +1650,8 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case XENMEM_acquire_resource: rc = acquire_resource( - guest_handle_cast(arg, xen_mem_acquire_resource_t)); + guest_handle_cast(arg, xen_mem_acquire_resource_t), + start_extent); break; default: From patchwork Tue Sep 22 18:24:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792967 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 59E946CB for ; Tue, 22 Sep 2020 18:35:29 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 242742065D for ; Tue, 22 Sep 2020 18:35:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="IjSYBNRu" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 242742065D Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKn7i-0001oe-A4; Tue, 22 Sep 2020 18:34:42 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKn7h-0001oJ-Du for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:34:41 +0000 X-Inumbo-ID: 0f8ab936-bd09-49ac-a0c9-1898283fc792 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 0f8ab936-bd09-49ac-a0c9-1898283fc792; Tue, 22 Sep 2020 18:34:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799675; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=ZjmZaUz16Rtfto5cL6MHuLw5U//b1IHlG7ceB93+qBg=; b=IjSYBNRulpdoJGMvasA0etwsBNbs9Fsc8/YHuTPP6lFj+frro2/lgI5k 6aZ7aPrjPNbQyyS/B7RfHDlyMt0G1/EvkVio9kOZCfaRYK192vDjxtvs4 WMnRDJ7bejv1z+jKSMoBFVp/fbGMmZ+ErekMECcGHyfDkgMXL0DLcBuY/ k=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: Z8DvEV+6vNjn7RLEMRYOHAc7l24LwDXDKsbrRRhi0mubwKZDtGyT7jT7yMq/bowjp45yGZq+sU bTy14CI8+P08ftLmuCqL9TN4qkCY3PUarm1eKZzUXI0hyM/EwNjh+slc8IgMIi8krkML2CRwtq m5gf8JckQrKJ/LyCQm5sAV/8LisVOoJmGWul76a5kCE363JN4G3vRrLMO3ydG+Da/UMEpoJV5v QGumYmA2y0mUHo94M2XpHKfsW6d4RwoqJBk6c/2UcYt5H6Yu4Ndp67cFKTIa53fmA2p51DbE20 w3o= X-SBRS: 2.7 X-MesageID: 27301294 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27301294" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper Subject: [PATCH v2 10/11] TESTING dom0 Date: Tue, 22 Sep 2020 19:24:43 +0100 Message-ID: <20200922182444.12350-11-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Poke xenforeignmemory_map_resource() from userspace. Confirm that all 40 grant frames can be mapped. Do not apply. Signed-off-by: Andrew Cooper --- tools/misc/Makefile | 4 ++ tools/misc/xen-resource.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 tools/misc/xen-resource.c diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 7d37f297a9..c1d262c329 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -76,6 +76,10 @@ distclean: clean xen-cpuid: xen-cpuid.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS) +xen-resource.o: APPEND_CFLAGS += -Wno-declaration-after-statement +xen-resource: xen-resource.o + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenforeignmemory) $(LDLIBS_libxendevicemodel) $(APPEND_LDFLAGS) + xen-hvmctx: xen-hvmctx.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) diff --git a/tools/misc/xen-resource.c b/tools/misc/xen-resource.c new file mode 100644 index 0000000000..3c29d43a35 --- /dev/null +++ b/tools/misc/xen-resource.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static xc_interface *xch; +static xenforeignmemory_handle *fh; +static xendevicemodel_handle *dh; + +static void test(unsigned int domid, unsigned int type, unsigned int id) +{ + unsigned long nr = ~0; + + printf("Testing d%u, type %u, id %u\n", domid, type, id); + + int rc = xenforeignmemory_resource_size(fh, domid, type, id, &nr); + if ( rc ) + { + printf(" failed %d\n", -errno); + return; + } + else + printf(" %lu frames\n", nr); + + printf(" Trying to map\n"); + void *addr = NULL; + xenforeignmemory_resource_handle *res = + xenforeignmemory_map_resource(fh, domid, type, id, 0, nr, + &addr, PROT_READ | PROT_WRITE, 0); + if ( !res ) + { + perror(" failed"); + return; + } + + printf(" Success\n"); + xenforeignmemory_unmap_resource(fh, res); +} + +int main(int argc, char **argv) +{ + int rc; + + xch = xc_interface_open(NULL, NULL, 0); + fh = xenforeignmemory_open(NULL, 0); + dh = xendevicemodel_open(NULL, 0); + + if ( !xch ) + err(1, "xc_interface_open"); + if ( !fh ) + err(1, "xenforeignmemory_open"); + if ( !dh ) + err(1, "xendevicemodel_open"); + + uint32_t domid = 0; + struct xen_domctl_createdomain dom = { + .flags = XEN_DOMCTL_CDF_hvm, + .max_vcpus = 8, + .max_grant_frames = 40, + + .arch = { + .emulation_flags = XEN_X86_EMU_LAPIC, + }, + }; + + rc = xc_domain_create(xch, &domid, &dom); + if ( rc ) + { + perror("xc_domain_create()"); + goto out; + } + printf("Created d%u\n", domid); + + ioservid_t id = -1; + rc = xendevicemodel_create_ioreq_server(dh, domid, 1, &id); + if ( rc ) + { + perror("xendevicemodel_create_ioreq_server()"); + goto out; + } + printf("Created ioreq server %u\n", id); + + + test(domid, XENMEM_resource_ioreq_server, id); + + test(domid, XENMEM_resource_grant_table, + XENMEM_resource_grant_table_id_shared); + test(domid, XENMEM_resource_grant_table, + XENMEM_resource_grant_table_id_status); + + test(domid, 2, 0); + +out: + if ( id >= 0 ) + xendevicemodel_destroy_ioreq_server(dh, domid, id); + if ( domid ) + xc_domain_destroy(xch, domid); + + return 0; +} From patchwork Tue Sep 22 18:24:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11792965 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 408EA6CB for ; Tue, 22 Sep 2020 18:35:21 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0678B2065D for ; Tue, 22 Sep 2020 18:35:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="CiiHomFN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0678B2065D Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKn7d-0001oO-2E; Tue, 22 Sep 2020 18:34:37 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kKn7c-0001oJ-Fv for xen-devel@lists.xenproject.org; Tue, 22 Sep 2020 18:34:36 +0000 X-Inumbo-ID: b58b9d75-dd97-46f4-8293-94b653e6d0da Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id b58b9d75-dd97-46f4-8293-94b653e6d0da; Tue, 22 Sep 2020 18:34:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1600799675; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=b+c0CfTBNQiJlQlBQvHSife6gvXLhWh6raYBfpFBV5I=; b=CiiHomFNVpxsCGjMKLyNXbRx16TRn5nyTKTIwkR+ZlazUCf3VC4lxOtc YXLgaZrXyDSpzx3gimw3wLss2x14O0PDVOulLocZtc5W4HUbZ4AxLksCo jr3D5PUQVFKRHDDQaKZjNiW6Sh7WAw+wnjqwlMtdJvZRLAcgfsux5xfq8 0=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: Woh/fzD8R2dGQ5igl0Bm4t3Q9PHj5i/c8IhV2mk4RvW9dpXTjtfl82STgG8kUiXF4uTEXnFJSj epOGRSvmbLl5bHJaLwsEjjxVjbLzD3noL/2dJXEq+3fuf8z5k6JSE1tWuvyhPnDpnr2CQMsaDS XT7dCYVDdqGDJAVhqf1Bko3Zh9IYnSOfQoGByagbXRn/eSAfaZVOPQy470rVOq3zqsw1FsKCU5 fLVLoj7XDtegf57dqyPDaYhHf2ObG7AYOHQi+W01tTSSYxS3J3f4Z+GJhVqrYbEcL9N9cRcEeO /+U= X-SBRS: 2.7 X-MesageID: 27269883 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.77,291,1596513600"; d="scan'208";a="27269883" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper Subject: [PATCH v2 11/11] TESTING XTF Date: Tue, 22 Sep 2020 19:24:44 +0100 Message-ID: <20200922182444.12350-12-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200922182444.12350-1-andrew.cooper3@citrix.com> References: <20200922182444.12350-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add an arbitrary "resource type 2" which uses "frames" of a fixed format so both Xen (for a PVH dom0) and XTF (for a PV dom0) can check the integrity of the marshalled buffer. Skip the hypercall preempt check to allow the compat PVH logic a chance to hit the 1020 limit in the XLAT buffer. Do not apply. Signed-off-by: Andrew Cooper --- xen/common/memory.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/xen/common/memory.c b/xen/common/memory.c index ec276cb9b1..15a8ed253e 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1022,11 +1022,33 @@ static unsigned int resource_max_frames(struct domain *d, case XENMEM_resource_grant_table: return gnttab_resource_max_frames(d, id); + case 2: + return 2900; + default: return arch_resource_max_frames(d, type, id); } } +static int _acquire_2(unsigned int id, unsigned long frame, + unsigned int nr_frames, xen_pfn_t mfn_list[]) +{ + unsigned int i; + + for ( i = 0; i < nr_frames; ++i ) + { + mfn_list[i] = 0xdead0000 + frame + i; + + /* Simulate some -ERESTARTs */ + if ( i && ((frame + i) == 22 || + (frame + i) == 37 || + (frame + i) == 1040) ) + break; + } + + return i; +} + /* * Returns -errno on error, or positive in the range [1, nr_frames] on * success. Returning less than nr_frames contitutes a request for a @@ -1041,6 +1063,9 @@ static int _acquire_resource( case XENMEM_resource_grant_table: return gnttab_acquire_resource(d, id, frame, nr_frames, mfn_list); + case 2: + return _acquire_2(id, frame, nr_frames, mfn_list); + default: return arch_acquire_resource(d, type, id, frame, nr_frames, mfn_list); } @@ -1151,6 +1176,18 @@ static int acquire_resource( for ( i = 0; !rc && i < done; i++ ) { + /* + * For debug type 2, check that the marshalled-in frames are + * correct, rather than actually inserting them into the P2M. + */ + if ( xmar.type == 2 ) + { + if ( gfn_list[i] != mfn_list[i] ) + panic("gfn %#lx != mfn %#lx, i %lu\n", + gfn_list[i], mfn_list[i], i + xmar.frame); + continue; + } + rc = set_foreign_p2m_entry(currd, gfn_list[i], _mfn(mfn_list[i])); /* rc should be -EIO for any iteration other than the first */ @@ -1172,7 +1209,7 @@ static int acquire_resource( * still got work to do other work is pending. */ if ( done < todo || - (xmar.nr_frames && hypercall_preempt_check()) ) + (0 && xmar.nr_frames && hypercall_preempt_check()) ) { rc = hypercall_create_continuation( __HYPERVISOR_memory_op, "lh",