From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853140; cv=none; d=zohomail.com; s=zohoarc; b=kZrmsMX0aO2ExoBTwhwAS6GsWxYMZY2OGGFd1qzF0AzryALdlNjSXNaRtJJdnDEE8bavLyn9ho1dkukDSMDjLJGW/n/+f3yB0bnnggNbA6+VX7wnEWku9BqO7SQ0S+3qjn7zY24mhyrlM4BLNf8Bd/CdtObHNbCllfevtIM2Fcs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853140; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=+mXNdyGY43esiw4nxUtJ7GF33WLTzWjtdIqsqswapk0=; b=N+F7tXvD6uL4nts9hbDXKar1tgA8xAKzro599D3V+s5qyD5gWJ7QI8bZ/tgoJzrwXvSvbvcO0c4r4Kr69fnRRpAcBH6kbxKK8vLM5lX6sspR0En65kjwGElhKytvG/oqXo1moAXPf60LKWcO0yo3+0QxJFULblRGfwLHPE/Jbh8= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853140963105.73563489412265; Mon, 24 May 2021 03:45:40 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232717AbhEXKrG (ORCPT ); Mon, 24 May 2021 06:47:06 -0400 Received: from foss.arm.com ([217.140.110.172]:40760 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232397AbhEXKqx (ORCPT ); Mon, 24 May 2021 06:46:53 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 64F9E113E; Mon, 24 May 2021 03:45:25 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A7FA23F719; Mon, 24 May 2021 03:45:22 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 1/8] arm64: mte: Handle race when synchronising tags Date: Mon, 24 May 2021 11:45:06 +0100 Message-Id: <20210524104513.13258-2-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" mte_sync_tags() used test_and_set_bit() to set the PG_mte_tagged flag before restoring/zeroing the MTE tags. However if another thread were to race and attempt to sync the tags on the same page before the first thread had completed restoring/zeroing then it would see the flag is already set and continue without waiting. This would potentially expose the previous contents of the tags to user space, and cause any updates that user space makes before the restoring/zeroing has completed to potentially be lost. Since this code is run from atomic contexts we can't just lock the page during the process. Instead implement a new (global) spinlock to protect the mte_sync_page_tags() function. Fixes: 34bfeea4a9e9 ("arm64: mte: Clear the tags when a page is mapped in u= ser-space with PROT_MTE") Reviewed-by: Catalin Marinas Signed-off-by: Steven Price --- --- arch/arm64/kernel/mte.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 125a10e413e9..45fac0e9c323 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -25,6 +25,7 @@ u64 gcr_kernel_excl __ro_after_init; =20 static bool report_fault_once =3D true; +static DEFINE_SPINLOCK(tag_sync_lock); =20 #ifdef CONFIG_KASAN_HW_TAGS /* Whether the MTE asynchronous mode is enabled. */ @@ -34,13 +35,22 @@ EXPORT_SYMBOL_GPL(mte_async_mode); =20 static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_= swap) { + unsigned long flags; pte_t old_pte =3D READ_ONCE(*ptep); =20 + spin_lock_irqsave(&tag_sync_lock, flags); + + /* Recheck with the lock held */ + if (test_bit(PG_mte_tagged, &page->flags)) + goto out; + if (check_swap && is_swap_pte(old_pte)) { swp_entry_t entry =3D pte_to_swp_entry(old_pte); =20 - if (!non_swap_entry(entry) && mte_restore_tags(entry, page)) - return; + if (!non_swap_entry(entry) && mte_restore_tags(entry, page)) { + set_bit(PG_mte_tagged, &page->flags); + goto out; + } } =20 page_kasan_tag_reset(page); @@ -53,6 +63,10 @@ static void mte_sync_page_tags(struct page *page, pte_t = *ptep, bool check_swap) */ smp_wmb(); mte_clear_page_tags(page_address(page)); + set_bit(PG_mte_tagged, &page->flags); + +out: + spin_unlock_irqrestore(&tag_sync_lock, flags); } =20 void mte_sync_tags(pte_t *ptep, pte_t pte) @@ -60,10 +74,11 @@ void mte_sync_tags(pte_t *ptep, pte_t pte) struct page *page =3D pte_page(pte); long i, nr_pages =3D compound_nr(page); bool check_swap =3D nr_pages =3D=3D 1; + bool pte_is_tagged =3D pte_tagged(pte); =20 /* if PG_mte_tagged is set, tags have already been initialised */ for (i =3D 0; i < nr_pages; i++, page++) { - if (!test_and_set_bit(PG_mte_tagged, &page->flags)) + if (!test_bit(PG_mte_tagged, &page->flags)) mte_sync_page_tags(page, ptep, check_swap); } } --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853153; cv=none; d=zohomail.com; s=zohoarc; b=ZCUTn5aWxIMv5ay2fjy1y38iZXlaAreM9mqj5mtcI1hAHAzABeD1zDoLFjqZNvQ7EkEVPUeZCy+s3FLIhVJCmKx9ZazecSiZLYVKTVAR/44nA7ExA5bfIfxwU+IDpAmQbhRPXfaiWMCSZS1+CV0YMt8COmEZ/V77EawYAFfra+Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853153; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=nBv4+qVg5C8ahUtity7yATAkI5cIwXrmTDiA31AF4Z0=; b=bXzWN30umfW0EuQhjl9YLFWIRvZcKtnEEjjKlxPRzAP/6meqn41RGxYiKpNJBoZ1EWoqFeJ6aViy0oBbCrIXktL0A3X8DpVTIITi2yX/pI05/4u/seIc0oRiPiAoM+Ar8XzYUFiZKU4u7Dw0fKU25IbSiJmPyUEJZPbCvcnhlMY= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853153248537.8334766349201; Mon, 24 May 2021 03:45:53 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232757AbhEXKrS (ORCPT ); Mon, 24 May 2021 06:47:18 -0400 Received: from foss.arm.com ([217.140.110.172]:40780 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232721AbhEXKq4 (ORCPT ); Mon, 24 May 2021 06:46:56 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 599361396; Mon, 24 May 2021 03:45:28 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9E4933F719; Mon, 24 May 2021 03:45:25 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 2/8] arm64: Handle MTE tags zeroing in __alloc_zeroed_user_highpage() Date: Mon, 24 May 2021 11:45:07 +0100 Message-Id: <20210524104513.13258-3-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Catalin Marinas Currently, on an anonymous page fault, the kernel allocates a zeroed page and maps it in user space. If the mapping is tagged (PROT_MTE), set_pte_at() additionally clears the tags under a spinlock to avoid a race on the page->flags. In order to optimise the lock, clear the page tags on allocation in __alloc_zeroed_user_highpage() if the vma flags have VM_MTE set. Signed-off-by: Catalin Marinas Signed-off-by: Steven Price --- arch/arm64/include/asm/page.h | 6 ++++-- arch/arm64/mm/fault.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 012cffc574e8..97853570d0f1 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -13,6 +13,7 @@ #ifndef __ASSEMBLY__ =20 #include /* for READ_IMPLIES_EXEC */ +#include #include =20 struct page; @@ -28,8 +29,9 @@ void copy_user_highpage(struct page *to, struct page *fro= m, void copy_highpage(struct page *to, struct page *from); #define __HAVE_ARCH_COPY_HIGHPAGE =20 -#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) +struct page *__alloc_zeroed_user_highpage(gfp_t movableflags, + struct vm_area_struct *vma, + unsigned long vaddr); #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE =20 #define clear_user_page(page, vaddr, pg) clear_page(page) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 871c82ab0a30..5a03428e97f3 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -921,3 +921,24 @@ void do_debug_exception(unsigned long addr_if_watchpoi= nt, unsigned int esr, debug_exception_exit(regs); } NOKPROBE_SYMBOL(do_debug_exception); + +/* + * Used during anonymous page fault handling. + */ +struct page *__alloc_zeroed_user_highpage(gfp_t movableflags, + struct vm_area_struct *vma, + unsigned long vaddr) +{ + struct page *page; + bool tagged =3D system_supports_mte() && (vma->vm_flags & VM_MTE); + + page =3D alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, + vaddr); + if (tagged && page) { + mte_clear_page_tags(page_address(page)); + page_kasan_tag_reset(page); + set_bit(PG_mte_tagged, &page->flags); + } + + return page; +} --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853145; cv=none; d=zohomail.com; s=zohoarc; b=IApfSgMDWMUez9H134S6fOi5MoLXWaofBC2xgo6iWjKAxj/gwlHgKhDciO6ccKITCbilCfvIcmG6BtuDne8IJhaXSZDGNPVm/gCgTm+bWrJJCZpwy6A5Al7qIozLbqgpG4278MF6ALi3Bbp4L1UR76a+MQltY1rutrpdld8dAc8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853145; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=wnZXS9XwrqSpnL+PRnOEfeynBYu3v9txEd7Q12QOYso=; b=VVQ6gTQgxptZCi9UWSL1Xa+IF0C29Lf1Nn3CkoIlwrzat4EKECC7EJBSvj4SiQmjUtIvvxp6M1m+5ZTTW5ZUh79Pxth7BocCrk537iMs9dcluT491G7EymKUIQEHf0FbZJpOMplVaUNmV3WKKiuDOJqoyDgb+Tb3A1gsqqNg3cU= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853145716821.0553634777801; Mon, 24 May 2021 03:45:45 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232736AbhEXKrL (ORCPT ); Mon, 24 May 2021 06:47:11 -0400 Received: from foss.arm.com ([217.140.110.172]:40798 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232724AbhEXKq7 (ORCPT ); Mon, 24 May 2021 06:46:59 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 58E51139F; Mon, 24 May 2021 03:45:31 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 941653F719; Mon, 24 May 2021 03:45:28 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 3/8] arm64: mte: Sync tags for pages where PTE is untagged Date: Mon, 24 May 2021 11:45:08 +0100 Message-Id: <20210524104513.13258-4-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" A KVM guest could store tags in a page even if the VMM hasn't mapped the page with PROT_MTE. So when restoring pages from swap we will need to check to see if there are any saved tags even if !pte_tagged(). However don't check pages for which pte_access_permitted() returns false as these will not have been swapped out. Signed-off-by: Steven Price Reviewed-by: Catalin Marinas --- arch/arm64/include/asm/mte.h | 4 ++-- arch/arm64/include/asm/pgtable.h | 22 +++++++++++++++++++--- arch/arm64/kernel/mte.c | 16 ++++++++++++---- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h index bc88a1ced0d7..347ef38a35f7 100644 --- a/arch/arm64/include/asm/mte.h +++ b/arch/arm64/include/asm/mte.h @@ -37,7 +37,7 @@ void mte_free_tag_storage(char *storage); /* track which pages have valid allocation tags */ #define PG_mte_tagged PG_arch_2 =20 -void mte_sync_tags(pte_t *ptep, pte_t pte); +void mte_sync_tags(pte_t old_pte, pte_t pte); void mte_copy_page_tags(void *kto, const void *kfrom); void mte_thread_init_user(void); void mte_thread_switch(struct task_struct *next); @@ -53,7 +53,7 @@ int mte_ptrace_copy_tags(struct task_struct *child, long = request, /* unused if !CONFIG_ARM64_MTE, silence the compiler */ #define PG_mte_tagged 0 =20 -static inline void mte_sync_tags(pte_t *ptep, pte_t pte) +static inline void mte_sync_tags(pte_t old_pte, pte_t pte) { } static inline void mte_copy_page_tags(void *kto, const void *kfrom) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgta= ble.h index 0b10204e72fc..db5402168841 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -314,9 +314,25 @@ static inline void set_pte_at(struct mm_struct *mm, un= signed long addr, if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) __sync_icache_dcache(pte); =20 - if (system_supports_mte() && - pte_present(pte) && pte_tagged(pte) && !pte_special(pte)) - mte_sync_tags(ptep, pte); + /* + * If the PTE would provide user space access to the tags associated + * with it then ensure that the MTE tags are synchronised. Although + * pte_access_permitted() returns false for exec only mappings, they + * don't expose tags (instruction fetches don't check tags). + */ + if (system_supports_mte() && pte_access_permitted(pte, false) && + !pte_special(pte)) { + pte_t old_pte =3D READ_ONCE(*ptep); + /* + * We only need to synchronise if the new PTE has tags enabled + * or if swapping in (in which case another mapping may have + * set tags in the past even if this PTE isn't tagged). + * (!pte_none() && !pte_present()) is an open coded version of + * is_swap_pte() + */ + if (pte_tagged(pte) || (!pte_none(old_pte) && !pte_present(old_pte))) + mte_sync_tags(old_pte, pte); + } =20 __check_racy_pte_update(mm, ptep, pte); =20 diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 45fac0e9c323..ae0a3c68fece 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -33,10 +33,10 @@ DEFINE_STATIC_KEY_FALSE(mte_async_mode); EXPORT_SYMBOL_GPL(mte_async_mode); #endif =20 -static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_= swap) +static void mte_sync_page_tags(struct page *page, pte_t old_pte, + bool check_swap, bool pte_is_tagged) { unsigned long flags; - pte_t old_pte =3D READ_ONCE(*ptep); =20 spin_lock_irqsave(&tag_sync_lock, flags); =20 @@ -53,6 +53,9 @@ static void mte_sync_page_tags(struct page *page, pte_t *= ptep, bool check_swap) } } =20 + if (!pte_is_tagged) + goto out; + page_kasan_tag_reset(page); /* * We need smp_wmb() in between setting the flags and clearing the @@ -69,17 +72,22 @@ static void mte_sync_page_tags(struct page *page, pte_t= *ptep, bool check_swap) spin_unlock_irqrestore(&tag_sync_lock, flags); } =20 -void mte_sync_tags(pte_t *ptep, pte_t pte) +void mte_sync_tags(pte_t old_pte, pte_t pte) { struct page *page =3D pte_page(pte); long i, nr_pages =3D compound_nr(page); bool check_swap =3D nr_pages =3D=3D 1; bool pte_is_tagged =3D pte_tagged(pte); =20 + /* Early out if there's nothing to do */ + if (!check_swap && !pte_is_tagged) + return; + /* if PG_mte_tagged is set, tags have already been initialised */ for (i =3D 0; i < nr_pages; i++, page++) { if (!test_bit(PG_mte_tagged, &page->flags)) - mte_sync_page_tags(page, ptep, check_swap); + mte_sync_page_tags(page, old_pte, check_swap, + pte_is_tagged); } } =20 --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853159; cv=none; d=zohomail.com; s=zohoarc; b=BVipWQLK1/yYcbOqervxC4rVj+K4nrXkeKswFgF1fTyD2h4kVjGWM2Km9wtreNaTeyPADO37hLEVH2jvg89yixUFXd8GtxYdmc4dscAQFEV92KK+P1Oub4SM0qrjnEIFAL056pmtW0YRY18Jlue5WDJJWsXprwljLXdlvaXwVu4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853159; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=B6xoF5/580CtMpOYw+Q4GcF60XJgBHOOCIG5SNgUORg=; b=P9hUdMau1EN77ZK+uKiRTxP0y+4/fH0pmIigmyVH2zmxF0zTpSi0Kofbq/umNh/zx+Z8pLvFOppC8DdHgarxCTGNlV6DwHE8w6Pz1h3MSrIzmHc44X8ctJE4xC/VS5kNJpoQJn6RU+eKGTJj42lcGOF/rCCfaP4szVsyQnR1XWY= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853159990190.7326409503362; Mon, 24 May 2021 03:45:59 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232748AbhEXKrZ (ORCPT ); Mon, 24 May 2021 06:47:25 -0400 Received: from foss.arm.com ([217.140.110.172]:40824 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232728AbhEXKrC (ORCPT ); Mon, 24 May 2021 06:47:02 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4F6BA113E; Mon, 24 May 2021 03:45:34 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 931563F719; Mon, 24 May 2021 03:45:31 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 4/8] KVM: arm64: Introduce MTE VM feature Date: Mon, 24 May 2021 11:45:09 +0100 Message-Id: <20210524104513.13258-5-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a new VM feature 'KVM_ARM_CAP_MTE' which enables memory tagging for a VM. This will expose the feature to the guest and automatically tag memory pages touched by the VM as PG_mte_tagged (and clear the tag storage) to ensure that the guest cannot see stale tags, and so that the tags are correctly saved/restored across swap. Actually exposing the new capability to user space happens in a later patch. Signed-off-by: Steven Price Reviewed-by: Catalin Marinas --- arch/arm64/include/asm/kvm_emulate.h | 3 ++ arch/arm64/include/asm/kvm_host.h | 3 ++ arch/arm64/kvm/hyp/exception.c | 3 +- arch/arm64/kvm/mmu.c | 48 +++++++++++++++++++++++++++- arch/arm64/kvm/sys_regs.c | 7 ++++ include/uapi/linux/kvm.h | 1 + 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/= kvm_emulate.h index f612c090f2e4..6bf776c2399c 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -84,6 +84,9 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) if (cpus_have_const_cap(ARM64_MISMATCHED_CACHE_TYPE) || vcpu_el1_is_32bit(vcpu)) vcpu->arch.hcr_el2 |=3D HCR_TID2; + + if (kvm_has_mte(vcpu->kvm)) + vcpu->arch.hcr_el2 |=3D HCR_ATA; } =20 static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 7cd7d5c8c4bc..afaa5333f0e4 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -132,6 +132,8 @@ struct kvm_arch { =20 u8 pfr0_csv2; u8 pfr0_csv3; + /* Memory Tagging Extension enabled for the guest */ + bool mte_enabled; }; =20 struct kvm_vcpu_fault_info { @@ -769,6 +771,7 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); #define kvm_arm_vcpu_sve_finalized(vcpu) \ ((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED) =20 +#define kvm_has_mte(kvm) (system_supports_mte() && (kvm)->arch.mte_enabled) #define kvm_vcpu_has_pmu(vcpu) \ (test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features)) =20 diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c index 73629094f903..56426565600c 100644 --- a/arch/arm64/kvm/hyp/exception.c +++ b/arch/arm64/kvm/hyp/exception.c @@ -112,7 +112,8 @@ static void enter_exception64(struct kvm_vcpu *vcpu, un= signed long target_mode, new |=3D (old & PSR_C_BIT); new |=3D (old & PSR_V_BIT); =20 - // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests) + if (kvm_has_mte(vcpu->kvm)) + new |=3D PSR_TCO_BIT; =20 new |=3D (old & PSR_DIT_BIT); =20 diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index c5d1f3c87dbd..226035cf7d6c 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -822,6 +822,42 @@ transparent_hugepage_adjust(struct kvm_memory_slot *me= mslot, return PAGE_SIZE; } =20 +static int sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn, + unsigned long size) +{ + if (kvm_has_mte(kvm)) { + /* + * The page will be mapped in stage 2 as Normal Cacheable, so + * the VM will be able to see the page's tags and therefore + * they must be initialised first. If PG_mte_tagged is set, + * tags have already been initialised. + * pfn_to_online_page() is used to reject ZONE_DEVICE pages + * that may not support tags. + */ + unsigned long i, nr_pages =3D size >> PAGE_SHIFT; + struct page *page =3D pfn_to_online_page(pfn); + + if (!page) + return -EFAULT; + + for (i =3D 0; i < nr_pages; i++, page++) { + /* + * There is a potential (but very unlikely) race + * between two VMs which are sharing a physical page + * entering this at the same time. However by splitting + * the test/set the only risk is tags being overwritten + * by the mte_clear_page_tags() call. + */ + if (!test_bit(PG_mte_tagged, &page->flags)) { + mte_clear_page_tags(page_address(page)); + set_bit(PG_mte_tagged, &page->flags); + } + } + } + + return 0; +} + static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_memory_slot *memslot, unsigned long hva, unsigned long fault_status) @@ -971,8 +1007,13 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys= _addr_t fault_ipa, if (writable) prot |=3D KVM_PGTABLE_PROT_W; =20 - if (fault_status !=3D FSC_PERM && !device) + if (fault_status !=3D FSC_PERM && !device) { + ret =3D sanitise_mte_tags(kvm, pfn, vma_pagesize); + if (ret) + goto out_unlock; + clean_dcache_guest_page(pfn, vma_pagesize); + } =20 if (exec_fault) { prot |=3D KVM_PGTABLE_PROT_X; @@ -1168,12 +1209,17 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kv= m_gfn_range *range) bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range) { kvm_pfn_t pfn =3D pte_pfn(range->pte); + int ret; =20 if (!kvm->arch.mmu.pgt) return 0; =20 WARN_ON(range->end - range->start !=3D 1); =20 + ret =3D sanitise_mte_tags(kvm, pfn, PAGE_SIZE); + if (ret) + return false; + /* * We've moved a page around, probably through CoW, so let's treat it * just like a translation fault and clean the cache to the PoC. diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 76ea2800c33e..4a98902eaf1a 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1047,6 +1047,13 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, break; case SYS_ID_AA64PFR1_EL1: val &=3D ~FEATURE(ID_AA64PFR1_MTE); + if (kvm_has_mte(vcpu->kvm)) { + u64 pfr, mte; + + pfr =3D read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); + mte =3D cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT= ); + val |=3D FIELD_PREP(FEATURE(ID_AA64PFR1_MTE), mte); + } break; case SYS_ID_AA64ISAR1_EL1: if (!vcpu_has_ptrauth(vcpu)) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 3fd9a7e9d90c..8c95ba0fadda 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1082,6 +1082,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_SGX_ATTRIBUTE 196 #define KVM_CAP_VM_COPY_ENC_CONTEXT_FROM 197 #define KVM_CAP_PTP_KVM 198 +#define KVM_CAP_ARM_MTE 199 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853168; cv=none; d=zohomail.com; s=zohoarc; b=Tb3dhIfoV25vkD3CIFbYbtCNYUhF9y38qFEidZCEk1hI330DlyxJGFjEKj8OxJpHsQ8BN7tOtfYZ8DG0QjyaJO9Bhlrt0XReBbbcFPMw1M9gJ/+dybt+FEhEgh6ngAn0EM5GclBfWXPhVCGzGNwQPxCoqBSio1hamD93ZmztvQY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853168; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=7NaQbk3MVcMfHkAU7y91tZm7xBWepbpITalwS24k7Nw=; b=fJAeyawnlSldfuXKYvO/28RPPVSANU8KLzi8+J1bj/6l1mu2nMNBx1Lbh2FaFwLFVSTodhtkTmuutWN1i4BFlQujaQYS9PD/H03SHMcv7Fkt9vXqaLpV72UPZejm+pN2/+AYuidxe1NiLD8W+cOQjTyOKhR2TSmlaK6mw6nkdOs= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853168788454.52823367904955; Mon, 24 May 2021 03:46:08 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232767AbhEXKre (ORCPT ); Mon, 24 May 2021 06:47:34 -0400 Received: from foss.arm.com ([217.140.110.172]:40844 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232733AbhEXKrF (ORCPT ); Mon, 24 May 2021 06:47:05 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4633B31B; Mon, 24 May 2021 03:45:37 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 89C933F719; Mon, 24 May 2021 03:45:34 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 5/8] KVM: arm64: Save/restore MTE registers Date: Mon, 24 May 2021 11:45:10 +0100 Message-Id: <20210524104513.13258-6-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Define the new system registers that MTE introduces and context switch them. The MTE feature is still hidden from the ID register as it isn't supported in a VM yet. Signed-off-by: Steven Price Reviewed-by: Catalin Marinas --- arch/arm64/include/asm/kvm_host.h | 6 ++ arch/arm64/include/asm/kvm_mte.h | 68 ++++++++++++++++++++++ arch/arm64/include/asm/sysreg.h | 3 +- arch/arm64/kernel/asm-offsets.c | 2 + arch/arm64/kvm/hyp/entry.S | 7 +++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 21 +++++++ arch/arm64/kvm/sys_regs.c | 22 +++++-- 7 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_mte.h diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index afaa5333f0e4..309e36cc1b42 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -208,6 +208,12 @@ enum vcpu_sysreg { CNTP_CVAL_EL0, CNTP_CTL_EL0, =20 + /* Memory Tagging Extension registers */ + RGSR_EL1, /* Random Allocation Tag Seed Register */ + GCR_EL1, /* Tag Control Register */ + TFSR_EL1, /* Tag Fault Status Register (EL1) */ + TFSRE0_EL1, /* Tag Fault Status Register (EL0) */ + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ diff --git a/arch/arm64/include/asm/kvm_mte.h b/arch/arm64/include/asm/kvm_= mte.h new file mode 100644 index 000000000000..eae4bce9e269 --- /dev/null +++ b/arch/arm64/include/asm/kvm_mte.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 ARM Ltd. + */ +#ifndef __ASM_KVM_MTE_H +#define __ASM_KVM_MTE_H + +#ifdef __ASSEMBLY__ + +#include + +#ifdef CONFIG_ARM64_MTE + +.macro mte_switch_to_guest g_ctxt, h_ctxt, reg1 +alternative_if_not ARM64_MTE + b .L__skip_switch\@ +alternative_else_nop_endif + mrs \reg1, hcr_el2 + and \reg1, \reg1, #(HCR_ATA) + cbz \reg1, .L__skip_switch\@ + + mrs_s \reg1, SYS_RGSR_EL1 + str \reg1, [\h_ctxt, #CPU_RGSR_EL1] + mrs_s \reg1, SYS_GCR_EL1 + str \reg1, [\h_ctxt, #CPU_GCR_EL1] + + ldr \reg1, [\g_ctxt, #CPU_RGSR_EL1] + msr_s SYS_RGSR_EL1, \reg1 + ldr \reg1, [\g_ctxt, #CPU_GCR_EL1] + msr_s SYS_GCR_EL1, \reg1 + +.L__skip_switch\@: +.endm + +.macro mte_switch_to_hyp g_ctxt, h_ctxt, reg1 +alternative_if_not ARM64_MTE + b .L__skip_switch\@ +alternative_else_nop_endif + mrs \reg1, hcr_el2 + and \reg1, \reg1, #(HCR_ATA) + cbz \reg1, .L__skip_switch\@ + + mrs_s \reg1, SYS_RGSR_EL1 + str \reg1, [\g_ctxt, #CPU_RGSR_EL1] + mrs_s \reg1, SYS_GCR_EL1 + str \reg1, [\g_ctxt, #CPU_GCR_EL1] + + ldr \reg1, [\h_ctxt, #CPU_RGSR_EL1] + msr_s SYS_RGSR_EL1, \reg1 + ldr \reg1, [\h_ctxt, #CPU_GCR_EL1] + msr_s SYS_GCR_EL1, \reg1 + + isb + +.L__skip_switch\@: +.endm + +#else /* CONFIG_ARM64_MTE */ + +.macro mte_switch_to_guest g_ctxt, h_ctxt, reg1 +.endm + +.macro mte_switch_to_hyp g_ctxt, h_ctxt, reg1 +.endm + +#endif /* CONFIG_ARM64_MTE */ +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_KVM_MTE_H */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 65d15700a168..347ccac2341e 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -651,7 +651,8 @@ =20 #define INIT_SCTLR_EL2_MMU_ON \ (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_ELx_I | \ - SCTLR_ELx_IESB | SCTLR_ELx_WXN | ENDIAN_SET_EL2 | SCTLR_EL2_RES1) + SCTLR_ELx_IESB | SCTLR_ELx_WXN | ENDIAN_SET_EL2 | \ + SCTLR_ELx_ITFSB | SCTLR_EL2_RES1) =20 #define INIT_SCTLR_EL2_MMU_OFF \ (SCTLR_EL2_RES1 | ENDIAN_SET_EL2) diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offset= s.c index 0cb34ccb6e73..6f0044cb233e 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -111,6 +111,8 @@ int main(void) DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_= flags)); DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_cpu_context, regs)); + DEFINE(CPU_RGSR_EL1, offsetof(struct kvm_cpu_context, sys_regs[RGSR_EL1= ])); + DEFINE(CPU_GCR_EL1, offsetof(struct kvm_cpu_context, sys_regs[GCR_EL1])= ); DEFINE(CPU_APIAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIA= KEYLO_EL1])); DEFINE(CPU_APIBKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIB= KEYLO_EL1])); DEFINE(CPU_APDAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APDA= KEYLO_EL1])); diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S index e831d3dfd50d..435346ea1504 100644 --- a/arch/arm64/kvm/hyp/entry.S +++ b/arch/arm64/kvm/hyp/entry.S @@ -13,6 +13,7 @@ #include #include #include +#include #include =20 .text @@ -51,6 +52,9 @@ alternative_else_nop_endif =20 add x29, x0, #VCPU_CONTEXT =20 + // mte_switch_to_guest(g_ctxt, h_ctxt, tmp1) + mte_switch_to_guest x29, x1, x2 + // Macro ptrauth_switch_to_guest format: // ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3) // The below macro to restore guest keys is not implemented in C code @@ -142,6 +146,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) // when this feature is enabled for kernel code. ptrauth_switch_to_hyp x1, x2, x3, x4, x5 =20 + // mte_switch_to_hyp(g_ctxt, h_ctxt, reg1) + mte_switch_to_hyp x1, x2, x3 + // Restore hyp's sp_el0 restore_sp_el0 x2, x3 =20 diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hy= p/include/hyp/sysreg-sr.h index cce43bfe158f..de7e14c862e6 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h @@ -14,6 +14,7 @@ #include #include #include +#include =20 static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { @@ -26,6 +27,16 @@ static inline void __sysreg_save_user_state(struct kvm_c= pu_context *ctxt) ctxt_sys_reg(ctxt, TPIDRRO_EL0) =3D read_sysreg(tpidrro_el0); } =20 +static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu =3D ctxt->__hyp_running_vcpu; + + if (!vcpu) + vcpu =3D container_of(ctxt, struct kvm_vcpu, arch.ctxt); + + return kvm_has_mte(kern_hyp_va(vcpu->kvm)); +} + static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, CSSELR_EL1) =3D read_sysreg(csselr_el1); @@ -46,6 +57,11 @@ static inline void __sysreg_save_el1_state(struct kvm_cp= u_context *ctxt) ctxt_sys_reg(ctxt, PAR_EL1) =3D read_sysreg_par(); ctxt_sys_reg(ctxt, TPIDR_EL1) =3D read_sysreg(tpidr_el1); =20 + if (ctxt_has_mte(ctxt)) { + ctxt_sys_reg(ctxt, TFSR_EL1) =3D read_sysreg_el1(SYS_TFSR); + ctxt_sys_reg(ctxt, TFSRE0_EL1) =3D read_sysreg_s(SYS_TFSRE0_EL1); + } + ctxt_sys_reg(ctxt, SP_EL1) =3D read_sysreg(sp_el1); ctxt_sys_reg(ctxt, ELR_EL1) =3D read_sysreg_el1(SYS_ELR); ctxt_sys_reg(ctxt, SPSR_EL1) =3D read_sysreg_el1(SYS_SPSR); @@ -107,6 +123,11 @@ static inline void __sysreg_restore_el1_state(struct k= vm_cpu_context *ctxt) write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1), par_el1); write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1), tpidr_el1); =20 + if (ctxt_has_mte(ctxt)) { + write_sysreg_el1(ctxt_sys_reg(ctxt, TFSR_EL1), SYS_TFSR); + write_sysreg_s(ctxt_sys_reg(ctxt, TFSRE0_EL1), SYS_TFSRE0_EL1); + } + if (!has_vhe() && cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT) && ctxt->__hyp_running_vcpu) { diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 4a98902eaf1a..440315a556c2 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1309,6 +1309,20 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, str= uct sys_reg_params *p, return true; } =20 +static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) +{ + return REG_HIDDEN; +} + +#define MTE_REG(name) { \ + SYS_DESC(SYS_##name), \ + .access =3D undef_access, \ + .reset =3D reset_unknown, \ + .reg =3D name, \ + .visibility =3D mte_visibility, \ +} + /* sys_reg_desc initialiser for known cpufeature ID registers */ #define ID_SANITISED(name) { \ SYS_DESC(SYS_##name), \ @@ -1477,8 +1491,8 @@ static const struct sys_reg_desc sys_reg_descs[] =3D { { SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 }, { SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 }, =20 - { SYS_DESC(SYS_RGSR_EL1), undef_access }, - { SYS_DESC(SYS_GCR_EL1), undef_access }, + MTE_REG(RGSR_EL1), + MTE_REG(GCR_EL1), =20 { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility =3D sve= _visibility }, { SYS_DESC(SYS_TRFCR_EL1), undef_access }, @@ -1505,8 +1519,8 @@ static const struct sys_reg_desc sys_reg_descs[] =3D { { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi }, { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi }, =20 - { SYS_DESC(SYS_TFSR_EL1), undef_access }, - { SYS_DESC(SYS_TFSRE0_EL1), undef_access }, + MTE_REG(TFSR_EL1), + MTE_REG(TFSRE0_EL1), =20 { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Received-SPF: pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; envelope-from=linux-kernel-owner@vger.kernel.org; helo=vger.kernel.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853177; cv=none; d=zohomail.com; s=zohoarc; b=n97jYphJVq1IVGVKBDi9zdsBT5vilKVS7PASX1nKwOLt6bmR6uWUhjFTI/XLjG6ABXs6zcdqo7hKHvjdYzcvqo8QsN06IEIXqoOk4j9mYaaBeozwJqmNkVsyLBzUIIOPd75EiVx5/8aLiiZbNHe4whBtpi636ZuzP1ScOjR+XEM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853177; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:MIME-Version:Message-ID:References:Subject:To; bh=cHHw+8RoqPIPcHYumr68MMQoUo9YjjCp4g9kJEz4zIA=; b=bi/i9xa+Y/oSedR33JqQuDkbN8jpQqTlisl4wmLtA+JczwjSXFysUrrJ7899x4vT0YG74VAEFyBKXPqJceI5M3H/eIOijvTNKyjp9NEuUL6ocesPlcgKykeDN4IndZdqZoopQJK4r1NHbj5HFezfcxlkC6EUdfsgS/3R+yN7lY0= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mx.zohomail.com with SMTP id 1621853177890787.8093487925906; Mon, 24 May 2021 03:46:17 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232800AbhEXKrn (ORCPT ); Mon, 24 May 2021 06:47:43 -0400 Received: from foss.arm.com ([217.140.110.172]:40874 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232718AbhEXKrI (ORCPT ); Mon, 24 May 2021 06:47:08 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3BF461396; Mon, 24 May 2021 03:45:40 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7FF4C3F719; Mon, 24 May 2021 03:45:37 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Cc: Steven Price , James Morse , Julien Thierry , Suzuki K Poulose , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Martin , Mark Rutland , Thomas Gleixner , qemu-devel@nongnu.org, Juan Quintela , "Dr. David Alan Gilbert" , Richard Henderson , Peter Maydell , Haibo Xu , Andrew Jones Subject: [PATCH v13 6/8] KVM: arm64: Expose KVM_ARM_CAP_MTE Date: Mon, 24 May 2021 11:45:11 +0100 Message-Id: <20210524104513.13258-7-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" It's now safe for the VMM to enable MTE in a guest, so expose the capability to user space. Signed-off-by: Steven Price Reviewed-by: Catalin Marinas --- arch/arm64/kvm/arm.c | 9 +++++++++ arch/arm64/kvm/reset.c | 3 ++- arch/arm64/kvm/sys_regs.c | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 1cb39c0803a4..e89a5e275e25 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -93,6 +93,12 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, r =3D 0; kvm->arch.return_nisv_io_abort_to_user =3D true; break; + case KVM_CAP_ARM_MTE: + if (!system_supports_mte() || kvm->created_vcpus) + return -EINVAL; + r =3D 0; + kvm->arch.mte_enabled =3D true; + break; default: r =3D -EINVAL; break; @@ -237,6 +243,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long = ext) */ r =3D 1; break; + case KVM_CAP_ARM_MTE: + r =3D system_supports_mte(); + break; case KVM_CAP_STEAL_TIME: r =3D kvm_arm_pvtime_supported(); break; diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index 956cdc240148..50635eacfa43 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -220,7 +220,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) switch (vcpu->arch.target) { default: if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { - if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1)) { + if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) || + vcpu->kvm->arch.mte_enabled) { ret =3D -EINVAL; goto out; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 440315a556c2..d4e1c1b1a08d 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1312,6 +1312,9 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, stru= ct sys_reg_params *p, static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { + if (kvm_has_mte(vcpu->kvm)) + return 0; + return REG_HIDDEN; } =20 --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853554; cv=none; d=zohomail.com; s=zohoarc; b=jsyl15PdMiCaw/MYQE7nUSPYV7HbQ2p8mHGoDlZb+jJEAVMIcJ4tZVwJOGm7voFdTsSEW04Wlw3TBxIOE4s6Gw73H1Jq2gkGT7zwphDEBPK/Lu0TWkhn+3biexxkGe0Is0AQdCCQay0Av1k1bhe0MCLB9XneihcGRAMNAVg7ir8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853554; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=YXEjC4F50T9Sg8aEGYhqdudrpCV7DXkVDFeLIRfnGeI=; b=MMXpJFZPn4SkEYQZ9Hz9SeDRb0Ydv2Ylk8QHoXslruw1tnR4aeyJD6qczhbLt5Lwyuhc9ej2WHw5T7QBwQ9g3EXMirq4DjO50ddf+lFRP5CHRP2SIS0g3T5p+aCNkeiTGPWKtPDuHLP1j1tOz8T9QZ19FofRAXb1V4yXWz7xbCk= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621853554992967.1509947883284; Mon, 24 May 2021 03:52:34 -0700 (PDT) Received: from localhost ([::1]:60740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ll8CH-0001xb-Vc for importer2@patchew.org; Mon, 24 May 2021 06:52:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48560) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ll85t-0005O1-Uk for qemu-devel@nongnu.org; Mon, 24 May 2021 06:45:57 -0400 Received: from foss.arm.com ([217.140.110.172]:33550) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ll85g-0005QI-1F for qemu-devel@nongnu.org; Mon, 24 May 2021 06:45:57 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3251F139F; Mon, 24 May 2021 03:45:43 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 761AE3F719; Mon, 24 May 2021 03:45:40 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Subject: [PATCH v13 7/8] KVM: arm64: ioctl to fetch/store tags in a guest Date: Mon, 24 May 2021 11:45:12 +0100 Message-Id: <20210524104513.13258-8-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=217.140.110.172; envelope-from=steven.price@arm.com; helo=foss.arm.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , "Dr. David Alan Gilbert" , Andrew Jones , Haibo Xu , Suzuki K Poulose , qemu-devel@nongnu.org, Dave Martin , Juan Quintela , Richard Henderson , linux-kernel@vger.kernel.org, Steven Price , James Morse , Julien Thierry , Thomas Gleixner , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The VMM may not wish to have it's own mapping of guest memory mapped with PROT_MTE because this causes problems if the VMM has tag checking enabled (the guest controls the tags in physical RAM and it's unlikely the tags are correct for the VMM). Instead add a new ioctl which allows the VMM to easily read/write the tags from guest memory, allowing the VMM's mapping to be non-PROT_MTE while the VMM can still read/write the tags for the purpose of migration. Signed-off-by: Steven Price --- arch/arm64/include/asm/kvm_host.h | 3 ++ arch/arm64/include/asm/mte-def.h | 1 + arch/arm64/include/uapi/asm/kvm.h | 11 +++++ arch/arm64/kvm/arm.c | 7 +++ arch/arm64/kvm/guest.c | 79 +++++++++++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + 6 files changed, 102 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 309e36cc1b42..66b6339df949 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -729,6 +729,9 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); =20 +int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, + struct kvm_arm_copy_mte_tags *copy_tags); + /* Guest/host FPSIMD coordination helpers */ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-= def.h index cf241b0f0a42..626d359b396e 100644 --- a/arch/arm64/include/asm/mte-def.h +++ b/arch/arm64/include/asm/mte-def.h @@ -7,6 +7,7 @@ =20 #define MTE_GRANULE_SIZE UL(16) #define MTE_GRANULE_MASK (~(MTE_GRANULE_SIZE - 1)) +#define MTE_GRANULES_PER_PAGE (PAGE_SIZE / MTE_GRANULE_SIZE) #define MTE_TAG_SHIFT 56 #define MTE_TAG_SIZE 4 #define MTE_TAG_MASK GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TA= G_SHIFT) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index 24223adae150..b3edde68bc3e 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -184,6 +184,17 @@ struct kvm_vcpu_events { __u32 reserved[12]; }; =20 +struct kvm_arm_copy_mte_tags { + __u64 guest_ipa; + __u64 length; + void __user *addr; + __u64 flags; + __u64 reserved[2]; +}; + +#define KVM_ARM_TAGS_TO_GUEST 0 +#define KVM_ARM_TAGS_FROM_GUEST 1 + /* If you need to interpret the index values, here is the key: */ #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 #define KVM_REG_ARM_COPROC_SHIFT 16 diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e89a5e275e25..baa33359e477 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1345,6 +1345,13 @@ long kvm_arch_vm_ioctl(struct file *filp, =20 return 0; } + case KVM_ARM_MTE_COPY_TAGS: { + struct kvm_arm_copy_mte_tags copy_tags; + + if (copy_from_user(©_tags, argp, sizeof(copy_tags))) + return -EFAULT; + return kvm_vm_ioctl_mte_copy_tags(kvm, ©_tags); + } default: return -EINVAL; } diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 5cb4a1cd5603..7a1e181eb463 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -995,3 +995,82 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, =20 return ret; } + +int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, + struct kvm_arm_copy_mte_tags *copy_tags) +{ + gpa_t guest_ipa =3D copy_tags->guest_ipa; + size_t length =3D copy_tags->length; + void __user *tags =3D copy_tags->addr; + gpa_t gfn; + bool write =3D !(copy_tags->flags & KVM_ARM_TAGS_FROM_GUEST); + int ret =3D 0; + + if (!kvm_has_mte(kvm)) + return -EINVAL; + + if (copy_tags->reserved[0] || copy_tags->reserved[1]) + return -EINVAL; + + if (copy_tags->flags & ~KVM_ARM_TAGS_FROM_GUEST) + return -EINVAL; + + if (length & ~PAGE_MASK || guest_ipa & ~PAGE_MASK) + return -EINVAL; + + gfn =3D gpa_to_gfn(guest_ipa); + + mutex_lock(&kvm->slots_lock); + + while (length > 0) { + kvm_pfn_t pfn =3D gfn_to_pfn_prot(kvm, gfn, write, NULL); + void *maddr; + unsigned long num_tags; + struct page *page; + + if (is_error_noslot_pfn(pfn)) { + ret =3D -EFAULT; + goto out; + } + + page =3D pfn_to_online_page(pfn); + if (!page) { + /* Reject ZONE_DEVICE memory */ + ret =3D -EFAULT; + goto out; + } + maddr =3D page_address(page); + + if (!write) { + if (test_bit(PG_mte_tagged, &page->flags)) + num_tags =3D mte_copy_tags_to_user(tags, maddr, + MTE_GRANULES_PER_PAGE); + else + /* No tags in memory, so write zeros */ + num_tags =3D MTE_GRANULES_PER_PAGE - + clear_user(tags, MTE_GRANULES_PER_PAGE); + kvm_release_pfn_clean(pfn); + } else { + num_tags =3D mte_copy_tags_from_user(maddr, tags, + MTE_GRANULES_PER_PAGE); + kvm_release_pfn_dirty(pfn); + } + + if (num_tags !=3D MTE_GRANULES_PER_PAGE) { + ret =3D -EFAULT; + goto out; + } + + /* Set the flag after checking the write completed fully */ + if (write) + set_bit(PG_mte_tagged, &page->flags); + + gfn++; + tags +=3D num_tags; + length -=3D PAGE_SIZE; + } + +out: + mutex_unlock(&kvm->slots_lock); + return ret; +} diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 8c95ba0fadda..4c011c60d468 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1428,6 +1428,7 @@ struct kvm_s390_ucas_mapping { /* Available with KVM_CAP_PMU_EVENT_FILTER */ #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_= filter) #define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3) +#define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte= _tags) =20 /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) --=20 2.20.1 From nobody Sat Apr 27 14:21:07 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1621853258; cv=none; d=zohomail.com; s=zohoarc; b=HETOkurOpVFb7tX81XTCKCQoWdDO7BTid2dNK8ToSpg7/WgCRek4VbAg+12a+w+QpsU1izEyczV5qaK3Byc5qPBPikKXc+Aox69ShGZEN41EEFcvBnrG2DqrBn6izNWJ0yqJeYfet5MaL6lp7wY2POE7zZ09XTNdbfSafsJ/0E0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621853258; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=mGEmy3kvL2TtkM2vnzAmaxnfa9coUOacVqBjGw0jek8=; b=j4ng3ED28ARfq7GqOT5qk27d5c2Sa66JU7dxw86auJRlyKJNl3rmHvqqas7qW8n46sW5b0evtZvwjZOmEer5qdJGzCWGugjaw0qe+11KvUFnV/255dV5mYzm4BtrohYdvkW0MvmEpG1bFdO6qjr5AdVCfy/LtWkyIzEmG/6SNVk= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621853258395132.26595257125246; Mon, 24 May 2021 03:47:38 -0700 (PDT) Received: from localhost ([::1]:45100 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ll87V-0008BW-EF for importer2@patchew.org; Mon, 24 May 2021 06:47:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48554) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ll85s-0005NP-1f for qemu-devel@nongnu.org; Mon, 24 May 2021 06:45:57 -0400 Received: from foss.arm.com ([217.140.110.172]:33532) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ll85i-0005Nc-VR for qemu-devel@nongnu.org; Mon, 24 May 2021 06:45:55 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2984831B; Mon, 24 May 2021 03:45:46 -0700 (PDT) Received: from e112269-lin.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6C6ED3F719; Mon, 24 May 2021 03:45:43 -0700 (PDT) From: Steven Price To: Catalin Marinas , Marc Zyngier , Will Deacon Subject: [PATCH v13 8/8] KVM: arm64: Document MTE capability and ioctl Date: Mon, 24 May 2021 11:45:13 +0100 Message-Id: <20210524104513.13258-9-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210524104513.13258-1-steven.price@arm.com> References: <20210524104513.13258-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=217.140.110.172; envelope-from=steven.price@arm.com; helo=foss.arm.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , "Dr. David Alan Gilbert" , Andrew Jones , Haibo Xu , Suzuki K Poulose , qemu-devel@nongnu.org, Dave Martin , Juan Quintela , Richard Henderson , linux-kernel@vger.kernel.org, Steven Price , James Morse , Julien Thierry , Thomas Gleixner , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" A new capability (KVM_CAP_ARM_MTE) identifies that the kernel supports granting a guest access to the tags, and provides a mechanism for the VMM to enable it. A new ioctl (KVM_ARM_MTE_COPY_TAGS) provides a simple way for a VMM to access the tags of a guest without having to maintain a PROT_MTE mapping in userspace. The above capability gates access to the ioctl. Signed-off-by: Steven Price --- Documentation/virt/kvm/api.rst | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 22d077562149..ab45d7fe2aa5 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5034,6 +5034,37 @@ see KVM_XEN_VCPU_SET_ATTR above. The KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST type may not be used with the KVM_XEN_VCPU_GET_ATTR ioctl. =20 +4.130 KVM_ARM_MTE_COPY_TAGS +--------------------------- + +:Capability: KVM_CAP_ARM_MTE +:Architectures: arm64 +:Type: vm ioctl +:Parameters: struct kvm_arm_copy_mte_tags +:Returns: 0 on success, < 0 on error + +:: + + struct kvm_arm_copy_mte_tags { + __u64 guest_ipa; + __u64 length; + void __user *addr; + __u64 flags; + __u64 reserved[2]; + }; + +Copies Memory Tagging Extension (MTE) tags to/from guest tag memory. The +``guest_ipa`` and ``length`` fields must be ``PAGE_SIZE`` aligned. The ``a= ddr`` +fieldmust point to a buffer which the tags will be copied to or from. + +``flags`` specifies the direction of copy, either ``KVM_ARM_TAGS_TO_GUEST`= ` or +``KVM_ARM_TAGS_FROM_GUEST``. + +The size of the buffer to store the tags is ``(length / 16)`` bytes +(granules in MTE are 16 bytes long). Each byte contains a single tag +value. This matches the format of ``PTRACE_PEEKMTETAGS`` and +``PTRACE_POKEMTETAGS``. + 5. The kvm_run structure =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -6362,6 +6393,27 @@ default. =20 See Documentation/x86/sgx/2.Kernel-internals.rst for more details. =20 +7.26 KVM_CAP_ARM_MTE +-------------------- + +:Architectures: arm64 +:Parameters: none + +This capability indicates that KVM (and the hardware) supports exposing the +Memory Tagging Extensions (MTE) to the guest. It must also be enabled by t= he +VMM before creating any VCPUs to allow the guest access. Note that MTE is = only +available to a guest running in AArch64 mode and enabling this capability = will +cause attempts to create AArch32 VCPUs to fail. + +When enabled the guest is able to access tags associated with any memory g= iven +to the guest. KVM will ensure that the pages are flagged ``PG_mte_tagged``= so +that the tags are maintained during swap or hibernation of the host; howev= er +the VMM needs to manually save/restore the tags as appropriate if the VM is +migrated. + +When enabled the VMM may make use of the ``KVM_ARM_MTE_COPY_TAGS`` ioctl to +perform a bulk copy of tags to/from the guest. + 8. Other capabilities. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.20.1