From patchwork Fri Apr 22 16:50:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823775 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 039ADC433F5 for ; Fri, 22 Apr 2022 16:52:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=dKKmUjosw4isCnxNKK821O7ekcJ8jfGP2hfspIHLBbU=; b=vewEicJQqNMf6V /FKjM/KkgrsN9zJ/WfUarS/svawlliAj59yEB+myOFwQrVCooBJctpgiWZF7VJNcKTjeo+bnpTFJ7 OTwxeuORiV48Ta9ZObGC3SB9fTkwpGAK3szrorlAi1bevvqKPE/wKH662XyY2pBYGRpva3FzxeTf+ 8SZUjfrZG4r7ag7fRKGgz7TKGh6iXrLVc1u81ucJsNseC+AxdSAsHueWdvc5W8dI7uG5AF5uvO2mj ZKiM35TNqecJDzlP8eUP9DJlteBVGR9kgErWmqGVt+PliUyahUpFzdnozZAL3Q2NU3JlwysFzHHaG rteYZfIKwEiRJZZV5OAw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVN-001YC6-Qg; Fri, 22 Apr 2022 16:51:37 +0000 Received: from mail-lj1-x22d.google.com ([2a00:1450:4864:20::22d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwV9-001Y46-4n for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:24 +0000 Received: by mail-lj1-x22d.google.com with SMTP id u24so2821882ljd.0 for ; Fri, 22 Apr 2022 09:51:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GMgjzuq0mtE7dfPwrz9iyN7XiqhJI/kKUBmloz8CHVM=; b=TvogOFhSkVoEFDDp2UyFM5JT+iRsMeAsMM/Ir0HL2o1J+3AsH38OlCvt5oXs8CCV0S xnxUElm53fIFEcmFNvNSvMmmh4juZ3+WxRoQAU7gWAgnSyXTv4uRTElLcGlojn+w9rdF qDNCuB/K5KxRpOUO1ACvBknXeQucuqYZcVPZzxDWH6TcyWGUucHe6OwZ+exVVrxtH5Wa xzdueEOQxmDYRx+fspEs14YJcnhc7fM4o0YNvW4kICFGZc/ebzCbRgyaUk87mgH3Hb+/ GgKojJu/EjHmouEBcVqfsA7l9jnJtbGlyY8Cf/h0HXmwLUzvJ+uSw/3SbFoXbhRUvmTW BPAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GMgjzuq0mtE7dfPwrz9iyN7XiqhJI/kKUBmloz8CHVM=; b=3sKFc1jOUfNDbdwsFCMJUf67tRATE/pebh2QWh3ujicF2xGe6RH9BH6m3qM5/IvSdH 7S0MfG5gKgj4ccRAUCzqE18sVQ1afoAJjdcPb3Q8iICo3qsBDslOgigLlqecAg2uD02b v/pwqANWhDh7byF0dobWBhGa/DGKcammL92O6PPjPk5qNMfce44F4yo01vX/QQs9ckEk J5J1PAza4rLJ1MaLQC50Jyajx7tkz32lhu/GGenx1Z/inXKqBlqxdHRF3CPRj3iq7FE3 OAn52GyoUTR+VEZ3KIrxHrsPJlZnPKo4QYsMpM/cjRaV2cmEQZxEeh6o/lPZl8QfCGhT Rpnw== X-Gm-Message-State: AOAM533iUDNg6ywfRbjfb/A17wt49KqYTlYy1RvUO7Yycd6ISWim/wA0 WzVnUBvw7UXBIagAz8qNK0s= X-Google-Smtp-Source: ABdhPJxBofHQqIEEOVD/ysfSrlTaHT4d23vVGsnsT2WqL8jP7PaAU3+Os5xoi30E2pyYaSKWwDmonw== X-Received: by 2002:a2e:8659:0:b0:24d:b379:4cc0 with SMTP id i25-20020a2e8659000000b0024db3794cc0mr3390687ljj.289.1650646279861; Fri, 22 Apr 2022 09:51:19 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.18 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:19 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Oleksandr Tyshchenko , Stefano Stabellini , Russell King , Catalin Marinas , Will Deacon , Boris Ostrovsky , Juergen Gross , Logan Gunthorpe , David Hildenbrand , Martin Oliveira , Kees Cook , Jean-Philippe Brucker , Julien Grall , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 1/6] arm/xen: Introduce xen_setup_dma_ops() Date: Fri, 22 Apr 2022 19:50:58 +0300 Message-Id: <1650646263-22047-2-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095123_228701_41CF23FD X-CRM114-Status: GOOD ( 20.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Oleksandr Tyshchenko This patch introduces new helper and places it in new header. The helper's purpose is to assign any Xen specific DMA ops in a single place. For now, we deal with xen-swiotlb DMA ops only. The one of the subsequent commits in current series will add xen-grant DMA ops case. Also re-use the xen_swiotlb_detect() check on Arm32. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini --- Changes RFC -> V1: - update commit description - move commit to the beginning of the series - move #ifdef CONFIG_XEN from dma-mapping.c to xen-ops.h --- arch/arm/include/asm/xen/xen-ops.h | 1 + arch/arm/mm/dma-mapping.c | 7 ++----- arch/arm64/include/asm/xen/xen-ops.h | 1 + arch/arm64/mm/dma-mapping.c | 7 ++----- include/xen/arm/xen-ops.h | 15 +++++++++++++++ 5 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 arch/arm/include/asm/xen/xen-ops.h create mode 100644 arch/arm64/include/asm/xen/xen-ops.h create mode 100644 include/xen/arm/xen-ops.h diff --git a/arch/arm/include/asm/xen/xen-ops.h b/arch/arm/include/asm/xen/xen-ops.h new file mode 100644 index 00000000..8d2fa24 --- /dev/null +++ b/arch/arm/include/asm/xen/xen-ops.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 82ffac6..059cce0 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "dma.h" #include "mm.h" @@ -2287,10 +2287,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, set_dma_ops(dev, dma_ops); -#ifdef CONFIG_XEN - if (xen_initial_domain()) - dev->dma_ops = &xen_swiotlb_dma_ops; -#endif + xen_setup_dma_ops(dev); dev->archdata.dma_ops_setup = true; } diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h new file mode 100644 index 00000000..8d2fa24 --- /dev/null +++ b/arch/arm64/include/asm/xen/xen-ops.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 6719f9e..6099c81 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -9,9 +9,9 @@ #include #include #include -#include #include +#include void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir) @@ -52,8 +52,5 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (iommu) iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1); -#ifdef CONFIG_XEN - if (xen_swiotlb_detect()) - dev->dma_ops = &xen_swiotlb_dma_ops; -#endif + xen_setup_dma_ops(dev); } diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h new file mode 100644 index 00000000..288deb1 --- /dev/null +++ b/include/xen/arm/xen-ops.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM_XEN_OPS_H +#define _ASM_ARM_XEN_OPS_H + +#include + +static inline void xen_setup_dma_ops(struct device *dev) +{ +#ifdef CONFIG_XEN + if (xen_swiotlb_detect()) + dev->dma_ops = &xen_swiotlb_dma_ops; +#endif +} + +#endif /* _ASM_ARM_XEN_OPS_H */ From patchwork Fri Apr 22 16:50:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823776 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 61409C433EF for ; Fri, 22 Apr 2022 16:52:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/Vl9RgovuR/TvPk+8XXKe4ZX/HWKsmhGLZowMtFnp2E=; b=VzeSLDLu1MT6hE WqEZk6jqgS5oFFdESBbDcz4ip/CYwueCsLeWrh88ISxUDBbGfiZhqYxsodXAJEFWTmkWSfzwrbH3P h3N9xfEr+dVOsdY3TV8lTLqd/0pwe9AFigTcU/2Mst5obf6alxUIPuFIc/qnj0ZvxmLFFajRbfXyw wf2/QgYgKi0a47m3N5e685J+2RQvlc94RzqHSMWRwtYm2IelctG1/G6BRUSI3WRo3DPilDfIzCtGY PAj2BwxRwkNcZI9Rmpj7r344QBSa2MZp/rO/Dw2z1Mya24By9OB7GXfK7ndu0hv5/jqqBFapXikXZ ZdECk+BNV6d37Iwz5Y6w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVX-001YFR-Vq; Fri, 22 Apr 2022 16:51:48 +0000 Received: from mail-lj1-x236.google.com ([2a00:1450:4864:20::236]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVA-001Y4a-49 for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:27 +0000 Received: by mail-lj1-x236.google.com with SMTP id q14so10337618ljc.12 for ; Fri, 22 Apr 2022 09:51:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pbGH0EJ6MfeeEzJEuzrpQca/NgV2qpOSu33pTptCq9E=; b=l5FeG5KZgUw75VEghyNLWNSsq1XbGFuddkrMY/kSwoz/2B4wHM7gyCFzKfP0cNxyan z8SPKUCXEVxkxcNsEP7gbZQiduwcfoLcBs5mjAIuC8gZBXbBnkxYjVVyDR8e2G7toS8R 69MktkPQK6iKJGYL2XZ1KzEiEOFe2wxAMQ16bBK3KsxpL7dlsloHnQalFGtfN0iIznvZ hCeI/uWsOIc9VtBfZ7iFb0wv2jnA4qZqABUCEQC5EiWEg0ZznfO049sxLpj82IYG8GbF dmcms/+GjyGaQlZtu02c65QMO8SMZcOn1ZRMAtPLfkyTPLTwgxLPNrIWnqPwU1TMwJCM p6pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pbGH0EJ6MfeeEzJEuzrpQca/NgV2qpOSu33pTptCq9E=; b=n9fILzHBIbPssxHbE1dN+5D3jp6AVlQaWBi1XIDpecfErTzzVjZjyoQbCncKNuITVT bt3CXW1epyhjUMwq7PKDfs+s+cvLQQXNeuIlC+eBsKUDUqlHQF3Qbdl8XoKVQtm+bEuW Vq9ui0kRIxHoRe0UhWAjGv+DKWb2tY1PyL1b6gMOrl7BLZbKNE1LJFJbbp7QOYkYFtWt pHQW+YM7+vh6IMrTMYtvoApz0/OmJjIWG+YpMe9hmWCXTjNdCAKF3NpHj8rf9cu93kZH zm1soDceHN6gtL7vun1LuIISOnve1EYkRK/1RTcEalAxOb/AHwQNIBQpgTH3fn+H5uZm snYw== X-Gm-Message-State: AOAM532Bdrcucq0CbdryFCfiRU8Og/MoTh1vGCO9D1q30PPzQIBAz6xT 41w2e43JlA+AUi+zKD+zwPY= X-Google-Smtp-Source: ABdhPJzXR1tqIb0yStMleNK7DtbOn2CfKFh2xfxXbFehkBHPpsyEBLUWQr+LG3hsAxYll2f+Op0pKA== X-Received: by 2002:a2e:a7d5:0:b0:24d:ba78:1d30 with SMTP id x21-20020a2ea7d5000000b0024dba781d30mr3375134ljp.285.1650646281488; Fri, 22 Apr 2022 09:51:21 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:20 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Juergen Gross , Boris Ostrovsky , Stefano Stabellini , Julien Grall , Oleksandr Tyshchenko , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 2/6] xen/grants: support allocating consecutive grants Date: Fri, 22 Apr 2022 19:50:59 +0300 Message-Id: <1650646263-22047-3-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095124_196180_0BE223AB X-CRM114-Status: GOOD ( 30.02 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Juergen Gross For support of virtio via grant mappings in rare cases larger mappings using consecutive grants are needed. Support those by adding a bitmap of free grants. As consecutive grants will be needed only in very rare cases (e.g. when configuring a virtio device with a multi-page ring), optimize for the normal case of non-consecutive allocations. Signed-off-by: Juergen Gross --- Changes RFC -> V1: - no changes --- drivers/xen/grant-table.c | 238 +++++++++++++++++++++++++++++++++++++++------- include/xen/grant_table.h | 4 + 2 files changed, 210 insertions(+), 32 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 8ccccac..1b458c0 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -33,6 +33,7 @@ #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -72,9 +73,32 @@ static grant_ref_t **gnttab_list; static unsigned int nr_grant_frames; + +/* + * Handling of free grants: + * + * Free grants are in a simple list anchored in gnttab_free_head. They are + * linked by grant ref, the last element contains GNTTAB_LIST_END. The number + * of free entries is stored in gnttab_free_count. + * Additionally there is a bitmap of free entries anchored in + * gnttab_free_bitmap. This is being used for simplifying allocation of + * multiple consecutive grants, which is needed e.g. for support of virtio. + * gnttab_last_free is used to add free entries of new frames at the end of + * the free list. + * gnttab_free_tail_ptr specifies the variable which references the start + * of consecutive free grants ending with gnttab_last_free. This pointer is + * updated in a rather defensive way, in order to avoid performance hits in + * hot paths. + * All those variables are protected by gnttab_list_lock. + */ static int gnttab_free_count; -static grant_ref_t gnttab_free_head; +static unsigned int gnttab_size; +static grant_ref_t gnttab_free_head = GNTTAB_LIST_END; +static grant_ref_t gnttab_last_free = GNTTAB_LIST_END; +static grant_ref_t *gnttab_free_tail_ptr; +static unsigned long *gnttab_free_bitmap; static DEFINE_SPINLOCK(gnttab_list_lock); + struct grant_frames xen_auto_xlat_grant_frames; static unsigned int xen_gnttab_version; module_param_named(version, xen_gnttab_version, uint, 0); @@ -170,16 +194,111 @@ static int get_free_entries(unsigned count) ref = head = gnttab_free_head; gnttab_free_count -= count; - while (count-- > 1) - head = gnttab_entry(head); + while (count--) { + bitmap_clear(gnttab_free_bitmap, head, 1); + if (gnttab_free_tail_ptr == __gnttab_entry(head)) + gnttab_free_tail_ptr = &gnttab_free_head; + if (count) + head = gnttab_entry(head); + } gnttab_free_head = gnttab_entry(head); gnttab_entry(head) = GNTTAB_LIST_END; + if (!gnttab_free_count) { + gnttab_last_free = GNTTAB_LIST_END; + gnttab_free_tail_ptr = NULL; + } + spin_unlock_irqrestore(&gnttab_list_lock, flags); return ref; } +static int get_seq_entry_count(void) +{ + if (gnttab_last_free == GNTTAB_LIST_END || !gnttab_free_tail_ptr || + *gnttab_free_tail_ptr == GNTTAB_LIST_END) + return 0; + + return gnttab_last_free - *gnttab_free_tail_ptr + 1; +} + +/* Rebuilds the free grant list and tries to find count consecutive entries. */ +static int get_free_seq(unsigned int count) +{ + int ret = -ENOSPC; + unsigned int from, to; + grant_ref_t *last; + + gnttab_free_tail_ptr = &gnttab_free_head; + last = &gnttab_free_head; + + for (from = find_first_bit(gnttab_free_bitmap, gnttab_size); + from < gnttab_size; + from = find_next_bit(gnttab_free_bitmap, gnttab_size, to + 1)) { + to = find_next_zero_bit(gnttab_free_bitmap, gnttab_size, + from + 1); + if (ret < 0 && to - from >= count) { + ret = from; + bitmap_clear(gnttab_free_bitmap, ret, count); + from += count; + gnttab_free_count -= count; + if (from == to) + continue; + } + + while (from < to) { + *last = from; + last = __gnttab_entry(from); + gnttab_last_free = from; + from++; + } + if (to < gnttab_size) + gnttab_free_tail_ptr = __gnttab_entry(to - 1); + } + + *last = GNTTAB_LIST_END; + if (gnttab_last_free != gnttab_size - 1) + gnttab_free_tail_ptr = NULL; + + return ret; +} + +static int get_free_entries_seq(unsigned int count) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&gnttab_list_lock, flags); + + if (gnttab_free_count < count) { + ret = gnttab_expand(count - gnttab_free_count); + if (ret < 0) + goto out; + } + + if (get_seq_entry_count() < count) { + ret = get_free_seq(count); + if (ret >= 0) + goto out; + ret = gnttab_expand(count - get_seq_entry_count()); + if (ret < 0) + goto out; + } + + ret = *gnttab_free_tail_ptr; + *gnttab_free_tail_ptr = gnttab_entry(ret + count - 1); + gnttab_free_count -= count; + if (!gnttab_free_count) + gnttab_free_tail_ptr = NULL; + bitmap_clear(gnttab_free_bitmap, ret, count); + + out: + spin_unlock_irqrestore(&gnttab_list_lock, flags); + + return ret; +} + static void do_free_callbacks(void) { struct gnttab_free_callback *callback, *next; @@ -206,17 +325,48 @@ static inline void check_free_callbacks(void) do_free_callbacks(); } -static void put_free_entry(grant_ref_t ref) +static void put_free_entry_locked(grant_ref_t ref) { - unsigned long flags; - spin_lock_irqsave(&gnttab_list_lock, flags); gnttab_entry(ref) = gnttab_free_head; gnttab_free_head = ref; + if (!gnttab_free_count) + gnttab_last_free = ref; + if (gnttab_free_tail_ptr == &gnttab_free_head) + gnttab_free_tail_ptr = __gnttab_entry(ref); gnttab_free_count++; + bitmap_set(gnttab_free_bitmap, ref, 1); +} + +static void put_free_entry(grant_ref_t ref) +{ + unsigned long flags; + + spin_lock_irqsave(&gnttab_list_lock, flags); + put_free_entry_locked(ref); check_free_callbacks(); spin_unlock_irqrestore(&gnttab_list_lock, flags); } +static void gnttab_set_free(unsigned int start, unsigned int n) +{ + unsigned int i; + + for (i = start; i < start + n - 1; i++) + gnttab_entry(i) = i + 1; + + gnttab_entry(i) = GNTTAB_LIST_END; + if (!gnttab_free_count) { + gnttab_free_head = start; + gnttab_free_tail_ptr = &gnttab_free_head; + } else { + gnttab_entry(gnttab_last_free) = start; + } + gnttab_free_count += n; + gnttab_last_free = i; + + bitmap_set(gnttab_free_bitmap, start, n); +} + /* * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2. * Introducing a valid entry into the grant table: @@ -448,23 +598,31 @@ void gnttab_free_grant_references(grant_ref_t head) { grant_ref_t ref; unsigned long flags; - int count = 1; - if (head == GNTTAB_LIST_END) - return; + spin_lock_irqsave(&gnttab_list_lock, flags); - ref = head; - while (gnttab_entry(ref) != GNTTAB_LIST_END) { - ref = gnttab_entry(ref); - count++; + while (head != GNTTAB_LIST_END) { + ref = gnttab_entry(head); + put_free_entry_locked(head); + head = ref; } - gnttab_entry(ref) = gnttab_free_head; - gnttab_free_head = head; - gnttab_free_count += count; check_free_callbacks(); spin_unlock_irqrestore(&gnttab_list_lock, flags); } EXPORT_SYMBOL_GPL(gnttab_free_grant_references); +void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&gnttab_list_lock, flags); + for (i = count; i > 0; i--) + put_free_entry_locked(head + i - 1); + check_free_callbacks(); + spin_unlock_irqrestore(&gnttab_list_lock, flags); +} +EXPORT_SYMBOL_GPL(gnttab_free_grant_reference_seq); + int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) { int h = get_free_entries(count); @@ -478,6 +636,24 @@ int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) } EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); +int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first) +{ + int h; + + if (count == 1) + h = get_free_entries(1); + else + h = get_free_entries_seq(count); + + if (h < 0) + return -ENOSPC; + + *first = h; + + return 0; +} +EXPORT_SYMBOL_GPL(gnttab_alloc_grant_reference_seq); + int gnttab_empty_grant_references(const grant_ref_t *private_head) { return (*private_head == GNTTAB_LIST_END); @@ -570,16 +746,13 @@ static int grow_gnttab_list(unsigned int more_frames) goto grow_nomem; } + gnttab_set_free(gnttab_size, extra_entries); - for (i = grefs_per_frame * nr_grant_frames; - i < grefs_per_frame * new_nr_grant_frames - 1; i++) - gnttab_entry(i) = i + 1; - - gnttab_entry(i) = gnttab_free_head; - gnttab_free_head = grefs_per_frame * nr_grant_frames; - gnttab_free_count += extra_entries; + if (!gnttab_free_tail_ptr) + gnttab_free_tail_ptr = __gnttab_entry(gnttab_size); nr_grant_frames = new_nr_grant_frames; + gnttab_size += extra_entries; check_free_callbacks(); @@ -1424,7 +1597,6 @@ int gnttab_init(void) int i; unsigned long max_nr_grant_frames; unsigned int max_nr_glist_frames, nr_glist_frames; - unsigned int nr_init_grefs; int ret; gnttab_request_version(); @@ -1452,6 +1624,13 @@ int gnttab_init(void) } } + i = gnttab_interface->grefs_per_grant_frame * max_nr_grant_frames; + gnttab_free_bitmap = bitmap_zalloc(i, GFP_KERNEL); + if (!gnttab_free_bitmap) { + ret = -ENOMEM; + goto ini_nomem; + } + ret = arch_gnttab_init(max_nr_grant_frames, nr_status_frames(max_nr_grant_frames)); if (ret < 0) @@ -1462,15 +1641,9 @@ int gnttab_init(void) goto ini_nomem; } - nr_init_grefs = nr_grant_frames * - gnttab_interface->grefs_per_grant_frame; - - for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) - gnttab_entry(i) = i + 1; + gnttab_size = nr_grant_frames * gnttab_interface->grefs_per_grant_frame; - gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; - gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; - gnttab_free_head = NR_RESERVED_ENTRIES; + gnttab_set_free(NR_RESERVED_ENTRIES, gnttab_size - NR_RESERVED_ENTRIES); printk("Grant table initialized\n"); return 0; @@ -1479,6 +1652,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); + bitmap_free(gnttab_free_bitmap); return ret; } EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index dfd5bf3..d815e1d 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -129,10 +129,14 @@ int gnttab_try_end_foreign_access(grant_ref_t ref); */ int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head); +int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first); + void gnttab_free_grant_reference(grant_ref_t ref); void gnttab_free_grant_references(grant_ref_t head); +void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count); + int gnttab_empty_grant_references(const grant_ref_t *pprivate_head); int gnttab_claim_grant_reference(grant_ref_t *pprivate_head); From patchwork Fri Apr 22 16:51:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823777 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 77E37C433FE for ; Fri, 22 Apr 2022 16:53:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=djntZ7cmFN/Paoiz1P375VH5KYla7b92EP3S85SOb4M=; b=ICqE9pQqdXL97Z xqNzDS7V+JV5GJjBLs+rlgzQ4Cr1hnLB4R/JcHwlrdTjJCjBPF8uWJAJI3LlI6diqWqw3qF/kGL4+ NYGMBkN4nbmqbWdzcN5nuVpaHuzpmcWmkmM+hFAHsVbyCE0i5j1tVie2uQnFN1TssqmbPqh131p6G D51OsxReoiuk5cYyUAQ+Dyv9kk5Np7ziU8X1ArTz76da/9tBgDDecuL6bJ3a6vsHZH4b8Zud2NAlh hicY2wot3KKG1OazjxPnP4uuBPcrWNCdGscx5lQwqH0hrzyUABhIWQYUa01BNoyQlRNglTUNujqQn yLk5Uyt5V955MxpHCL7A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVj-001YJ3-8S; Fri, 22 Apr 2022 16:51:59 +0000 Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVB-001Y5W-CZ for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:28 +0000 Received: by mail-lf1-x129.google.com with SMTP id h3so10578424lfu.8 for ; Fri, 22 Apr 2022 09:51:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=o6f6b9Ed2EOTSIl43sWJ1e4CyXkESkrVfEWzvoot9Wk=; b=mAUA9xma+eay/TnfhAP6yaN1yv/vOdxInTPx3XbLjEy67v+x1BSm6nrFpg3Cj2/Dun JDvJobIjZFNimuCmWOJGHF2Le3njiIeAjD0jp8RVAlb/iCh309R96+lQzF2+nuZKgkRo 1FI1ChP7jLX3bOf7kgAEAud9NHv6fDGSG+IC/DNbDJzeHAH1za4wBtv5HDezvWv4L78w Q0fxrK8rqC6zcO7os3J4orGrGe2ijTtjKZWKjd19vxXdpKlIlXZV9VX1aTikdRNH5PqF NA1+MdqActyKZ9hxk5RzK2Hv61ZFl+PWOsltfbV4YX7aMBHEo3Ftue6aABERdx8ACvKS HL9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=o6f6b9Ed2EOTSIl43sWJ1e4CyXkESkrVfEWzvoot9Wk=; b=Fu9SZMdo4kvo26/2u4kRfm4M7aCU1DXk+tWRV2QHkiDdC8H/Y179KSa3fxTgZQtzQm v2GA1yBRLlZ26gfFm5qy+uVUQc43khSIjRQzPEyX9Q7S8ONo3UjD95Tg8RO/YURlEFrL 5aJp0IBLwo0X4gCozCd3S0C1+y8MtlQL1Sd+1uu0ET1bd56Hpwv8KZln0o0/hPWahZZh Wy6kMQimwMUW3P5rT00e4uNmZapLqmgN9zKz87OaPgaj3tVmkcpJHjzFGJeckbaMaG8I R6bx3nmypaSiWp1QCMJJ65iIIsq0BhPLcg/ROaJSezIJRM6b1j0ZWWf8mlSMMLJLm100 Xpxg== X-Gm-Message-State: AOAM530kx4l2ick3n2BIwsELQpzWtjzghfKAJIw679G/q8GmbkFIBMXU HgMQYVtZuh+b4UZKaoMEXlE= X-Google-Smtp-Source: ABdhPJxUulQza4XzwHS+vn+t0JcKH1tSxdalQ0Xh720bOQBE/5H0dXKzgQ/JULuYgnjvPsZUQgNOsg== X-Received: by 2002:a05:6512:2385:b0:470:6e19:7ec8 with SMTP id c5-20020a056512238500b004706e197ec8mr3580179lfv.303.1650646282914; Fri, 22 Apr 2022 09:51:22 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:22 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, x86@kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Juergen Gross , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Boris Ostrovsky , Stefano Stabellini , Julien Grall , Oleksandr Tyshchenko , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 3/6] xen/virtio: Add option to restrict memory access under Xen Date: Fri, 22 Apr 2022 19:51:00 +0300 Message-Id: <1650646263-22047-4-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095125_542511_61F96C93 X-CRM114-Status: GOOD ( 34.39 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Juergen Gross Introduce Xen grant DMA-mapping layer which contains special DMA-mapping routines for providing grant references as DMA addresses to be used by frontends (e.g. virtio) in Xen guests. In order to support virtio in Xen guests add a config option XEN_VIRTIO enabling the user to specify whether in all Xen guests virtio should be able to access memory via Xen grant mappings only on the host side. As this also requires providing arch_has_restricted_virtio_memory_access implementation, switch from a pure stub to a real function on Arm and combine with existing implementation for the SEV guests on x86. Add the needed functionality by providing a special set of DMA ops handling the needed grant operations for the I/O pages. Signed-off-by: Juergen Gross Signed-off-by: Oleksandr Tyshchenko --- Changes RFC -> V1: - squash with almost all changes from commit (except handling "xen,dev-domid" property): "[PATCH 4/6] virtio: Various updates to xen-virtio DMA ops layer" - update commit subject/description and comments in code - leave only single Kconfig option XEN_VIRTIO and remove architectural dependencies - introduce common xen_has_restricted_virtio_memory_access() in xen.h and update arch_has_restricted_virtio_memory_access() for both Arm and x86 to call new helper - use (1ULL << 63) instead of 0x8000000000000000ULL for XEN_GRANT_ADDR_OFF - implement xen_virtio_dma_map(unmap)_sg() using example in swiotlb-xen.c - optimize padding by moving "broken" field in struct xen_virtio_data - remove unneeded per-device spinlock - remove the inclusion of virtio_config.h - remane everything according to the new naming scheme: s/virtio/grant_dma - add new hidden config option XEN_GRANT_DMA_OPS --- arch/arm/xen/enlighten.c | 8 ++ arch/x86/mm/init.c | 11 ++ arch/x86/mm/mem_encrypt.c | 5 - drivers/xen/Kconfig | 15 +++ drivers/xen/Makefile | 1 + drivers/xen/grant-dma-ops.c | 317 ++++++++++++++++++++++++++++++++++++++++++++ include/xen/xen-ops.h | 8 ++ include/xen/xen.h | 5 + 8 files changed, 365 insertions(+), 5 deletions(-) create mode 100644 drivers/xen/grant-dma-ops.c diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index ec5b082..49af493 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -409,6 +409,14 @@ int __init arch_xen_unpopulated_init(struct resource **res) } #endif +#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS +int arch_has_restricted_virtio_memory_access(void) +{ + return xen_has_restricted_virtio_memory_access(); +} +EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access); +#endif + static void __init xen_dt_guest_init(void) { struct device_node *xen_node; diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index d8cfce2..fe84a3e 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include @@ -1065,3 +1067,12 @@ unsigned long max_swapfile_size(void) return pages; } #endif + +#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS +int arch_has_restricted_virtio_memory_access(void) +{ + return (xen_has_restricted_virtio_memory_access() || + cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)); +} +EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access); +#endif diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index 50d2099..dda020f 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -77,8 +77,3 @@ void __init mem_encrypt_init(void) print_mem_encrypt_feature_info(); } -int arch_has_restricted_virtio_memory_access(void) -{ - return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT); -} -EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access); diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 120d32f..b95581f 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -335,4 +335,19 @@ config XEN_UNPOPULATED_ALLOC having to balloon out RAM regions in order to obtain physical memory space to create such mappings. +config XEN_GRANT_DMA_OPS + bool + select DMA_OPS + +config XEN_VIRTIO + bool "Xen virtio support" + default n + depends on VIRTIO + select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS + select XEN_GRANT_DMA_OPS + help + Enable virtio support for running as Xen guest. Depending on the + guest type this will require special support on the backend side + (qemu or kernel, depending on the virtio device types used). + endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 5aae66e..1a23cb0 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -39,3 +39,4 @@ xen-gntalloc-y := gntalloc.o xen-privcmd-y := privcmd.o privcmd-buf.o obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF) += xen-front-pgdir-shbuf.o obj-$(CONFIG_XEN_UNPOPULATED_ALLOC) += unpopulated-alloc.o +obj-$(CONFIG_XEN_GRANT_DMA_OPS) += grant-dma-ops.o diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c new file mode 100644 index 00000000..0e69aa8 --- /dev/null +++ b/drivers/xen/grant-dma-ops.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: GPL-2.0-only +/****************************************************************************** + * Xen grant DMA-mapping layer - contains special DMA-mapping routines + * for providing grant references as DMA addresses to be used by frontends + * (e.g. virtio) in Xen guests + * + * Copyright (c) 2021, Juergen Gross + */ + +#include +#include +#include +#include +#include +#include +#include + +struct xen_grant_dma_data { + /* The ID of backend domain */ + domid_t dev_domid; + /* Is device behaving sane? */ + bool broken; + struct device *dev; + struct list_head list; +}; + +static LIST_HEAD(xen_grant_dma_devices); +static DEFINE_SPINLOCK(xen_grant_dma_lock); + +#define XEN_GRANT_DMA_ADDR_OFF (1ULL << 63) + +static inline dma_addr_t grant_to_dma(grant_ref_t grant) +{ + return XEN_GRANT_DMA_ADDR_OFF | ((dma_addr_t)grant << PAGE_SHIFT); +} + +static inline grant_ref_t dma_to_grant(dma_addr_t dma) +{ + return (grant_ref_t)((dma & ~XEN_GRANT_DMA_ADDR_OFF) >> PAGE_SHIFT); +} + +static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev) +{ + struct xen_grant_dma_data *data = NULL; + bool found = false; + + spin_lock(&xen_grant_dma_lock); + + list_for_each_entry(data, &xen_grant_dma_devices, list) { + if (data->dev == dev) { + found = true; + break; + } + } + + spin_unlock(&xen_grant_dma_lock); + + return found ? data : NULL; +} + +/* + * DMA ops for Xen frontends (e.g. virtio). + * + * Used to act as a kind of software IOMMU for Xen guests by using grants as + * DMA addresses. + * Such a DMA address is formed by using the grant reference as a frame + * number and setting the highest address bit (this bit is for the backend + * to be able to distinguish it from e.g. a mmio address). + * + * Note that for now we hard wire dom0 to be the backend domain. In order + * to support any domain as backend we'd need to add a way to communicate + * the domid of this backend, e.g. via Xenstore, via the PCI-device's + * config space or DT/ACPI. + */ +static void *xen_grant_dma_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + unsigned long pfn; + grant_ref_t grant; + void *ret; + + data = find_xen_grant_dma_data(dev); + if (!data) + return NULL; + + if (unlikely(data->broken)) + return NULL; + + ret = alloc_pages_exact(n_pages * PAGE_SIZE, gfp); + if (!ret) + return NULL; + + pfn = virt_to_pfn(ret); + + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) { + free_pages_exact(ret, n_pages * PAGE_SIZE); + return NULL; + } + + for (i = 0; i < n_pages; i++) { + gnttab_grant_foreign_access_ref(grant + i, data->dev_domid, + pfn_to_gfn(pfn + i), 0); + } + + *dma_handle = grant_to_dma(grant); + + return ret; +} + +static void xen_grant_dma_free(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle, unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + + data = find_xen_grant_dma_data(dev); + if (!data) + return; + + if (unlikely(data->broken)) + return; + + grant = dma_to_grant(dma_handle); + + for (i = 0; i < n_pages; i++) { + if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) { + dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n"); + data->broken = true; + return; + } + } + + gnttab_free_grant_reference_seq(grant, n_pages); + + free_pages_exact(vaddr, n_pages * PAGE_SIZE); +} + +static struct page *xen_grant_dma_alloc_pages(struct device *dev, size_t size, + dma_addr_t *dma_handle, + enum dma_data_direction dir, + gfp_t gfp) +{ + WARN_ONCE(1, "xen_grant_dma_alloc_pages size %zu\n", size); + return NULL; +} + +static void xen_grant_dma_free_pages(struct device *dev, size_t size, + struct page *vaddr, dma_addr_t dma_handle, + enum dma_data_direction dir) +{ + WARN_ONCE(1, "xen_grant_dma_free_pages size %zu\n", size); +} + +static dma_addr_t xen_grant_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + dma_addr_t dma_handle; + + BUG_ON(dir == DMA_NONE); + + data = find_xen_grant_dma_data(dev); + if (!data) + return DMA_MAPPING_ERROR; + + if (unlikely(data->broken)) + return DMA_MAPPING_ERROR; + + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) + return DMA_MAPPING_ERROR; + + for (i = 0; i < n_pages; i++) { + gnttab_grant_foreign_access_ref(grant + i, data->dev_domid, + xen_page_to_gfn(page) + i, dir == DMA_TO_DEVICE); + } + + dma_handle = grant_to_dma(grant) + offset; + + return dma_handle; +} + +static void xen_grant_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + + BUG_ON(dir == DMA_NONE); + + data = find_xen_grant_dma_data(dev); + if (!data) + return; + + if (unlikely(data->broken)) + return; + + grant = dma_to_grant(dma_handle); + + for (i = 0; i < n_pages; i++) { + if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) { + dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n"); + data->broken = true; + return; + } + } + + gnttab_free_grant_reference_seq(grant, n_pages); +} + +static void xen_grant_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct scatterlist *s; + unsigned int i; + + BUG_ON(dir == DMA_NONE); + + for_each_sg(sg, s, nents, i) + xen_grant_dma_unmap_page(dev, s->dma_address, sg_dma_len(s), dir, + attrs); +} + +static int xen_grant_dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct scatterlist *s; + unsigned int i; + + BUG_ON(dir == DMA_NONE); + + for_each_sg(sg, s, nents, i) { + s->dma_address = xen_grant_dma_map_page(dev, sg_page(s), s->offset, + s->length, dir, attrs); + if (s->dma_address == DMA_MAPPING_ERROR) + goto out; + + sg_dma_len(s) = s->length; + } + + return nents; + +out: + xen_grant_dma_unmap_sg(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); + sg_dma_len(sg) = 0; + + return -EIO; +} + +static int xen_grant_dma_supported(struct device *dev, u64 mask) +{ + return mask == DMA_BIT_MASK(64); +} + +static const struct dma_map_ops xen_grant_dma_ops = { + .alloc = xen_grant_dma_alloc, + .free = xen_grant_dma_free, + .alloc_pages = xen_grant_dma_alloc_pages, + .free_pages = xen_grant_dma_free_pages, + .mmap = dma_common_mmap, + .get_sgtable = dma_common_get_sgtable, + .map_page = xen_grant_dma_map_page, + .unmap_page = xen_grant_dma_unmap_page, + .map_sg = xen_grant_dma_map_sg, + .unmap_sg = xen_grant_dma_unmap_sg, + .dma_supported = xen_grant_dma_supported, +}; + +void xen_grant_setup_dma_ops(struct device *dev) +{ + struct xen_grant_dma_data *data; + uint32_t dev_domid; + + data = find_xen_grant_dma_data(dev); + if (data) { + dev_err(dev, "Xen grant DMA data is already created\n"); + return; + } + + /* XXX The dom0 is hardcoded as the backend domain for now */ + dev_domid = 0; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + dev_err(dev, "Сannot allocate Xen grant DMA data\n"); + goto err; + } + data->dev_domid = dev_domid; + data->dev = dev; + + spin_lock(&xen_grant_dma_lock); + list_add(&data->list, &xen_grant_dma_devices); + spin_unlock(&xen_grant_dma_lock); + + dev->dma_ops = &xen_grant_dma_ops; + + return; + +err: + dev_err(dev, "Сannot set up Xen grant DMA ops, retain platform DMA ops\n"); +} +EXPORT_SYMBOL_GPL(xen_grant_setup_dma_ops); + +MODULE_DESCRIPTION("Xen grant DMA-mapping layer"); +MODULE_AUTHOR("Juergen Gross "); +MODULE_LICENSE("GPL"); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index a3584a3..4f9fad5 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -221,4 +221,12 @@ static inline void xen_preemptible_hcall_end(void) { } #endif /* CONFIG_XEN_PV && !CONFIG_PREEMPTION */ +#ifdef CONFIG_XEN_GRANT_DMA_OPS +void xen_grant_setup_dma_ops(struct device *dev); +#else +static inline void xen_grant_setup_dma_ops(struct device *dev) +{ +} +#endif /* CONFIG_XEN_GRANT_DMA_OPS */ + #endif /* INCLUDE_XEN_OPS_H */ diff --git a/include/xen/xen.h b/include/xen/xen.h index a99bab8..fe6e6bb 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -52,6 +52,11 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, extern u64 xen_saved_max_mem_size; #endif +static inline int xen_has_restricted_virtio_memory_access(void) +{ + return IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain(); +} + #ifdef CONFIG_XEN_UNPOPULATED_ALLOC int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages); void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages); From patchwork Fri Apr 22 16:51:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823778 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1A214C433F5 for ; Fri, 22 Apr 2022 16:53:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=wlMby1Ix+niHctsyzJkXX4+vAzMfXlQdwr5wT/km+vM=; b=Uc/F11lDjkuONa no/TcCmV49NkGFv7n3A+losy9XpxYbMeGugzfO+48V13DsA3TXy3GIh2n7xAWkfxtV3O5SA/NH/fP Wiw9XbEGMZuZsigxYozz9vJ1HhTsLtx1N0h/cBC3/fQSjGlAmNPOHRdiM4aB4xbtzCH0ITFvkX1b5 kSHQXbxS4gClml0ebmhw6Phjos3/DOtDad0r6vzXhUf9fGeexItwspkQ/ys5I8D/OyrNRhxFFCiiG rT1SRDpRNUV8aFwqBwl6RzawmlxvSpNenbRVX4K2MkzlGbze0olfchfpIUVzAeYaMul3Rwc4Ch11t lc5N5lkozzys4rkci2TQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwW2-001YS3-Rw; Fri, 22 Apr 2022 16:52:19 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVC-001Y6C-LV for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:29 +0000 Received: by mail-lf1-x12e.google.com with SMTP id p10so15276236lfa.12 for ; Fri, 22 Apr 2022 09:51:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=99hspxuLODhQpov2wjpLVe38h5x1eJYakvWm7x8e6iI=; b=F23kF0eGH2ZVB+UGEjmW9/zKmFnzoAMLghAwzApvwMCcMhtBG9yJPpY4U1QzTxgJqh dlRXZHbEg3zZ7nY0RRV+8fUOu1XkZkXeqKyrW16n02fiZBATqOd2CzVkTaqbBEsKlX+6 r6aK5PoP5QLM42PK/aLq8s/VUKQChEmq/ezbmXtxZxY1a/RDaoMGUVuns/+Ft+exgVHV qbfu1h52HdfRiNt9rNvFnhuiPOsYt6N8H7gak3I0DBjmtU3G2m7PdaKAunzdkWOdWVMV ovHh6R/nKxeNIZ67iu83BqdSWGokrQ3h7RK4/vcpMr2+xi4nqmoXe2TQmCa8LS8q13oq 2CTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=99hspxuLODhQpov2wjpLVe38h5x1eJYakvWm7x8e6iI=; b=B3ckiEk2hFzTsVtFfKXLp8F0nnHjE/514QZMc0PXPWEHRudy9BHuD2Kx0Dzy/74Kog qgkG8Zsudj95TPkATZrAoyDSMBSqYtU2kFr5kA14AowQcqEubrqF/d9/coiRz7BCGaW+ kjkmodTemSvZPgfUPvSyMp9GWMQQGjIkFVaaGrfReo3Q2jygm/OD4lG4g24VJNGZdJvC rZH53tO+eSx7pJbrdS/zo5aY/+iHCY3UaH8fBf9vwCaI2BiRENT6HoQCxX58XKKuRYT0 BzWfcrnu4qAJmhAe02q6PZB4yY9eeR8EoeLeLPxS6NhPwLcg+xFXTN3oidTu8AmyjVlj UowA== X-Gm-Message-State: AOAM531P5tMPuQ0Ug48cjoQu0bssMNQWR2rjBPUqr55VJgqQ60CPojrI P28wU3gdBOHOaMEw1js9nBk= X-Google-Smtp-Source: ABdhPJxHzbye4XRLnSvBlQObswNpXjTS3XrDqE1jJLqg0maTMcfec1EnyxM49kxDQRnXmTUAz/llKg== X-Received: by 2002:a05:6512:499:b0:46f:d419:a19b with SMTP id v25-20020a056512049900b0046fd419a19bmr3576799lfq.654.1650646284247; Fri, 22 Apr 2022 09:51:24 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:23 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, virtualization@lists.linux-foundation.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Oleksandr Tyshchenko , Jason Wang , Rob Herring , Krzysztof Kozlowski , Julien Grall , Juergen Gross , Stefano Stabellini , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 4/6] dt-bindings: Add xen, dev-domid property description for xen-grant DMA ops Date: Fri, 22 Apr 2022 19:51:01 +0300 Message-Id: <1650646263-22047-5-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095126_779472_EE98A4BA X-CRM114-Status: GOOD ( 19.87 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Oleksandr Tyshchenko Introduce Xen specific binding for the virtualized device (e.g. virtio) to be used by Xen grant DMA-mapping layer in the subsequent commit. This binding indicates that Xen grant mappings scheme needs to be enabled for the device which DT node contains that property and specifies the ID of Xen domain where the corresponding backend resides. The ID (domid) is used as an argument to the grant mapping APIs. This is needed for the option to restrict memory access using Xen grant mappings to work which primary goal is to enable using virtio devices in Xen guests. Signed-off-by: Oleksandr Tyshchenko --- Changes RFC -> V1: - update commit subject/description and text in description - move to devicetree/bindings/arm/ --- .../devicetree/bindings/arm/xen,dev-domid.yaml | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/xen,dev-domid.yaml diff --git a/Documentation/devicetree/bindings/arm/xen,dev-domid.yaml b/Documentation/devicetree/bindings/arm/xen,dev-domid.yaml new file mode 100644 index 00000000..ef0f747 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/xen,dev-domid.yaml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/xen,dev-domid.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xen specific binding for the virtualized device (e.g. virtio) + +maintainers: + - Oleksandr Tyshchenko + +select: true + +description: + This binding indicates that Xen grant mappings scheme needs to be enabled + for that device and specifies the ID of Xen domain where the corresponding + device (backend) resides. This is needed for the option to restrict memory + access using Xen grant mappings to work. + +properties: + xen,dev-domid: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The domid (domain ID) of the domain where the device (backend) is running. + +additionalProperties: true + +examples: + - | + virtio_block@3000 { + compatible = "virtio,mmio"; + reg = <0x3000 0x100>; + interrupts = <41>; + + /* The device is located in Xen domain with ID 1 */ + xen,dev-domid = <1>; + }; From patchwork Fri Apr 22 16:51:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F35C3C433F5 for ; Fri, 22 Apr 2022 16:53:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kAJWrzgiLtJXKGhyzy6OvJ2dtB00zdM0bQym8qkCRro=; b=lKC8fYfFBhp/6n m0Meldeku1zJzO30/Cq2bsWFydQaDNafZEDmDE1Oos1omyUcErSoqHrALV0RJr5SpuKV4EbCea/r4 btJ7JRzP5qH99yYjjlx99URuyJ0bOKXOZBS0sBHmL0Lmjgsee/kD7StDnSXc8cPfdZBjxXcnhpbjo 2q8FA8gaR2AxqovYMP4dVRPQW4n44sgPt8ZF4TyG9bC9KbKyeg4OwCQWh3OSScDit4vht74JTSR3r TGoBXJqRmYGM3Sls/gH2ev77HhPnWcnsa9eZmcBdt9Oo6mlkGwvjJdaqgMw5fqBAfY6TrLspD8/+m /UtCm8MRbFMuJC750FsQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwWN-001Ycn-U8; Fri, 22 Apr 2022 16:52:40 +0000 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVC-001Y71-Pn for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:29 +0000 Received: by mail-lf1-x12c.google.com with SMTP id t25so15287791lfg.7 for ; Fri, 22 Apr 2022 09:51:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KhuPWU8Ck/Zqwd8QYGNbplUi9vy17AnQZagSCJ37QGk=; b=NOb0zaTNkpTy3DsQIPg0dlh0OMrNEZEmtlKznw8XqFpcusEUdvVM6zMbTVNhxDwSXb 9s37u6+satXYoHdp9aa7oR59besAWm0FyfFiy6XEjvSmmpgqVORyHmPjGB9ycHQDJJWY NhBHK5PmSgHWKDXsrY1o7I3msHW/lE2r8fRLPkm+huQTPVs0JPTel+isPlp+aKY9PECA TgXI2IbEGgOzT7qwLsqu/TyulQid0mXcPa7j9ZtTDusbzC4o3xYvxYVruqLq6WimAnlD NuIvwpd8kt/kRI2bBQnCc3VInK9vHaSdv0v4tgUnpJpgPie2NhI61zNXsHV+nBAVrH8s y7vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KhuPWU8Ck/Zqwd8QYGNbplUi9vy17AnQZagSCJ37QGk=; b=BwiDsxvhm49fbKzdxCtL7+TOLlD6e0obI7OoVDkxKeFGq6UD70k7Z80vXGBc3aC4Xg vTzyF5HZPBH8tAqNJivMx4wPc5HWxYlIHwbNn+U1MwPRrlP9iI1/S+N6bb99MwQLIIuS ioak+b0CCWrHn2EPDIhLgacTZms5Yqn7xlBvrsZ+5XBu8M2c12gvZgeSy8VmK2pUGfKt NDmiROuzFGSkC5E+GVyP/c92rBsp5XIVtpm8UOfkR7m2pxBfMrkEywuZNAj8HLEOarpC mo6AiVJ02iUn4EZLNoM0rBYY9kOoISdv+VMMzIV3n93PF/ZUKybgr81f07/LFUfi0GQ4 rIHA== X-Gm-Message-State: AOAM531qjY5OoQmx6PRlXlaTyI45geGEV/uDw0QrsNFSUjNJqKeEeRhc 13tmiV0Ko9o/IJAsHB1O2jQ= X-Google-Smtp-Source: ABdhPJwYOQYW+DLtmEipeBoU8JAOfR2j+jhgl2CJGFYZXuwNwDTvK1p0Ec2CwRYofuAFV0Wcslpcwg== X-Received: by 2002:ac2:4e95:0:b0:471:ee3b:6534 with SMTP id o21-20020ac24e95000000b00471ee3b6534mr808665lfr.291.1650646285373; Fri, 22 Apr 2022 09:51:25 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:24 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Oleksandr Tyshchenko , Stefano Stabellini , Boris Ostrovsky , Juergen Gross , Julien Grall , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 5/6] xen/grant-dma-ops: Retrieve the ID of backend's domain for DT devices Date: Fri, 22 Apr 2022 19:51:02 +0300 Message-Id: <1650646263-22047-6-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095126_887002_58F5C576 X-CRM114-Status: GOOD ( 23.70 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Oleksandr Tyshchenko Use the presence of recently introduced "xen,dev-domid" property in the device node as a clear indicator of enabling Xen grant mappings scheme for that device and read the ID of Xen domain where the corresponding backend resides. The ID (domid) is used as an argument to the Xen grant mapping APIs. Also introduce xen_is_grant_dma_device() to check whether xen-grant DMA ops need to be set for a passed device. Remove the hardcoded domid 0 in xen_grant_setup_dma_ops(). Signed-off-by: Oleksandr Tyshchenko --- Changes RFC -> V1: - new patch, split required changes from commit: "[PATCH 4/6] virtio: Various updates to xen-virtio DMA ops layer" - update checks in xen_virtio_setup_dma_ops() to only support DT devices for now - remove the "virtio,mmio" check from xen_is_virtio_device() - remane everything according to the new naming scheme: s/virtio/grant_dma --- drivers/xen/grant-dma-ops.c | 25 ++++++++++++++++++------- include/xen/xen-ops.h | 5 +++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c index 0e69aa8..70d5d77 100644 --- a/drivers/xen/grant-dma-ops.c +++ b/drivers/xen/grant-dma-ops.c @@ -66,11 +66,6 @@ static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev) * Such a DMA address is formed by using the grant reference as a frame * number and setting the highest address bit (this bit is for the backend * to be able to distinguish it from e.g. a mmio address). - * - * Note that for now we hard wire dom0 to be the backend domain. In order - * to support any domain as backend we'd need to add a way to communicate - * the domid of this backend, e.g. via Xenstore, via the PCI-device's - * config space or DT/ACPI. */ static void *xen_grant_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, @@ -277,6 +272,16 @@ static const struct dma_map_ops xen_grant_dma_ops = { .dma_supported = xen_grant_dma_supported, }; +bool xen_is_grant_dma_device(struct device *dev) +{ + /* XXX Handle only DT devices for now */ + if (!dev->of_node) + return false; + + return of_property_read_bool(dev->of_node, "xen,dev-domid"); +} +EXPORT_SYMBOL_GPL(xen_is_grant_dma_device); + void xen_grant_setup_dma_ops(struct device *dev) { struct xen_grant_dma_data *data; @@ -288,8 +293,14 @@ void xen_grant_setup_dma_ops(struct device *dev) return; } - /* XXX The dom0 is hardcoded as the backend domain for now */ - dev_domid = 0; + /* XXX ACPI and PCI devices unsupported for now */ + if (dev_is_pci(dev) || !dev->of_node) + goto err; + + if (of_property_read_u32(dev->of_node, "xen,dev-domid", &dev_domid)) { + dev_err(dev, "xen,dev-domid property is not present\n"); + goto err; + } data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) { diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 4f9fad5..62be9dc 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -223,10 +223,15 @@ static inline void xen_preemptible_hcall_end(void) { } #ifdef CONFIG_XEN_GRANT_DMA_OPS void xen_grant_setup_dma_ops(struct device *dev); +bool xen_is_grant_dma_device(struct device *dev); #else static inline void xen_grant_setup_dma_ops(struct device *dev) { } +static inline bool xen_is_grant_dma_device(struct device *dev) +{ + return false; +} #endif /* CONFIG_XEN_GRANT_DMA_OPS */ #endif /* INCLUDE_XEN_OPS_H */ From patchwork Fri Apr 22 16:51:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12823787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 79978C433EF for ; Fri, 22 Apr 2022 16:54:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=IvGDluxwdsT04BGElBCtbVv/qFtMAZ57BQiCauVyUac=; b=hrKUiEITBWiZKZ CNyLOMZ+hMIzmvQGcXy3DIgvac1LjsmNEXglsQPmyus7ewJHivp/oQ6VuEPrp/TWNlzJ+2CIGB4NO mG4j38sMfOLwUONvkGhuqbqwrXCrH47mffHxIwchMyQvh0LgjyDe+Q3Ocg0GDXoiCA1JuhAIvQZ7B 6NtwmymsRWN4FvrnACHfOaBY8W6In83sgoaQRdHE8SkPJSfkyoHoQCwENr8o32sgb9oRrKMWWtFeW UCcEaohuqWlbGnVwobNipY3nPM6agJCWjoq8avkWWWZQMJHSkgtrbz7syonrUtryEdjAQonMhSEYI goBve/U01tqoc34FPq7A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwWe-001Ykt-RP; Fri, 22 Apr 2022 16:52:57 +0000 Received: from mail-lf1-x130.google.com ([2a00:1450:4864:20::130]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhwVE-001Y85-9s for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2022 16:51:31 +0000 Received: by mail-lf1-x130.google.com with SMTP id h3so10578655lfu.8 for ; Fri, 22 Apr 2022 09:51:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FWaKUpxpKzKjbtSZ6ZKtWz+3C1vj9orKjhUr2xwY4lM=; b=hZs3izeCtmtt43a0UNm5IqmPSa6o2CTFdv4hT95HlTt8sq4U8H2GVbe8LO7gpfIx9P nUCA0BIFr8bWe4R+3Vx5F5V5bZlcVUxVU6cfKnoKPtW9fYpu4rM0I3NA6A9jDYVP/9eT 5v6R6JbVvZdOMWrOceZlrUlagLbrTSPHZ85X9eWLHsTTCGbqBvoaWLAPWUgbs6Idby5s 4LtwH2Lnu3gjEMNKSbuabCyQMifLdMh/r+T6OpIX4rBGG1FX/6XuNg2Nq2vJTPVMJqWK NdOH6K0tTIKQxd1NLk5+6LC7bTT/3ZCxi4f0143G79Y5OyjlhU1DkqwMqAELZuYMQgwV 5rHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FWaKUpxpKzKjbtSZ6ZKtWz+3C1vj9orKjhUr2xwY4lM=; b=z237c6cXQSL/M83g+7xzChvIleV+eDnFGxI1FaOu5iRdzT37bSSTd3veX0MaRet8pk cb92BzdfyZu2aOAQ7QAN04ycxLkhdWvwacUnLwgREKwcG1LG29tiXLWDWCIj/kCOMLUh nqxSJQDRc6mmOoi8byR1j6Mf3CPCTNSeVFFaJdxZ2eb9f+IlTXmoJSQyTZtMeEnA4t6m YoItYTEF17DjJZk2Nyxt0KCdGnYh9nEDqPV6rDhQ2n2/7kpCUj4m9pYgzjETYzdEuhDU 8PXyrEMA5KUiKXKhW8DVW9EXEoW25uxvXWaitOI2hlKLBj6AiRLWCIukOoz+mxNPht1V XRMg== X-Gm-Message-State: AOAM531zjok0fC/QE9gyU1eYIRgELTeE8PY5JkEMzWCmW6LpGHZpy7wi +kGd2V0ywdS+g2hY1+At0UsQN+/8xM8= X-Google-Smtp-Source: ABdhPJw7+T0P6Ouxeu7dgpNbQZDF5EXBC/YTqVl/e4VxLwsPs+mJYBXNMvJhS0HMKIGJGQ32Omz2oQ== X-Received: by 2002:a05:6512:3d14:b0:46b:81d9:b9ee with SMTP id d20-20020a0565123d1400b0046b81d9b9eemr3709015lfv.109.1650646286428; Fri, 22 Apr 2022 09:51:26 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id n2-20020a056512310200b0046e2f507a3asm279742lfb.167.2022.04.22.09.51.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2022 09:51:26 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Oleksandr Tyshchenko , Boris Ostrovsky , Juergen Gross , Stefano Stabellini , Julien Grall , "Michael S. Tsirkin" , Christoph Hellwig Subject: [PATCH V1 6/6] arm/xen: Assign xen-grant DMA ops for xen-grant DMA devices Date: Fri, 22 Apr 2022 19:51:03 +0300 Message-Id: <1650646263-22047-7-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> References: <1650646263-22047-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220422_095128_420272_B76BB40B X-CRM114-Status: GOOD ( 14.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Oleksandr Tyshchenko As the main (and single at the moment) purpose of xen-grant DMA devices is to enable using virtio devices in Xen guests in a safe manner, assign xen-grant DMA ops only if restricted access to the guest memory is enabled. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini --- Changes RFC -> V1: - update commit subject/description - remove #ifdef CONFIG_XEN_VIRTIO - re-organize the check taking into the account that swiotlb and virtio cases are mutually exclusive - update according to the new naming scheme: s/virtio/grant_dma --- include/xen/arm/xen-ops.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h index 288deb1..26954e5 100644 --- a/include/xen/arm/xen-ops.h +++ b/include/xen/arm/xen-ops.h @@ -2,12 +2,17 @@ #ifndef _ASM_ARM_XEN_OPS_H #define _ASM_ARM_XEN_OPS_H +#include #include +#include static inline void xen_setup_dma_ops(struct device *dev) { #ifdef CONFIG_XEN - if (xen_swiotlb_detect()) + if (arch_has_restricted_virtio_memory_access() && + xen_is_grant_dma_device(dev)) + xen_grant_setup_dma_ops(dev); + else if (xen_swiotlb_detect()) dev->dma_ops = &xen_swiotlb_dma_ops; #endif }