* Re: [PATCH 01/15] x86/virt/tdx: Read global metadata for TDX Module Extensions
From: Adrian Hunter @ 2026-06-09 13:06 UTC (permalink / raw)
To: Xu Yilun, kas, djbw, rick.p.edgecombe, x86, peter.fang
Cc: linux-coco, linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <20260522034128.3144354-2-yilun.xu@linux.intel.com>
On 22/05/2026 06:41, Xu Yilun wrote:
> Add reading of the global metadata for TDX Module Extensions.
For tip, isn't the expectation to explain the context first. The
very first patch, might be a good place to explain a bit about
TDX Module Extensions in general.
>
> TDX Module Extensions is an add-on feature enumerated by TDX_FEATURES0.
> But for the Module's integrity, Linux requires that all features that a
> Module advertises must have a complete, valid set of metadata, and the
> validation must succeed at core TDX initialization time.
>
> Check TDX_FEATURES0 before reading these metadata. If a feature is
> advertised, a failure in reading associated metadata causes the entire
> TDX initialization to fail, otherwise skip.
>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> ---
> arch/x86/include/asm/tdx_global_metadata.h | 6 ++++++
> arch/x86/virt/vmx/tdx/tdx.h | 1 +
> arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
> 3 files changed, 23 insertions(+)
>
> diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
> index 40689c8dc67e..533afe50a3f1 100644
> --- a/arch/x86/include/asm/tdx_global_metadata.h
> +++ b/arch/x86/include/asm/tdx_global_metadata.h
> @@ -40,12 +40,18 @@ struct tdx_sys_info_td_conf {
> u64 cpuid_config_values[128][2];
> };
>
> +struct tdx_sys_info_ext {
> + u16 memory_pool_required_pages;
> + u8 ext_required;
> +};
> +
> struct tdx_sys_info {
> struct tdx_sys_info_version version;
> struct tdx_sys_info_features features;
> struct tdx_sys_info_tdmr tdmr;
> struct tdx_sys_info_td_ctrl td_ctrl;
> struct tdx_sys_info_td_conf td_conf;
> + struct tdx_sys_info_ext ext;
> };
>
> #endif
> diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
> index e2cf2dd48755..a5eec8e3cc71 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.h
> +++ b/arch/x86/virt/vmx/tdx/tdx.h
> @@ -87,6 +87,7 @@ struct tdmr_info {
>
> /* Bit definitions of TDX_FEATURES0 metadata field */
> #define TDX_FEATURES0_NO_RBP_MOD BIT(18)
> +#define TDX_FEATURES0_EXT BIT_ULL(39)
>
> /*
> * Do not put any hardware-defined TDX structure representations below
> diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> index c7db393a9cfb..3d3b56ef3d2f 100644
> --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> @@ -100,6 +100,19 @@ static __init int get_tdx_sys_info_td_conf(struct tdx_sys_info_td_conf *sysinfo_
> return ret;
> }
>
> +static __init int get_tdx_sys_info_ext(struct tdx_sys_info_ext *sysinfo_ext)
> +{
> + int ret = 0;
> + u64 val;
> +
> + if (!ret && !(ret = read_sys_metadata_field(0x3100000100000000, &val)))
> + sysinfo_ext->memory_pool_required_pages = val;
> + if (!ret && !(ret = read_sys_metadata_field(0x3100000000000001, &val)))
> + sysinfo_ext->ext_required = val;
> +
> + return ret;
> +}
> +
> static __init int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
> {
> int ret = 0;
> @@ -116,5 +129,8 @@ static __init int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
> ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);
> ret = ret ?: get_tdx_sys_info_td_conf(&sysinfo->td_conf);
>
> + if (sysinfo->features.tdx_features0 & TDX_FEATURES0_EXT)
> + ret = ret ?: get_tdx_sys_info_ext(&sysinfo->ext);
> +
> return ret;
> }
^ permalink raw reply
* Re: [PATCH v6 14/20] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Petr Tesarik @ 2026-06-09 13:12 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley
In-Reply-To: <20260604083959.1265923-15-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:53 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
>
> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> again, and pass the CPU address back through an out-parameter for the
> dma_direct_alloc() caller.
>
> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> Cc: stable@vger.kernel.org
While I totally agree with the reasoning and the fix, it's interesting
that this bug has been apparently present in the kernel for 5+ years
without anybody hitting nasty memory corruption bugs.
How can it be? Is the buggy code path never actually used in practice?
Does it hint at a missed opportunity to simplify the code?
Anyway, these these thoughts are intended for a possible future
cleanup. For now, let's apply the fix as is, of course.
Petr T
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> kernel/dma/direct.c | 21 ++++++++++++---------
> 1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 4e446aa4130e..e0ab9ff3f1d6 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -157,24 +157,24 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
> return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
> }
>
> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> - dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> + dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp,
> + unsigned long attrs)
> {
> struct page *page;
> u64 phys_limit;
> - void *ret;
>
> if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
> return NULL;
>
> gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
> - page = dma_alloc_from_pool(dev, size, &ret, gfp, attrs,
> + page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, attrs,
> dma_coherent_ok);
> if (!page)
> return NULL;
> *dma_handle = phys_to_dma_direct(dev, page_to_phys(page),
> !!(attrs & DMA_ATTR_CC_SHARED));
> - return ret;
> + return page;
> }
>
> static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
> @@ -270,9 +270,12 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> * the atomic pools instead if we aren't allowed block.
> */
> if ((remap || (attrs & DMA_ATTR_CC_SHARED)) &&
> - dma_direct_use_pool(dev, gfp))
> - return dma_direct_alloc_from_pool(dev, size, dma_handle,
> - gfp, attrs);
> + dma_direct_use_pool(dev, gfp)) {
> + page = dma_direct_alloc_from_pool(dev, size,
> + dma_handle, &cpu_addr,
> + gfp, attrs);
> + return page ? cpu_addr : NULL;
> + }
>
> if (is_swiotlb_for_alloc(dev)) {
> page = dma_direct_alloc_swiotlb(dev, size, attrs);
> @@ -445,7 +448,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
>
> if ((attrs & DMA_ATTR_CC_SHARED) && dma_direct_use_pool(dev, gfp))
> return dma_direct_alloc_from_pool(dev, size, dma_handle,
> - gfp, attrs);
> + &cpu_addr, gfp, attrs);
>
> if (is_swiotlb_for_alloc(dev)) {
> page = dma_direct_alloc_swiotlb(dev, size, attrs);
^ permalink raw reply
* Re: [PATCH v6 16/20] dma: swiotlb: free dynamic pools from process context
From: Petr Tesarik @ 2026-06-09 13:23 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-17-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:55 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> swiotlb_dyn_free() is used after removing a dynamic swiotlb pool from
> RCU-protected lists. It can call swiotlb_free_tlb(), which may need to
> restore the encryption state of an unencrypted pool with
> set_memory_encrypted() before freeing the pages.
>
> RCU callbacks run in atomic context, but set_memory_encrypted() is not
> guaranteed to be atomic-safe on all architectures. For example, page
> attribute updates may allocate page tables or take sleeping locks.
Good catch!
> Use queue_rcu_work() for dynamic pool freeing instead. This keeps the RCU
> grace period before freeing a published pool, while running the actual pool
> teardown from workqueue context. Use the same helper for the transient-pool
> error path, since that path may also be reached from atomic DMA mapping
> context.
Strictly speaking, it's not necessary, because this is in the error
path just after allocating a transient pool. There are only two
possible scenarios:
a. The transient buffer was allocated from a sleeping context, and then
it's also OK to decrypt memory.
b. The transient buffer was allocated in atomic context, but then it was
allocated from a coherent pool and it is returned to that pool
rather than decrypted.
However, it's also fine to queue an RCU work. The logic is definitely
cleaner and easier to maintain.
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> ---
> include/linux/swiotlb.h | 4 ++--
> kernel/dma/swiotlb.c | 19 +++++++++++--------
> 2 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 4dcbf3931be1..526f82e9da45 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -64,7 +64,7 @@ extern void __init swiotlb_update_mem_attributes(void);
> * @areas: Array of memory area descriptors.
> * @slots: Array of slot descriptors.
> * @node: Member of the IO TLB memory pool list.
> - * @rcu: RCU head for swiotlb_dyn_free().
> + * @dyn_free: RCU work item used to free the pool from process context.
> * @transient: %true if transient memory pool.
> */
> struct io_tlb_pool {
> @@ -79,7 +79,7 @@ struct io_tlb_pool {
> struct io_tlb_slot *slots;
> #ifdef CONFIG_SWIOTLB_DYNAMIC
> struct list_head node;
> - struct rcu_head rcu;
> + struct rcu_work dyn_free;
> bool transient;
> bool unencrypted;
> #endif
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index f4e8b241a1c4..4c56f64602ea 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -774,13 +774,10 @@ static void swiotlb_dyn_alloc(struct work_struct *work)
> add_mem_pool(mem, pool);
> }
>
> -/**
> - * swiotlb_dyn_free() - RCU callback to free a memory pool
> - * @rcu: RCU head in the corresponding struct io_tlb_pool.
> - */
> -static void swiotlb_dyn_free(struct rcu_head *rcu)
> +static void swiotlb_dyn_free_work(struct work_struct *work)
> {
> - struct io_tlb_pool *pool = container_of(rcu, struct io_tlb_pool, rcu);
> + struct io_tlb_pool *pool =
> + container_of(to_rcu_work(work), struct io_tlb_pool, dyn_free);
> size_t slots_size = array_size(sizeof(*pool->slots), pool->nslabs);
> size_t tlb_size = pool->end - pool->start;
>
> @@ -789,6 +786,12 @@ static void swiotlb_dyn_free(struct rcu_head *rcu)
> kfree(pool);
> }
>
> +static void swiotlb_schedule_dyn_free(struct io_tlb_pool *pool)
> +{
> + INIT_RCU_WORK(&pool->dyn_free, swiotlb_dyn_free_work);
> + queue_rcu_work(system_wq, &pool->dyn_free);
> +}
> +
> /**
> * __swiotlb_find_pool() - find the IO TLB pool for a physical address
> * @dev: Device which has mapped the DMA buffer.
> @@ -835,7 +838,7 @@ static void swiotlb_del_pool(struct device *dev, struct io_tlb_pool *pool)
> list_del_rcu(&pool->node);
> spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags);
>
> - call_rcu(&pool->rcu, swiotlb_dyn_free);
> + swiotlb_schedule_dyn_free(pool);
> }
>
> #endif /* CONFIG_SWIOTLB_DYNAMIC */
> @@ -1276,7 +1279,7 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr,
> index = swiotlb_search_pool_area(dev, pool, 0, orig_addr, tbl_dma_addr,
> alloc_size, alloc_align_mask);
> if (index < 0) {
> - swiotlb_dyn_free(&pool->rcu);
> + swiotlb_schedule_dyn_free(pool);
> return -1;
> }
>
^ permalink raw reply
* Re: [PATCH v6 15/20] iommu/dma: Check atomic pool allocation result directly
From: Petr Tesarik @ 2026-06-09 13:13 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-16-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:54 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> The non-blocking, non-coherent allocation path uses dma_alloc_from_pool(),
> which returns the allocated page and fills cpu_addr only on success.
>
> Do not rely on cpu_addr to detect allocation failure in this path. Check
> the returned page directly before using it for the IOMMU mapping.
>
> Fixes: 9420139f516d ("dma-pool: fix coherent pool allocations for IOMMU mappings")
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> ---
> drivers/iommu/dma-iommu.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 725c7adb0a8d..52c599f4472c 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -1671,13 +1671,16 @@ void *iommu_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> }
>
> if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> - !gfpflags_allow_blocking(gfp) && !coherent)
> + !gfpflags_allow_blocking(gfp) && !coherent) {
> page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
> gfp, attrs, NULL);
> - else
> + if (!page)
> + return NULL;
> + } else {
> cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs);
> - if (!cpu_addr)
> - return NULL;
> + if (!cpu_addr)
> + return NULL;
> + }
>
> *handle = __iommu_dma_map(dev, page_to_phys(page), size, ioprot,
> dev->coherent_dma_mask);
^ permalink raw reply
* Re: [PATCH v6 17/20] dma: swiotlb: handle set_memory_decrypted() failures
From: Petr Tesarik @ 2026-06-09 13:32 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-18-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:56 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> Check the return value when converting swiotlb pools between encrypted and
> decrypted mappings. If the default pool cannot be decrypted after early
> initialization, mark the pool fully used so it cannot satisfy future bounce
> allocations.
>
> For late initialization, return the `set_memory_decrypted()` failure. For
> restricted DMA pools, fail device initialization if the reserved pool
> cannot be decrypted.
>
> This prevents swiotlb from using pools whose encryption attributes do not
> match their metadata, and avoids returning pages with uncertain encryption
> state back to the allocator.
This works fine, but instead of effectively leaking the memory, we
could return it to the buddy allocator and reset nslabs to zero as if
SWIOTLB was not even initialized.
OTOH I don't want to overthink this, because the system is probably not
too useful after such a boot-time failure, so unless you _want_ to
improve the error path, you can simply add:
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> kernel/dma/swiotlb.c | 80 +++++++++++++++++++++++++++++++++++---------
> 1 file changed, 65 insertions(+), 15 deletions(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 4c56f64602ea..14d834ca298b 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -248,6 +248,23 @@ static inline unsigned long nr_slots(u64 val)
> return DIV_ROUND_UP(val, IO_TLB_SIZE);
> }
>
> +static void swiotlb_mark_pool_used(struct io_tlb_pool *pool)
> +{
> + unsigned long i;
> +
> + for (i = 0; i < pool->nareas; i++) {
> + pool->areas[i].index = 0;
> + pool->areas[i].used = pool->area_nslabs;
> + }
> +
> + for (i = 0; i < pool->nslabs; i++) {
> + pool->slots[i].list = 0;
> + pool->slots[i].orig_addr = INVALID_PHYS_ADDR;
> + pool->slots[i].alloc_size = 0;
> + pool->slots[i].pad_slots = 0;
> + }
> +}
> +
> /*
> * Early SWIOTLB allocation may be too early to allow an architecture to
> * perform the desired operations. This function allows the architecture to
> @@ -272,8 +289,16 @@ void __init swiotlb_update_mem_attributes(void)
> return;
> bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_decrypted((unsigned long)mem->vaddr, bytes >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + int ret;
> +
> + ret = set_memory_decrypted((unsigned long)mem->vaddr,
> + bytes >> PAGE_SHIFT);
> + if (ret) {
> + pr_warn("Failed to decrypt default memory pool, disabling it\n");
> + swiotlb_mark_pool_used(mem);
> + }
> + }
> }
>
> static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> @@ -442,9 +467,10 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> {
> struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
> unsigned long nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
> + unsigned int order, area_order, slot_order;
> + bool leak_pages = false;
> unsigned int nareas;
> unsigned char *vstart = NULL;
> - unsigned int order, area_order;
> bool retried = false;
> int rc = 0;
>
> @@ -504,6 +530,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> (PAGE_SIZE << order) >> 20);
> }
>
> + rc = -ENOMEM;
> nareas = limit_nareas(default_nareas, nslabs);
> area_order = get_order(array_size(sizeof(*mem->areas), nareas));
> mem->areas = (struct io_tlb_area *)
> @@ -511,14 +538,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> if (!mem->areas)
> goto error_area;
>
> + slot_order = get_order(array_size(sizeof(*mem->slots), nslabs));
> mem->slots = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> - get_order(array_size(sizeof(*mem->slots), nslabs)));
> + slot_order);
> if (!mem->slots)
> goto error_slots;
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_decrypted((unsigned long)vstart,
> - (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + rc = set_memory_decrypted((unsigned long)vstart,
> + (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> + if (rc) {
> + leak_pages = true;
> + goto error_decrypt;
> + }
> + }
>
> swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), nslabs, true,
> nareas);
> @@ -527,16 +560,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> swiotlb_print_info();
> return 0;
>
> +error_decrypt:
> + free_pages((unsigned long)mem->slots, slot_order);
> error_slots:
> free_pages((unsigned long)mem->areas, area_order);
> error_area:
> - free_pages((unsigned long)vstart, order);
> - return -ENOMEM;
> + if (!leak_pages)
> + free_pages((unsigned long)vstart, order);
> + return rc;
> }
>
> void __init swiotlb_exit(void)
> {
> struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
> + bool leak_pages = false;
> unsigned long tbl_vaddr;
> size_t tbl_size, slots_size;
> unsigned int area_order;
> @@ -552,19 +589,23 @@ void __init swiotlb_exit(void)
> tbl_size = PAGE_ALIGN(mem->end - mem->start);
> slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs));
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + if (set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT))
> + leak_pages = true;
> + }
>
> if (mem->late_alloc) {
> area_order = get_order(array_size(sizeof(*mem->areas),
> mem->nareas));
> free_pages((unsigned long)mem->areas, area_order);
> - free_pages(tbl_vaddr, get_order(tbl_size));
> + if (!leak_pages)
> + free_pages(tbl_vaddr, get_order(tbl_size));
> free_pages((unsigned long)mem->slots, get_order(slots_size));
> } else {
> memblock_free(mem->areas,
> array_size(sizeof(*mem->areas), mem->nareas));
> - memblock_phys_free(mem->start, tbl_size);
> + if (!leak_pages)
> + memblock_phys_free(mem->start, tbl_size);
> memblock_free(mem->slots, slots_size);
> }
>
> @@ -1938,9 +1979,18 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
> * restricted mem pool is decrypted by default
> */
> if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
> + int ret;
> +
> mem->unencrypted = true;
> - set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> - rmem->size >> PAGE_SHIFT);
> + ret = set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> + rmem->size >> PAGE_SHIFT);
> + if (ret) {
> + dev_err(dev, "Failed to decrypt restricted DMA pool\n");
> + kfree(pool->areas);
> + kfree(pool->slots);
> + kfree(mem);
> + return ret;
> + }
> } else {
> mem->unencrypted = false;
> }
^ permalink raw reply
* Re: [PATCH 02/15] x86/virt/tdx: Add extra memory to TDX Module for Extensions
From: Adrian Hunter @ 2026-06-09 13:38 UTC (permalink / raw)
To: Xu Yilun, kas, djbw, rick.p.edgecombe, x86, peter.fang
Cc: linux-coco, linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <20260522034128.3144354-3-yilun.xu@linux.intel.com>
On 22/05/2026 06:41, Xu Yilun wrote:
> +static int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
> +{
> + struct tdx_module_args args = {
> + .rcx = to_hpa_list_info(root, nr_pages),
> + };
> + u64 r;
> +
> + tdx_clflush_hpa_list(root, nr_pages);
> +
> + do {
> + /*
> + * TDH_EXT_MEM_ADD is designed to use output parameter RCX to
> + * override/update input parameter RCX, so the caller doesn't
> + * have to do manual parameter update on retry call.
> + */
> + r = seamcall_ret(TDH_EXT_MEM_ADD, &args);
> + } while (r == TDX_INTERRUPTED_RESUMABLE);
Kishon already mentioned checking only the status
> +
> + if (r != TDX_SUCCESS)
Similarly could this also be TDX_EXT_MEMORY_POOL_FULL?
> + return -EFAULT;
> +
> + return 0;
> +}
^ permalink raw reply
* Re: [PATCH v6 19/20] swiotlb: Preserve allocation virtual address for dynamic pools
From: Petr Tesarik @ 2026-06-09 13:40 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-20-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:58 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> swiotlb_alloc_tlb() can allocate from the DMA atomic pool when a decrypted
> pool is needed from atomic context. With CONFIG_DMA_DIRECT_REMAP, the
> atomic pool is backed by remapped virtual addresses, which are not the same
> as the direct-map addresses returned by phys_to_virt().
>
> swiotlb_init_io_tlb_pool() currently reconstructs the pool virtual address
> from the physical start address. For atomic-pool backed allocations this
> stores the wrong address in pool->vaddr. Later, swiotlb_free_tlb() passes
> that address to dma_free_from_pool(), which will fail to recognize the
> chunk
>
> Pass the virtual address returned by the allocation path into
> swiotlb_init_io_tlb_pool(), and store that address in pool->vaddr. This
> keeps the pool free path using the same virtual address as the allocator.
>
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Hm, so the old code was broken; you may want to add:
Fixes: 79636caad361 ("swiotlb: if swiotlb is full, fall back to a transient memory pool")
And of course:
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Thank you!
Petr T
> ---
> kernel/dma/swiotlb.c | 32 +++++++++++++++++++-------------
> 1 file changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 14d834ca298b..e4bd8c9eaeda 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -302,9 +302,9 @@ void __init swiotlb_update_mem_attributes(void)
> }
>
> static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> - unsigned long nslabs, bool late_alloc, unsigned int nareas)
> + void *vaddr, unsigned long nslabs, bool late_alloc,
> + unsigned int nareas)
> {
> - void *vaddr = phys_to_virt(start);
> unsigned long bytes = nslabs << IO_TLB_SHIFT, i;
>
> mem->nslabs = nslabs;
> @@ -445,7 +445,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
> return;
> }
>
> - swiotlb_init_io_tlb_pool(mem, __pa(tlb), nslabs, false, nareas);
> + swiotlb_init_io_tlb_pool(mem, __pa(tlb), tlb, nslabs, false, nareas);
> add_mem_pool(&io_tlb_default_mem, mem);
>
> if (flags & SWIOTLB_VERBOSE)
> @@ -553,7 +553,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> }
> }
>
> - swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), nslabs, true,
> + swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), vstart, nslabs, true,
> nareas);
> add_mem_pool(&io_tlb_default_mem, mem);
>
> @@ -664,25 +664,26 @@ static struct page *alloc_dma_pages(gfp_t gfp, size_t bytes,
> * @phys_limit: Maximum allowed physical address of the buffer.
> * @attrs: DMA attributes for the allocation.
> * @gfp: GFP flags for the allocation.
> + * @vaddr: Receives the virtual address for the allocated buffer.
> *
> * Return: Allocated pages, or %NULL on allocation failure.
> */
> static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
> - u64 phys_limit, unsigned long attrs, gfp_t gfp)
> + u64 phys_limit, unsigned long attrs, gfp_t gfp, void **vaddr)
> {
> struct page *page;
>
> + *vaddr = NULL;
> +
> /*
> * Allocate from the atomic pools if memory is encrypted and
> * the allocation is atomic, because decrypting may block.
> */
> if (!gfpflags_allow_blocking(gfp) && (attrs & DMA_ATTR_CC_SHARED)) {
> - void *vaddr;
> -
> if (!IS_ENABLED(CONFIG_DMA_COHERENT_POOL))
> return NULL;
>
> - return dma_alloc_from_pool(dev, bytes, &vaddr, gfp,
> + return dma_alloc_from_pool(dev, bytes, vaddr, gfp,
> attrs, dma_coherent_ok);
> }
>
> @@ -705,6 +706,8 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
> return NULL;
> }
>
> + if (page)
> + *vaddr = phys_to_virt(page_to_phys(page));
> return page;
> }
>
> @@ -750,6 +753,7 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> {
> struct io_tlb_pool *pool;
> unsigned int slot_order;
> + void *tlb_vaddr;
> struct page *tlb;
> size_t pool_size;
> size_t tlb_size;
> @@ -767,7 +771,8 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> pool->unencrypted = !!(attrs & DMA_ATTR_CC_SHARED);
>
> tlb_size = nslabs << IO_TLB_SHIFT;
> - while (!(tlb = swiotlb_alloc_tlb(dev, tlb_size, phys_limit, attrs, gfp))) {
> + while (!(tlb = swiotlb_alloc_tlb(dev, tlb_size, phys_limit, attrs, gfp,
> + &tlb_vaddr))) {
> if (nslabs <= minslabs)
> goto error_tlb;
> nslabs = ALIGN(nslabs >> 1, IO_TLB_SEGSIZE);
> @@ -781,12 +786,12 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> if (!pool->slots)
> goto error_slots;
>
> - swiotlb_init_io_tlb_pool(pool, page_to_phys(tlb), nslabs, true, nareas);
> + swiotlb_init_io_tlb_pool(pool, page_to_phys(tlb), tlb_vaddr, nslabs,
> + true, nareas);
> return pool;
>
> error_slots:
> - swiotlb_free_tlb(page_address(tlb), tlb_size,
> - !!(attrs & DMA_ATTR_CC_SHARED));
> + swiotlb_free_tlb(tlb_vaddr, tlb_size, !!(attrs & DMA_ATTR_CC_SHARED));
> error_tlb:
> kfree(pool);
> error:
> @@ -1995,7 +2000,8 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
> mem->unencrypted = false;
> }
>
> - swiotlb_init_io_tlb_pool(pool, rmem->base, nslabs,
> + swiotlb_init_io_tlb_pool(pool, rmem->base, phys_to_virt(rmem->base),
> + nslabs,
> false, nareas);
> mem->force_bounce = true;
> mem->for_alloc = true;
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Catalin Marinas @ 2026-06-09 13:43 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260604083959.1265923-1-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:39PM +0530, Aneesh Kumar K.V (Arm) wrote:
> This series propagates DMA_ATTR_CC_SHARED through the dma-direct,
> dma-pool, and swiotlb paths so that encrypted and decrypted DMA buffers
> are handled consistently.
>
> Today, the direct DMA path mostly relies on force_dma_unencrypted() for
> shared/decrypted buffer handling. This series consolidates the
> force_dma_unencrypted() checks in the top-level functions and ensures
> that the remaining DMA interfaces use DMA attributes to make the correct
> decisions.
Please check Sashiko's reports, it has some good points:
https://sashiko.dev/#/patchset/20260604083959.1265923-1-aneesh.kumar@kernel.org
I think the main one is the swiotlb_tbl_map_single() changes which break
AMD SME host support. There cc_platform_has(CC_ATTR_MEM_ENCRYPT) is true
but force_dma_unencrypted() is false. Normally you'd not end up on this
path but you can have swiotlb=force.
> Aneesh Kumar K.V (Arm) (20):
> s390: Expose protected virtualization through cc_platform_has()
> dma-direct: swiotlb: handle swiotlb alloc/free outside
> __dma_direct_alloc_pages
> dma-direct: use DMA_ATTR_CC_SHARED in alloc/free paths
> dma-pool: track decrypted atomic pools and select them via attrs
> dma: swiotlb: pass mapping attributes by reference
> dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED
> dma-mapping: make dma_pgprot() honor DMA_ATTR_CC_SHARED
> dma-direct: pass attrs to dma_capable() for DMA_ATTR_CC_SHARED checks
> dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED
> dma-direct: set decrypted flag for remapped DMA allocations
Patch 10 above...
> dma-direct: select DMA address encoding from DMA_ATTR_CC_SHARED
> dma-pool: fix page leak in atomic_pool_expand() cleanup
Patch 12...
> dma-direct: rename ret to cpu_addr in alloc helpers
> dma-direct: return struct page from dma_direct_alloc_from_pool()
> iommu/dma: Check atomic pool allocation result directly
and I think patches 14, 15 are independent fixes. Some of them even have
Fixes: tags and Cc: stable. Please move them to the beginning of the
series to avoid inadvertent dependencies and make them harder to
backport. It's also easier to follow the series without random fixes for
mainline in the middle.
> dma: swiotlb: free dynamic pools from process context
> dma: swiotlb: handle set_memory_decrypted() failures
> dma: free atomic pool pages by physical address
> swiotlb: Preserve allocation virtual address for dynamic pools
> swiotlb: remove unused SWIOTLB_FORCE flag
--
Catalin
^ permalink raw reply
* Re: [PATCH v6 01/20] s390: Expose protected virtualization through cc_platform_has()
From: Catalin Marinas @ 2026-06-09 13:44 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Halil Pasic,
Matthew Rosato, Jaehoon Kim
In-Reply-To: <20260604083959.1265923-2-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:40PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Protected virtualization guests use memory encryption, so advertise that to
> the rest of the kernel through cc_platform_has(CC_ATTR_MEM_ENCRYPT).
>
> s390 already forces DMA mappings to be unencrypted for protected
> virtualization guests through force_dma_unencrypted(). Add
> ARCH_HAS_CC_PLATFORM and provide the matching cc_platform_has()
> implementation
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
Nit: just drop the --- line if you did intend to cc those people.
Nothing wrong for them to end up in the commit log (proof that they've
been cc'ed if they did not reply ;)).
--
Catalin
^ permalink raw reply
* Re: [PATCH v6 20/20] swiotlb: remove unused SWIOTLB_FORCE flag
From: Petr Tesarik @ 2026-06-09 13:44 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260604083959.1265923-21-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:59 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> SWIOTLB_FORCE has no remaining in-tree users. Forced bouncing is now
> controlled through the swiotlb=force command line option via
> swiotlb_force_bounce.
>
> Remove the unused flag and simplify the force_bounce initialization.
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> include/linux/swiotlb.h | 1 -
> kernel/dma/swiotlb.c | 3 +--
> 2 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 526f82e9da45..af88ca7182f4 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -15,7 +15,6 @@ struct page;
> struct scatterlist;
>
> #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */
> -#define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */
> #define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */
These constants are kernel-internal, so let's not leave a hole in the
bitmask... I mean, what about changing SWIOTLB_ANY to (1 << 1) after
you remove SWIOTLB_FORCE?
Other than that, LGTM.
I consider this whole series a big step towards saner handling of
encrypted/decrypted memory for DMA buffers. Thank you for your effort!
Petr T
>
> /*
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index e4bd8c9eaeda..81cc4928e949 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -400,8 +400,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
> if (swiotlb_force_disable)
> return;
>
> - io_tlb_default_mem.force_bounce =
> - swiotlb_force_bounce || (flags & SWIOTLB_FORCE);
> + io_tlb_default_mem.force_bounce = swiotlb_force_bounce;
>
> #ifdef CONFIG_SWIOTLB_DYNAMIC
> if (!remap)
^ permalink raw reply
* Re: [PATCH v6 14/20] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Catalin Marinas @ 2026-06-09 13:45 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley
In-Reply-To: <20260604083959.1265923-15-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:53PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
>
> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> again, and pass the CPU address back through an out-parameter for the
> dma_direct_alloc() caller.
>
> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> Cc: stable@vger.kernel.org
>
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Nit: remove the empty line after Cc: stable. It may confuse tooling.
--
Catalin
^ permalink raw reply
* Re: [PATCH v6 14/20] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Jason Gunthorpe @ 2026-06-09 14:15 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley
In-Reply-To: <20260604083959.1265923-15-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:53PM +0530, Aneesh Kumar K.V (Arm) wrote:
> @@ -270,9 +270,12 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> * the atomic pools instead if we aren't allowed block.
> */
> if ((remap || (attrs & DMA_ATTR_CC_SHARED)) &&
> - dma_direct_use_pool(dev, gfp))
> - return dma_direct_alloc_from_pool(dev, size, dma_handle,
> - gfp, attrs);
> + dma_direct_use_pool(dev, gfp)) {
> + page = dma_direct_alloc_from_pool(dev, size,
> + dma_handle, &cpu_addr,
> + gfp, attrs);
> + return page ? cpu_addr : NULL;
> + }
You should probably put this at the start of the series so it can be
backported
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
To Petr's question I think this just shows nobody is really stressing
the PCI dma paths on CC VMs today.
if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
For instance the places even calling dma_alloc_pages() don't look like
things people would use in a CC VM.
Jason
^ permalink raw reply
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Jason Gunthorpe @ 2026-06-09 14:32 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <20260604083959.1265923-5-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
> struct page *dma_alloc_from_pool(struct device *dev, size_t size,
> - void **cpu_addr, gfp_t gfp,
> + void **cpu_addr, gfp_t gfp, unsigned long attrs,
> bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
> {
> - struct gen_pool *pool = NULL;
> + struct dma_gen_pool *dma_pool = NULL;
> struct page *page;
> bool pool_found = false;
>
> - while ((pool = dma_guess_pool(pool, gfp))) {
> + while ((dma_pool = dma_guess_pool(dma_pool, gfp))) {
> +
> + if (dma_pool->unencrypted != !!(attrs & DMA_ATTR_CC_SHARED))
> + continue;
I don't think you should be overloading DMA_ATTR_CC_SHARED like this.
/*
* DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
* attribute. The direct allocator uses it internally after it has
* decided that the backing pages must be shared/decrypted, so the
* rest of the allocation path can consistently select DMA addresses,
* choose compatible pools and restore encryption on free.
*/
if (attrs & DMA_ATTR_CC_SHARED)
return NULL;
if (force_dma_unencrypted(dev)) {
attrs |= DMA_ATTR_CC_SHARED;
mark_mem_decrypt = true;
}
It is fine to have a bit inside the attrs that is only used by the
internal logic, but it needs to have a clearer name
__DMA_ATTR_REQUIRE_CC_SHARED perhaps.
The sashiko note does look legit though:
if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
!gfpflags_allow_blocking(gfp) && !coherent) {
page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
gfp, attrs, NULL);
if (!page)
return NULL;
I don't see anything doing the force_dma_unencrypted test along this
callchain..
I guess it should be done one step up in dma_alloc_attrs() instead of
in dma_direct_alloc()?
Jason
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Jason Gunthorpe @ 2026-06-09 14:47 UTC (permalink / raw)
To: Catalin Marinas, Alexey Kardashevskiy
Cc: Aneesh Kumar K.V (Arm), iommu, linux-arm-kernel, linux-kernel,
linux-coco, Robin Murphy, Marek Szyprowski, Will Deacon,
Marc Zyngier, Steven Price, Suzuki K Poulose, Jiri Pirko,
Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun, linuxppc-dev,
linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <aigYbK12D8uKQvJF@arm.com>
On Tue, Jun 09, 2026 at 02:43:08PM +0100, Catalin Marinas wrote:
> On Thu, Jun 04, 2026 at 02:09:39PM +0530, Aneesh Kumar K.V (Arm) wrote:
> > This series propagates DMA_ATTR_CC_SHARED through the dma-direct,
> > dma-pool, and swiotlb paths so that encrypted and decrypted DMA buffers
> > are handled consistently.
> >
> > Today, the direct DMA path mostly relies on force_dma_unencrypted() for
> > shared/decrypted buffer handling. This series consolidates the
> > force_dma_unencrypted() checks in the top-level functions and ensures
> > that the remaining DMA interfaces use DMA attributes to make the correct
> > decisions.
>
> Please check Sashiko's reports, it has some good points:
>
> https://sashiko.dev/#/patchset/20260604083959.1265923-1-aneesh.kumar@kernel.org
>
> I think the main one is the swiotlb_tbl_map_single() changes which break
> AMD SME host support. There cc_platform_has(CC_ATTR_MEM_ENCRYPT) is true
> but force_dma_unencrypted() is false. Normally you'd not end up on this
> path but you can have swiotlb=force.
IMHO that's an AMD issue, not with the design of this series..
The series is right, a device that is !force_dma_decrypted() must be
considerd to be a trusted device and we must never place any DMA
mappings for a trusted device into shared memory.
That AMD has done somethine insane:
bool force_dma_unencrypted(struct device *dev)
{
/*
* For SEV, all DMA must be to unencrypted addresses.
*/
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
return true;
/*
* For SME, all DMA must be to unencrypted addresses if the
* device does not support DMA to addresses that include the
* encryption mask.
*/
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
dev->bus_dma_limit);
if (dma_dev_mask <= dma_enc_mask)
return true;
}
Is an AMD issue. We already have an address mask limit system built
into the DMA API, arch code should not be co-opting the CC mechanism
to create a special pool for address limited devices.
The correct thing is to ensure the DMA API is checking any address
limits on the actual true dma_addr_t, not on an intermediate like a
phys_addr before it is adjusted with any C bit. Then it is a normal
low address swiotlb bounce like any other.
I think we can ignore this Sashiko remark, in real systems the use of
swiotlb for 64 bit devices is very rare. Though it would be good to
remove this code from AMD...
Jason
^ permalink raw reply
* SVSM Development Call June 10th, 2026
From: Jörg Rödel @ 2026-06-09 14:47 UTC (permalink / raw)
To: coconut-svsm, linux-coco
Hi,
Here is the call for agenda items for this weeks SVSM development call. Please
send any agenda items you have in mind as a reply to this email or raise them
in the meeting.
We will use the LF Zoom instance. Details of the meeting can be found in our
governance repository at:
https://github.com/coconut-svsm/governance
The link to the COCONUT-SVSM calendar is:
https://zoom-lfx.platform.linuxfoundation.org/meetings/coconut-svsm?view=week
The meeting will be recorded and the recording eventually published.
Regards,
Jörg
^ permalink raw reply
* Re: [PATCH 03/15] x86/virt/tdx: Make TDX Module initialize Extensions
From: Adrian Hunter @ 2026-06-09 15:14 UTC (permalink / raw)
To: Xu Yilun, kas, djbw, rick.p.edgecombe, x86, peter.fang
Cc: linux-coco, linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <20260522034128.3144354-4-yilun.xu@linux.intel.com>
On 22/05/2026 06:41, Xu Yilun wrote:
> +/* Initialize the TDX Module Extensions then Extension-SEAMCALLs can be used */
Reads slightly better without "the", so taking Tony's suggestion
one word less:
"Initialize TDX Module Extensions for Extension-SEAMCALLs"
> +static int tdx_ext_init(void)
> +{
> + struct tdx_module_args args = {};
> + u64 r;
> +
> + do {
> + r = seamcall(TDH_EXT_INIT, &args);
> + } while (r == TDX_INTERRUPTED_RESUMABLE);
> +
> + if (r != TDX_SUCCESS)
There seems to be TDX_PREV_FEATURES_ENABLED which is unused,
but could it turn up here?
> + return -EFAULT;
> +
> + return 0;
> +}
Otherwise:
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
^ permalink raw reply
* Re: [PATCH v4 01/47] x86/tsc: Never re-calibrate TSC frequency if its exact timing is known
From: Sean Christopherson @ 2026-06-09 17:17 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Paolo Bonzini, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
Kiryl Shutsemau, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Ajay Kaher, Alexey Makhalov, Jan Kiszka,
Andy Lutomirski, Peter Zijlstra, Juergen Gross, Daniel Lezcano,
John Stultz, H. Peter Anvin, Rick Edgecombe, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, kvm, linux-kernel, linux-coco, linux-hyperv,
virtualization, xen-devel, David Woodhouse, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, Michael Kelley
In-Reply-To: <87a4t86a0l.ffs@fw13>
On Fri, Jun 05, 2026, Thomas Gleixner wrote:
> On Fri, Jun 05 2026 at 11:04, Sean Christopherson wrote:
> But we also should have a check in the TSC init code somewhere which
> validates that X86_FEATURE_CONSTANT_TSC is set when
> X86_FEATURE_TSC_KNOWN_FREQ is set. X86_FEATURE_TSC_KNOWN_FREQ is useless
> w/o X86_FEATURE_CONSTANT_TSC.
Ugh, any objection to punting on this for now? KVM and Xen guests will trigger
TSC_KNOWN_FREQ without CONSTANT_TSC, thanks to commits:
e10f78050323 ("kvmclock: fix TSC calibration for nested guests")
898ec52d2ba0 ("x86/xen/time: Set the X86_FEATURE_TSC_KNOWN_FREQ flag in xen_tsc_khz()")
Hyper-V guests might as well? Hyper-V's handling of TSC is weird, even for a
hypervisor.
Even when the frequency is provided in CPUID by the hypervisor, QEMU at least
requires a fairly explicit opt-in to advertise CONSTANT_TSC, presumably to try
to prevent users from shooting themselves in the foot.
^ permalink raw reply
* Re: [PATCH v4 01/47] x86/tsc: Never re-calibrate TSC frequency if its exact timing is known
From: Thomas Gleixner @ 2026-06-09 19:27 UTC (permalink / raw)
To: Sean Christopherson
Cc: Paolo Bonzini, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
Kiryl Shutsemau, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Ajay Kaher, Alexey Makhalov, Jan Kiszka,
Andy Lutomirski, Peter Zijlstra, Juergen Gross, Daniel Lezcano,
John Stultz, H. Peter Anvin, Rick Edgecombe, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, kvm, linux-kernel, linux-coco, linux-hyperv,
virtualization, xen-devel, David Woodhouse, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, Michael Kelley
In-Reply-To: <aihKj-0nP7bUbNHH@google.com>
On Tue, Jun 09 2026 at 10:17, Sean Christopherson wrote:
> On Fri, Jun 05, 2026, Thomas Gleixner wrote:
>> On Fri, Jun 05 2026 at 11:04, Sean Christopherson wrote:
>> But we also should have a check in the TSC init code somewhere which
>> validates that X86_FEATURE_CONSTANT_TSC is set when
>> X86_FEATURE_TSC_KNOWN_FREQ is set. X86_FEATURE_TSC_KNOWN_FREQ is useless
>> w/o X86_FEATURE_CONSTANT_TSC.
>
> Ugh, any objection to punting on this for now? KVM and Xen guests will trigger
> TSC_KNOWN_FREQ without CONSTANT_TSC, thanks to commits:
>
> e10f78050323 ("kvmclock: fix TSC calibration for nested guests")
> 898ec52d2ba0 ("x86/xen/time: Set the X86_FEATURE_TSC_KNOWN_FREQ flag in xen_tsc_khz()")
>
> Hyper-V guests might as well? Hyper-V's handling of TSC is weird, even for a
> hypervisor.
Hypervisors are ranked by weirdness? I ranked them by insanity so far.
> Even when the frequency is provided in CPUID by the hypervisor, QEMU at least
> requires a fairly explicit opt-in to advertise CONSTANT_TSC, presumably to try
> to prevent users from shooting themselves in the foot.
Bah. We really should have enforced the dependency when we introduced
KNOWN_FREQ. But that ship has sailed.
Though for correctness sake this should be fixed at some point in the
foreseeable future.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v4 02/47] x86/tsc: Add a standalone helpers for getting TSC info from CPUID.0x15
From: Sean Christopherson @ 2026-06-09 19:28 UTC (permalink / raw)
To: Borislav Petkov
Cc: Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, x86,
Kiryl Shutsemau, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Ajay Kaher, Alexey Makhalov, Jan Kiszka,
Andy Lutomirski, Peter Zijlstra, Juergen Gross, Daniel Lezcano,
John Stultz, H. Peter Anvin, Rick Edgecombe, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, kvm, linux-kernel, linux-coco, linux-hyperv,
virtualization, xen-devel, David Woodhouse, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, Michael Kelley,
Thomas Gleixner
In-Reply-To: <20260602034916.GGah5SvARd77mkvxe3@fat_crate.local>
On Mon, Jun 01, 2026, Borislav Petkov wrote:
> On Fri, May 29, 2026 at 07:43:49AM -0700, Sean Christopherson wrote:
> > +static int cpuid_get_tsc_info(struct cpuid_tsc_info *info)
> > +{
> > + unsigned int ecx_hz, edx;
> > +
> > + memset(info, 0, sizeof(*info));
>
> Let's not clear this unnecessarily...
>
> > +
> > + if (boot_cpu_data.cpuid_level < CPUID_LEAF_TSC)
> > + return -ENOENT;
>
> ... just to return here...
>
> > +
> > + /* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
> > + cpuid(CPUID_LEAF_TSC, &info->denominator, &info->numerator, &ecx_hz, &edx);
> > +
> > + if (!info->denominator || !info->numerator)
> > + return -ENOENT;
>
> ... or here.
>
> We wanna clear it here, when we'll return success.
Actually, if we take the approach of relying on the user to check the return
code, then there's no need to zero the struct since all fields will be explicitly
written, especially if we drop the "tsc_khz" field. I was zeroing the field
purely as defense in depth.
^ permalink raw reply
* Re: [PATCH 01/15] x86/virt/tdx: Read global metadata for TDX Module Extensions
From: Xu Yilun @ 2026-06-10 3:20 UTC (permalink / raw)
To: Adrian Hunter
Cc: kas, djbw, rick.p.edgecombe, x86, peter.fang, linux-coco,
linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <1783e7bd-3759-41f7-93e3-2f9e21264bd4@intel.com>
On Tue, Jun 09, 2026 at 04:06:50PM +0300, Adrian Hunter wrote:
> On 22/05/2026 06:41, Xu Yilun wrote:
> > Add reading of the global metadata for TDX Module Extensions.
>
> For tip, isn't the expectation to explain the context first. The
> very first patch, might be a good place to explain a bit about
> TDX Module Extensions in general.
Yes. I'm trying to add a long context for the first patch but was
suggested to move to cover-letter. I think I can add a brief
introduction at the beginning:
TDX module introduces a new concept caled "TDX module Extension" to
support long running / hard-irq preemptible flows inside. ...
^ permalink raw reply
* Re: [PATCH 02/15] x86/virt/tdx: Add extra memory to TDX Module for Extensions
From: Xu Yilun @ 2026-06-10 5:13 UTC (permalink / raw)
To: Adrian Hunter
Cc: kas, djbw, rick.p.edgecombe, x86, peter.fang, linux-coco,
linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <f7238ced-73a0-44f3-8a50-23eb5a2da5dc@intel.com>
On Tue, Jun 09, 2026 at 04:38:31PM +0300, Adrian Hunter wrote:
> On 22/05/2026 06:41, Xu Yilun wrote:
> > +static int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
> > +{
> > + struct tdx_module_args args = {
> > + .rcx = to_hpa_list_info(root, nr_pages),
> > + };
> > + u64 r;
> > +
> > + tdx_clflush_hpa_list(root, nr_pages);
> > +
> > + do {
> > + /*
> > + * TDH_EXT_MEM_ADD is designed to use output parameter RCX to
> > + * override/update input parameter RCX, so the caller doesn't
> > + * have to do manual parameter update on retry call.
> > + */
> > + r = seamcall_ret(TDH_EXT_MEM_ADD, &args);
> > + } while (r == TDX_INTERRUPTED_RESUMABLE);
>
> Kishon already mentioned checking only the status
Could you elaborate on why we should mask? I assume the mask is only
needed when the lower bits ([31:0]) are defined to contain extra
information. TDX_INTERRUPTED_RESUMABLE is not the case so we could make
the code change simpler.
And if some non-zero bits appears there, it is a Module bug that we
should not skip.
>
> > +
> > + if (r != TDX_SUCCESS)
>
> Similarly could this also be TDX_EXT_MEMORY_POOL_FULL?
I don't think we should pass the case. The Module provides the number of
required pages via metadata, host follows and feeds pages but the Module
said "Sorry, I'm already full". This is inconsistent behavior that we
should call out.
>
> > + return -EFAULT;
> > +
> > + return 0;
> > +}
>
^ permalink raw reply
* Re: [PATCH 02/15] x86/virt/tdx: Add extra memory to TDX Module for Extensions
From: Adrian Hunter @ 2026-06-10 5:43 UTC (permalink / raw)
To: Xu Yilun
Cc: kas, djbw, rick.p.edgecombe, x86, peter.fang, linux-coco,
linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <aijygJ9YqskIOvB3@yilunxu-OptiPlex-7050>
On 10/06/2026 08:13, Xu Yilun wrote:
> On Tue, Jun 09, 2026 at 04:38:31PM +0300, Adrian Hunter wrote:
>> On 22/05/2026 06:41, Xu Yilun wrote:
>>> +static int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
>>> +{
>>> + struct tdx_module_args args = {
>>> + .rcx = to_hpa_list_info(root, nr_pages),
>>> + };
>>> + u64 r;
>>> +
>>> + tdx_clflush_hpa_list(root, nr_pages);
>>> +
>>> + do {
>>> + /*
>>> + * TDH_EXT_MEM_ADD is designed to use output parameter RCX to
>>> + * override/update input parameter RCX, so the caller doesn't
>>> + * have to do manual parameter update on retry call.
>>> + */
>>> + r = seamcall_ret(TDH_EXT_MEM_ADD, &args);
>>> + } while (r == TDX_INTERRUPTED_RESUMABLE);
>>
>> Kishon already mentioned checking only the status
>
> Could you elaborate on why we should mask? I assume the mask is only
> needed when the lower bits ([31:0]) are defined to contain extra
> information. TDX_INTERRUPTED_RESUMABLE is not the case so we could make
> the code change simpler.
>
> And if some non-zero bits appears there, it is a Module bug that we
> should not skip.
Agreed
>
>>
>>> +
>>> + if (r != TDX_SUCCESS)
>>
>> Similarly could this also be TDX_EXT_MEMORY_POOL_FULL?
>
> I don't think we should pass the case. The Module provides the number of
> required pages via metadata, host follows and feeds pages but the Module
> said "Sorry, I'm already full". This is inconsistent behavior that we
> should call out.
TDX_EXT_MEMORY_POOL_FULL is not an error code. It is a success code,
so the question is whether it will ever show up on, say, the very last
TDH_EXT_MEM_ADD.
>
>>
>>> + return -EFAULT;
>>> +
>>> + return 0;
>>> +}
>>
^ permalink raw reply
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Aneesh Kumar K.V @ 2026-06-10 8:07 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <20260609143242.GK2764304@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Thu, Jun 04, 2026 at 02:09:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> struct page *dma_alloc_from_pool(struct device *dev, size_t size,
>> - void **cpu_addr, gfp_t gfp,
>> + void **cpu_addr, gfp_t gfp, unsigned long attrs,
>> bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
>> {
>> - struct gen_pool *pool = NULL;
>> + struct dma_gen_pool *dma_pool = NULL;
>> struct page *page;
>> bool pool_found = false;
>>
>> - while ((pool = dma_guess_pool(pool, gfp))) {
>> + while ((dma_pool = dma_guess_pool(dma_pool, gfp))) {
>> +
>> + if (dma_pool->unencrypted != !!(attrs & DMA_ATTR_CC_SHARED))
>> + continue;
>
> I don't think you should be overloading DMA_ATTR_CC_SHARED like this.
>
> /*
> * DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
> * attribute. The direct allocator uses it internally after it has
> * decided that the backing pages must be shared/decrypted, so the
> * rest of the allocation path can consistently select DMA addresses,
> * choose compatible pools and restore encryption on free.
> */
> if (attrs & DMA_ATTR_CC_SHARED)
> return NULL;
>
> if (force_dma_unencrypted(dev)) {
> attrs |= DMA_ATTR_CC_SHARED;
> mark_mem_decrypt = true;
> }
>
> It is fine to have a bit inside the attrs that is only used by the
> internal logic, but it needs to have a clearer name
> __DMA_ATTR_REQUIRE_CC_SHARED perhaps.
>
Are you suggesting adding another attribute in addition to
DMA_ATTR_CC_SHARED?
Is the idea that __DMA_ATTR_REQUIRE_CC_SHARED would be used in the
allocation path to request a CC_SHARED allocation, while
DMA_ATTR_CC_SHARED would be used in the mapping path to describe the
attribute of the address?
>
> The sashiko note does look legit though:
>
> if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> !gfpflags_allow_blocking(gfp) && !coherent) {
> page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
> gfp, attrs, NULL);
> if (!page)
> return NULL;
>
> I don't see anything doing the force_dma_unencrypted test along this
> callchain..
>
> I guess it should be done one step up in dma_alloc_attrs() instead of
> in dma_direct_alloc()?
>
Yes, I'll move it there.
-aneesh
^ permalink raw reply
* Re: [PATCH 02/15] x86/virt/tdx: Add extra memory to TDX Module for Extensions
From: Xu Yilun @ 2026-06-10 7:44 UTC (permalink / raw)
To: Adrian Hunter
Cc: kas, djbw, rick.p.edgecombe, x86, peter.fang, linux-coco,
linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <33974159-ec7c-4c5a-845f-02ea4e67a0c4@intel.com>
> >>> + if (r != TDX_SUCCESS)
> >>
> >> Similarly could this also be TDX_EXT_MEMORY_POOL_FULL?
> >
> > I don't think we should pass the case. The Module provides the number of
> > required pages via metadata, host follows and feeds pages but the Module
> > said "Sorry, I'm already full". This is inconsistent behavior that we
> > should call out.
>
> TDX_EXT_MEMORY_POOL_FULL is not an error code. It is a success code,
> so the question is whether it will ever show up on, say, the very last
> TDH_EXT_MEM_ADD.
It will not show up. I got from Module team that it shows up when the
poll is already full and host still adds more pages.
^ permalink raw reply
* Re: [PATCH 03/15] x86/virt/tdx: Make TDX Module initialize Extensions
From: Xu Yilun @ 2026-06-10 8:09 UTC (permalink / raw)
To: Adrian Hunter
Cc: kas, djbw, rick.p.edgecombe, x86, peter.fang, linux-coco,
linux-kernel, kvm, sohil.mehta, yilun.xu, baolu.lu,
zhenzhong.duan, xiaoyao.li
In-Reply-To: <1f6bf040-6a90-47f8-93dd-0e36d4f256dc@intel.com>
On Tue, Jun 09, 2026 at 06:14:22PM +0300, Adrian Hunter wrote:
> On 22/05/2026 06:41, Xu Yilun wrote:
> > +/* Initialize the TDX Module Extensions then Extension-SEAMCALLs can be used */
>
> Reads slightly better without "the", so taking Tony's suggestion
> one word less:
>
> "Initialize TDX Module Extensions for Extension-SEAMCALLs"
OK, included.
>
> > +static int tdx_ext_init(void)
> > +{
> > + struct tdx_module_args args = {};
> > + u64 r;
> > +
> > + do {
> > + r = seamcall(TDH_EXT_INIT, &args);
> > + } while (r == TDX_INTERRUPTED_RESUMABLE);
> > +
> > + if (r != TDX_SUCCESS)
>
> There seems to be TDX_PREV_FEATURES_ENABLED which is unused,
> but could it turn up here?
“Yes, but not now.” from Module team. It is some future thing
under discussion.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox