On Mon, Sep 30, 2019 at 8:57 AM Ayan Halder <Ayan.Halder(a)arm.com> wrote:
>
> On Mon, Sep 30, 2019 at 09:51:35AM +0000, Brian Starkey wrote:
> > Hi,
> >
> > On Tue, Sep 17, 2019 at 07:36:45PM +0200, Daniel Vetter wrote:
> > > On Tue, Sep 17, 2019 at 6:15 PM Neil Armstrong <narmstrong(a)baylibre.com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On 17/09/2019 18:07, Liviu Dudau wrote:
> > > > > On Tue, Sep 17, 2019 at 02:53:01PM +0200, Daniel Vetter wrote:
> > > > >> On Mon, Sep 09, 2019 at 01:42:53PM +0000, Ayan Halder wrote:
> > > > >>> Add a modifier 'DRM_FORMAT_MOD_ARM_PROTECTED' which denotes that the framebuffer
> > > > >>> is allocated in a protected system memory.
> > > > >>> Essentially, we want to support EGL_EXT_protected_content in our komeda driver.
> > > > >>>
> > > > >>> Signed-off-by: Ayan Kumar Halder <ayan.halder(a)arm.com>
> > > > >>>
> > > > >>> /-- Note to reviewer
> > > > >>> Komeda driver is capable of rendering DRM (Digital Rights Management) protected
> > > > >>> content. The DRM content is stored in a framebuffer allocated in system memory
> > > > >>> (which needs some special hardware signals for access).
> > > > >>>
> > > > >>> Let us ignore how the protected system memory is allocated and for the scope of
> > > > >>> this discussion, we want to figure out the best way possible for the userspace
> > > > >>> to communicate to the drm driver to turn the protected mode on (for accessing the
> > > > >>> framebuffer with the DRM content) or off.
> > > > >>>
> > > > >>> The possible ways by which the userspace could achieve this is via:-
> > > > >>>
> > > > >>> 1. Modifiers :- This looks to me the best way by which the userspace can
> > > > >>> communicate to the kernel to turn the protected mode on for the komeda driver
> > > > >>> as it is going to access one of the protected framebuffers. The only problem is
> > > > >>> that the current modifiers describe the tiling/compression format. However, it
> > > > >>> does not hurt to extend the meaning of modifiers to denote other attributes of
> > > > >>> the framebuffer as well.
> > > > >>>
> > > > >>> The other reason is that on Android, we get an info from Gralloc
> > > > >>> (GRALLOC_USAGE_PROTECTED) which tells us that the buffer is protected. This can
> > > > >>> be used to set up the modifier/s (AddFB2) during framebuffer creation.
> > > > >>
> > > > >> How does this mesh with other modifiers, like AFBC? That's where I see the
> > > > >> issue here.
> > > > >
> > > > > AFBC modifiers are currently under Arm's namespace, the thought behind the DRM
> > > > > modifiers would be to have it as a "generic" modifier.
> > >
> > > But if it's a generic flag, how do you combine that with other
> > > modifiers? Like if you have a tiled buffer, but also encrypted? Or
> > > afbc compressed, or whatever else. I'd expect for your hw encryption
> > > is orthogonal to the buffer/tiling/compression format used?
> >
> > This bit doesn't overlap with any of the other AFBC modifiers, so as
> > you say it'd be orthogonal, and could be set on AFBC buffers (if we
> > went that route).
> >
> > >
> > > > >>> 2. Framebuffer flags :- As of today, this can be one of the two values
> > > > >>> ie (DRM_MODE_FB_INTERLACED/DRM_MODE_FB_MODIFIERS). Unlike modifiers, the drm
> > > > >>> framebuffer flags are generic to the drm subsystem and ideally we should not
> > > > >>> introduce any driver specific constraint/feature.
> > > > >>>
> > > > >>> 3. Connector property:- I could see the following properties used for DRM
> > > > >>> protected content:-
> > > > >>> DRM_MODE_CONTENT_PROTECTION_DESIRED / ENABLED :- "This property is used by
> > > > >>> userspace to request the kernel protect future content communicated over
> > > > >>> the link". Clearly, we are not concerned with the protection attributes of the
> > > > >>> transmitter. So, we cannot use this property for our case.
> > > > >>>
> > > > >>> 4. DRM plane property:- Again, we want to communicate that the framebuffer(which
> > > > >>> can be attached to any plane) is protected. So introducing a new plane property
> > > > >>> does not help.
> > > > >>>
> > > > >>> 5. DRM crtc property:- For the same reason as above, introducing a new crtc
> > > > >>> property does not help.
> > > > >>
> > > > >> 6. Just track this as part of buffer allocation, i.e. I think it does
> > > > >> matter how you allocate these protected buffers. We could add a "is
> > > > >> protected buffer" flag at the dma_buf level for this.
> >
> > I also like this approach. The protected-ness is a property of the
> > allocation, so makes sense to store it with the allocation IMO.
> >
> > > > >>
> > > > >> So yeah for this stuff here I think we do want the full userspace side,
> > > > >> from allocator to rendering something into this protected buffers (no need
> > > > >> to also have the entire "decode a protected bitstream part" imo, since
> > > > >> that will freak people out). Unfortunately, in my experience, that kills
> > > > >> it for upstream :-/ But also in my experience of looking into this for
> > > > >> other gpu's, we really need to have the full picture here to make sure
> > > > >> we're not screwing this up.
> > > > >
> > > > > Maybe Ayan could've been a bit clearer in his message, but the ask here is for ideas
> > > > > on how userspace "communicates" (stores?) the fact that the buffers are protected to
> > > > > the kernel driver. In our display processor we need to the the hardware that the
> > > > > buffers are protected before it tries to fetch them so that it can 1) enable the
> > > > > additional hardware signaling that sets the protection around the stream; and 2) read
> > > > > the protected buffers in a special mode where there the magic happens.
> > >
> > > That was clear, but for the full picture we also need to know how
> > > these buffers are produced and where they are allocated. One approach
> > > would be to have a dma-buf heap that gives you encrypted buffers back.
> > > With that we need to make sure that only encryption-aware drivers
> > > allow such buffers to be imported, and the entire problem becomes a
> > > kernel-internal one - aside from allocating the right kind of buffer
> > > at the right place.
> > >
> >
> > In our case, we'd be supporting a system like TZMP-1, there's a
> > Linaro connect presentation on it here:
> > https://connect.linaro.org/resources/hkg18/hkg18-408/
> >
> > The simplest way to implement this is for firmware to set up a
> > carveout which it tells linux is secure. A linux allocator (ion, gem,
> > vb2, whatever) can allocate from this carveout, and tag the buffer as
> > secure.
> >
> > In this kind of system, linux doesn't necessarily need to know
> > anything about how buffers are protected, or what HW is capable of -
> > it only needs to carry around the "is_protected" flag.
> >
> > Here, the TEE is ultimately responsible for deciding which HW gets
> > access to a buffer. I don't see a benefit of having linux decide which
> > drivers can or cannot import a buffer, because that decision should be
> > handled by the TEE.
> >
> > For proving out the pipeline, IMO it doesn't matter whether the
> > buffers are protected or not. For our DPU, all that matters is that if
> > the buffer claims to be protected, we have to set our protected
> > control bit. Nothing more. AFAIK it should work the same for other
> > TZMP-1 implementations.
> >
> > > > > So yeah, we know we do want full userspace support, we're prodding the community on
> > > > > answers on how to best let the kernel side know what userspace has done.
> > > >
> > > > Actually this is interesting for other multimedia SoCs implementing secure video decode
> > > > paths where video buffers are allocated and managed by a trusted app.
> > >
> > > Yeah I expect there's more than just arm wanting this. I also wonder
> > > how that interacts with the secure memory allocator that was bobbing
> > > around on dri-devel for a while, but seems to not have gone anywhere.
> > > That thing implemented my idea of "secure memory is only allocated by
> > > a special entity".
> > > -Daniel
> >
> > Like I said, for us all we need is a way to carry around a 1-bit
> > "is_protected" flag with a buffer. Could other folks share what's
> > needed for their systems so we can reason about something that works
> > for all?
>
> To make things a bit more specific, we are thinking of the following
> patch :-
>
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index ec212cb27fdc..36f0813073a2 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -279,6 +279,7 @@ struct dma_buf_ops {
> * kernel module.
> * @list_node: node for dma_buf accounting and debugging.
> * @priv: exporter specific private data for this buffer object.
> + * @is_protected: denotes that the buffer is
> secure/protected/encrypted/trusted.
> * @resv: reservation object linked to this dma-buf
> * @poll: for userspace poll support
> * @cb_excl: for userspace poll support
> @@ -306,6 +307,7 @@ struct dma_buf {
> struct module *owner;
> struct list_head list_node;
> void *priv;
> + bool is_protected;
> struct dma_resv *resv;
>
> /* poll support */
>
> @all, @amdgpu-folks :- Is this something you can use of to denote
> secure/protected/encrypted/trusted buffers ?
I suppose. At the moment, we don't really have a need for it since we
only our IPs support our encryption scheme and if we share buffers
between we can get to the secure status when we look up the amdgpu
buffer object internally in the kernel side. Still might be useful
for cases where secure buffers get shared across drivers so we have a
generic check for secure status.
Alex
>
> The way 'is_protected' flag gets used to allocate
> secure/protected/encrypted buffers will be vendor specific.
>
> Please comment to let us know if it looks useful to non Arm folks.
> >
> > Thanks!
> > -Brian
> >
> > >
> > > >
> > > > Neil
> > > >
> > > > >
> > > > > Best regards,
> > > > > Liviu
> > > > >
> > > > >
> > > > >> -Daniel
> > > > >>
> > > > >>>
> > > > >>> --/
> > > > >>>
> > > > >>> ---
> > > > >>> include/uapi/drm/drm_fourcc.h | 9 +++++++++
> > > > >>> 1 file changed, 9 insertions(+)
> > > > >>>
> > > > >>> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> > > > >>> index 3feeaa3f987a..38e5e81d11fe 100644
> > > > >>> --- a/include/uapi/drm/drm_fourcc.h
> > > > >>> +++ b/include/uapi/drm/drm_fourcc.h
> > > > >>> @@ -742,6 +742,15 @@ extern "C" {
> > > > >>> */
> > > > >>> #define AFBC_FORMAT_MOD_BCH (1ULL << 11)
> > > > >>>
> > > > >>> +/*
> > > > >>> + * Protected framebuffer
> > > > >>> + *
> > > > >>> + * The framebuffer is allocated in a protected system memory which can be accessed
> > > > >>> + * via some special hardware signals from the dpu. This is used to support
> > > > >>> + * 'GRALLOC_USAGE_PROTECTED' in our framebuffer for EGL_EXT_protected_content.
> > > > >>> + */
> > > > >>> +#define DRM_FORMAT_MOD_ARM_PROTECTED fourcc_mod_code(ARM, (1ULL << 55))
> > > > >>> +
> > > > >>> /*
> > > > >>> * Allwinner tiled modifier
> > > > >>> *
> > > > >>> --
> > > > >>> 2.23.0
> > > > >>>
> > > > >>
> > > > >> --
> > > > >> Daniel Vetter
> > > > >> Software Engineer, Intel Corporation
> > > > >> http://blog.ffwll.ch
> > > > >
> > > >
> > > > _______________________________________________
> > > > dri-devel mailing list
> > > > dri-devel(a)lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > >
> > >
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > +41 (0) 79 365 57 48 - http://blog.ffwll.ch
On 9/29/19 3:28 AM, jun.zhang(a)intel.com wrote:
> From: zhang jun <jun.zhang(a)intel.com>
>
> we see tons of warning like:
> [ 45.846872] x86/PAT: NDK MediaCodec_:3753 map pfn RAM range req
> write-combining for [mem 0x1e7a80000-0x1e7a87fff], got write-back
> [ 45.848827] x86/PAT: .vorbis.decoder:4088 map pfn RAM range req
> write-combining for [mem 0x1e7a58000-0x1e7a58fff], got write-back
> [ 45.848875] x86/PAT: NDK MediaCodec_:3753 map pfn RAM range req
> write-combining for [mem 0x1e7a48000-0x1e7a4ffff], got write-back
> [ 45.849403] x86/PAT: .vorbis.decoder:4088 map pfn RAM range
> req write-combining for [mem 0x1e7a70000-0x1e7a70fff], got write-back
>
> check the kernel Documentation/x86/pat.txt, it says:
> A. Exporting pages to users with remap_pfn_range, io_remap_pfn_range,
> vm_insert_pfn
> Drivers wanting to export some pages to userspace do it by using
> mmap interface and a combination of
> 1) pgprot_noncached()
> 2) io_remap_pfn_range() or remap_pfn_range() or vm_insert_pfn()
> With PAT support, a new API pgprot_writecombine is being added.
> So, drivers can continue to use the above sequence, with either
> pgprot_noncached() or pgprot_writecombine() in step 1, followed by step 2.
>
> In addition, step 2 internally tracks the region as UC or WC in
> memtype list in order to ensure no conflicting mapping.
>
> Note that this set of APIs only works with IO (non RAM) regions.
> If driver ants to export a RAM region, it has to do set_memory_uc() or
> set_memory_wc() as step 0 above and also track the usage of those pages
> and use set_memory_wb() before the page is freed to free pool.
>
> the fix follow the pat document, do set_memory_wc() as step 0 and
> use the set_memory_wb() before the page is freed.
>
All this work needs to be done on the new dma-buf heap rework and I
don't think it makes sense to put it on the staging version
https://lore.kernel.org/lkml/20190906184712.91980-1-john.stultz@linaro.org/
(I also continue to question the value of uncached buffers, especially on
x86)
> Signed-off-by: he, bo <bo.he(a)intel.com>
> Signed-off-by: zhang jun <jun.zhang(a)intel.com>
> Signed-off-by: Bai, Jie A <jie.a.bai(a)intel.com>
> ---
> drivers/staging/android/ion/ion_system_heap.c | 28 ++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
> index b83a1d16bd89..d298b8194820 100644
> --- a/drivers/staging/android/ion/ion_system_heap.c
> +++ b/drivers/staging/android/ion/ion_system_heap.c
> @@ -13,6 +13,7 @@
> #include <linux/scatterlist.h>
> #include <linux/slab.h>
> #include <linux/vmalloc.h>
> +#include <asm/set_memory.h>
>
> #include "ion.h"
>
> @@ -134,6 +135,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
> sg = table->sgl;
> list_for_each_entry_safe(page, tmp_page, &pages, lru) {
> sg_set_page(sg, page, page_size(page), 0);
> +
> +#ifdef CONFIG_X86
> + if (!(buffer->flags & ION_FLAG_CACHED))
> + set_memory_wc((unsigned long)page_address(sg_page(sg)),
> + PAGE_ALIGN(sg->length) >> PAGE_SHIFT);
> +#endif
> +
> sg = sg_next(sg);
> list_del(&page->lru);
> }
> @@ -162,8 +170,15 @@ static void ion_system_heap_free(struct ion_buffer *buffer)
> if (!(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE))
> ion_heap_buffer_zero(buffer);
>
> - for_each_sg(table->sgl, sg, table->nents, i)
> + for_each_sg(table->sgl, sg, table->nents, i) {
> +#ifdef CONFIG_X86
> + if (!(buffer->flags & ION_FLAG_CACHED))
> + set_memory_wb((unsigned long)page_address(sg_page(sg)),
> + PAGE_ALIGN(sg->length) >> PAGE_SHIFT);
> +#endif
> +
> free_buffer_page(sys_heap, buffer, sg_page(sg));
> + }
> sg_free_table(table);
> kfree(table);
> }
> @@ -316,6 +331,12 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap,
>
> buffer->sg_table = table;
>
> +#ifdef CONFIG_X86
> + if (!(buffer->flags & ION_FLAG_CACHED))
> + set_memory_wc((unsigned long)page_address(page),
> + PAGE_ALIGN(len) >> PAGE_SHIFT);
> +#endif
> +
> return 0;
>
> free_table:
> @@ -334,6 +355,11 @@ static void ion_system_contig_heap_free(struct ion_buffer *buffer)
> unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT;
> unsigned long i;
>
> +#ifdef CONFIG_X86
> + if (!(buffer->flags & ION_FLAG_CACHED))
> + set_memory_wb((unsigned long)page_address(page), pages);
> +#endif
> +
> for (i = 0; i < pages; i++)
> __free_page(page + i);
> sg_free_table(table);
>
On Sun, Sep 29, 2019 at 03:28:41PM +0800, jun.zhang(a)intel.com wrote:
> From: zhang jun <jun.zhang(a)intel.com>
>
> we see tons of warning like:
> [ 45.846872] x86/PAT: NDK MediaCodec_:3753 map pfn RAM range req
> write-combining for [mem 0x1e7a80000-0x1e7a87fff], got write-back
> [ 45.848827] x86/PAT: .vorbis.decoder:4088 map pfn RAM range req
> write-combining for [mem 0x1e7a58000-0x1e7a58fff], got write-back
> [ 45.848875] x86/PAT: NDK MediaCodec_:3753 map pfn RAM range req
> write-combining for [mem 0x1e7a48000-0x1e7a4ffff], got write-back
> [ 45.849403] x86/PAT: .vorbis.decoder:4088 map pfn RAM range
> req write-combining for [mem 0x1e7a70000-0x1e7a70fff], got write-back
>
> check the kernel Documentation/x86/pat.txt, it says:
> A. Exporting pages to users with remap_pfn_range, io_remap_pfn_range,
> vm_insert_pfn
> Drivers wanting to export some pages to userspace do it by using
> mmap interface and a combination of
> 1) pgprot_noncached()
> 2) io_remap_pfn_range() or remap_pfn_range() or vm_insert_pfn()
> With PAT support, a new API pgprot_writecombine is being added.
> So, drivers can continue to use the above sequence, with either
> pgprot_noncached() or pgprot_writecombine() in step 1, followed by step 2.
>
> In addition, step 2 internally tracks the region as UC or WC in
> memtype list in order to ensure no conflicting mapping.
>
> Note that this set of APIs only works with IO (non RAM) regions.
> If driver ants to export a RAM region, it has to do set_memory_uc() or
> set_memory_wc() as step 0 above and also track the usage of those pages
> and use set_memory_wb() before the page is freed to free pool.
>
> the fix follow the pat document, do set_memory_wc() as step 0 and
> use the set_memory_wb() before the page is freed.
>
> Signed-off-by: he, bo <bo.he(a)intel.com>
> Signed-off-by: zhang jun <jun.zhang(a)intel.com>
> Signed-off-by: Bai, Jie A <jie.a.bai(a)intel.com>
> ---
> drivers/staging/android/ion/ion_system_heap.c | 28 ++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
> index b83a1d16bd89..d298b8194820 100644
> --- a/drivers/staging/android/ion/ion_system_heap.c
> +++ b/drivers/staging/android/ion/ion_system_heap.c
> @@ -13,6 +13,7 @@
> #include <linux/scatterlist.h>
> #include <linux/slab.h>
> #include <linux/vmalloc.h>
> +#include <asm/set_memory.h>
>
> #include "ion.h"
>
> @@ -134,6 +135,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
> sg = table->sgl;
> list_for_each_entry_safe(page, tmp_page, &pages, lru) {
> sg_set_page(sg, page, page_size(page), 0);
> +
> +#ifdef CONFIG_X86
> + if (!(buffer->flags & ION_FLAG_CACHED))
> + set_memory_wc((unsigned long)page_address(sg_page(sg)),
> + PAGE_ALIGN(sg->length) >> PAGE_SHIFT);
> +#endif
There is no way to do this without these #ifdefs? That feels odd, why
can't you just always test for this?
thanks,
greg k-h
On Sun, Sep 08, 2019 at 02:34:50PM +1000, Adam Zerella wrote:
> Using strncpy() does not always terminate the destination string.
> stracpy() is a alternative function that does, by using this new
> function we will no longer need to insert a null separator.
>
> Signed-off-by: Adam Zerella <adam.zerella(a)gmail.com>
> ---
> drivers/staging/android/ion/ion.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
> index e6b1ca141b93..17901bd626be 100644
> --- a/drivers/staging/android/ion/ion.c
> +++ b/drivers/staging/android/ion/ion.c
> @@ -433,8 +433,7 @@ static int ion_query_heaps(struct ion_heap_query *query)
> max_cnt = query->cnt;
>
> plist_for_each_entry(heap, &dev->heaps, node) {
> - strncpy(hdata.name, heap->name, MAX_HEAP_NAME);
> - hdata.name[sizeof(hdata.name) - 1] = '\0';
> + stracpy(hdata.name, heap->name, MAX_HEAP_NAME);
stracpy() only takes two arguments. This doesn't compile.
regards,
dan carpenter
This is the new dma_fence_array based container for shared fences in the dma_resv object.
Advantage of this approach is that you can grab a reference to the current set of shared fences at any time, which allows us to drop the sequence number increment and makes the whole RCU handling much more easier.
Disadvantage is that RCU users now have to grab a reference instead of using the sequence counter. As far as I can see i915 was actually the only driver doing this.
So we optimize for adding more fences instead of reading them now.
Another behavior change worth noting is that the shared fences are now only visible after unlocking the dma_resv object or calling dma_resv_fences_commit() manually.
Please review and/or comment,
Christian.
Hi everyone,
In previous discussion it surfaced that different drivers use the shared and explicit fences in the dma_resv object with different meanings.
This is problematic when we share buffers between those drivers and requirements for implicit and explicit synchronization leaded to quite a number of workarounds related to this.
So I started an effort to get all drivers back to a common understanding of what the fences in the dma_resv object mean and be able to use the object for different kind of workloads independent of the classic DRM command submission interface.
The result is this patch set which modifies the dma_resv API to get away from a single explicit fence and multiple shared fences, towards a notation where we have explicit categories for writers, readers and others.
To do this I came up with a new container called dma_resv_fences which can store both a single fence as well as multiple fences in a dma_fence_array.
This turned out to actually be even be quite a bit simpler, since we don't need any complicated dance between RCU and sequence count protected updates any more.
Instead we can just grab a reference to the dma_fence_array under RCU and so keep the current state of synchronization alive until we are done with it.
This results in both a small performance improvement since we don't need so many barriers any more, as well as fewer lines of code in the actual implementation.
Please review and/or comment,
Christian.