From patchwork Thu Apr 14 19:19:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12818582 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 E3802C433F5 for ; Fri, 15 Apr 2022 11:23: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: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:Resent-Message-ID:Resent-Date:Resent-CC: Resent-To:Resent-From:Reply-To:Content-ID:Content-Description:Resent-Sender: List-Owner; bh=BOFG9cHO4vcw7oWEVPrBq14N+q1d9j+mvqOIFZoAHf4=; b=F0gVLYFtSObrOV D7XvJyZPtNwb9Z0xx7Ft6BxvMiTxqBU/MLJH+rHhN9GVxN7bmwjdBLhYMkkYaFUXtyWOcVCZMGeCb 9tVN5oUR7LdbbKTJKgzLrPeEkZJtVEjnUSUTUTRRxpP9s0idSEP8AJFyaiKd3CAyJI5oAIJPoCs+H ShfQ6OKNrSaz8PsnKA3arrn6H4+N3cygzc+jps07fxtDqefWeOvGl1McqPq7aISqc8Ns+suYEb2oI FaMV8FrRIqbCn4E6hGONPC9V38A4HgiTMOmzs8/BJCKSrDqsZGQbql5GC9M4QN0dXOipO0ICvgEab rsIFvGc4544XaLvtafUQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK1Z-009non-Jr; Fri, 15 Apr 2022 11:22:01 +0000 Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK1V-009nn7-LZ for linux-arm-kernel@lists.infradead.org; Fri, 15 Apr 2022 11:21:59 +0000 Received: by mail-lf1-x12d.google.com with SMTP id b21so13603699lfb.5 for ; Fri, 15 Apr 2022 04:21:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=resent-from:resent-to:resent-cc:resent-date:resent-message-id:from :to:cc:subject:date:message-id:in-reply-to:references; bh=dof6CivR5ktaOrwRlo+Yx4ESbsQ7cxmBJatNzZcwa2k=; b=pYu+VqU9opegv0VsV417n9OmLGQMhl+CtQ+vPSMX4totOe3si2sYFkFDcl75tTbXio JRLZzHMY9fl+iytuUBuNDoOlARyagWueNNK5DuTdBrOZS+EEeLE2lX4LqxjswfbQZLQA KJvZF66qrI67qByL8XVBTQwxy0dSrolhA69CpU2AgiJY94OcVkb2YLvv1m6JCyfdX83x eH6M2+x1YRKPHvI24X254uaDKrQVkHjTNpxTAvSyLrpSzEaNmlqcAgRN+mRRLTvn3bXB egVJxL8uNvxPg+Fqrk6cWfYE7n/+Km/aN6d3WD1imPgaS6Vi7GNQJuaZsXTByVhgxDQ3 kE5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:resent-from:resent-to:resent-cc:resent-date :resent-message-id:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dof6CivR5ktaOrwRlo+Yx4ESbsQ7cxmBJatNzZcwa2k=; b=bAI0hfr0xHxPDw3Lk3fIhM7htmntseBZKa/szRyNwa1XcLI3fwNXM93JMAZQEMDPT2 sO7IsoCJtfP6iEAi+G1uc6ndhzBnqei3v6JecBSvYpHO+NvItSPmtuR3HFDJXAugrd3F 4VKqDoysQ4hX7DzzyH1OJ4LIGireB0AHSENxaOQv2x63V1Mih5inq39EvPGfajQZa3n8 Iw4Sk/X1dmgiqRJ0ktH5DtMEoE/98s9ASolW1Hc5aFxlLoHmiNIc/mAktSW7nnaGrazU b7bICa0kbf2YGvAsep6LMAgufw8MsRvxovyH0RkPjPT3UXacuBlheyQ1AOD2OumkAv4W VprQ== X-Gm-Message-State: AOAM530gpf9S/n+z61AsEqT3MO5EuZS04BsODbRl3gvDakFm8oJ4z2rF UZAMZiz+StC7yKodxvFgWy4= X-Google-Smtp-Source: ABdhPJwE8krEyFvbM8BEo26Q373WJizFRDu38QLPGY+wsbJRtLtrqXl0xr9eQroZ545r8BcN2LNdrQ== X-Received: by 2002:ac2:5d6a:0:b0:464:efd7:f964 with SMTP id h10-20020ac25d6a000000b00464efd7f964mr4657736lft.70.1650021715634; Fri, 15 Apr 2022 04:21:55 -0700 (PDT) Received: from [192.168.1.7] ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id 10-20020a2eb94a000000b0024ca063060fsm242996ljs.140.2022.04.15.04.21.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 15 Apr 2022 04:21:55 -0700 (PDT) Resent-From: Oleksandr Resent-To: linux-arm-kernel@lists.infradead.org Resent-CC: Christoph Hellwig , "Michael S. Tsirkin" Resent-Date: Fri, 15 Apr 2022 14:21:38 +0300 Resent-Message-ID: <5e715389-57b4-f1c9-ac21-c7c7f7fa2c70@gmail.com> Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.38 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:38 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org Cc: Juergen Gross , Boris Ostrovsky , Stefano Stabellini , Julien Grall , Oleksandr Tyshchenko Subject: [RFC PATCH 1/6] xen/grants: support allocating consecutive grants Date: Thu, 14 Apr 2022 22:19:28 +0300 Message-Id: <1649963973-22879-2-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220415_042157_778836_AEFD4C5E X-CRM114-Status: GOOD ( 28.91 ) 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 --- 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 Thu Apr 14 19:19:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12818583 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 D449AC433EF for ; Fri, 15 Apr 2022 11:27: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: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:Resent-Message-ID:Resent-Date:Resent-CC: Resent-To:Resent-From:Reply-To:Content-ID:Content-Description:Resent-Sender: List-Owner; bh=rtPZ3XuGgIgKdA/N1k9NLlOKTqPI+3IGyiwJJ712CHU=; b=jkM92C0gn7nkP9 fwEPEn2Q5EabVPENb+WKFCGsslYymWGbPvZqIq+qDAIPFVleOIZhFbvKut+9a8YjLQKEC7iugYURr /xMDgOMLWvnLv3j/7bp6CjAIjOO8h+pV8Nc/NwnZOn2immwXuM0UmycR7HikXCFMMUXDk12IZhfUt sLjWbbrb41M50fb9Od8tNbb8bkUbQbt/LesEHmpUhFRZHcZdx3J1HdBCXimrmqwXsskz1sU2fXdKI 5IGSVMTwQKpidBsFV+d5F6fMRxnHV2LIamblRqyPLvXdABV6mRE3LZuBesEfPBkdoNYgPlvaw2eXx 3zf+TNfKBnH4VzciS+dw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK5a-009oyV-BI; Fri, 15 Apr 2022 11:26:10 +0000 Received: from mail-lf1-x131.google.com ([2a00:1450:4864:20::131]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK5U-009owS-1d for linux-arm-kernel@lists.infradead.org; Fri, 15 Apr 2022 11:26:08 +0000 Received: by mail-lf1-x131.google.com with SMTP id o2so13550886lfu.13 for ; Fri, 15 Apr 2022 04:26:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=resent-from:resent-to:resent-cc:resent-date:resent-message-id:from :to:cc:subject:date:message-id:in-reply-to:references; bh=nXDE5bXmpYq/ePRB6NaY2RzAfrYEzRtO2mFypRZiPSg=; b=Eq7PwnM0XleRm5YPsGqg91OHdJc5Bz/QYoNmr8a1zdr97ZFSW21u0AsS3lhKeonB3x HVdJYrNQnjSOWOhewkW4iFO8FLebwzh4uRvKJbJFmLnAjqFXnP7mBmwOO4joggQb65Q5 wckYGbhPA9i1ADbGtw1jKrgSczHEg8xLOhMQ4tmI9D1/HdStmITY3G6zVccDu5+UQDFV f9SJYRunrCNuD7WTgwkQxfzme98rBQ25wEE6uMJvWkThMLME9SkG3GUsul6Uxo7XJgoA MSOeGuYDW3ujH2PnK0n9OOpWIqvQ8VIYgk1g/ENZl5OjCDEdI1w8d3nuC244Q4hP2qkh /xGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:resent-from:resent-to:resent-cc:resent-date :resent-message-id:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nXDE5bXmpYq/ePRB6NaY2RzAfrYEzRtO2mFypRZiPSg=; b=cv0kBlYdP2VTqci9uH38jVocbbuAwJAWFVLDgsVRmr0vwBTtXgXYhD9IKQLcifdA+e wpdbdU4YvAOYLo7AQ6y28grybVjrAalMYAO2SJfUsSt1yft6bCPmv5cSFi7WgQCkofkP ydEViRD89+DVK8dhYmBjfeFn8VuQUGr+L7PzhDs3/6prpLph0buaZLeaWGkIc9c/Ovdf HTe5UhtTUSzhs95X+zhZkLz6xR5rrOM7u5h6HeyO6PyW4ffgi2GdNUxUN2VOA+s0+taT 8j7GIKHEFOlHXg7BofXmAD9OMw1nDekYF0e/EYzWLJ2xwmWO3juW5xCV7Bk03YX2SbCy 1L9g== X-Gm-Message-State: AOAM531Yrg2U7qEJCcgBQmQyThGkEUeOQ+tV2IxcHCKOfK/XsFDmWMJt uHW93qAlxq3EwrwFBeOCiOYMVEh3mAM= X-Google-Smtp-Source: ABdhPJwQUMLDuQmDNQ9duq8PHRInfJALjMJoF+AvpFCI7v8cLXSm2dXjetT5oApLe8iGQOKRvYazvw== X-Received: by 2002:a05:6512:3a85:b0:464:f83e:f680 with SMTP id q5-20020a0565123a8500b00464f83ef680mr4852202lfu.371.1650021960536; Fri, 15 Apr 2022 04:26:00 -0700 (PDT) Received: from [192.168.1.7] ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id q17-20020a2e8751000000b00244beaacef1sm253479ljj.18.2022.04.15.04.25.59 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 15 Apr 2022 04:26:00 -0700 (PDT) Resent-From: Oleksandr Resent-To: linux-arm-kernel@lists.infradead.org Resent-CC: Christoph Hellwig , "Michael S. Tsirkin" Resent-Date: Fri, 15 Apr 2022 14:25:59 +0300 Resent-Message-ID: Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:40 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org, x86@kernel.org, linux-kernel@vger.kernel.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 Subject: [RFC PATCH 2/6] virtio: add option to restrict memory access under Xen Date: Thu, 14 Apr 2022 22:19:29 +0300 Message-Id: <1649963973-22879-3-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220415_042604_179411_274757D5 X-CRM114-Status: GOOD ( 32.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: , 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 In order to support virtio in Xen guests add a config option 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. This applies to fully virtualized guests only, as for paravirtualized guests this is mandatory. This requires to switch arch_has_restricted_virtio_memory_access() from a pure stub to a real function on x86 systems (Arm systems are not covered by now). 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 --- arch/x86/mm/init.c | 15 ++++ arch/x86/mm/mem_encrypt.c | 5 -- arch/x86/xen/Kconfig | 9 +++ drivers/xen/Kconfig | 20 ++++++ drivers/xen/Makefile | 1 + drivers/xen/xen-virtio.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++ include/xen/xen-ops.h | 8 +++ 7 files changed, 230 insertions(+), 5 deletions(-) create mode 100644 drivers/xen/xen-virtio.c diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index d8cfce2..526a3b2 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,16 @@ 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) +{ + if (IS_ENABLED(CONFIG_XEN_PV_VIRTIO) && xen_pv_domain()) + return 1; + if (IS_ENABLED(CONFIG_XEN_HVM_VIRTIO_GRANT) && xen_hvm_domain()) + return 1; + + return 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/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 85246dd..dffdffd 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -92,3 +92,12 @@ config XEN_DOM0 select X86_X2APIC if XEN_PVH && X86_64 help Support running as a Xen Dom0 guest. + +config XEN_PV_VIRTIO + bool "Xen virtio support for PV guests" + depends on XEN_VIRTIO && XEN_PV + default y + help + Support virtio for running as a paravirtualized guest. This will + need support on the backend side (qemu or kernel, depending on the + virtio device types used). diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 120d32f..fc61f7a 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -335,4 +335,24 @@ config XEN_UNPOPULATED_ALLOC having to balloon out RAM regions in order to obtain physical memory space to create such mappings. +config XEN_VIRTIO + bool "Xen virtio support" + default n + depends on VIRTIO && DMA_OPS + select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS + 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). + +config XEN_HVM_VIRTIO_GRANT + bool "Require virtio for fully virtualized guests to use grant mappings" + depends on XEN_VIRTIO && X86_64 + default y + help + Require virtio for fully virtualized guests to use grant mappings. + This will avoid the need to give the backend the right to map all + of the guest memory. This will need 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..767009c 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_VIRTIO) += xen-virtio.o diff --git a/drivers/xen/xen-virtio.c b/drivers/xen/xen-virtio.c new file mode 100644 index 00000000..cfd5eda --- /dev/null +++ b/drivers/xen/xen-virtio.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0-only +/****************************************************************************** + * Xen virtio driver - enables using virtio devices in Xen guests. + * + * Copyright (c) 2021, Juergen Gross + */ + +#include +#include +#include +#include +#include +#include +#include + +#define XEN_GRANT_ADDR_OFF 0x8000000000000000ULL + +static inline dma_addr_t grant_to_dma(grant_ref_t grant) +{ + return XEN_GRANT_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_ADDR_OFF) >> PAGE_SHIFT); +} + +/* + * DMA ops for Xen virtio frontends. + * + * 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 or via the PCI-device's config + * space. + */ +static void *xen_virtio_dma_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs) +{ + unsigned int n_pages = PFN_UP(size); + unsigned int i; + unsigned long pfn; + grant_ref_t grant; + void *ret; + + ret = (void *)__get_free_pages(gfp, get_order(size)); + if (!ret) + return NULL; + + pfn = virt_to_pfn(ret); + + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) { + free_pages((unsigned long)ret, get_order(size)); + return NULL; + } + + for (i = 0; i < n_pages; i++) { + gnttab_grant_foreign_access_ref(grant + i, 0, + pfn_to_gfn(pfn + i), 0); + } + + *dma_handle = grant_to_dma(grant); + + return ret; +} + +static void xen_virtio_dma_free(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle, unsigned long attrs) +{ + unsigned int n_pages = PFN_UP(size); + unsigned int i; + grant_ref_t grant; + + grant = dma_to_grant(dma_handle); + + for (i = 0; i < n_pages; i++) + gnttab_end_foreign_access_ref(grant + i); + + gnttab_free_grant_reference_seq(grant, n_pages); + + free_pages((unsigned long)vaddr, get_order(size)); +} + +static struct page *xen_virtio_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_virtio_dma_alloc_pages size %ld\n", size); + return NULL; +} + +static void xen_virtio_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_virtio_dma_free_pages size %ld\n", size); +} + +static dma_addr_t xen_virtio_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + grant_ref_t grant; + + if (gnttab_alloc_grant_references(1, &grant)) + return 0; + + gnttab_grant_foreign_access_ref(grant, 0, xen_page_to_gfn(page), + dir == DMA_TO_DEVICE); + + return grant_to_dma(grant) + offset; +} + +static void xen_virtio_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + unsigned long attrs) +{ + grant_ref_t grant; + + grant = dma_to_grant(dma_handle); + + gnttab_end_foreign_access_ref(grant); + + gnttab_free_grant_reference(grant); +} + +static int xen_virtio_dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + WARN_ONCE(1, "xen_virtio_dma_map_sg nents %d\n", nents); + return -EINVAL; +} + +static void xen_virtio_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + WARN_ONCE(1, "xen_virtio_dma_unmap_sg nents %d\n", nents); +} + +static int xen_virtio_dma_dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +static const struct dma_map_ops xen_virtio_dma_ops = { + .alloc = xen_virtio_dma_alloc, + .free = xen_virtio_dma_free, + .alloc_pages = xen_virtio_dma_alloc_pages, + .free_pages = xen_virtio_dma_free_pages, + .mmap = dma_common_mmap, + .get_sgtable = dma_common_get_sgtable, + .map_page = xen_virtio_dma_map_page, + .unmap_page = xen_virtio_dma_unmap_page, + .map_sg = xen_virtio_dma_map_sg, + .unmap_sg = xen_virtio_dma_unmap_sg, + .dma_supported = xen_virtio_dma_dma_supported, +}; + +void xen_virtio_setup_dma_ops(struct device *dev) +{ + dev->dma_ops = &xen_virtio_dma_ops; +} +EXPORT_SYMBOL_GPL(xen_virtio_setup_dma_ops); + +MODULE_DESCRIPTION("Xen virtio support driver"); +MODULE_AUTHOR("Juergen Gross "); +MODULE_LICENSE("GPL"); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index a3584a3..ae3c1bc 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_VIRTIO +void xen_virtio_setup_dma_ops(struct device *dev); +#else +static inline void xen_virtio_setup_dma_ops(struct device *dev) +{ +} +#endif /* CONFIG_XEN_VIRTIO */ + #endif /* INCLUDE_XEN_OPS_H */ From patchwork Thu Apr 14 19:19:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12818584 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 1ABBEC433EF for ; Fri, 15 Apr 2022 11:31:21 +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:Resent-Message-ID:Resent-Date:Resent-CC: Resent-To:Resent-From:Reply-To:Content-ID:Content-Description:Resent-Sender: List-Owner; bh=HQg5At7Dlb3JfYFnx7twYgFCJ6JMlbMOddUkRKPZQ0U=; b=QRnnfk4MiOSdQo kwCIpdHjVai7Q4YEBUdhAmxusjgc/XSJSH2iI6sbzHiPP1FNav+v5qaZ1T20zwFJqUBQ5yVmpKAU3 oW/ss6FUKoNW5GwqavoITeOx4KwuMv5ZwkKn3STA+X8ugLZop04pUuBMuz7eRVx+rwVn+FgB22ETt kgSZ7b8evk+LPKj1atepMqlTrDMvxDn7YuDQCsM1r1VQOm0rG712wCozyIUF4C9XiAyeszOOqbkXe U4B9BpPvmihihz1pgIcpgzmQiJ7aW7W9cbMvhInOb1vCsTVCFOPCTalcy+ksyVdMxY33OJp8+YR23 T3nT3bsrjerpA53W5pUw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK9T-009pjT-U8; Fri, 15 Apr 2022 11:30:12 +0000 Received: from mail-lf1-x12f.google.com ([2a00:1450:4864:20::12f]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nfK9Q-009pia-Ri for linux-arm-kernel@lists.infradead.org; Fri, 15 Apr 2022 11:30:10 +0000 Received: by mail-lf1-x12f.google.com with SMTP id bq30so13635207lfb.3 for ; Fri, 15 Apr 2022 04:30:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=resent-from:resent-to:resent-cc:resent-date:resent-message-id:from :to:cc:subject:date:message-id:in-reply-to:references; bh=R46jQ8Mh8wQzPdylSEViVF+ujde6F3v3VBI24iINPTM=; b=KeWfl67mdcuRvrKBa5wIPPFe8y9QMAOfCy01692FgAhUzvumB1hzx3pLSABU1WPtm3 +lRmBJVXnJElMN1jUwAb9PCqeInAr6EOr8SnmjmbRfjNH2YwnvmfPPy7RHyvotLoN+lH rXDwKyCQ/snna5cLLYzChv9K4hDFiXEMMHNNdrhMuAqVbWm9rtoF6aKAToVtn4RiIqho PSbYl/WRIt8FmOEGM7+zbcy8bfdqwkaBSyrzWNhOo/L3Yoqq4kDrrp1mum+H39upnI7A J2ZqC+EVvJltXvmV6gpUVY7Khvh6bLO3vWTxchEFeOCC1LMPh+dM6krX+3Q6z/4Xdvn6 Wb7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:resent-from:resent-to:resent-cc:resent-date :resent-message-id:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R46jQ8Mh8wQzPdylSEViVF+ujde6F3v3VBI24iINPTM=; b=cb4yyuGzFjmpnCfzQx3g1jfpU4O698hgzEC2Fk+teyULnlmHmVcdT78xwhlFsxt9Us yS1jOoVOxjrzzNVd85axzNvLiRS8EfbPhu3rZ7bITIPzVQ3BIl2MsMRUHW3icVfiAQ4y HUVY17nWS8kqWwqCgQ9nJSVGaTeieYTVWgrIsdt7vHXHnNKERmmHnypTGzOTJ7lV/Cl3 MBV3PTyRzub5SQpdVrlC3Oygis45762Z6r5kCX1oiiq70lhq/E7SLnWY/pJ04uXzNOeP TZLyUpRTZ0RATqpuR8wdHRLSerQFVlHRHACfHO7YVgBaRlwj3Ip429wcm27NTfyjsyj0 z+Hg== X-Gm-Message-State: AOAM5316p4rvc8TYez7cEdZOK8lyuuCDlt8TRlU3Wvt7xsiUNg4fqDmE FnOK5uoCOWsQfUkSpnhgZZBPIllzuAU= X-Google-Smtp-Source: ABdhPJy0FCKmbFf2JDff5fmfPTV6me2hKoRdU0V2jxeL8S9+vRmbeZHVDqBY+M2jw+k9yMQgmAM7DA== X-Received: by 2002:a05:6512:1585:b0:448:3936:a5a0 with SMTP id bp5-20020a056512158500b004483936a5a0mr4896645lfb.108.1650022206220; Fri, 15 Apr 2022 04:30:06 -0700 (PDT) Received: from [192.168.1.7] ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id 25-20020ac24d59000000b0046d06f31bc2sm298746lfp.282.2022.04.15.04.30.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 15 Apr 2022 04:30:05 -0700 (PDT) Resent-From: Oleksandr Resent-To: linux-arm-kernel@lists.infradead.org Resent-CC: Christoph Hellwig Resent-Date: Fri, 15 Apr 2022 14:30:05 +0300 Resent-Message-ID: <52174902-60ae-d322-f158-c0839f5de214@gmail.com> Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.40 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:41 -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 Cc: Oleksandr Tyshchenko , "Michael S. Tsirkin" , Jason Wang , Rob Herring , Krzysztof Kozlowski , Julien Grall , Juergen Gross , Stefano Stabellini Subject: [RFC PATCH 3/6] dt-bindings: xen: Add xen, dev-domid property description for xen-virtio layer Date: Thu, 14 Apr 2022 22:19:30 +0300 Message-Id: <1649963973-22879-4-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220415_043008_920677_260AC1C8 X-CRM114-Status: GOOD ( 18.26 ) 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 virtio-mmio device to be used by Xen virtio support driver in a subsequent commit. This binding 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. Signed-off-by: Oleksandr Tyshchenko --- .../devicetree/bindings/virtio/xen,dev-domid.yaml | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/virtio/xen,dev-domid.yaml diff --git a/Documentation/devicetree/bindings/virtio/xen,dev-domid.yaml b/Documentation/devicetree/bindings/virtio/xen,dev-domid.yaml new file mode 100644 index 00000000..78be993 --- /dev/null +++ b/Documentation/devicetree/bindings/virtio/xen,dev-domid.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/virtio/xen,dev-domid.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xen specific binding for the virtio device + +maintainers: + - Oleksandr Tyshchenko + +select: true + +description: + This binding 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. + + Note that current and generic "iommus" bindings are mutually exclusive, since + the restricted memory access model on Xen behaves as a kind of software IOMMU. + +properties: + xen,dev-domid: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Should contain the ID of device's domain. + +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 Thu Apr 14 19:19:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12813943 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 3A24BC433F5 for ; Thu, 14 Apr 2022 19:21:05 +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=AdzPEyh7naj1Q29sEN9FLMLUqxARD9fsjZBfqz42V+o=; b=30Y9V0w9kXbKfC obIdajVdwTx3RVgPrQbjfIUsN1Vb9hRktwTc40gZn38pJ+oaj0ho3ci/y0zM0mw0i6RlBwlwPsfQt Tlgd+RkkbpwQ+1JK36MDPvvoWHOQtB5R4Ku5/StBaSG7sJE03MO2hjm8nkCYIeX3/5N1+rRrLHfru CpBoTpZALPalkgZvX0KxYexkOV45gu4Cl8HV0O8ieG2EB0kwPfH7a7GkL6BfsGDOZFhGrilgMRUsD B8sFuLYDjL12pzl594g51irLL/+tqa6JueO6Deqh8GMfXEUwXDs2K4BCXPvOfhfFy5qKtTF9MWtAP fsrX8wmEh6riNcrTd4hA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50X-00722C-Ip; Thu, 14 Apr 2022 19:19:57 +0000 Received: from mail-lj1-x231.google.com ([2a00:1450:4864:20::231]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50L-0071vs-7r for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 19:19:47 +0000 Received: by mail-lj1-x231.google.com with SMTP id c15so7251212ljr.9 for ; Thu, 14 Apr 2022 12:19:44 -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=HH0lNJhCKrn1KVzcgV/uI3rqOPkxUwMay92nkSrAjww=; b=CSmQsWmMPhKn65VWOLhlyWUk/5YwfpW6oHGmDgSr8oyIRtln1bgL/FxXCzwqOQ2scW Kul15jhG/xUMsrq9hwxgzV7VZ+jj3hupZRanvoSdnRr8nY+F8D9bVK1bhDZDRzNimT23 LAh7fUHs+YKWYCqE86acY6uO/YWr6KZAKVBtZxwCRFor0ambo4hAmrApMjmGMTo04/Vx omjZqW9FpYwni3wQwXilVmnhhBiTL44fcofN4KwMa0r/naLAzWmPO9D0cVR9OT/QkH7A h4d5ucGnzxq/vZwtYADqFA6IbCHPqfZ2O1SM0pyYOBrcVF6qgnYeOnQS+OhyTtG8dwru XDgw== 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=HH0lNJhCKrn1KVzcgV/uI3rqOPkxUwMay92nkSrAjww=; b=TWFtw3wWoDd1OMqEuTxy10ereXrj/mpO2K6w4wqljq7u3Rb0ZR1oTt2IFTlwVuiiOO guPY/ISkV8F8b6igHFMazSN/51MXBhJ0Ynx/7pufsUqdPDCWOP+YJh85TkDV9/cznNbs 1ZhSVtipeULDz+Zr8zTM6PPODU7WtnAlc20IfG+uQpOsaHNKdzqEJWhcoCChzzWlkHlN d0c9iItmLNzhHwXblzT56UY0rs2yx/Z6UZX60jx9B1qZO+YsJh/bStelvuvSxXSjuj7G 4E/JB1Fb966bpfWLGI9Y+V+JYbydQN5kirAhuIuH7v2wvRYE9qtdyMM8FBv3NgiNQ1SQ kafQ== X-Gm-Message-State: AOAM531wg0cVl5w0OFqHWYssMXGkQuvDhWPwKCah7lsXzkAo0wSBvFmG +pgLOC6+vGwtacNWWdisKOU= X-Google-Smtp-Source: ABdhPJyqaIJqLPokLPf5w1P1n+RXHoKfPPFHkJ8cRMG0ZDENL1jq4zsAVzAnYaGGBHo3X65+xfsMjQ== X-Received: by 2002:a2e:9c2:0:b0:24a:c757:b9bb with SMTP id 185-20020a2e09c2000000b0024ac757b9bbmr2493120ljj.360.1649963982965; Thu, 14 Apr 2022 12:19:42 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.41 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:42 -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 , Boris Ostrovsky , Juergen Gross , Julien Grall Subject: [RFC PATCH 4/6] virtio: Various updates to xen-virtio DMA ops layer Date: Thu, 14 Apr 2022 22:19:31 +0300 Message-Id: <1649963973-22879-5-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-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-20220414_121945_359268_CB782323 X-CRM114-Status: GOOD ( 29.98 ) 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: Oleksandr Tyshchenko In the context of current patch do the following: 1. Update code to support virtio-mmio devices 2. Introduce struct xen_virtio_data and account passed virtio devices (using list) as we need to store some per-device data 3. Add multi-page support for xen_virtio_dma_map(unmap)_page callbacks 4. Harden code against malicious backend 5. Change to use alloc_pages_exact() instead of __get_free_pages() 6. Introduce locking scheme to protect mappings (I am not 100% sure whether per-device lock is really needed) 7. Handle virtio device's DMA mask 8. Retrieve the ID of backend domain from DT for virtio-mmio device instead of hardcoding it. Signed-off-by: Oleksandr Tyshchenko --- arch/arm/xen/enlighten.c | 11 +++ drivers/xen/Kconfig | 2 +- drivers/xen/xen-virtio.c | 200 ++++++++++++++++++++++++++++++++++++++++++----- include/xen/xen-ops.h | 5 ++ 4 files changed, 196 insertions(+), 22 deletions(-) diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index ec5b082..870d92f 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -409,6 +409,17 @@ 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) +{ + if (IS_ENABLED(CONFIG_XEN_HVM_VIRTIO_GRANT) && xen_hvm_domain()) + return 1; + + return 0; +} +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/drivers/xen/Kconfig b/drivers/xen/Kconfig index fc61f7a..56afe6a 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -347,7 +347,7 @@ config XEN_VIRTIO config XEN_HVM_VIRTIO_GRANT bool "Require virtio for fully virtualized guests to use grant mappings" - depends on XEN_VIRTIO && X86_64 + depends on XEN_VIRTIO && (X86_64 || ARM || ARM64) default y help Require virtio for fully virtualized guests to use grant mappings. diff --git a/drivers/xen/xen-virtio.c b/drivers/xen/xen-virtio.c index cfd5eda..c5b2ec9 100644 --- a/drivers/xen/xen-virtio.c +++ b/drivers/xen/xen-virtio.c @@ -7,12 +7,26 @@ #include #include +#include #include #include #include #include #include +struct xen_virtio_data { + /* The ID of backend domain */ + domid_t dev_domid; + struct device *dev; + struct list_head list; + spinlock_t lock; + /* Is device behaving sane? */ + bool broken; +}; + +static LIST_HEAD(xen_virtio_devices); +static DEFINE_SPINLOCK(xen_virtio_lock); + #define XEN_GRANT_ADDR_OFF 0x8000000000000000ULL static inline dma_addr_t grant_to_dma(grant_ref_t grant) @@ -25,6 +39,25 @@ static inline grant_ref_t dma_to_grant(dma_addr_t dma) return (grant_ref_t)((dma & ~XEN_GRANT_ADDR_OFF) >> PAGE_SHIFT); } +static struct xen_virtio_data *find_xen_virtio_data(struct device *dev) +{ + struct xen_virtio_data *data = NULL; + bool found = false; + + spin_lock(&xen_virtio_lock); + + list_for_each_entry( data, &xen_virtio_devices, list) { + if (data->dev == dev) { + found = true; + break; + } + } + + spin_unlock(&xen_virtio_lock); + + return found ? data : NULL; +} + /* * DMA ops for Xen virtio frontends. * @@ -43,48 +76,78 @@ static void *xen_virtio_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { - unsigned int n_pages = PFN_UP(size); - unsigned int i; + struct xen_virtio_data *data; + unsigned int i, n_pages = PFN_UP(size); unsigned long pfn; grant_ref_t grant; - void *ret; + void *ret = NULL; - ret = (void *)__get_free_pages(gfp, get_order(size)); - if (!ret) + data = find_xen_virtio_data(dev); + if (!data) return NULL; + spin_lock(&data->lock); + + if (unlikely(data->broken)) + goto out; + + ret = alloc_pages_exact(n_pages * PAGE_SIZE, gfp); + if (!ret) + goto out; + pfn = virt_to_pfn(ret); if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) { - free_pages((unsigned long)ret, get_order(size)); - return NULL; + free_pages_exact(ret, n_pages * PAGE_SIZE); + ret = NULL; + goto out; } for (i = 0; i < n_pages; i++) { - gnttab_grant_foreign_access_ref(grant + i, 0, + gnttab_grant_foreign_access_ref(grant + i, data->dev_domid, pfn_to_gfn(pfn + i), 0); } *dma_handle = grant_to_dma(grant); +out: + spin_unlock(&data->lock); + return ret; } static void xen_virtio_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) { - unsigned int n_pages = PFN_UP(size); - unsigned int i; + struct xen_virtio_data *data; + unsigned int i, n_pages = PFN_UP(size); grant_ref_t grant; + data = find_xen_virtio_data(dev); + if (!data) + return; + + spin_lock(&data->lock); + + if (unlikely(data->broken)) + goto out; + grant = dma_to_grant(dma_handle); - for (i = 0; i < n_pages; i++) - gnttab_end_foreign_access_ref(grant + i); + 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; + goto out; + } + } gnttab_free_grant_reference_seq(grant, n_pages); - free_pages((unsigned long)vaddr, get_order(size)); + free_pages_exact(vaddr, n_pages * PAGE_SIZE); + +out: + spin_unlock(&data->lock); } static struct page *xen_virtio_dma_alloc_pages(struct device *dev, size_t size, @@ -108,28 +171,71 @@ static dma_addr_t xen_virtio_dma_map_page(struct device *dev, struct page *page, enum dma_data_direction dir, unsigned long attrs) { + struct xen_virtio_data *data; + unsigned int i, n_pages = PFN_UP(size); grant_ref_t grant; + dma_addr_t dma_handle = DMA_MAPPING_ERROR; + + BUG_ON(dir == DMA_NONE); + + data = find_xen_virtio_data(dev); + if (!data) + return DMA_MAPPING_ERROR; + + spin_lock(&data->lock); - if (gnttab_alloc_grant_references(1, &grant)) - return 0; + if (unlikely(data->broken)) + goto out; - gnttab_grant_foreign_access_ref(grant, 0, xen_page_to_gfn(page), - dir == DMA_TO_DEVICE); + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) + goto out; - return grant_to_dma(grant) + offset; + 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; + +out: + spin_unlock(&data->lock); + + return dma_handle; } static void xen_virtio_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, unsigned long attrs) { + struct xen_virtio_data *data; + unsigned int i, n_pages = PFN_UP(size); grant_ref_t grant; + BUG_ON(dir == DMA_NONE); + + data = find_xen_virtio_data(dev); + if (!data) + return; + + spin_lock(&data->lock); + + if (unlikely(data->broken)) + goto out; + grant = dma_to_grant(dma_handle); - gnttab_end_foreign_access_ref(grant); + 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; + goto out; + } + } + + gnttab_free_grant_reference_seq(grant, n_pages); - gnttab_free_grant_reference(grant); +out: + spin_unlock(&data->lock); } static int xen_virtio_dma_map_sg(struct device *dev, struct scatterlist *sg, @@ -149,7 +255,7 @@ static void xen_virtio_dma_unmap_sg(struct device *dev, struct scatterlist *sg, static int xen_virtio_dma_dma_supported(struct device *dev, u64 mask) { - return 1; + return mask == DMA_BIT_MASK(64); } static const struct dma_map_ops xen_virtio_dma_ops = { @@ -166,9 +272,61 @@ static const struct dma_map_ops xen_virtio_dma_ops = { .dma_supported = xen_virtio_dma_dma_supported, }; +bool xen_is_virtio_device(struct device *dev) +{ + /* XXX Handle only DT devices for now */ + if (!dev->of_node) + return false; + + if (!of_device_is_compatible(dev->of_node, "virtio,mmio")) + return false; + + return of_property_read_bool(dev->of_node, "xen,dev-domid"); +} +EXPORT_SYMBOL_GPL(xen_is_virtio_device); + void xen_virtio_setup_dma_ops(struct device *dev) { + struct xen_virtio_data *data; + uint32_t dev_domid; + + data = find_xen_virtio_data(dev); + if (data) { + dev_err(dev, "xen_virtio data is already created\n"); + return; + } + + if (dev_is_pci(dev)) { + /* XXX Leave it hard wired to dom0 for now */ + dev_domid = 0; + } else if (dev->of_node) { + 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; + } + } else + /* The ACPI case is not supported */ + goto err; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + dev_err(dev, "Сannot allocate xen_virtio data\n"); + goto err; + } + data->dev_domid = dev_domid; + data->dev = dev; + spin_lock_init(&data->lock); + + spin_lock(&xen_virtio_lock); + list_add(&data->list, &xen_virtio_devices); + spin_unlock(&xen_virtio_lock); + dev->dma_ops = &xen_virtio_dma_ops; + + return; + +err: + dev_err(dev, "Сannot set up xen_virtio DMA ops, retain platform DMA ops\n"); } EXPORT_SYMBOL_GPL(xen_virtio_setup_dma_ops); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index ae3c1bc..fdbcb99 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_VIRTIO void xen_virtio_setup_dma_ops(struct device *dev); +bool xen_is_virtio_device(struct device *dev); #else static inline void xen_virtio_setup_dma_ops(struct device *dev) { } +static inline bool xen_is_virtio_device(struct device *dev) +{ + return false; +} #endif /* CONFIG_XEN_VIRTIO */ #endif /* INCLUDE_XEN_OPS_H */ From patchwork Thu Apr 14 19:19:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12813944 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 229A8C433EF for ; Thu, 14 Apr 2022 19:21:14 +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=WlOlc4zg8imWTC4a/+eHB8coAsjMAa+q+z5YxLz4QjU=; b=2FGKWqw44O2jnv 3sqe7ohYI6YGTdCqShBxD/5VR16voZ0QDBxSKmmJ2+tyDfceKfFmpQfCyg+xTro04fl9j2vlF1A+L 90YhLKHHekWENMotSQ1mKwLTrT/B/925hTlwKw9RWVCypAr3gNnocwxDsHOBoSiG6hKoTxckxJPVz PpyWIlen92to+xXSD304uHLRLfwg/rhfmC/n7jIgyLMuYb6hJK0Q6qwHpLjdXpxIfPWYa/oFp28Xq xuw6RDZw2vs0x1w3VX0WyWh/8LbZiBpgsSLza7ZRcJ9VipwG6tyIi4/pA1RbjB06NioyoUMn3OXFw ccRPfLJoiYTcB+pqyuAA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50k-00726j-QP; Thu, 14 Apr 2022 19:20:11 +0000 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50L-0071w4-M1 for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 19:19:48 +0000 Received: by mail-lf1-x135.google.com with SMTP id u7so10757007lfs.8 for ; Thu, 14 Apr 2022 12:19:45 -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=lMGcVfKV8sctWGleZvUOf73V/MSGq5S+Npr1qVNtBaA=; b=HouaAb9VHQFNGxR9MIu6VzU91fVp9m4H9MFuGHWemt2O82W51Jf7w0svknXQnp9eoL Goijg/CjOJm12gw7O79o4tOKKi3VWVpFlGcCExQrgrgWjTLybck87oaBE8839ZFvqsgt PHA9UIv4u9ZIJ0KRv79B8BNi7Ma48plv0i8Ikw6DPDjZOba9itZELQd6iL42ER4Do5KC KnGW1lDf5sUT5lSWC5BOctu4TM3VkGzNie7bvNS2Bn7x53eayd0Dgb1qqP6phAjj3tzd uRuUa2wtuEaXrTf/kpJoJpqL9whQiLU0m+UmApeEsmIl/mWjegT0468noSCexcMl91FI NpKQ== 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=lMGcVfKV8sctWGleZvUOf73V/MSGq5S+Npr1qVNtBaA=; b=MaUGtY2B8I5oP2EAnnMzPjrqlwEJrgMKqEbEd60KxG4hlbeqMufMp0YbhTX2I2mXEI +ZhoC+RRKoMQMJM0GSn5sjqkHL7DFoCDt1pio/xqfVt9WoMaB0GPSHxU86NFfdeUfXSv j9yhP5SJwi3EvMHp8EIcjv+IFV06ubOPMPJo0EJCfMvovFmaCM3EV0Fzy1wgAhvDtF1U hLY3Aj6+OGCzNU+weC0TT+jrK/1PA1j4wzvkk/yaclDiEgoTq3IoXSy8Gsfs/lyZea3t QzEZ89hmo1e44JD9rj5eOLbnyJb0dLhIwBeLNCiAXaWvVPjr8L0kcs3/AlZqzlYphVt4 TrXQ== X-Gm-Message-State: AOAM530CwL1Sx0LWojAtbHFwcJ6bivhoVQAaCNvGe26cARyMgi8Uge3q MQln0nw7P1F0MGDVYx0Uqk4= X-Google-Smtp-Source: ABdhPJyqpKzQq/8peqyhT0SdO2Fz0WkprUG2NmtNhK+vB9NhUMwVEFgX8mPVozIXpha113okS20X4g== X-Received: by 2002:a05:6512:3f97:b0:44a:f67d:7d8 with SMTP id x23-20020a0565123f9700b0044af67d07d8mr2755017lfa.81.1649963984241; Thu, 14 Apr 2022 12:19:44 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.43 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:43 -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 Subject: [RFC PATCH 5/6] arm/xen: Introduce xen_setup_dma_ops() Date: Thu, 14 Apr 2022 22:19:32 +0300 Message-Id: <1649963973-22879-6-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220414_121945_790022_E38394D7 X-CRM114-Status: GOOD ( 19.24 ) 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 subsequent patch will add xen-virtio DMA ops case. Also re-use the xen_swiotlb_detect() check on Arm32. Signed-off-by: Oleksandr Tyshchenko --- arch/arm/include/asm/xen/xen-ops.h | 1 + arch/arm/mm/dma-mapping.c | 5 ++--- arch/arm64/include/asm/xen/xen-ops.h | 1 + arch/arm64/mm/dma-mapping.c | 5 ++--- include/xen/arm/xen-ops.h | 13 +++++++++++++ 5 files changed, 19 insertions(+), 6 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..a1bf9dd 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" @@ -2288,8 +2288,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; + xen_setup_dma_ops(dev); #endif 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..831e673 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) @@ -53,7 +53,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, 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; + xen_setup_dma_ops(dev); #endif } diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h new file mode 100644 index 00000000..621da05 --- /dev/null +++ b/include/xen/arm/xen-ops.h @@ -0,0 +1,13 @@ +/* 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) +{ + if (xen_swiotlb_detect()) + dev->dma_ops = &xen_swiotlb_dma_ops; +} + +#endif /* _ASM_ARM_XEN_OPS_H */ From patchwork Thu Apr 14 19:19:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 12813945 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 A9426C433F5 for ; Thu, 14 Apr 2022 19:21:25 +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=NdM0Jdw9l0M+frFULNbinvw7x/T1raic4xd/eSs8z7c=; b=zys/wSMCnFLXxM O4iYsyeZNf0yKXzxpoBmLLMjBkPQxzYvhBMs+wrvP1RTWencKC8bC0wDyh5r9OKZXEg37QpIfI1nC cJuT2gNit2DiTYgsO1JY9JelFEyALm+T5Fwd6BNjPCOlUN2ai8wFfwTeq+pJGrI/U3qGWTDWo4hzc BET6rbhEA4n1d9sw3wovaMK/wKgdFqWMykK24xEbIrDgbsQ6jL2uM/4epeqjw2CH0CtBkQu2FQzBV kbMXNvWdK1DCEy+eo6RdnYeoeEAK5lYhN2qi5FFGOtQqE6KXJFPn2EVwr8ib0YlZE/1cF2vWHmsi+ m54uFSCQAy28LOL8Mz0g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50w-0072AW-JS; Thu, 14 Apr 2022 19:20:22 +0000 Received: from mail-lf1-x12f.google.com ([2a00:1450:4864:20::12f]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nf50N-0071wj-9x for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 19:19:49 +0000 Received: by mail-lf1-x12f.google.com with SMTP id x17so10742480lfa.10 for ; Thu, 14 Apr 2022 12:19:46 -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=JLvcL2fLROn3t3atjcd/ETf/m7mMDU63S8SDHDmllis=; b=PHixjVnS4M4CDbB1CHxDVeo28b/aVzSp0mJdrnkLOhqhj+Q/2wwhqo/TFVejF1D2cn M+V0zaS78dJd9lsRuBeMiEdLy1jV96PMJyIQ6tdjGX+3REplXlVqvCJvz8NPjkgZDOPf 0khIrkBNwrWYo3QJ78y6BdHbLNpK0mHknzDWftCsqrE3xGyfA0HJKlIH7azM+WvVfhCo FHFrJ5hJRJK3Z7+BjHY/QTvixVEHiQzKm5aCRqRcCN/lRd8u9CYEkm4z/L9bHAfjRB0R fxISXS4qdfBlfdENdbDSL4T/6mCEkKAVOD6Rznx/DdO6NACB2S+j7tbT1uhlqWI/zvSd XiZQ== 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=JLvcL2fLROn3t3atjcd/ETf/m7mMDU63S8SDHDmllis=; b=BZKDzevLokf+STVGXgULS8mbqt1oVaLSxc6o+GeVJujPcQbagg6EpjSSHK5IHUf1mA 3XgQJelgo/pvDVIGBVbRkdzV38YxRbcM9cBvjf+hF+i5S5TlKPs9mN5Y60Q55xmy2Jhi URD8eoS/eLvmK5FhcINrs6jXxX1xk6Yrtej4bjYqSMOxTu7u4fhBGsOQLZc8C0GATTnd qUnyhKuNy9TOdEKbtJwDMhxiJ3PwecGnZSgXBL3h8OGDi0fIrtYcMLtELMdG7CKwBBZJ 2LMRFAoJ2z1HORA4T/buA6YYRaVBe/sgHoki48+yE5lB9iOl61D7zGR9A9S0ulEiJMid HZvw== X-Gm-Message-State: AOAM531wedEZLiITLcuseY7t2UdqPQ3atNQ3e4HPsU7dDu/ndFZaYxbK ymfs4RmWIGbA7QXl+/ROMH0= X-Google-Smtp-Source: ABdhPJwMUxbIWiWwpSwBanMHzTQNTMGbJ4JbV9MkuLqT17euk/S+BBLtlBgciKyx0qEt1KTBdH2vcw== X-Received: by 2002:a05:6512:1082:b0:44a:a6be:90b with SMTP id j2-20020a056512108200b0044aa6be090bmr2827259lfg.45.1649963985288; Thu, 14 Apr 2022 12:19:45 -0700 (PDT) Received: from otyshchenko.router ([212.22.223.21]) by smtp.gmail.com with ESMTPSA id l3-20020a194943000000b0046b928d2795sm85001lfj.67.2022.04.14.12.19.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Apr 2022 12:19:44 -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 Subject: [RFC PATCH 6/6] arm/xen: Assign xen-virtio DMA ops for virtio devices in Xen guests Date: Thu, 14 Apr 2022 22:19:33 +0300 Message-Id: <1649963973-22879-7-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> References: <1649963973-22879-1-git-send-email-olekstysh@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220414_121947_414258_D6B3E3A3 X-CRM114-Status: GOOD ( 12.00 ) 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 Call xen_virtio_setup_dma_ops() only for Xen-aware virtio devices in Xen guests if restricted access to the guest memory is enabled. Signed-off-by: Oleksandr Tyshchenko --- include/xen/arm/xen-ops.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h index 621da05..28b2ad3 100644 --- a/include/xen/arm/xen-ops.h +++ b/include/xen/arm/xen-ops.h @@ -2,12 +2,19 @@ #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) { if (xen_swiotlb_detect()) dev->dma_ops = &xen_swiotlb_dma_ops; + +#ifdef CONFIG_XEN_VIRTIO + if (arch_has_restricted_virtio_memory_access() && xen_is_virtio_device(dev)) + xen_virtio_setup_dma_ops(dev); +#endif } #endif /* _ASM_ARM_XEN_OPS_H */