Report from 2013 ARM kernel summit

Will Deacon will.deacon at arm.com
Mon Nov 25 13:03:52 EST 2013


Hi Stephen,

On Thu, Nov 21, 2013 at 06:40:28PM +0000, Stephen Warren wrote:
> On 11/21/2013 04:00 AM, Will Deacon wrote:
> > On Wed, Nov 20, 2013 at 08:02:10PM +0000, Rob Herring wrote:
> >> For the topology above where you are chaining iommu's, I think
> >> something like this is more accurately describing the hierarchy:
> >>
> >>   smmu_b: iommu at xxxxxxxx {
> >>         #iommu-cells = <3>;
> >>          iommus = <&smmu_a param1 param2>;
> >>        ....
> >>   };
> >>   device_a {
> >>          iommus = <&smmu_b param1 param2 param3>;
> >>   };
> >>
> >> I remember discussing this with Will and seem to recall some issue
> >> with describing things this way. But looking at it now, I don't see
> >> what that was.
> > 
> > I think it was the usual issue with StreamID remastering. For example, if
>              ^^^ s/was/had/ I assume

Take your pick!

> > you had a device going into two chained IOMMUs, you need a way to relate the
> > StreamIDs of the device to the remastered IDs coming out of the first SMMU.
> 
> That seems pretty easy to deal with. Am I missing something. Here's how
> I assume that would work:
> 
> 1)
> 
> If the mapping is static in HW, then you simply have a table that
> describes the remapping. A table representation could be in the DT or
> the driver itself. Either way, any static mapping is a property of the
> HW itself, so shouldn't need to leak into the client DT nodes at all, right?
> 
> That might look like:
> 
> smmu_a: iommu at xxxxxxxx {
> 	#iommu-cells = <1>;
> };
> smmu_b: iommu at xxxxxxxx {
> 	#iommu-cells = <1>;
> 
> 	// a) All stream IDs squashed down to 1 ID
> 	iommus = <&smmu_a SMMU_B's_STREAM_ID_IN_SMMU_A>;
> 
> 	// OR b) stream IDs translated:
> 	iommus = <&smmu_a 0>,
> 		 <&smmu_a 1>,
> 		 <&smmu_a 2> ...;
> 	// this table could be in the driver instead
> 	iommu-stream-id-map =
> 		<DEV_A's_STREAM_ID_IN_SMMU_B 0>,
> 		<DEV_B's_STREAM_ID_IN_SMMU_B 1>,
> 		<DEV_C's_STREAM_ID_IN_SMMU_B 2>,

Actually, something like this could work. I think we should also support the
case where a range of IDs are `windowed' (i.e. there is a constant offset
applied to incoming IDs to get the outgoing IDs) to avoid huge tables in
some cases.

> };
> device_a {
> 	iommus = <&smmu_b DEV_A's_STREAM_ID_IN_SMMU_B>;
> };
> 
> or 2)
> 
> If the remapping is entirely dynamic, then you'd either need a table in
> the DT to describe how to set it up for the particular use-case (similar
> to the above), or a function in the driver to manage the mapping at
> run-time, probably hooked into the of_xlate() of the parent IOMMU, which
> would call into some function of the source IOMMU.
> 
> In other words, of_xlate for smmu_a would do both:
> 
> a) Parse the SMMU specifier in the client's iommus property
> 
> b) If the parse specifier represents a "dynamic stream ID device/IOMMU",
> call some function in the client driver to find out which stream ID(s)
> the parse iommus entry (specifier) represents.

Sure. We just need to get the binding right so we're prepared when these
platforms turn up. There's also the usual problem of continuing to support
what we already do for existing SMMU bindings.

Will



More information about the linux-arm-kernel mailing list