mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@amd.com>
To: <x86@kernel.org>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	linux-crypto@vger.kernel.org, linux-pci@vger.kernel.org,
	"Thomas Gleixner" <tglx@kernel.org>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Sean Christopherson" <seanjc@google.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Andy Lutomirski" <luto@kernel.org>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Ashish Kalra" <ashish.kalra@amd.com>,
	"Tom Lendacky" <thomas.lendacky@amd.com>,
	"Herbert Xu" <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Juergen Gross" <jgross@suse.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Oleksandr Tyshchenko" <oleksandr_tyshchenko@epam.com>,
	"Marek Szyprowski" <m.szyprowski@samsung.com>,
	"Robin Murphy" <robin.murphy@arm.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"David Hildenbrand" <david@kernel.org>,
	"Lorenzo Stoakes" <ljs@kernel.org>,
	"Liam R. Howlett" <liam@infradead.org>,
	"Vlastimil Babka" <vbabka@kernel.org>,
	"Mike Rapoport" <rppt@kernel.org>,
	"Suren Baghdasaryan" <surenb@google.com>,
	"Michal Hocko" <mhocko@suse.com>,
	"Catalin Marinas" <catalin.marinas@arm.com>,
	"Jini Susan George" <jinisusan.george@amd.com>,
	"Kees Cook" <kees@kernel.org>,
	"Michael Ellerman" <mpe@ellerman.id.au>,
	"Nikunj A Dadhania" <nikunj@amd.com>,
	"Ard Biesheuvel" <ardb@kernel.org>,
	"Eric Biggers" <ebiggers@kernel.org>,
	"Kim Phillips" <kim.phillips@amd.com>,
	"Joerg Roedel" <jroedel@suse.de>,
	"Ethan Nelson-Moore" <enelsonmoore@gmail.com>,
	"Tycho Andersen (AMD)" <tycho@kernel.org>,
	"Liam Merwick" <liam.merwick@oracle.com>,
	"Michael Kerrisk" <mtk.manpages@gmail.com>,
	"Suresh Siddha" <suresh.b.siddha@intel.com>,
	"Xiaotian Feng" <dfeng@redhat.com>,
	"Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>,
	"Andi Kleen" <ak@linux.intel.com>,
	"Kiryl Shutsemau" <kas@kernel.org>,
	"Tony Luck" <tony.luck@intel.com>,
	"Jason Gunthorpe" <jgg@ziepe.ca>,
	"Lu Baolu" <baolu.lu@linux.intel.com>,
	"Xu Yilun" <yilun.xu@linux.intel.com>,
	"Carlos López" <clopez@suse.de>,
	"Jonathan Cameron" <jic23@kernel.org>,
	"Jori Koolstra" <jkoolstra@xs4all.nl>,
	"Thomas Weißschuh" <thomas.weissschuh@linutronix.de>,
	"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
	"Ian Campbell" <ian.campbell@citrix.com>,
	"Jeremy Fitzhardinge" <jeremy.fitzhardinge@citrix.com>,
	"Petr Tesarik" <ptesarik@suse.com>,
	"David Howells" <dhowells@redhat.com>,
	"Haavard Skinnemoen" <hskinnemoen@atmel.com>,
	"Kenji Kaneshige" <kaneshige.kenji@jp.fujitsu.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Christian Marangi" <ansuelsmth@gmail.com>,
	"Dave Jiang" <dave.jiang@intel.com>,
	"Michael Kelley" <mhklinux@outlook.com>,
	"Ilias Stamatis" <ilstam@amazon.com>,
	"Sumanth Korikkar" <sumanthk@linux.ibm.com>,
	"Simona Vetter" <simona.vetter@ffwll.ch>,
	"Toshi Kani" <toshi.kani@hp.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Vinod Koul" <vkoul@kernel.org>,
	"Jiang Liu" <jiang.liu@linux.intel.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Anshuman Khandual" <anshuman.khandual@arm.com>,
	"Kefeng Wang" <wangkefeng.wang@huawei.com>,
	"Palmer Dabbelt" <palmerdabbelt@google.com>,
	linux-coco@lists.linux.dev, xen-devel@lists.xenproject.org,
	iommu@lists.linux.dev, linux-mm@kvack.org,
	"Alexey Kardashevskiy" <aik@amd.com>,
	aik@ozlabs.ru, "Santosh Shukla" <santosh.shukla@amd.com>,
	"Pratik R . Sampat" <prsampat@amd.com>,
	"Scott Soule Cheloha" <scott.cheloha@amd.com>,
	"Ackerley Tng" <ackerleytng@google.com>,
	"Fuad Tabba" <tabba@google.com>
Subject: [RFC PATCH kernel 17/17] x86/sev: Flush IOMMU TLB for trusted devices
Date: Wed, 16 Sep 2026 21:51:57 +1000	[thread overview]
Message-ID: <20260916115159.1938195-18-aik@amd.com> (raw)
In-Reply-To: <20260916115159.1938195-1-aik@amd.com>

IOMMU performs RMP checks when SNP is enabled, the results are
cached along with the IOMMU translations. When a VM lowers permission
of a mapped page (moves to a lower VMPL level or from read+write to
read-only or private to shared), the cached RMP check results require
invalidation.

At the moment the only way to invalidate IOMMU cache is the RMPUPDATE
instruction which flushes all IOMMU TLBs. It is a host privileged
instruction so a VM needs a way to ensure the host has done it.
Note that the guest's RMPADJUST/PVALIDATE do not flush IOMMU TLBs.

The host implements a new "IOMMU TLB Flush" VMGEXIT code which is
advertised via bit#11 in the GHCB Hypervisor capabilities.

Use RMPUPDATE in the following way:
- allocate a page per VCPU (to allow lockless flushing);
- When invalidation is needed, copy two patterns (A and B) to the page;
- invalidate the page so the host can make it shared;
- use new GHCB call to request RMPUPDATE on the host;
- the host makes the page shared;
- the host clears pattern A;
- the host makes the page private again;
- the host returns to the guest;
- check if pattern A has changed and pattern B has not;
- if the above failed, panic().

The patterns are located far enough to not hit the same cache line to
work with the cipher text hiding feature.

The host can choose to not execute the request, WARN_ON if this
is the case. Further patches will attempt to handle this in other way.

Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
---
 arch/x86/include/asm/sev-common.h |  2 +
 arch/x86/include/uapi/asm/svm.h   |  3 +
 arch/x86/coco/sev/core.c          | 92 ++++++++++++++++++++
 3 files changed, 97 insertions(+)

diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index ff763c3c5d63..51abf8d061fa 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h
@@ -138,6 +138,7 @@ enum psc_op {
 #define GHCB_HV_FT_SNP_AP_CREATION	BIT_ULL(1)
 #define GHCB_HV_FT_SNP_MULTI_VMPL	BIT_ULL(5)
 #define GHCB_HV_FT_SNP_SEV_TIO		BIT_ULL(7)
+#define GHCB_HV_FT_SNP_IOMMU_TLB_FLUSH	BIT_ULL(11)
 
 /*
  * SNP Page State Change NAE event
@@ -210,6 +211,7 @@ struct snp_psc_desc {
 #define GHCB_TERM_SECURE_TSC		10	/* Secure TSC initialization failed */
 #define GHCB_TERM_SVSM_CA_REMAP_FAIL	11	/* SVSM is present but CA could not be remapped */
 #define GHCB_TERM_SAVIC_FAIL		12	/* Secure AVIC-specific failure */
+#define GHCB_TERM_IOMMUTLB_FLUSH	13	/* IOMMUTLB flush failed for SEV-TIO device */
 
 #define GHCB_RESP_CODE(v)		((v) & GHCB_MSR_INFO_MASK)
 
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 93597ad492bf..269050942c8e 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -160,6 +160,8 @@
 #define SVM_VMGEXIT_SEV_TIO_OP_UNBIND	1
 #define SVM_VMGEXIT_SEV_TIO_OP_RUN	2
 #define SVM_VMGEXIT_SEV_TIO_OP_STOP	3
+#define SVM_VMGEXIT_IOMMU_TLB_FLUSH		0x80000022ull
+#define SVM_VMGEXIT_IOMMU_TLB_FLUSH_NO_ACTION	1
 #define SVM_VMGEXIT_HV_FEATURES			0x8000fffdull
 #define SVM_VMGEXIT_TERM_REQUEST		0x8000fffeull
 #define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code)	\
@@ -285,6 +287,7 @@
 	{ SVM_VMGEXIT_AP_CREATION,	"vmgexit_ap_creation" }, \
 	{ SVM_VMGEXIT_SEV_TIO_GR,	"vmgexit_sev_tio_guest_request" }, \
 	{ SVM_VMGEXIT_SEV_TIO_OP,	"vmgexit_sev_tio_op" }, \
+	{ SVM_VMGEXIT_IOMMU_TLB_FLUSH, "vmgexit_sev_tio_iommu_tlb_flush" }, \
 	{ SVM_VMGEXIT_HV_FEATURES,	"vmgexit_hypervisor_feature" }, \
 	{ SVM_EXIT_ERR,         "invalid_guest_state" }
 
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index ed0e4546d5e5..aa5a3abb4796 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -44,6 +44,7 @@
 #include <asm/cpuid/api.h>
 #include <asm/cmdline.h>
 #include <asm/msr.h>
+#include <asm/archrandom.h>
 
 #include "internal.h"
 
@@ -103,6 +104,36 @@ static unsigned long snp_tsc_freq_khz __ro_after_init;
 
 DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data);
 DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
+DEFINE_PER_CPU(u8 *, iommu_tlb_flush_ghcb_page);
+static atomic_t sev_tio_devices_num;
+
+static int alloc_iommu_tlb_flush_ghcb_pages(void)
+{
+	unsigned int cpu;
+	struct page *pg;
+	void *p;
+
+	/*
+	 * Allocate per CPU pages while encrypted DMA is not happening yet
+	 * and smashing is cheap.
+	 */
+	for_each_possible_cpu(cpu) {
+		if (per_cpu(iommu_tlb_flush_ghcb_page, cpu))
+			continue;
+
+		pg = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, 0);
+		if (!pg)
+			return -ENOMEM;
+
+		p = page_to_virt(pg);
+		/* Trigger psmash in the host os now to avoid psmash race later */
+		snp_set_memory_shared((unsigned long)p, 1);
+		snp_set_memory_private((unsigned long)p, 1);
+		per_cpu(iommu_tlb_flush_ghcb_page, cpu) = p;
+	}
+
+	return 0;
+}
 
 int sev_tio_op(u32 guest_rid, unsigned int op, u64 *fw_err, u64 *tdi_id)
 {
@@ -111,6 +142,24 @@ int sev_tio_op(u32 guest_rid, unsigned int op, u64 *fw_err, u64 *tdi_id)
 	struct ghcb *ghcb;
 	int ret;
 
+	if (!(sev_hv_features & GHCB_HV_FT_SNP_SEV_TIO))
+		return -EPERM;
+
+	if (op == SVM_VMGEXIT_SEV_TIO_OP_RUN || op == SVM_VMGEXIT_SEV_TIO_OP_STOP) {
+		if (!(sev_hv_features & GHCB_HV_FT_SNP_IOMMU_TLB_FLUSH))
+			return -EPERM;
+
+		if (op == SVM_VMGEXIT_SEV_TIO_OP_RUN) {
+			if (atomic_inc_return(&sev_tio_devices_num) == 1) {
+				ret = alloc_iommu_tlb_flush_ghcb_pages();
+				if (ret)
+					return ret;
+			}
+		} else if (atomic_dec_return(&sev_tio_devices_num) == 0) {
+			/* Do cleanup or leave it like this? */
+		}
+	}
+
 	/* __sev_get_ghcb() needs IRQs disabled because it uses per-CPU GHCB. */
 	guard(irqsave)();
 
@@ -347,6 +396,42 @@ static int vmgexit_psc(struct ghcb *ghcb, struct snp_psc_desc *desc)
 	return ret;
 }
 
+static int ghcb_flush_iommu_tlb(struct ghcb *ghcb)
+{
+	/* AES encrypts with 16 byte blocks */
+	unsigned long s1[BITS_TO_LONGS(128)], s2[BITS_TO_LONGS(128)];
+	void *p = this_cpu_read(iommu_tlb_flush_ghcb_page), *p2;
+	struct es_em_ctxt ctxt;
+	int ret;
+
+	if (!p)
+		return -ENOMEM;
+
+	/* Keep patterns apart far enough to not share the same cache line */
+	p2 = (u8 *) p + 2048;
+
+	vc_ghcb_invalidate(ghcb);
+
+	BUILD_BUG_ON(ARRAY_SIZE(s1) != 2);
+	if (!rdrand_long(s1) || !rdrand_long(s1 + 1) ||
+	    !rdrand_long(s2) || !rdrand_long(s2 + 1))
+		return -EFAULT;
+
+	memcpy(p, s1, sizeof(s1));
+	memcpy(p2, s2, sizeof(s2));
+
+	pvalidate((unsigned long) p, RMP_PG_SIZE_4K, false);
+	ret = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_IOMMU_TLB_FLUSH, __pa(p), 0);
+	pvalidate((unsigned long) p, RMP_PG_SIZE_4K, true);
+
+	/* Ensure that the host change is visible */
+	smp_mb();
+
+	if (!memcmp(p, s1, sizeof(s1)) || memcmp(p2, s2, sizeof(s2)))
+		return -EFAULT;
+
+	return 0;
+}
 static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
 				       unsigned long vaddr_end, int op)
 {
@@ -404,6 +489,13 @@ static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long
 	if (!ghcb || vmgexit_psc(ghcb, data))
 		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
 
+	if (atomic_read(&sev_tio_devices_num)) {
+		int ret = ghcb_flush_iommu_tlb(ghcb);
+
+		if (ret)
+			sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_IOMMUTLB_FLUSH);
+	}
+
 	__sev_put_ghcb(&state);
 
 	local_irq_restore(flags);
-- 
2.55.0


      parent reply	other threads:[~2026-09-16 12:03 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 11:51 [RFC PATCH kernel 00/17] PCI/TSM: coco/sev-guest: Implement SEV-TIO PCIe TDISP (phase2) Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 01/17] pci/dma/tsm: Call disable DMA bus hook on cleanup Alexey Kardashevskiy
2026-09-16 17:49   ` Borislav Petkov
2026-09-16 11:51 ` [RFC PATCH kernel 02/17] pci/tsm: Fix stale comment about TDI report range start Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 03/17] tsm/core: Store range_id in pci_tsm_mmio_entry Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 04/17] crypto/ccp/tsm: Use TSM API for DOE Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 05/17] tsm-core: Register nevertheless Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 06/17] x86/io/tsm: Allow mixed ioremap for shared+private BARs Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 07/17] x86/dma: Revert "x86: Remove unnecessary architecture-specific <asm/device.h>" Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 08/17] x86/dma: Add ARCH_HAS_PHYS_TO_DMA Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 09/17] dma/swiotlb: Force shared DMA for allocatios from SWIOTLB Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 10/17] x86, dma: Allow accepted devices to map private memory Alexey Kardashevskiy
2026-09-16 12:48   ` Jason Gunthorpe
2026-09-16 11:51 ` [RFC PATCH kernel 11/17] tsm/core: Add TDI status Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 12/17] coco/sev-guest: Allow multiple source files in the driver Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 13/17] x86/sev: Pass HV features to sev-guest device via platform data Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 14/17] x86/sev: Add GHCB calls for SEV-TIO Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 15/17] x86/sev: Implement guest TSM driver for SEV-TIO (phase2, DMA) Alexey Kardashevskiy
2026-09-16 11:51 ` [RFC PATCH kernel 16/17] x86/sev: Enable secure MMIO (phase2) Alexey Kardashevskiy
2026-09-16 11:51 ` Alexey Kardashevskiy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916115159.1938195-18-aik@amd.com \
    --to=aik@amd.com \
    --cc=ackerleytng@google.com \
    --cc=aik@ozlabs.ru \
    --cc=ak@linux.intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@kernel.org \
    --cc=anshuman.khandual@arm.com \
    --cc=ansuelsmth@gmail.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=ashish.kalra@amd.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=bhelgaas@google.com \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=clopez@suse.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=dave.jiang@intel.com \
    --cc=davem@davemloft.net \
    --cc=david@kernel.org \
    --cc=dfeng@redhat.com \
    --cc=dhowells@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=enelsonmoore@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=hpa@zytor.com \
    --cc=hskinnemoen@atmel.com \
    --cc=ian.campbell@citrix.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=ilstam@amazon.com \
    --cc=iommu@lists.linux.dev \
    --cc=jeremy.fitzhardinge@citrix.com \
    --cc=jgg@ziepe.ca \
    --cc=jgross@suse.com \
    --cc=jiang.liu@linux.intel.com \
    --cc=jic23@kernel.org \
    --cc=jinisusan.george@amd.com \
    --cc=jkoolstra@xs4all.nl \
    --cc=jroedel@suse.de \
    --cc=kaneshige.kenji@jp.fujitsu.com \
    --cc=kas@kernel.org \
    --cc=kees@kernel.org \
    --cc=kim.phillips@amd.com \
    --cc=kvm@vger.kernel.org \
    --cc=liam.merwick@oracle.com \
    --cc=liam@infradead.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=luto@kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mhklinux@outlook.com \
    --cc=mhocko@suse.com \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=mtk.manpages@gmail.com \
    --cc=nikunj@amd.com \
    --cc=oleksandr_tyshchenko@epam.com \
    --cc=palmerdabbelt@google.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=prsampat@amd.com \
    --cc=ptesarik@suse.com \
    --cc=robin.murphy@arm.com \
    --cc=rppt@kernel.org \
    --cc=santosh.shukla@amd.com \
    --cc=scott.cheloha@amd.com \
    --cc=seanjc@google.com \
    --cc=simona.vetter@ffwll.ch \
    --cc=sstabellini@kernel.org \
    --cc=sumanthk@linux.ibm.com \
    --cc=surenb@google.com \
    --cc=suresh.b.siddha@intel.com \
    --cc=tabba@google.com \
    --cc=tglx@kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=thomas.weissschuh@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=toshi.kani@hp.com \
    --cc=tycho@kernel.org \
    --cc=vbabka@kernel.org \
    --cc=venkatesh.pallipadi@intel.com \
    --cc=vkoul@kernel.org \
    --cc=wangkefeng.wang@huawei.com \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    --cc=yilun.xu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®