dma-mapping: Use DMA_ATTR_CC_DECRYPTED through direct, pool and swiotlb paths
Subsystems (3)
cover dma-mapping: Use DMA_ATTR_CC_DECRYPTED through direct, pool and swiotlb paths
This series propagates DMA_ATTR_CC_DECRYPTED 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.
The series:
- moves swiotlb-backed allocations out of __dma_direct_alloc_pages(),
- propagates DMA_ATTR_CC_DECRYPTED through the dma-direct alloc/free paths,
- teaches the atomic DMA pools to track encrypted versus decrypted state,
- tracks swiotlb pool encryption state and enforces strict pool selection,
- centralizes encrypted/decrypted pgprot handling in dma_pgprot() using DMA attributes,
- makes dma_direct_map_phys() choose the DMA address encoding from attrs, and
- uses the selected swiotlb pool state to derive the returned DMA address.
Aneesh Kumar K.V (Arm) (7):
dma-direct: swiotlb: handle swiotlb alloc/free outside
__dma_direct_alloc_pages
dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
dma-pool: track decrypted atomic pools and select them via attrs
dma: swiotlb: track pool encryption state and honor
DMA_ATTR_CC_DECRYPTED
dma-mapping: make dma_pgprot() honor DMA_ATTR_CC_DECRYPTED
dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_DECRYPTED
dma-direct: set decrypted flag for remapped DMA allocations
drivers/iommu/dma-iommu.c | 2 +- include/linux/dma-direct.h | 10 +++ include/linux/dma-map-ops.h | 2 +- include/linux/swiotlb.h | 7 +- kernel/dma/direct.c | 129 ++++++++++++++++++++++++------ kernel/dma/direct.h | 25 +++--- kernel/dma/mapping.c | 16 +++- kernel/dma/pool.c | 154 +++++++++++++++++++++++------------- kernel/dma/swiotlb.c | 89 ++++++++++++++++----- 9 files changed, 318 insertions(+), 116 deletions(-)
Signature · 1 line
2.43.0
RFC PATCH 1/7 dma-direct: swiotlb: handle swiotlb alloc/free outside __dma_direct_alloc_pages
Move swiotlb allocation out of __dma_direct_alloc_pages() and handle it in dma_direct_alloc() / dma_direct_alloc_pages().
This is needed for follow-up changes that align shared decrypted buffers to hypervisor page size. swiotlb pool memory is decrypted as a whole and does not need per-allocation alignment handling.
swiotlb backing pages are already mapped decrypted by swiotlb_update_mem_attributes() and rmem_swiotlb_device_init(), so dma-direct should not call dma_set_decrypted() on allocation nor dma_set_encrypted() on free for swiotlb-backed memory.
Update alloc/free paths to detect swiotlb-backed pages and skip encrypt/decrypt transitions for those paths. Keep the existing highmem rejection in dma_direct_alloc_pages() for swiotlb allocations.
Only for "restricted-dma-pool", we currently set for_alloc = true, while rmem_swiotlb_device_init() decrypts the whole pool up front. This pool is typically used together with "shared-dma-pool", where the shared region is accessed after remap/ioremap and the returned address is suitable for decrypted memory access. So existing code paths remain valid.
--- kernel/dma/direct.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-)
kernel/dma/direct.c +37 -7
@@ -125,9 +125,6 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,WARN_ON_ONCE (!PAGE_ALIGNED (size)); -if (is_swiotlb_for_alloc (dev)) -return dma_direct_alloc_swiotlb (dev, size); - gfp |=dma_direct_optimal_gfp_mask (dev, &phys_limit); page =dma_alloc_contiguous (dev, size, gfp);if (page) {
@@ -204,6 +201,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; +bool mark_mem_decrypt = true;struct page *page;void *ret;
@@ -250,11 +248,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_direct_use_pool(dev, gfp))return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp); +if (is_swiotlb_for_alloc (dev)) { + page =dma_direct_alloc_swiotlb (dev, size); +if (page) { + mark_mem_decrypt = false; + goto setup_page; + } +return NULL ; + } +/* we always manually zero the memory once we are done */ page =__dma_direct_alloc_pages (dev, size, gfp & ~__GFP_ZERO, true);if (!page)return NULL ; +setup_page:/* * dma_alloc_contiguous can return highmem pages depending on a * combination the cma= arguments and per-arch setup. These need to be
@@ -281,7 +289,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, goto out_free_pages; }else { ret =page_address (page); -if (dma_set_decrypted (dev, ret, size)) +if (mark_mem_decrypt &&dma_set_decrypted (dev, ret, size)) goto out_leak_pages; }
@@ -298,7 +306,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,return ret; out_encrypt_pages: -if (dma_set_encrypted (dev,page_address (page), size)) +if (mark_mem_decrypt &&dma_set_encrypted (dev,page_address (page), size))return NULL ; out_free_pages:__dma_direct_free_pages (dev, page, size);
@@ -310,6 +318,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,void dma_direct_free (struct device *dev,size_t size,void *cpu_addr,dma_addr_t dma_addr,unsigned long attrs) { +bool mark_mem_encrypted = true;unsigned int page_order =get_order (size); if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
@@ -338,12 +347,15 @@ void dma_direct_free(struct device *dev, size_t size, dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size))) return; +if (swiotlb_find_pool (dev,dma_to_phys (dev, dma_addr))) + mark_mem_encrypted = false; +if (is_vmalloc_addr (cpu_addr)) {vunmap (cpu_addr); }else {if (IS_ENABLED (CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED ))arch_dma_clear_uncached (cpu_addr, size); -if (dma_set_encrypted (dev, cpu_addr, size)) +if (mark_mem_encrypted &&dma_set_encrypted (dev, cpu_addr, size))return ; }
@@ -359,6 +371,19 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,if (force_dma_unencrypted (dev) &&dma_direct_use_pool (dev, gfp))return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp); +if (is_swiotlb_for_alloc (dev)) { + page =dma_direct_alloc_swiotlb (dev, size); +if (!page) +return NULL ; + +if (PageHighMem (page)) { +swiotlb_free (dev, page, size); +return NULL ; + } + ret =page_address (page); + goto setup_page; + } + page =__dma_direct_alloc_pages (dev, size, gfp, false);if (!page)return NULL ;
@@ -366,6 +391,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, ret =page_address (page);if (dma_set_decrypted (dev, ret, size)) goto out_leak_pages; +setup_page:memset (ret,0 , size); *dma_handle =phys_to_dma_direct (dev,page_to_phys (page));return page;
@@ -378,13 +404,17 @@ void dma_direct_free_pages(struct device *dev, size_t size, enum dma_data_direction dir) {void *vaddr =page_address (page); +bool mark_mem_encrypted = true;/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */ if (IS_ENABLED (CONFIG_DMA_COHERENT_POOL ) &&dma_free_from_pool (dev, vaddr, size))return ; -if (dma_set_encrypted (dev, vaddr, size)) +if (swiotlb_find_pool (dev,page_to_phys (page))) + mark_mem_encrypted = false; + +if (mark_mem_encrypted &&dma_set_encrypted (dev, vaddr, size))return ;__dma_direct_free_pages (dev, page, size); }
Signature · 1 line
2.43.0
RFC PATCH 2/7 dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
In reply to Aneesh Kumar K.V (Arm)Propagate force_dma_unencrypted() into DMA_ATTR_CC_DECRYPTED in the dma-direct allocation path and use the attribute to drive the related decisions.
This updates dma_direct_alloc(), dma_direct_free(), and dma_direct_alloc_pages() to fold the forced unencrypted case into attrs.
--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)
kernel/dma/direct.c +26 -8
@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;void *ret; +if (force_dma_unencrypted (dev)) { + attrs |=DMA_ATTR_CC_DECRYPTED ; + mark_mem_decrypt = true; + } + size =PAGE_ALIGN (size);if (attrs &DMA_ATTR_NO_WARN ) gfp |= __GFP_NOWARN; -if ((attrs &DMA_ATTR_NO_KERNEL_MAPPING ) && - !force_dma_unencrypted (dev) && !is_swiotlb_for_alloc (dev)) +if (((attrs & (DMA_ATTR_NO_KERNEL_MAPPING |DMA_ATTR_CC_DECRYPTED )) == +DMA_ATTR_NO_KERNEL_MAPPING ) && !is_swiotlb_for_alloc (dev))return dma_direct_alloc_no_mapping (dev, size, dma_handle, gfp);if (!dev_is_dma_coherent (dev)) {
@@ -244,7 +249,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,* Remapping or decrypting memory may block, allocate the memory from * the atomic pools instead if we aren't allowed block. */ -if ((remap ||force_dma_unencrypted (dev)) && +if ((remap || (attrs &DMA_ATTR_CC_DECRYPTED )) &&dma_direct_use_pool (dev, gfp))return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp);
@@ -318,11 +323,20 @@ void *dma_direct_alloc(struct device *dev, size_t size,void dma_direct_free (struct device *dev,size_t size,void *cpu_addr,dma_addr_t dma_addr,unsigned long attrs) { -bool mark_mem_encrypted = true; +bool mark_mem_encrypted = !!(attrs &DMA_ATTR_CC_DECRYPTED );unsigned int page_order =get_order (size); -if ((attrs &DMA_ATTR_NO_KERNEL_MAPPING ) && - !force_dma_unencrypted (dev) && !is_swiotlb_for_alloc (dev)) { +/* +* if the device had requested for an unencrypted buffer, +* convert it to encrypted on free +*/ +if (force_dma_unencrypted (dev)) { + attrs |=DMA_ATTR_CC_DECRYPTED ; + mark_mem_encrypted = true; + } + +if (((attrs & (DMA_ATTR_NO_KERNEL_MAPPING |DMA_ATTR_CC_DECRYPTED )) == +DMA_ATTR_NO_KERNEL_MAPPING ) && !is_swiotlb_for_alloc (dev)) {/* cpu_addr is a struct page cookie, not a kernel address */ dma_free_contiguous (dev, cpu_addr, size);return ;
@@ -365,10 +379,14 @@ void dma_direct_free(struct device *dev, size_t size,struct page *dma_direct_alloc_pages (struct device *dev,size_t size,dma_addr_t *dma_handle,enum dma_data_direction dir,gfp_t gfp) { +unsigned long attrs =0 ;struct page *page;void *ret; -if (force_dma_unencrypted (dev) &&dma_direct_use_pool (dev, gfp)) +if (force_dma_unencrypted (dev)) + attrs |=DMA_ATTR_CC_DECRYPTED ; + +if ((attrs &DMA_ATTR_CC_DECRYPTED ) &&dma_direct_use_pool (dev, gfp))return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp);if (is_swiotlb_for_alloc (dev)) {
Signature · 1 line
2.43.0
Re: [RFC PATCH 2/7] dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
Quoted 17 lines · Aneesh Kumar K.V (Arm)
Propagate
force_dma_unencrypted()intoDMA_ATTR_CC_DECRYPTEDin the dma-direct allocation path and use the attribute to drive the related decisions.This updates
dma_direct_alloc(),dma_direct_free(), anddma_direct_alloc_pages()to fold the forced unencrypted case into attrs.Signed-off-by Aneesh Kumar K.V (Arm) <[email protected]>--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)kernel/dma/direct.c +0
-0
kernel/dma/direct.c void *dma_direct_alloc(struct device *dev, size_t size, · line 205
Quoted 6 lines
kernel/dma/direct.c +1
-1@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;
This is changing the API, I think it should not be hidden in a patch like this, also not sure it even makes sense..
DMA_ATTR_CC_DECRYPTED only says the address passed to mapping is decrypted. It is like DMA_ATTR_MMIO in this regard.
Passing it to dma_alloc_attrs() is currently invalid, and I think it should remain invalid, or at least this new behavior introduced in its own patch deliberately.
Meaning, if you call dma_direct_alloc() force_dma_decrypted decides what setting DMA_ATTR_CC_DECRYPTED takes and it is EOPNOTSUPP if the user passes it in.
Jason
Re: [RFC PATCH 2/7] dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
Quoted 28 lines · Jason Gunthorpe
Quoted 17 lines · Aneesh Kumar K.V (Arm)
Propagate
force_dma_unencrypted()intoDMA_ATTR_CC_DECRYPTEDin the dma-direct allocation path and use the attribute to drive the related decisions.This updates
dma_direct_alloc(),dma_direct_free(), anddma_direct_alloc_pages()to fold the forced unencrypted case into attrs.Signed-off-by Aneesh Kumar K.V (Arm) <[email protected]>--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)kernel/dma/direct.c +0
-0kernel/dma/direct.c void *dma_direct_alloc(struct device *dev, size_t size, · line 205
Quoted 6 lines
kernel/dma/direct.c +1
-1@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;This is changing the API, I think it should not be hidden in a patch like this, also not sure it even makes sense..
Quoted 7 lines
DMA_ATTR_CC_DECRYPTEDonly says the address passed to mapping is decrypted. It is likeDMA_ATTR_MMIOin this regard.Passing it to
dma_alloc_attrs()is currently invalid, and I think it should remain invalid, or at least this new behavior introduced in its own patch deliberately.
That is probably confusion on my side. I thought all the DMA attr can be used on the alloc side to specify the attribute for DMA allocation buffer.
Quoted 5 lines
Meaning, if you call
dma_direct_alloc()force_dma_decrypteddecides what settingDMA_ATTR_CC_DECRYPTEDtakes and it is EOPNOTSUPP if the user passes it in.
Sure, I can update the patchset to implement the above.
-aneesh
Re: [RFC PATCH 2/7] dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
Quoted 30 lines · Aneesh Kumar K.V
Quoted 28 lines · Jason Gunthorpe
Quoted 17 lines · Aneesh Kumar K.V (Arm)
Propagate
force_dma_unencrypted()intoDMA_ATTR_CC_DECRYPTEDin the dma-direct allocation path and use the attribute to drive the related decisions.This updates
dma_direct_alloc(),dma_direct_free(), anddma_direct_alloc_pages()to fold the forced unencrypted case into attrs.Signed-off-by Aneesh Kumar K.V (Arm) <[email protected]>--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)kernel/dma/direct.c +0
-0kernel/dma/direct.c void *dma_direct_alloc(struct device *dev, size_t size, · line 205
Quoted 6 lines
kernel/dma/direct.c +1
-1@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;This is changing the API, I think it should not be hidden in a patch like this, also not sure it even makes sense..
Quoted 7 lines
Quoted 7 lines
DMA_ATTR_CC_DECRYPTEDonly says the address passed to mapping is decrypted. It is likeDMA_ATTR_MMIOin this regard.Passing it to
dma_alloc_attrs()is currently invalid, and I think it should remain invalid, or at least this new behavior introduced in its own patch deliberately.
Thinking about this further, I am wondering why you consider passing DMA_ATTR_CC_DECRYPTED invalid. That could be one way for a T=1 device to request decrypted memory. We do not fully support that today, but is there any specific reason you object to allowing DMA_ATTR_CC_DECRYPTED in the allocation paths?
I understand that DMA_ATTR_CC_DECRYPTED is currently used to describe already allocated memory, but extending it to also indicate a DMA address attribute would simplify the allocation path. We could then avoid passing a separate unencrypted/decrypted flag to the various functions that already take an attrs argument in the allocation path.
How about making the change below so that we only prevent dma_alloc_attrs() from accepting DMA_ATTR_CC_DECRYPTED?
modified kernel/dma/direct.c
@@ -204,11 +204,14 @@ void *dma_direct_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
bool remap = false, set_uncached = false;
- bool mark_mem_decrypt = !!(attrs & DMA_ATTR_CC_DECRYPTED);
+ bool mark_mem_decrypt = false;
bool allow_highmem = true;
struct page *page;
void *ret;
+ if (attrs & DMA_ATTR_CC_DECRYPTED)
+ return NULL;
+
if (force_dma_unencrypted(dev)) {
attrs |= DMA_ATTR_CC_DECRYPTED; mark_mem_decrypt = true;
@@ -345,7 +348,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
void dma_direct_free(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
{
- bool mark_mem_encrypted = !!(attrs & DMA_ATTR_CC_DECRYPTED);
+ bool mark_mem_encrypted = false;
unsigned int page_order = get_order(size);
/*
-aneesh
Re: [RFC PATCH 2/7] dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
Quoted 35 lines · Aneesh Kumar K.V
Quoted 33 lines · Aneesh Kumar K.V
Quoted 31 lines · Jason Gunthorpe
Quoted 17 lines · Aneesh Kumar K.V (Arm)
Propagate
force_dma_unencrypted()intoDMA_ATTR_CC_DECRYPTEDin the dma-direct allocation path and use the attribute to drive the related decisions.This updates
dma_direct_alloc(),dma_direct_free(), anddma_direct_alloc_pages()to fold the forced unencrypted case into attrs.Signed-off-by Aneesh Kumar K.V (Arm) <[email protected]>--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)kernel/dma/direct.c +0
-0kernel/dma/direct.c void *dma_direct_alloc(struct device *dev, size_t size, · line 205
Quoted 6 lines
kernel/dma/direct.c +1
-1@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;This is changing the API, I think it should not be hidden in a patch like this, also not sure it even makes sense..
DMA_ATTR_CC_DECRYPTEDonly says the address passed to mapping is decrypted. It is likeDMA_ATTR_MMIOin this regard.
Quoted 7 lines
Quoted 4 lines
Quoted 4 lines
Passing it to
dma_alloc_attrs()is currently invalid, and I think it should remain invalid, or at least this new behavior introduced in its own patch deliberately.Thinking about this further, I am wondering why you consider passing
DMA_ATTR_CC_DECRYPTEDinvalid.
It doesn't do that today. My point is if you want to add then then do it in its own patch and justify what it is for..
I cannot think of a reason for anything to want to do this. The purpose of decrypted memory is to allow a T=0 device to access it and you cannot take memory allocated by dma_alloc and pass it to some other device as a matter of API. So it would be *really* suspicious if some driver wanted this.
Quoted 2 lines
How about making the change below so that we only prevent
dma_alloc_attrs()from acceptingDMA_ATTR_CC_DECRYPTED?
Yeah, that is what I was trying to say. No issue with it using it inside I think.
Jason
Re: [RFC PATCH 2/7] dma-direct: use DMA_ATTR_CC_DECRYPTED in alloc/free paths
Quoted 44 lines · Sat, Apr 18, 2026 at 06:06:17PM +0200, [email protected] wrote:
Quoted 35 lines · Aneesh Kumar K.V
Quoted 33 lines · Aneesh Kumar K.V
Quoted 31 lines · Jason Gunthorpe
Quoted 17 lines · Aneesh Kumar K.V (Arm)
Propagate
force_dma_unencrypted()intoDMA_ATTR_CC_DECRYPTEDin the dma-direct allocation path and use the attribute to drive the related decisions.This updates
dma_direct_alloc(),dma_direct_free(), anddma_direct_alloc_pages()to fold the forced unencrypted case into attrs.Signed-off-by Aneesh Kumar K.V (Arm) <[email protected]>--- kernel/dma/direct.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)kernel/dma/direct.c +0
-0kernel/dma/direct.c void *dma_direct_alloc(struct device *dev, size_t size, · line 205
Quoted 6 lines
kernel/dma/direct.c +1
-1@@ -201,16 +201,21 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { bool remap = false, set_uncached = false; -bool mark_mem_decrypt = true; +bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED );struct page *page;This is changing the API, I think it should not be hidden in a patch like this, also not sure it even makes sense..
DMA_ATTR_CC_DECRYPTEDonly says the address passed to mapping is decrypted. It is likeDMA_ATTR_MMIOin this regard.Quoted 7 lines
Quoted 4 lines
Quoted 4 lines
Passing it to
dma_alloc_attrs()is currently invalid, and I think it should remain invalid, or at least this new behavior introduced in its own patch deliberately.Thinking about this further, I am wondering why you consider passing
DMA_ATTR_CC_DECRYPTEDinvalid.
Quoted 8 lines
It doesn't do that today. My point is if you want to add then then do it in its own patch and justify what it is for..
I cannot think of a reason for anything to want to do this. The purpose of decrypted memory is to allow a T=0 device to access it and you cannot take memory allocated by
dma_allocand pass it to some other device as a matter of API. So it would be *really* suspicious if some driver wanted this.
Agreed. I think that allowing map with DMA_ATTR_CC_DECRYPTED for those devices would need very clear usecase described alongside.
Quoted 8 lines
Quoted 3 lines
How about making the change below so that we only prevent
dma_alloc_attrs()from acceptingDMA_ATTR_CC_DECRYPTED?Yeah, that is what I was trying to say. No issue with it using it inside I think.
Jason
RFC PATCH 3/7 dma-pool: track decrypted atomic pools and select them via attrs
In reply to Aneesh Kumar K.V (Arm)Teach the atomic DMA pool code to distinguish between encrypted and decrypted pools, and make pool allocation select the matching pool based on DMA attributes.
Introduce a dma_gen_pool wrapper that records whether a pool is decrypted, initialize that state when the atomic pools are created, and use it when expanding and resizing the pools. Update dma_alloc_from_pool() to take attrs and skip pools whose encrypted/decrypted state does not match DMA_ATTR_CC_DECRYPTED. Update dma_free_from_pool() accordingly.
Also pass DMA_ATTR_CC_DECRYPTED from the swiotlb atomic allocation path so decrypted swiotlb allocations are taken from the correct atomic pool.
--- drivers/iommu/dma-iommu.c | 2 +- include/linux/dma-map-ops.h | 2 +- kernel/dma/direct.c | 11 ++- kernel/dma/pool.c | 154 +++++++++++++++++++++++------------- kernel/dma/swiotlb.c | 2 + 5 files changed, 109 insertions(+), 62 deletions(-)
drivers/iommu/dma-iommu.c +1 -1
@@ -1650,7 +1650,7 @@ 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) page =dma_alloc_from_pool (dev,PAGE_ALIGN (size), &cpu_addr, - gfp,NULL ); + gfp, attrs,NULL );else cpu_addr =iommu_dma_alloc_pages (dev, size, &page, gfp, attrs);if (!cpu_addr)
include/linux/dma-map-ops.h +1 -1
@@ -217,7 +217,7 @@ void *dma_common_pages_remap(struct page **pages, size_t size, pgprot_t prot,void dma_common_free_remap (void *cpu_addr,size_t size);struct page *dma_alloc_from_pool (struct device *dev,size_t size, -void **cpu_addr,gfp_t flags, +void **cpu_addr,gfp_t flags,unsigned long attrs,bool (*phys_addr_ok)(struct device *,phys_addr_t ,size_t ));bool dma_free_from_pool (struct device *dev,void *start,size_t size);
kernel/dma/direct.c +7 -4
@@ -162,7 +162,7 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp) }static void *dma_direct_alloc_from_pool (struct device *dev,size_t size, -dma_addr_t *dma_handle,gfp_t gfp) +dma_addr_t *dma_handle,gfp_t gfp,unsigned long attrs) {struct page *page;u64 phys_limit;
@@ -172,7 +172,8 @@ static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,return NULL ; gfp |=dma_direct_optimal_gfp_mask (dev, &phys_limit); - page =dma_alloc_from_pool (dev, size, &ret, gfp, dma_coherent_ok); + page =dma_alloc_from_pool (dev, size, &ret, gfp, attrs, + dma_coherent_ok);if (!page)return NULL ; *dma_handle =phys_to_dma_direct (dev,page_to_phys (page));
@@ -251,7 +252,8 @@ void *dma_direct_alloc(struct device *dev, size_t size,*/ if ((remap || (attrs &DMA_ATTR_CC_DECRYPTED )) &&dma_direct_use_pool (dev, gfp)) -return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp); +return dma_direct_alloc_from_pool (dev, size, dma_handle, + gfp, attrs);if (is_swiotlb_for_alloc (dev)) { page =dma_direct_alloc_swiotlb (dev, size);
@@ -387,7 +389,8 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, attrs |=DMA_ATTR_CC_DECRYPTED ;if ((attrs &DMA_ATTR_CC_DECRYPTED ) &&dma_direct_use_pool (dev, gfp)) -return dma_direct_alloc_from_pool (dev, size, dma_handle, gfp); +return dma_direct_alloc_from_pool (dev, size, dma_handle, + gfp, attrs);if (is_swiotlb_for_alloc (dev)) { page =dma_direct_alloc_swiotlb (dev, size);
kernel/dma/pool.c +98 -56
253 lines not on this page · raw message
kernel/dma/swiotlb.c +2 -0
@@ -623,7 +623,9 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,if (!IS_ENABLED (CONFIG_DMA_COHERENT_POOL ))return NULL ; +/* considered decrypted by default */ return dma_alloc_from_pool (dev, bytes, &vaddr, gfp, +DMA_ATTR_CC_DECRYPTED , dma_coherent_ok); }
Signature · 1 line
2.43.0
RFC PATCH 4/7 dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_DECRYPTED
In reply to Aneesh Kumar K.V (Arm)Teach swiotlb to distinguish between encrypted and decrypted bounce buffer pools, and make allocation and mapping paths select a pool whose state matches the requested DMA attributes.
Add a decrypted flag to io_tlb_mem, initialize it for the default and restricted pools, and propagate DMA_ATTR_CC_DECRYPTED into swiotlb pool allocation. Reject swiotlb alloc/map requests when the selected pool does not match the required encrypted/decrypted state.
Also return DMA addresses with the matching phys_to_dma_{encrypted, unencrypted} helper so the DMA address encoding stays consistent with the chosen pool.
--- include/linux/dma-direct.h | 10 +++++ include/linux/swiotlb.h | 7 ++- kernel/dma/direct.c | 14 ++++-- kernel/dma/swiotlb.c | 89 ++++++++++++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 25 deletions(-)
include/linux/dma-direct.h +10 -0
@@ -77,6 +77,10 @@ static inline dma_addr_t dma_range_map_max(const struct bus_dma_region *map)#ifndef phys_to_dma_unencrypted#define phys_to_dma_unencrypted phys_to_dma#endif + +#ifndef phys_to_dma_encrypted +#define phys_to_dma_encrypted phys_to_dma +#endif #else static inline dma_addr_t __phys_to_dma (struct device *dev,phys_addr_t paddr) {
@@ -90,6 +94,12 @@ static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, {return dma_addr_unencrypted (__phys_to_dma (dev, paddr)); } + +static inline dma_addr_t phys_to_dma_encrypted (struct device *dev, +phys_addr_t paddr) +{ +return dma_addr_encrypted (__phys_to_dma (dev, paddr)); +}/* * If memory encryption is supported, phys_to_dma will set the memory encryption * bit in the DMA address, and dma_to_phys will clear it.
include/linux/swiotlb.h +5 -2
@@ -111,6 +111,7 @@ struct io_tlb_mem {struct dentry *debugfs;bool force_bounce;bool for_alloc; +bool decrypted;#ifdef CONFIG_SWIOTLB_DYNAMIC bool can_grow;u64 phys_limit;
@@ -282,7 +283,8 @@ static inline void swiotlb_sync_single_for_cpu(struct device *dev,extern void swiotlb_print_info (void );#ifdef CONFIG_DMA_RESTRICTED_POOL -struct page *swiotlb_alloc (struct device *dev,size_t size); +struct page *swiotlb_alloc (struct device *dev,size_t size, +unsigned long attrs);bool swiotlb_free (struct device *dev,struct page *page,size_t size);static inline bool is_swiotlb_for_alloc (struct device *dev)
@@ -290,7 +292,8 @@ static inline bool is_swiotlb_for_alloc(struct device *dev) return dev->dma_io_tlb_mem->for_alloc; }#else -static inline struct page *swiotlb_alloc (struct device *dev,size_t size) +static inline struct page *swiotlb_alloc (struct device *dev,size_t size, +unsigned long attrs) {return NULL ; }
kernel/dma/direct.c +10 -4
@@ -104,9 +104,10 @@ static void __dma_direct_free_pages(struct device *dev, struct page *page,dma_free_contiguous (dev, page, size); } -static struct page *dma_direct_alloc_swiotlb (struct device *dev,size_t size) +static struct page *dma_direct_alloc_swiotlb (struct device *dev,size_t size, +unsigned long attrs) { -struct page *page =swiotlb_alloc (dev, size); +struct page *page =swiotlb_alloc (dev, size, attrs);if (page && !dma_coherent_ok (dev,page_to_phys (page), size)) {swiotlb_free (dev, page, size);
@@ -256,8 +257,12 @@ void *dma_direct_alloc(struct device *dev, size_t size, gfp, attrs);if (is_swiotlb_for_alloc (dev)) { - page =dma_direct_alloc_swiotlb (dev, size); + page =dma_direct_alloc_swiotlb (dev, size, attrs);if (page) { +/* +* swiotlb allocations comes from pool already marked +* decrypted +*/ mark_mem_decrypt = false; goto setup_page; }
@@ -364,6 +369,7 @@ void dma_direct_free(struct device *dev, size_t size,return ;if (swiotlb_find_pool (dev,dma_to_phys (dev, dma_addr))) +/* Swiotlb doesn't need a page attribute update on free */ mark_mem_encrypted = false;if (is_vmalloc_addr (cpu_addr)) {
@@ -393,7 +399,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, gfp, attrs);if (is_swiotlb_for_alloc (dev)) { - page =dma_direct_alloc_swiotlb (dev, size); + page =dma_direct_alloc_swiotlb (dev, size, attrs);if (!page)return NULL ;
kernel/dma/swiotlb.c +70 -19
214 lines not on this page · raw message
Signature · 1 line
2.43.0
RFC PATCH 5/7 dma-mapping: make dma_pgprot() honor DMA_ATTR_CC_DECRYPTED
In reply to Aneesh Kumar K.V (Arm)Fold encrypted/decrypted pgprot selection into dma_pgprot() so callers do not need to adjust the page protection separately.
Update dma_pgprot() to apply pgprot_decrypted() when DMA_ATTR_CC_DECRYPTED is set and pgprot_encrypted() otherwise Convert the dma-direct allocation and mmap paths to pass DMA_ATTR_CC_DECRYPTED instead of open-coding force_dma_unencrypted() handling around dma_pgprot().
--- kernel/dma/direct.c | 8 +++----- kernel/dma/mapping.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 9 deletions(-)
kernel/dma/direct.c +3 -5
@@ -288,9 +288,6 @@ void *dma_direct_alloc(struct device *dev, size_t size,if (remap) {pgprot_t prot =dma_pgprot (dev,PAGE_KERNEL , attrs); -if (force_dma_unencrypted (dev)) - prot =pgprot_decrypted (prot); -/* remove any dirty cache lines on the kernel alias */ arch_dma_prep_coherent (page, size);
@@ -580,9 +577,10 @@ int dma_direct_mmap(struct device *dev, struct vm_area_struct *vma,unsigned long pfn =PHYS_PFN (dma_to_phys (dev, dma_addr));int ret = -ENXIO ; - vma->vm_page_prot =dma_pgprot (dev, vma->vm_page_prot, attrs);if (force_dma_unencrypted (dev)) - vma->vm_page_prot =pgprot_decrypted (vma->vm_page_prot); + attrs |=DMA_ATTR_CC_DECRYPTED ; + + vma->vm_page_prot =dma_pgprot (dev, vma->vm_page_prot, attrs);if (dma_mmap_from_dev_coherent (dev, vma, cpu_addr, size, &ret))return ret;
kernel/dma/mapping.c +12 -4
@@ -534,13 +534,21 @@ EXPORT_SYMBOL(dma_get_sgtable_attrs);*/ pgprot_t dma_pgprot (struct device *dev,pgprot_t prot,unsigned long attrs) { +pgprot_t dma_prot; +if (dev_is_dma_coherent (dev)) -return prot; + dma_prot = prot;#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE -if (attrs &DMA_ATTR_WRITE_COMBINE ) -return pgprot_writecombine (prot); + else if (attrs & DMA_ATTR_WRITE_COMBINE) + dma_prot =pgprot_writecombine (prot);#endif -return pgprot_dmacoherent (prot); + else + dma_prot =pgprot_dmacoherent (prot); + +if (attrs &DMA_ATTR_CC_DECRYPTED ) +return pgprot_decrypted (dma_prot); +else +return pgprot_encrypted (dma_prot); }#endif /* CONFIG_MMU */
Signature · 1 line
2.43.0
RFC PATCH 6/7 dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_DECRYPTED
In reply to Aneesh Kumar K.V (Arm)Teach dma_direct_map_phys() to select the DMA address encoding based on DMA_ATTR_CC_DECRYPTED.
Use phys_to_dma_unencrypted() for decrypted mappings and phys_to_dma_encrypted() otherwise. If a device requires unencrypted DMA but the source physical address is still encrypted, force the mapping through swiotlb so the DMA address and backing memory attributes remain consistent.
--- kernel/dma/direct.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
kernel/dma/direct.h +16 -9
@@ -81,9 +81,14 @@ static inline dma_addr_t dma_direct_map_phys(struct device *dev, phys_addr_t phys, size_t size, enum dma_data_direction dir, unsigned long attrs) { + bool force_swiotlb_map = false;dma_addr_t dma_addr; -if (is_swiotlb_force_bounce (dev)) { +/* if phys addr attribute is encrypted but the device is forcing an encrypted dma addr */ +if (!(attrs &DMA_ATTR_CC_DECRYPTED ) &&force_dma_unencrypted (dev)) + force_swiotlb_map = true; + +if (is_swiotlb_force_bounce (dev) || force_swiotlb_map) {if (attrs & (DMA_ATTR_MMIO |DMA_ATTR_REQUIRE_COHERENT ))return DMA_MAPPING_ERROR ;
@@ -94,16 +99,18 @@ static inline dma_addr_t dma_direct_map_phys(struct device *dev, dma_addr = phys;if (unlikely (!dma_capable (dev, dma_addr, size, false))) goto err_overflow; + }else if (attrs &DMA_ATTR_CC_DECRYPTED ) { + dma_addr =phys_to_dma_unencrypted (dev, phys); }else { - dma_addr =phys_to_dma (dev, phys); -if (unlikely (!dma_capable (dev, dma_addr, size, true)) || -dma_kmalloc_needs_bounce (dev, size, dir)) { -if (is_swiotlb_active (dev) && - !(attrs &DMA_ATTR_REQUIRE_COHERENT )) -return swiotlb_map (dev, phys, size, dir, attrs); + dma_addr =phys_to_dma_encrypted (dev, phys); + } - goto err_overflow; - } +if (unlikely (!dma_capable (dev, dma_addr, size, true)) || +dma_kmalloc_needs_bounce (dev, size, dir)) { +if (is_swiotlb_active (dev) && + !(attrs &DMA_ATTR_REQUIRE_COHERENT )) +return swiotlb_map (dev, phys, size, dir, attrs); + goto err_overflow; } if (!dev_is_dma_coherent(dev) &&
Signature · 1 line
2.43.0
RFC PATCH 7/7 dma-direct: set decrypted flag for remapped DMA allocations
In reply to Aneesh Kumar K.V (Arm)Devices that are DMA non-coherent and require a remap were skipping dma_set_decrypted(), leaving DMA buffers encrypted even when the device requires unencrypted access. Move the call after the if (remap) branch so that both the direct and remapped allocation paths correctly mark the allocation as decrypted (or fail cleanly) before use.
Architectures such as arm64 cannot mark vmap addresses as decrypted, and highmem pages necessarily require a vmap remap. As a result, such allocations cannot be safely used for unencrypted DMA. Therefore, when an unencrypted DMA buffer is requested, avoid allocating high PFNs from __dma_direct_alloc_pages().
Other architectures (e.g. x86) do not have this limitation. However, rather than making this architecture-specific, apply the restriction only when the device requires unencrypted DMA access, for simplicity.
--- kernel/dma/direct.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
kernel/dma/direct.c +27 -3
@@ -204,6 +204,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, {bool remap = false, set_uncached = false;bool mark_mem_decrypt = !!(attrs &DMA_ATTR_CC_DECRYPTED ); +bool allow_highmem = true;struct page *page;void *ret;
@@ -212,6 +213,15 @@ void *dma_direct_alloc(struct device *dev, size_t size, mark_mem_decrypt = true; } +if (attrs &DMA_ATTR_CC_DECRYPTED ) +/* +* Unencrypted/shared DMA requires a linear-mapped buffer +* address to look up the PFN and set architecture-required PFN +* attributes. This is not possible with HighMem. Avoid HighMem +* allocation. +*/ + allow_highmem = false; + size =PAGE_ALIGN (size);if (attrs &DMA_ATTR_NO_WARN ) gfp |= __GFP_NOWARN;
@@ -270,7 +280,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, }/* we always manually zero the memory once we are done */ - page =__dma_direct_alloc_pages (dev, size, gfp & ~__GFP_ZERO, true); + page =__dma_direct_alloc_pages (dev, size, gfp & ~__GFP_ZERO, allow_highmem);if (!page)return NULL ;
@@ -298,7 +308,13 @@ void *dma_direct_alloc(struct device *dev, size_t size, goto out_free_pages; }else { ret =page_address (page); -if (mark_mem_decrypt &&dma_set_decrypted (dev, ret, size)) + } + +if (mark_mem_decrypt) { +void *lm_addr; + + lm_addr =page_address (page); +if (set_memory_decrypted ((unsigned long )lm_addr,PFN_UP (size))) goto out_leak_pages; }
@@ -374,8 +390,16 @@ void dma_direct_free(struct device *dev, size_t size, }else {if (IS_ENABLED (CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED ))arch_dma_clear_uncached (cpu_addr, size); -if (mark_mem_encrypted &&dma_set_encrypted (dev, cpu_addr, size)) + } + +if (mark_mem_encrypted) { +void *lm_addr; + + lm_addr =phys_to_virt (dma_to_phys (dev, dma_addr)); +if (set_memory_encrypted ((unsigned long )lm_addr,PFN_UP (size))) { +pr_warn_ratelimited ("leaking DMA memory that can't be re-encrypted\n" );return ; + } }__dma_direct_free_pages (dev,dma_direct_to_page (dev, dma_addr), size);
Signature · 1 line
2.43.0
RFC PATCH 1/1 dma-direct: select DMA address encoding from DMA_ATTR_CC_DECRYPTED
In reply to Aneesh Kumar K.V (Arm)From: "Aneesh Kumar K.V (Arm)" <[email protected]>
Make the dma-direct helpers derive the DMA address encoding from DMA_ATTR_CC_DECRYPTED instead of implicitly relying on force_dma_unencrypted() inside phys_to_dma_direct()
Pass an explicit unencrypted/decrypted state into phys_to_dma_direct(), make the alloc paths return DMA addresses that match the requested buffer encryption state. Also only call dma_set_decrypted() when DMA_ATTR_CC_DECRYPTED is actually set.
---
Missed doing this conversion in the pervious set.
--- kernel/dma/direct.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-)
kernel/dma/direct.c +24 -17
@@ -24,11 +24,11 @@u64 zone_dma_limit__ro_after_init =DMA_BIT_MASK (24 );static inline dma_addr_t phys_to_dma_direct (struct device *dev, -phys_addr_t phys) +phys_addr_t phys,bool unencrypted) { -if (force_dma_unencrypted (dev)) +if (unencrypted)return phys_to_dma_unencrypted (dev, phys); -return phys_to_dma (dev, phys); +return phys_to_dma_encrypted (dev, phys); } static inline struct page *dma_direct_to_page(struct device *dev,
@@ -39,8 +39,9 @@ static inline struct page *dma_direct_to_page(struct device *dev,u64 dma_direct_get_required_mask (struct device *dev) { +bool require_decrypted =force_dma_unencrypted (dev);phys_addr_t phys = (phys_addr_t)(max_pfn -1 ) <<PAGE_SHIFT ; -u64 max_dma =phys_to_dma_direct (dev, phys); +u64 max_dma =phys_to_dma_direct (dev, phys, require_decrypted);return (1ULL << (fls64 (max_dma) -1 )) *2 -1 ; }
@@ -69,7 +70,8 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit)bool dma_coherent_ok (struct device *dev,phys_addr_t phys,size_t size) { -dma_addr_t dma_addr =phys_to_dma_direct (dev, phys); +bool require_decrypted =force_dma_unencrypted (dev); +dma_addr_t dma_addr =phys_to_dma_direct (dev, phys, require_decrypted);if (dma_addr ==DMA_MAPPING_ERROR )return false;
@@ -79,8 +81,6 @@ bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)static int dma_set_decrypted (struct device *dev,void *vaddr,size_t size) { -if (!force_dma_unencrypted (dev)) -return 0 ;return set_memory_decrypted ((unsigned long )vaddr,PFN_UP (size)); }
@@ -88,8 +88,6 @@ static int dma_set_encrypted(struct device *dev, void *vaddr, size_t size) {int ret; -if (!force_dma_unencrypted (dev)) -return 0 ; ret =set_memory_encrypted ((unsigned long )vaddr,PFN_UP (size));if (ret)pr_warn_ratelimited ("leaking DMA memory that can't be re-encrypted\n" );
@@ -177,7 +175,8 @@ static void *dma_direct_alloc_from_pool(struct device *dev, size_t size, dma_coherent_ok);if (!page)return NULL ; - *dma_handle =phys_to_dma_direct (dev,page_to_phys (page)); + *dma_handle =phys_to_dma_direct (dev,page_to_phys (page), + !!(attrs &DMA_ATTR_CC_DECRYPTED ));return ret; }
@@ -193,9 +192,11 @@ static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,/* remove any dirty cache lines on the kernel alias */ if (!PageHighMem (page))arch_dma_prep_coherent (page, size); - -/* return the page pointer as the opaque cookie */ - *dma_handle =phys_to_dma_direct (dev,page_to_phys (page)); +/* +* return the page pointer as the opaque cookie. +* Never used for unencrypted allocation +*/ + *dma_handle =phys_to_dma_direct (dev,page_to_phys (page), false);return page; }
@@ -327,7 +328,8 @@ void *dma_direct_alloc(struct device *dev, size_t size, goto out_encrypt_pages; } - *dma_handle =phys_to_dma_direct (dev,page_to_phys (page)); + *dma_handle =phys_to_dma_direct (dev,page_to_phys (page), + !!(attrs &DMA_ATTR_CC_DECRYPTED ));return ret; out_encrypt_pages:
@@ -437,11 +439,12 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,return NULL ; ret =page_address (page); -if (dma_set_decrypted (dev, ret, size)) +if ((attrs &DMA_ATTR_CC_DECRYPTED ) &&dma_set_decrypted (dev, ret, size)) goto out_leak_pages; setup_page:memset (ret,0 , size); - *dma_handle =phys_to_dma_direct (dev,page_to_phys (page)); + *dma_handle =phys_to_dma_direct (dev,page_to_phys (page), + !!(attrs &DMA_ATTR_CC_DECRYPTED ));return page; out_leak_pages:return NULL ;
@@ -451,8 +454,12 @@ void dma_direct_free_pages(struct device *dev, size_t size, struct page *page, dma_addr_t dma_addr, enum dma_data_direction dir) { +/* +* if the device had requested for an unencrypted buffer, +* convert it to encrypted on free +*/ +bool mark_mem_encrypted =force_dma_unencrypted (dev);void *vaddr =page_address (page); -bool mark_mem_encrypted = true;/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */ if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
Signature · 1 line
2.43.0