Re: [PATCH 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74

2017-05-04 Thread Jon Masters
On 05/03/2017 05:47 AM, Will Deacon wrote:
> Hi Geetha,
> 
> On Tue, May 02, 2017 at 12:01:15PM +0530, Geetha Akula wrote:
>> SMMU_IIDR register is broken on T99, that the reason we are using MIDR.
> 
> Urgh, that's unfortunate. In what way is it broken?
> 
>> If using MIDR is not accepted, can we enable errata based on SMMU resource 
>> size?
>> some thing like below.
> 
> No, you need to get your model number added to IORT after all if the IIDR
> can't uniqely identify the part.
> 
> Sorry

[I've pinged the IORT author directly with a copy of the above message]

Can folks please take action urgently if the IORT spec needs updating to
accommodate additional vendor IDs.

Jon.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 03/20] intel_iommu: add "svm" option

2017-05-04 Thread Raj, Ashok
On Thu, May 04, 2017 at 02:28:53PM -0600, Alex Williamson wrote:
> On Thu, 27 Apr 2017 18:53:17 +0800
> Peter Xu  wrote:
> 
> > On Wed, Apr 26, 2017 at 06:06:33PM +0800, Liu, Yi L wrote:
> > > Expose "Shared Virtual Memory" to guest by using "svm" option.
> > > Also use "svm" to expose SVM related capabilities to guest.
> > > e.g. "-device intel-iommu, svm=on"
> > > 
> > > Signed-off-by: Liu, Yi L 
> > > ---
> > >  hw/i386/intel_iommu.c  | 10 ++
> > >  hw/i386/intel_iommu_internal.h |  5 +
> > >  include/hw/i386/intel_iommu.h  |  1 +
> > >  3 files changed, 16 insertions(+)
> > > 
> > > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > > index bf98fa5..ba1e7eb 100644
> > > --- a/hw/i386/intel_iommu.c
> > > +++ b/hw/i386/intel_iommu.c
> > > @@ -2453,6 +2453,7 @@ static Property vtd_properties[] = {
> > >  DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false),
> > >  DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, 
> > > FALSE),
> > >  DEFINE_PROP_BOOL("ecs", IntelIOMMUState, ecs, FALSE),
> > > +DEFINE_PROP_BOOL("svm", IntelIOMMUState, svm, FALSE),
> > >  DEFINE_PROP_END_OF_LIST(),
> > >  };
> > >  
> > > @@ -2973,6 +2974,15 @@ static void vtd_init(IntelIOMMUState *s)
> > >  s->ecap |= VTD_ECAP_ECS;
> > >  }
> > >  
> > > +if (s->svm) {
> > > +if (!s->ecs || !x86_iommu->pt_supported || !s->caching_mode) {
> > > +error_report("Need to set ecs, pt, caching-mode for svm");
> > > +exit(1);
> > > +}
> > > +s->cap |= VTD_CAP_DWD | VTD_CAP_DRD;
> > > +s->ecap |= VTD_ECAP_PRS | VTD_ECAP_PTS | VTD_ECAP_PASID28;
> > > +}
> > > +
> > >  if (s->caching_mode) {
> > >  s->cap |= VTD_CAP_CM;
> > >  }
> > > diff --git a/hw/i386/intel_iommu_internal.h 
> > > b/hw/i386/intel_iommu_internal.h
> > > index 71a1c1e..f2a7d12 100644
> > > --- a/hw/i386/intel_iommu_internal.h
> > > +++ b/hw/i386/intel_iommu_internal.h
> > > @@ -191,6 +191,9 @@
> > >  #define VTD_ECAP_PT (1ULL << 6)
> > >  #define VTD_ECAP_MHMV   (15ULL << 20)
> > >  #define VTD_ECAP_ECS(1ULL << 24)
> > > +#define VTD_ECAP_PASID28(1ULL << 28)  
> > 
> > Could I ask what's this bit? On my spec, it says this bit is reserved
> > and defunct (spec version: June 2016).
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d42fde70849c5ba2f00c37a0666305eb507a47b8
> 
> Do we really need to emulate the buggy implementation?  Seems like we
> could just pretend bit28 never happened here and use bit40 instead.
> 

Agree, bit28 can be gone.  
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 03/20] intel_iommu: add "svm" option

2017-05-04 Thread Alex Williamson
On Thu, 27 Apr 2017 18:53:17 +0800
Peter Xu  wrote:

> On Wed, Apr 26, 2017 at 06:06:33PM +0800, Liu, Yi L wrote:
> > Expose "Shared Virtual Memory" to guest by using "svm" option.
> > Also use "svm" to expose SVM related capabilities to guest.
> > e.g. "-device intel-iommu, svm=on"
> > 
> > Signed-off-by: Liu, Yi L 
> > ---
> >  hw/i386/intel_iommu.c  | 10 ++
> >  hw/i386/intel_iommu_internal.h |  5 +
> >  include/hw/i386/intel_iommu.h  |  1 +
> >  3 files changed, 16 insertions(+)
> > 
> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > index bf98fa5..ba1e7eb 100644
> > --- a/hw/i386/intel_iommu.c
> > +++ b/hw/i386/intel_iommu.c
> > @@ -2453,6 +2453,7 @@ static Property vtd_properties[] = {
> >  DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false),
> >  DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),
> >  DEFINE_PROP_BOOL("ecs", IntelIOMMUState, ecs, FALSE),
> > +DEFINE_PROP_BOOL("svm", IntelIOMMUState, svm, FALSE),
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> >  
> > @@ -2973,6 +2974,15 @@ static void vtd_init(IntelIOMMUState *s)
> >  s->ecap |= VTD_ECAP_ECS;
> >  }
> >  
> > +if (s->svm) {
> > +if (!s->ecs || !x86_iommu->pt_supported || !s->caching_mode) {
> > +error_report("Need to set ecs, pt, caching-mode for svm");
> > +exit(1);
> > +}
> > +s->cap |= VTD_CAP_DWD | VTD_CAP_DRD;
> > +s->ecap |= VTD_ECAP_PRS | VTD_ECAP_PTS | VTD_ECAP_PASID28;
> > +}
> > +
> >  if (s->caching_mode) {
> >  s->cap |= VTD_CAP_CM;
> >  }
> > diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
> > index 71a1c1e..f2a7d12 100644
> > --- a/hw/i386/intel_iommu_internal.h
> > +++ b/hw/i386/intel_iommu_internal.h
> > @@ -191,6 +191,9 @@
> >  #define VTD_ECAP_PT (1ULL << 6)
> >  #define VTD_ECAP_MHMV   (15ULL << 20)
> >  #define VTD_ECAP_ECS(1ULL << 24)
> > +#define VTD_ECAP_PASID28(1ULL << 28)  
> 
> Could I ask what's this bit? On my spec, it says this bit is reserved
> and defunct (spec version: June 2016).

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d42fde70849c5ba2f00c37a0666305eb507a47b8

Do we really need to emulate the buggy implementation?  Seems like we
could just pretend bit28 never happened here and use bit40 instead.

> 
> > +#define VTD_ECAP_PRS(1ULL << 29)
> > +#define VTD_ECAP_PTS(0xeULL << 35)  
> 
> Would it better we avoid using 0xe here, or at least add some comment?
> 
> >  
> >  /* CAP_REG */
> >  /* (offset >> 4) << 24 */
> > @@ -207,6 +210,8 @@
> >  #define VTD_CAP_PSI (1ULL << 39)
> >  #define VTD_CAP_SLLPS   ((1ULL << 34) | (1ULL << 35))
> >  #define VTD_CAP_CM  (1ULL << 7)
> > +#define VTD_CAP_DWD (1ULL << 54)
> > +#define VTD_CAP_DRD (1ULL << 55)  
> 
> Just to confirm: after this series, we should support drain read/write
> then, right?
> 
> Thanks,
> 
> >  
> >  /* Supported Adjusted Guest Address Widths */
> >  #define VTD_CAP_SAGAW_SHIFT 8
> > diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
> > index ae21fe5..8981615 100644
> > --- a/include/hw/i386/intel_iommu.h
> > +++ b/include/hw/i386/intel_iommu.h
> > @@ -267,6 +267,7 @@ struct IntelIOMMUState {
> >  
> >  bool caching_mode;  /* RO - is cap CM enabled? */
> >  bool ecs;   /* Extended Context Support */
> > +bool svm;   /* Shared Virtual Memory */
> >  
> >  dma_addr_t root;/* Current root table pointer */
> >  bool root_extended; /* Type of root table (extended or 
> > not) */
> > -- 
> > 1.9.1
> >   
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/3] of/pci/dma: fix DMA configuration for PCI masters

2017-05-04 Thread Oza Oza via iommu
On Thu, May 4, 2017 at 11:32 PM, Robin Murphy  wrote:
> [apologies for the silence - I've been on holiday]
>
> On 03/05/17 05:46, Oza Pawandeep wrote:
>> current device framework and of framework integration assumes
>> dma-ranges in a way where memory-mapped devices define their
>> dma-ranges. (child-bus-address, parent-bus-address, length).
>
> Well, yes, that is simply the definition of dma-ranges, and remains true
> regardless of the particular format of either bus address.
>
>> of_dma_configure is specifically written to take care of memory
>> mapped devices. but no implementation exists for pci to take
>> care of pcie based memory ranges.
>
> That still doesn't make sense. To repeat myself again, PCI devices *ARE*
> memory-mapped devices. Yes, there do exist some platforms where I/O
> space is not treated as MMIO, but config space and memory space are very
> much memory-mapped however you look at them, and in the context of DMA,
> only memory space is relevant anyway.
>
> What *is* true about the current code is that of_dma_get_range() expects
> to be passed an OF node representing the device itself, and doesn't work
> properly when passed the node of the device's parent bus directly, which
> happens to be what pci_dma_configure() currently does. That's the only
> reason why it doesn't work for (single-entry) host controller dma-ranges
> today. This does not mean it's a PCI problem, it is simply the case that
> pci_dma_configure() is the only caller currently hitting it. Other
> discoverable, DMA-capable buses like fsl-mc are still going to face the
> exact same problem with or without this patch.
>

the new v2 is hooking callbacks for defualt and pci bus.
so now the implementation will not really look cluttered.
and for fsl-mc buses, we could choose to implement it in default bus callbacks.
will post the patch-set soon.

also with these patch-set we really do not need to prepare emulated child node.


>> for e.g. iproc based SOCs and other SOCs(suc as rcar) have PCI
>> world dma-ranges.
>> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
>>
>> this patch serves following:
>>
>> 1) exposes interface to the pci host driver for their
>> inbound memory ranges
>>
>> 2) provide an interface to callers such as of_dma_get_ranges.
>> so then the returned size get best possible (largest) dma_mask.
>> because PCI RC drivers do not call APIs such as
>> dma_set_coherent_mask() and hence rather it shows its addressing
>> capabilities based on dma-ranges.
>> for e.g.
>> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
>> we should get dev->coherent_dma_mask=0x7f.
>>
>> 3) this patch handles multiple inbound windows and dma-ranges.
>> it is left to the caller, how it wants to use them.
>> the new function returns the resources in a standard and unform way
>>
>> 4) this way the callers of for e.g. of_dma_get_ranges
>> does not need to change.
>>
>> 5) leaves scope of adding PCI flag handling for inbound memory
>> by the new function.
>
> Which flags would ever actually matter? DMA windows aren't going to be
> to config or I/O space, so the memory type can be assumed, and the
> 32/64-bit distinction is irrelevant as it's not a relocatable BAR;
> DMA-able system memory isn't going to be read-sensitive, so the
> prefetchable flag shouldn't matter; and not being a BAR none of the
> others would be relevant either.
>
>>
>> Bug: SOC-5216
>> Change-Id: Ie045386df91e1e0587846bb147ae40d96f6d7d2e
>> Signed-off-by: Oza Pawandeep 
>> Reviewed-on: http://gerrit-ccxsw.broadcom.net/40428
>> Reviewed-by: vpx_checkpatch status 
>> Reviewed-by: CCXSW 
>> Reviewed-by: Ray Jui 
>> Tested-by: vpx_autobuild status 
>> Tested-by: vpx_smoketest status 
>> Tested-by: CCXSW 
>> Reviewed-by: Scott Branden 
>>
>> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> index 0ee42c3..ed6e69a 100644
>> --- a/drivers/of/of_pci.c
>> +++ b/drivers/of/of_pci.c
>> @@ -283,6 +283,83 @@ int of_pci_get_host_bridge_resources(struct device_node 
>> *dev,
>>   return err;
>>  }
>>  EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
>> +
>> +/**
>> + * of_pci_get_dma_ranges - Parse PCI host bridge inbound resources from DT
>> + * @np: device node of the host bridge having the dma-ranges property
>> + * @resources: list where the range of resources will be added after DT 
>> parsing
>> + *
>> + * It is the caller's job to free the @resources list.
>> + *
>> + * This function will parse the "dma-ranges" property of a
>> + * PCI host bridge device node and setup the resource mapping based
>> + * on its content.
>> + *
>> + * It returns zero if the range parsing has been successful or a standard 
>> error
>> + * value if it failed.
>> + */
>> +
>> +int of_pci_get_dma_ranges(struct device_node *np, struct 

Re: [PATCH 2/3] iommu/pci: reserve iova for PCI masters

2017-05-04 Thread Oza Oza via iommu
On Thu, May 4, 2017 at 11:50 PM, Robin Murphy  wrote:
> On 03/05/17 05:46, Oza Pawandeep wrote:
>> this patch reserves the iova for PCI masters.
>> ARM64 based SOCs may have scattered memory banks.
>> such as iproc based SOC has
>>
>> <0x 0x8000 0x0 0x8000>, /* 2G @ 2G */
>> <0x0008 0x8000 0x3 0x8000>, /* 14G @ 34G */
>> <0x0090 0x 0x4 0x>, /* 16G @ 576G */
>> <0x00a0 0x 0x4 0x>; /* 16G @ 640G */
>>
>> but incoming PCI transcation addressing capability is limited
>> by host bridge, for example if max incoming window capability
>> is 512 GB, then 0x0090 and 0x00a0 will fall beyond it.
>>
>> to address this problem, iommu has to avoid allocating iovas which
>> are reserved. which inturn does not allocate iova if it falls into hole.
>
> I don't necessarily disagree with doing this, as we could do with facing
> up to the issue of discontiguous DMA ranges in particular (I too have a
> platform with this problem), but I'm still not overly keen on pulling DT
> specifics into this layer. More than that, though, if we are going to do
> it, then we should do it for all devices with a restrictive
> "dma-ranges", not just PCI ones.
>

How do you propose to do it ?

my thinking is this:
iova_reserve_pci_windows is written specific for PCI, and I am adding there.

ideally
struct pci_host_bridge should have new member:

struct list_head inbound_windows; /* resource_entry */

but somehow this resource have to be filled much before
iommu_dma_init_domain happens.
and use brdge resource directly in iova_reserve_pci_windows as it is
already doing it for outbound memory.

this will detach the DT specifics from dma-immu layer.
let me know how this sounds.


>> Bug: SOC-5216
>> Change-Id: Icbfc99a045d730be143fef427098c937b9d46353
>> Signed-off-by: Oza Pawandeep 
>> Reviewed-on: http://gerrit-ccxsw.broadcom.net/40760
>> Reviewed-by: vpx_checkpatch status 
>> Reviewed-by: CCXSW 
>> Tested-by: vpx_autobuild status 
>> Tested-by: vpx_smoketest status 
>> Tested-by: CCXSW 
>> Reviewed-by: Scott Branden 
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>> index 48d36ce..08764b0 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -27,6 +27,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -171,8 +172,12 @@ static void iova_reserve_pci_windows(struct pci_dev 
>> *dev,
>>   struct iova_domain *iovad)
>>  {
>>   struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
>> + struct device_node *np = bridge->dev.parent->of_node;
>>   struct resource_entry *window;
>>   unsigned long lo, hi;
>> + int ret;
>> + dma_addr_t tmp_dma_addr = 0, dma_addr;
>> + LIST_HEAD(res);
>>
>>   resource_list_for_each_entry(window, >windows) {
>>   if (resource_type(window->res) != IORESOURCE_MEM &&
>> @@ -183,6 +188,36 @@ static void iova_reserve_pci_windows(struct pci_dev 
>> *dev,
>>   hi = iova_pfn(iovad, window->res->end - window->offset);
>>   reserve_iova(iovad, lo, hi);
>>   }
>> +
>> + /* PCI inbound memory reservation. */
>> + ret = of_pci_get_dma_ranges(np, );
>> + if (!ret) {
>> + resource_list_for_each_entry(window, ) {
>> + struct resource *res_dma = window->res;
>> +
>> + dma_addr = res_dma->start - window->offset;
>> + if (tmp_dma_addr > dma_addr) {
>> + pr_warn("PCI: failed to reserve iovas; ranges 
>> should be sorted\n");
>
> I don't see anything in the DT spec about the entries having to be
> sorted, and it's not exactly impossible to sort a list if you need it so
> (and if I'm being really pedantic, one could still trigger this with a
> list that *is* sorted, only by different criteria).
>

we have to sort it the way we want then. I can make it sort then.
thanks for the suggestion.

> Robin.
>
>> + return;
>> + }
>> + if (tmp_dma_addr != dma_addr) {
>> + lo = iova_pfn(iovad, tmp_dma_addr);
>> + hi = iova_pfn(iovad, dma_addr - 1);
>> + reserve_iova(iovad, lo, hi);
>> + }
>> + tmp_dma_addr = window->res->end - window->offset;
>> + }
>> + /*
>> +  * the last dma-range should honour based on the
>> +  * 32/64-bit dma addresses.
>> +  */
>> + if (tmp_dma_addr < DMA_BIT_MASK(sizeof(dma_addr_t) * 8)) {
>> + lo = iova_pfn(iovad, tmp_dma_addr);
>> + hi = 

Re: [PATCH 1/3] of/pci/dma: fix DMA configuration for PCI masters

2017-05-04 Thread Oza Oza via iommu
On Thu, May 4, 2017 at 11:32 PM, Robin Murphy  wrote:
> [apologies for the silence - I've been on holiday]
>
> On 03/05/17 05:46, Oza Pawandeep wrote:
>> current device framework and of framework integration assumes
>> dma-ranges in a way where memory-mapped devices define their
>> dma-ranges. (child-bus-address, parent-bus-address, length).
>
> Well, yes, that is simply the definition of dma-ranges, and remains true
> regardless of the particular format of either bus address.
>
>> of_dma_configure is specifically written to take care of memory
>> mapped devices. but no implementation exists for pci to take
>> care of pcie based memory ranges.
>
> That still doesn't make sense. To repeat myself again, PCI devices *ARE*
> memory-mapped devices. Yes, there do exist some platforms where I/O
> space is not treated as MMIO, but config space and memory space are very
> much memory-mapped however you look at them, and in the context of DMA,
> only memory space is relevant anyway.
>
> What *is* true about the current code is that of_dma_get_range() expects
> to be passed an OF node representing the device itself, and doesn't work
> properly when passed the node of the device's parent bus directly, which
> happens to be what pci_dma_configure() currently does. That's the only
> reason why it doesn't work for (single-entry) host controller dma-ranges
> today. This does not mean it's a PCI problem, it is simply the case that
> pci_dma_configure() is the only caller currently hitting it. Other
> discoverable, DMA-capable buses like fsl-mc are still going to face the
> exact same problem with or without this patch.
>
>> for e.g. iproc based SOCs and other SOCs(suc as rcar) have PCI
>> world dma-ranges.
>> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
>>
>> this patch serves following:
>>
>> 1) exposes interface to the pci host driver for their
>> inbound memory ranges
>>
>> 2) provide an interface to callers such as of_dma_get_ranges.
>> so then the returned size get best possible (largest) dma_mask.
>> because PCI RC drivers do not call APIs such as
>> dma_set_coherent_mask() and hence rather it shows its addressing
>> capabilities based on dma-ranges.
>> for e.g.
>> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
>> we should get dev->coherent_dma_mask=0x7f.
>>
>> 3) this patch handles multiple inbound windows and dma-ranges.
>> it is left to the caller, how it wants to use them.
>> the new function returns the resources in a standard and unform way
>>
>> 4) this way the callers of for e.g. of_dma_get_ranges
>> does not need to change.
>>
>> 5) leaves scope of adding PCI flag handling for inbound memory
>> by the new function.
>
> Which flags would ever actually matter? DMA windows aren't going to be
> to config or I/O space, so the memory type can be assumed, and the
> 32/64-bit distinction is irrelevant as it's not a relocatable BAR;
> DMA-able system memory isn't going to be read-sensitive, so the
> prefetchable flag shouldn't matter; and not being a BAR none of the
> others would be relevant either.
>

Thanks Robin; for your reply and attention:

agree with you, at present it would not matter,
but it does not mean that we do not scope it to make it matter in future.

now where it could matter:
there is Relaxed Ordering for inbound memory for PCI.
According to standard, Relaxed Ordering (RO) bit can be set only for
Memory requests and completions (if present in the original request).
Also, according to transaction ordering rules, I/O and configuration
requests can still be re-ordered ahead of each other.
and we would like to make use of it.
for e.g. lets say we mark memory as Relaxed Ordered with flag.
the special about this memory is incoming PCI transactions can be
reordered and rest memory has to be strongly ordered.

how it our SOC would make use of this is out of scope for the
discussion at this point of time, but I am just bringing in the
idea/point how flags could be useful
for inbound memory, since we would not like throw-away flags completely.

>>
>> Bug: SOC-5216
>> Change-Id: Ie045386df91e1e0587846bb147ae40d96f6d7d2e
>> Signed-off-by: Oza Pawandeep 
>> Reviewed-on: http://gerrit-ccxsw.broadcom.net/40428
>> Reviewed-by: vpx_checkpatch status 
>> Reviewed-by: CCXSW 
>> Reviewed-by: Ray Jui 
>> Tested-by: vpx_autobuild status 
>> Tested-by: vpx_smoketest status 
>> Tested-by: CCXSW 
>> Reviewed-by: Scott Branden 
>>
>> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> index 0ee42c3..ed6e69a 100644
>> --- a/drivers/of/of_pci.c
>> +++ b/drivers/of/of_pci.c
>> @@ -283,6 +283,83 @@ int of_pci_get_host_bridge_resources(struct device_node 
>> *dev,
>>   return err;
>>  }
>>  EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
>> +
>> +/**
>> + * 

Re: [PATCH 2/3] iommu/pci: reserve iova for PCI masters

2017-05-04 Thread Robin Murphy
On 03/05/17 05:46, Oza Pawandeep wrote:
> this patch reserves the iova for PCI masters.
> ARM64 based SOCs may have scattered memory banks.
> such as iproc based SOC has
> 
> <0x 0x8000 0x0 0x8000>, /* 2G @ 2G */
> <0x0008 0x8000 0x3 0x8000>, /* 14G @ 34G */
> <0x0090 0x 0x4 0x>, /* 16G @ 576G */
> <0x00a0 0x 0x4 0x>; /* 16G @ 640G */
> 
> but incoming PCI transcation addressing capability is limited
> by host bridge, for example if max incoming window capability
> is 512 GB, then 0x0090 and 0x00a0 will fall beyond it.
> 
> to address this problem, iommu has to avoid allocating iovas which
> are reserved. which inturn does not allocate iova if it falls into hole.

I don't necessarily disagree with doing this, as we could do with facing
up to the issue of discontiguous DMA ranges in particular (I too have a
platform with this problem), but I'm still not overly keen on pulling DT
specifics into this layer. More than that, though, if we are going to do
it, then we should do it for all devices with a restrictive
"dma-ranges", not just PCI ones.

> Bug: SOC-5216
> Change-Id: Icbfc99a045d730be143fef427098c937b9d46353
> Signed-off-by: Oza Pawandeep 
> Reviewed-on: http://gerrit-ccxsw.broadcom.net/40760
> Reviewed-by: vpx_checkpatch status 
> Reviewed-by: CCXSW 
> Tested-by: vpx_autobuild status 
> Tested-by: vpx_smoketest status 
> Tested-by: CCXSW 
> Reviewed-by: Scott Branden 
> 
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 48d36ce..08764b0 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -27,6 +27,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -171,8 +172,12 @@ static void iova_reserve_pci_windows(struct pci_dev *dev,
>   struct iova_domain *iovad)
>  {
>   struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
> + struct device_node *np = bridge->dev.parent->of_node;
>   struct resource_entry *window;
>   unsigned long lo, hi;
> + int ret;
> + dma_addr_t tmp_dma_addr = 0, dma_addr;
> + LIST_HEAD(res);
>  
>   resource_list_for_each_entry(window, >windows) {
>   if (resource_type(window->res) != IORESOURCE_MEM &&
> @@ -183,6 +188,36 @@ static void iova_reserve_pci_windows(struct pci_dev *dev,
>   hi = iova_pfn(iovad, window->res->end - window->offset);
>   reserve_iova(iovad, lo, hi);
>   }
> +
> + /* PCI inbound memory reservation. */
> + ret = of_pci_get_dma_ranges(np, );
> + if (!ret) {
> + resource_list_for_each_entry(window, ) {
> + struct resource *res_dma = window->res;
> +
> + dma_addr = res_dma->start - window->offset;
> + if (tmp_dma_addr > dma_addr) {
> + pr_warn("PCI: failed to reserve iovas; ranges 
> should be sorted\n");

I don't see anything in the DT spec about the entries having to be
sorted, and it's not exactly impossible to sort a list if you need it so
(and if I'm being really pedantic, one could still trigger this with a
list that *is* sorted, only by different criteria).

Robin.

> + return;
> + }
> + if (tmp_dma_addr != dma_addr) {
> + lo = iova_pfn(iovad, tmp_dma_addr);
> + hi = iova_pfn(iovad, dma_addr - 1);
> + reserve_iova(iovad, lo, hi);
> + }
> + tmp_dma_addr = window->res->end - window->offset;
> + }
> + /*
> +  * the last dma-range should honour based on the
> +  * 32/64-bit dma addresses.
> +  */
> + if (tmp_dma_addr < DMA_BIT_MASK(sizeof(dma_addr_t) * 8)) {
> + lo = iova_pfn(iovad, tmp_dma_addr);
> + hi = iova_pfn(iovad,
> +   DMA_BIT_MASK(sizeof(dma_addr_t) * 8) - 1);
> + reserve_iova(iovad, lo, hi);
> + }
> + }
>  }
>  
>  /**
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/3] of/pci/dma: fix DMA configuration for PCI masters

2017-05-04 Thread Robin Murphy
[apologies for the silence - I've been on holiday]

On 03/05/17 05:46, Oza Pawandeep wrote:
> current device framework and of framework integration assumes
> dma-ranges in a way where memory-mapped devices define their
> dma-ranges. (child-bus-address, parent-bus-address, length).

Well, yes, that is simply the definition of dma-ranges, and remains true
regardless of the particular format of either bus address.

> of_dma_configure is specifically written to take care of memory
> mapped devices. but no implementation exists for pci to take
> care of pcie based memory ranges.

That still doesn't make sense. To repeat myself again, PCI devices *ARE*
memory-mapped devices. Yes, there do exist some platforms where I/O
space is not treated as MMIO, but config space and memory space are very
much memory-mapped however you look at them, and in the context of DMA,
only memory space is relevant anyway.

What *is* true about the current code is that of_dma_get_range() expects
to be passed an OF node representing the device itself, and doesn't work
properly when passed the node of the device's parent bus directly, which
happens to be what pci_dma_configure() currently does. That's the only
reason why it doesn't work for (single-entry) host controller dma-ranges
today. This does not mean it's a PCI problem, it is simply the case that
pci_dma_configure() is the only caller currently hitting it. Other
discoverable, DMA-capable buses like fsl-mc are still going to face the
exact same problem with or without this patch.

> for e.g. iproc based SOCs and other SOCs(suc as rcar) have PCI
> world dma-ranges.
> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
> 
> this patch serves following:
> 
> 1) exposes interface to the pci host driver for their
> inbound memory ranges
> 
> 2) provide an interface to callers such as of_dma_get_ranges.
> so then the returned size get best possible (largest) dma_mask.
> because PCI RC drivers do not call APIs such as
> dma_set_coherent_mask() and hence rather it shows its addressing
> capabilities based on dma-ranges.
> for e.g.
> dma-ranges = <0x4300 0x00 0x00 0x00 0x00 0x80 0x00>;
> we should get dev->coherent_dma_mask=0x7f.
> 
> 3) this patch handles multiple inbound windows and dma-ranges.
> it is left to the caller, how it wants to use them.
> the new function returns the resources in a standard and unform way
> 
> 4) this way the callers of for e.g. of_dma_get_ranges
> does not need to change.
> 
> 5) leaves scope of adding PCI flag handling for inbound memory
> by the new function.

Which flags would ever actually matter? DMA windows aren't going to be
to config or I/O space, so the memory type can be assumed, and the
32/64-bit distinction is irrelevant as it's not a relocatable BAR;
DMA-able system memory isn't going to be read-sensitive, so the
prefetchable flag shouldn't matter; and not being a BAR none of the
others would be relevant either.

> 
> Bug: SOC-5216
> Change-Id: Ie045386df91e1e0587846bb147ae40d96f6d7d2e
> Signed-off-by: Oza Pawandeep 
> Reviewed-on: http://gerrit-ccxsw.broadcom.net/40428
> Reviewed-by: vpx_checkpatch status 
> Reviewed-by: CCXSW 
> Reviewed-by: Ray Jui 
> Tested-by: vpx_autobuild status 
> Tested-by: vpx_smoketest status 
> Tested-by: CCXSW 
> Reviewed-by: Scott Branden 
> 
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 0ee42c3..ed6e69a 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -283,6 +283,83 @@ int of_pci_get_host_bridge_resources(struct device_node 
> *dev,
>   return err;
>  }
>  EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> +
> +/**
> + * of_pci_get_dma_ranges - Parse PCI host bridge inbound resources from DT
> + * @np: device node of the host bridge having the dma-ranges property
> + * @resources: list where the range of resources will be added after DT 
> parsing
> + *
> + * It is the caller's job to free the @resources list.
> + *
> + * This function will parse the "dma-ranges" property of a
> + * PCI host bridge device node and setup the resource mapping based
> + * on its content.
> + *
> + * It returns zero if the range parsing has been successful or a standard 
> error
> + * value if it failed.
> + */
> +
> +int of_pci_get_dma_ranges(struct device_node *np, struct list_head 
> *resources)
> +{
> + struct device_node *node = of_node_get(np);
> + int rlen;
> + int ret = 0;
> + const int na = 3, ns = 2;
> + struct resource *res;
> + struct of_pci_range_parser parser;
> + struct of_pci_range range;
> +
> + if (!node)
> + return -EINVAL;
> +
> + parser.node = node;
> + parser.pna = of_n_addr_cells(node);
> + parser.np = parser.pna + na + ns;
> +
> + parser.range = of_get_property(node, "dma-ranges", );
> +
> 

Re: [PATCH v5 09/32] x86/mm: Provide general kernel support for memory encryption

2017-05-04 Thread Borislav Petkov
On Thu, May 04, 2017 at 09:34:09AM -0500, Tom Lendacky wrote:
> I masked it out here based on a previous comment from Dave Hansen:
> 
>   http://marc.info/?l=linux-kernel=148778719826905=2
> 
> I could move the __sme_clr into the individual defines of:

Nah, it is fine as it is. I was just wondering...

Thanks.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 1/7] iommu/arm-smmu-v3: Introduce SMMU option PAGE0_REGS_ONLY

2017-05-04 Thread Mark Rutland
On Thu, May 04, 2017 at 06:05:33PM +0530, Geetha sowjanya wrote:
> From: Linu Cherian 
> 
> Cavium ThunderX2 SMMU implementation doesn't support page 1 register space
> and PAGE0_REGS_ONLY option will be enabled as an errata workaround.
> 
> This option when turned on, replaces all page 1 offsets used for
> EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets.
> 
> Signed-off-by: Linu Cherian 
> Signed-off-by: Geetha Sowjanya 
> ---
>  drivers/iommu/arm-smmu-v3.c | 44 
>  1 file changed, 32 insertions(+), 12 deletions(-)

>  static struct arm_smmu_option_prop arm_smmu_options[] = {

> + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"},

No patch in this series documented the new property.

Please update Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt,
with a description of the property. i.e. what it describes, and when it
should be set.

Please either make that a prepatory path, or merge it in with this one.

Thanksm
Mark.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Benjamin Tissoires
On May 04 2017 or thereabouts, Andy Shevchenko wrote:
> acpi_evaluate_dsm() and friends take a pointer to a raw buffer of 16
> bytes. Instead we convert them to use uuid_le type. At the same time we
> convert current users.
> 
> acpi_str_to_uuid() becomes useless after the conversion and it's safe to
> get rid of it.
> 
> The conversion fixes a potential bug in int340x_thermal as well since
> we have to use memcmp() on binary data.
> 
> Cc: Rafael J. Wysocki 
> Cc: Mika Westerberg 
> Cc: Borislav Petkov 
> Cc: Dan Williams 
> Cc: Amir Goldstein 
> Cc: Jarkko Sakkinen 
> Cc: Jani Nikula 
> Cc: Ben Skeggs 
> Cc: Benjamin Tissoires 
> Cc: Joerg Roedel 
> Cc: Adrian Hunter 
> Cc: Yisen Zhuang 
> Cc: Bjorn Helgaas 
> Cc: Zhang Rui 
> Cc: Felipe Balbi 
> Cc: Mathias Nyman 
> Cc: Heikki Krogerus 
> Cc: Liam Girdwood 
> Cc: Mark Brown 
> Signed-off-by: Andy Shevchenko 
> ---

For i2c-hid:
Acked-by: Benjamin Tissoires 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 12/32] x86/mm: Insure that boot memory areas are mapped properly

2017-05-04 Thread Tom Lendacky

On 5/4/2017 5:16 AM, Borislav Petkov wrote:

On Tue, Apr 18, 2017 at 04:18:22PM -0500, Tom Lendacky wrote:

The boot data and command line data are present in memory in a decrypted
state and are copied early in the boot process.  The early page fault
support will map these areas as encrypted, so before attempting to copy
them, add decrypted mappings so the data is accessed properly when copied.

For the initrd, encrypt this data in place. Since the future mapping of the
initrd area will be mapped as encrypted the data will be accessed properly.

Signed-off-by: Tom Lendacky 
---
 arch/x86/include/asm/mem_encrypt.h |   11 +
 arch/x86/include/asm/pgtable.h |3 +
 arch/x86/kernel/head64.c   |   30 --
 arch/x86/kernel/setup.c|   10 +
 arch/x86/mm/mem_encrypt.c  |   77 
 5 files changed, 127 insertions(+), 4 deletions(-)


...


diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 603a166..a95800b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -115,6 +115,7 @@
 #include 
 #include 
 #include 
+#include 

 /*
  * max_low_pfn_mapped: highest direct mapped pfn under 4GB
@@ -374,6 +375,15 @@ static void __init reserve_initrd(void)
!ramdisk_image || !ramdisk_size)
return; /* No initrd provided by bootloader */

+   /*
+* If SME is active, this memory will be marked encrypted by the
+* kernel when it is accessed (including relocation). However, the
+* ramdisk image was loaded decrypted by the bootloader, so make
+* sure that it is encrypted before accessing it.
+*/
+   if (sme_active())


That test is not needed here because __sme_early_enc_dec() already tests
sme_me_mask. There you should change that test to sme_active() instead.


Yeah, I was probably thinking slightly ahead to SEV where the initrd
will already be encrypted and so we only want to do this for SME.
That change can come in the SEV support patches, though.

Thanks,
Tom




+   sme_early_encrypt(ramdisk_image, ramdisk_end - ramdisk_image);
+
initrd_start = 0;

mapped_size = memblock_mem_size(max_pfn_mapped);



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 06/32] x86/mm: Add Secure Memory Encryption (SME) support

2017-05-04 Thread Borislav Petkov
On Thu, May 04, 2017 at 09:24:11AM -0500, Tom Lendacky wrote:
> I did this so that an the include order wouldn't cause issues (including
> asm/mem_encrypt.h followed by later by a linux/mem_encrypt.h include).
> I can make this a bit clearer by having separate #defines for each
> thing, e.g.:
> 
> #ifndef sme_me_mask
> #define sme_me_mask 0UL
> #endif
> 
> #ifndef sme_active
> #define sme_active sme_active
> static inline ...
> #endif
> 
> Is that better/clearer?

I guess but where do we have to include both the asm/ and the linux/
version?

IOW, can we avoid these issues altogether by partitioning symbol
declarations differently among the headers?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 09/32] x86/mm: Provide general kernel support for memory encryption

2017-05-04 Thread Tom Lendacky



On 4/27/2017 11:12 AM, Borislav Petkov wrote:

On Tue, Apr 18, 2017 at 04:17:54PM -0500, Tom Lendacky wrote:

Changes to the existing page table macros will allow the SME support to
be enabled in a simple fashion with minimal changes to files that use these
macros.  Since the memory encryption mask will now be part of the regular
pagetable macros, we introduce two new macros (_PAGE_TABLE_NOENC and
_KERNPG_TABLE_NOENC) to allow for early pagetable creation/initialization
without the encryption mask before SME becomes active.  Two new pgprot()
macros are defined to allow setting or clearing the page encryption mask.


...


@@ -55,7 +57,7 @@ static inline void copy_user_page(void *to, void *from, 
unsigned long vaddr,
__phys_addr_symbol(__phys_reloc_hide((unsigned long)(x)))

 #ifndef __va
-#define __va(x)((void *)((unsigned 
long)(x)+PAGE_OFFSET))
+#define __va(x)((void *)(__sme_clr(x) + PAGE_OFFSET))
 #endif

 #define __boot_va(x)   __va(x)
diff --git a/arch/x86/include/asm/page_types.h 
b/arch/x86/include/asm/page_types.h
index 7bd0099..fead0a5 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -15,7 +15,7 @@
 #define PUD_PAGE_SIZE  (_AC(1, UL) << PUD_SHIFT)
 #define PUD_PAGE_MASK  (~(PUD_PAGE_SIZE-1))

-#define __PHYSICAL_MASK((phys_addr_t)((1ULL << 
__PHYSICAL_MASK_SHIFT) - 1))
+#define __PHYSICAL_MASK((phys_addr_t)(__sme_clr((1ULL << 
__PHYSICAL_MASK_SHIFT) - 1)))


That looks strange: poking SME mask hole into a mask...?


I masked it out here based on a previous comment from Dave Hansen:

  http://marc.info/?l=linux-kernel=148778719826905=2

I could move the __sme_clr into the individual defines of:

PHYSICAL_PAGE_MASK, PHYSICAL_PMD_PAGE_MASK and PHYSICAL_PUD_PAGE_MASK

Either way works for me.

Thanks,
Tom




 #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)

 /* Cast *PAGE_MASK to a signed type so that it is sign-extended if



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/4] iommu: add qcom_iommu

2017-05-04 Thread Rob Herring
On Thu, May 4, 2017 at 8:34 AM, Rob Clark  wrote:
> An iommu driver for Qualcomm "B" family devices which do not completely
> implement the ARM SMMU spec.  These devices have context-bank register
> layout that is similar to ARM SMMU, but no global register space (or at
> least not one that is accessible).
>
> Signed-off-by: Rob Clark 
> Signed-off-by: Stanimir Varbanov 
> ---
>  drivers/iommu/Kconfig  |  10 +
>  drivers/iommu/Makefile |   1 +
>  drivers/iommu/qcom_iommu.c | 825 
> +
>  3 files changed, 836 insertions(+)
>  create mode 100644 drivers/iommu/qcom_iommu.c
>
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 37e204f..400a404 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -359,4 +359,14 @@ config MTK_IOMMU_V1
>
>   if unsure, say N here.
>
> +config QCOM_IOMMU
> +   bool "Qualcomm IOMMU Support"
> +   depends on ARM || ARM64

This is redundant as you have ARCH_QCOM

> +   depends on ARCH_QCOM || COMPILE_TEST
> +   select IOMMU_API
> +   select IOMMU_IO_PGTABLE_LPAE
> +   select ARM_DMA_USE_IOMMU
> +   help
> + Support for IOMMU on certain Qualcomm SoCs.
> +
>  endif # IOMMU_SUPPORT
> diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> index 195f7b9..b910aea 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -27,3 +27,4 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
>  obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
>  obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
>  obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
> +obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
> diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
> new file mode 100644
> index 000..1cf7c8e
> --- /dev/null
> +++ b/drivers/iommu/qcom_iommu.c
> @@ -0,0 +1,825 @@
> +/*
> + * IOMMU API for QCOM secure IOMMUs.  Somewhat based on arm-smmu.c
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

Don't put FSF address in.

> + *
> + * Copyright (C) 2013 ARM Limited
> + * Copyright (C) 2017 Red Hat
> + */
> +
> +#define pr_fmt(fmt) "qcom-iommu: " fmt

Unused as dev_* prints are used?

> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

This driver is boolean and not a module.

> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "io-pgtable.h"
> +#include "arm-smmu-regs.h"
> +
> +#define SMMU_INTR_SEL_NS 0x2000
> +
> +struct qcom_iommu_dev {
> +   /* IOMMU core code handle */
> +   struct iommu_device  iommu;
> +   struct device   *dev;
> +   struct clk  *iface_clk;
> +   struct clk  *bus_clk;
> +   void __iomem*local_base;
> +   u32  sec_id;
> +   struct list_head context_list;   /* list of 
> qcom_iommu_context */
> +};
> +
> +struct qcom_iommu_ctx {
> +   struct device   *dev;
> +   void __iomem*base;
> +   unsigned int irq;
> +   bool secure_init;
> +   u32  asid;  /* asid and ctx bank # are 1:1 */
> +   struct iommu_group  *group;
> +   struct list_head node;  /* head in 
> qcom_iommu_device::context_list */
> +};
> +
> +struct qcom_iommu_domain {
> +   struct io_pgtable_ops   *pgtbl_ops;
> +   spinlock_t   pgtbl_lock;
> +   struct mutex init_mutex; /* Protects iommu pointer */
> +   struct iommu_domain  domain;
> +   struct qcom_iommu_dev   *iommu;
> +};
> +
> +static struct qcom_iommu_domain *to_qcom_iommu_domain(struct iommu_domain 
> *dom)
> +{
> +   return container_of(dom, struct qcom_iommu_domain, domain);
> +}
> +
> +static const struct iommu_ops qcom_iommu_ops;
> +
> +static struct qcom_iommu_dev * __to_iommu(struct iommu_fwspec *fwspec)
> +{
> +   if (!fwspec || fwspec->ops != _iommu_ops)
> +   return NULL;
> +   return fwspec->iommu_priv;
> +}
> +
> +static struct qcom_iommu_dev * to_iommu(struct iommu_fwspec *fwspec)
> +{
> +   struct 

Re: [PATCH v5 06/32] x86/mm: Add Secure Memory Encryption (SME) support

2017-05-04 Thread Tom Lendacky

On 4/27/2017 10:46 AM, Borislav Petkov wrote:

On Tue, Apr 18, 2017 at 04:17:27PM -0500, Tom Lendacky wrote:

Add support for Secure Memory Encryption (SME). This initial support
provides a Kconfig entry to build the SME support into the kernel and
defines the memory encryption mask that will be used in subsequent
patches to mark pages as encrypted.


...


diff --git a/arch/x86/include/asm/mem_encrypt.h 
b/arch/x86/include/asm/mem_encrypt.h
new file mode 100644
index 000..d5c4a2b
--- /dev/null
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -0,0 +1,42 @@
+/*
+ * AMD Memory Encryption Support
+ *
+ * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+


These ifdeffery closing #endif markers look strange:


+#ifndef __X86_MEM_ENCRYPT_H__
+#define __X86_MEM_ENCRYPT_H__
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+
+extern unsigned long sme_me_mask;
+
+static inline bool sme_active(void)
+{
+   return !!sme_me_mask;
+}
+
+#else  /* !CONFIG_AMD_MEM_ENCRYPT */
+
+#ifndef sme_me_mask
+#define sme_me_mask0UL
+
+static inline bool sme_active(void)
+{
+   return false;
+}
+#endif


this endif is the sme_me_mask closing one and it has sme_active() in it.
Shouldn't it be:

#ifndef sme_me_mask
#define sme_me_mask  0UL
#endif

and have sme_active below it, in the !CONFIG_AMD_MEM_ENCRYPT branch?

The same thing is in include/linux/mem_encrypt.h


I did this so that an the include order wouldn't cause issues (including
asm/mem_encrypt.h followed by later by a linux/mem_encrypt.h include).
I can make this a bit clearer by having separate #defines for each
thing, e.g.:

#ifndef sme_me_mask
#define sme_me_mask 0UL
#endif

#ifndef sme_active
#define sme_active sme_active
static inline ...
#endif

Is that better/clearer?

Thanks,
Tom




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 31/32] x86: Add sysfs support for Secure Memory Encryption

2017-05-04 Thread Tom Lendacky

On 4/27/2017 10:52 AM, Dave Hansen wrote:

On 04/27/2017 12:25 AM, Dave Young wrote:

On 04/21/17 at 02:55pm, Dave Hansen wrote:

On 04/18/2017 02:22 PM, Tom Lendacky wrote:

Add sysfs support for SME so that user-space utilities (kdump, etc.) can
determine if SME is active.

A new directory will be created:
  /sys/kernel/mm/sme/

And two entries within the new directory:
  /sys/kernel/mm/sme/active
  /sys/kernel/mm/sme/encryption_mask


Why do they care, and what will they be doing with this information?


Since kdump will copy old memory but need this to know if the old memory
was encrypted or not. With this sysfs file we can know the previous SME
status and pass to kdump kernel as like a kernel param.

Tom, have you got chance to try if it works or not?


What will the kdump kernel do with it though?  We kexec() into that
kernel so the SME keys will all be the same, right?  So, will the kdump


Yes, the SME key will be same after a kexec.


kernel be just setting the encryption bit in the PTE so it can copy the
old plaintext out?


Yes, the idea would be to set the encryption bit in the PTE when mapping
and copying encrypted pages and not set it for unencrypted pages.



Why do we need both 'active' and 'encryption_mask'?  How could it be
that the hardware-enumerated 'encryption_mask' changes across a kexec()?



We don't need both, I just added the 'encryption mask' entry for
information. It won't change across a kexec, I can remove it.

Thanks,
Tom
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 31/32] x86: Add sysfs support for Secure Memory Encryption

2017-05-04 Thread Tom Lendacky

On 4/27/2017 2:25 AM, Dave Young wrote:

On 04/21/17 at 02:55pm, Dave Hansen wrote:

On 04/18/2017 02:22 PM, Tom Lendacky wrote:

Add sysfs support for SME so that user-space utilities (kdump, etc.) can
determine if SME is active.

A new directory will be created:
  /sys/kernel/mm/sme/

And two entries within the new directory:
  /sys/kernel/mm/sme/active
  /sys/kernel/mm/sme/encryption_mask


Why do they care, and what will they be doing with this information?


Since kdump will copy old memory but need this to know if the old memory
was encrypted or not. With this sysfs file we can know the previous SME
status and pass to kdump kernel as like a kernel param.

Tom, have you got chance to try if it works or not?


Sorry, I haven't had a chance to test this yet.

Thanks,
Tom



Thanks
Dave


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Bjorn Helgaas via iommu
On Thu, May 4, 2017 at 4:21 AM, Andy Shevchenko
 wrote:
> acpi_evaluate_dsm() and friends take a pointer to a raw buffer of 16
> bytes. Instead we convert them to use uuid_le type. At the same time we
> convert current users.
>
> acpi_str_to_uuid() becomes useless after the conversion and it's safe to
> get rid of it.
>
> The conversion fixes a potential bug in int340x_thermal as well since
> we have to use memcmp() on binary data.
>
> Cc: Rafael J. Wysocki 
> Cc: Mika Westerberg 
> Cc: Borislav Petkov 
> Cc: Dan Williams 
> Cc: Amir Goldstein 
> Cc: Jarkko Sakkinen 
> Cc: Jani Nikula 
> Cc: Ben Skeggs 
> Cc: Benjamin Tissoires 
> Cc: Joerg Roedel 
> Cc: Adrian Hunter 
> Cc: Yisen Zhuang 
> Cc: Bjorn Helgaas 
> Cc: Zhang Rui 
> Cc: Felipe Balbi 
> Cc: Mathias Nyman 
> Cc: Heikki Krogerus 
> Cc: Liam Girdwood 
> Cc: Mark Brown 
> Signed-off-by: Andy Shevchenko 

For the drivers/pci parts:

Acked-by: Bjorn Helgaas 

> ---
>  drivers/acpi/acpi_extlog.c | 10 +++---
>  drivers/acpi/bus.c | 29 ++--
>  drivers/acpi/nfit/core.c   | 40 
> +++---
>  drivers/acpi/nfit/nfit.h   |  3 +-
>  drivers/acpi/utils.c   |  4 +--
>  drivers/char/tpm/tpm_crb.c |  9 +++--
>  drivers/char/tpm/tpm_ppi.c | 20 +--
>  drivers/gpu/drm/i915/intel_acpi.c  | 14 +++-
>  drivers/gpu/drm/nouveau/nouveau_acpi.c | 20 +--
>  drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c |  9 +++--
>  drivers/hid/i2c-hid/i2c-hid.c  |  9 +++--
>  drivers/iommu/dmar.c   | 11 +++---
>  drivers/mmc/host/sdhci-pci-core.c  |  9 +++--
>  drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 15 
>  drivers/pci/pci-acpi.c | 11 +++---
>  drivers/pci/pci-label.c|  4 +--
>  drivers/thermal/int340x_thermal/int3400_thermal.c  |  8 ++---
>  drivers/usb/dwc3/dwc3-pci.c|  6 ++--
>  drivers/usb/host/xhci-pci.c|  9 +++--
>  drivers/usb/misc/ucsi.c|  2 +-
>  drivers/usb/typec/typec_wcove.c|  4 +--
>  include/acpi/acpi_bus.h|  9 ++---
>  include/linux/acpi.h   |  4 +--
>  include/linux/pci-acpi.h   |  2 +-
>  sound/soc/intel/skylake/skl-nhlt.c |  7 ++--
>  tools/testing/nvdimm/test/iomap.c  |  2 +-
>  tools/testing/nvdimm/test/nfit.c   |  2 +-
>  27 files changed, 116 insertions(+), 156 deletions(-)
>
> diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
> index 502ea4dc2080..69d6140b6afa 100644
> --- a/drivers/acpi/acpi_extlog.c
> +++ b/drivers/acpi/acpi_extlog.c
> @@ -182,17 +182,17 @@ static int extlog_print(struct notifier_block *nb, 
> unsigned long val,
>
>  static bool __init extlog_get_l1addr(void)
>  {
> -   u8 uuid[16];
> +   uuid_le uuid;
> acpi_handle handle;
> union acpi_object *obj;
>
> -   acpi_str_to_uuid(extlog_dsm_uuid, uuid);
> -
> +   if (uuid_le_to_bin(extlog_dsm_uuid, ))
> +   return false;
> if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", )))
> return false;
> -   if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << 
> EXTLOG_FN_ADDR))
> +   if (!acpi_check_dsm(handle, , EXTLOG_DSM_REV, 1 << 
> EXTLOG_FN_ADDR))
> return false;
> -   obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV,
> +   obj = acpi_evaluate_dsm_typed(handle, , EXTLOG_DSM_REV,
>   EXTLOG_FN_ADDR, NULL, 
> ACPI_TYPE_INTEGER);
> if (!obj) {
> return false;
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 784bda663d16..e8130a4873e9 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -196,42 +196,19 @@ static void acpi_print_osc_error(acpi_handle handle,
> pr_debug("\n");
>  }
>
> -acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
> -{
> -   int i;
> -   static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
> -   24, 26, 28, 30, 32, 34};
> -
> -   if (strlen(str) != 36)
> -   return 

[PATCH 4/4] iommu: qcom: initialize secure page table

2017-05-04 Thread Rob Clark
From: Stanimir Varbanov 

This basically gets the secure page table size, allocates memory for
secure pagetables and passes the physical address to the trusted zone.

Signed-off-by: Stanimir Varbanov 
Signed-off-by: Rob Clark 
---
 drivers/iommu/qcom_iommu.c | 64 ++
 1 file changed, 64 insertions(+)

diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index 1cf7c8e..a35d4cc 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -615,6 +615,51 @@ static void qcom_iommu_disable_clocks(struct 
qcom_iommu_dev *qcom_iommu)
clk_disable_unprepare(qcom_iommu->iface_clk);
 }
 
+static int qcom_iommu_sec_ptbl_init(struct device *dev)
+{
+   size_t psize = 0;
+   unsigned int spare = 0;
+   void *cpu_addr;
+   dma_addr_t paddr;
+   unsigned long attrs;
+   static bool allocated = false;
+   int ret;
+
+   if (allocated)
+   return 0;
+
+   ret = qcom_scm_iommu_secure_ptbl_size(spare, );
+   if (ret) {
+   dev_err(dev, "failed to get iommu secure pgtable size (%d)\n",
+   ret);
+   return ret;
+   }
+
+   dev_info(dev, "iommu sec: pgtable size: %zu\n", psize);
+
+   attrs = DMA_ATTR_NO_KERNEL_MAPPING;
+
+   cpu_addr = dma_alloc_attrs(dev, psize, , GFP_KERNEL, attrs);
+   if (!cpu_addr) {
+   dev_err(dev, "failed to allocate %zu bytes for pgtable\n",
+   psize);
+   return -ENOMEM;
+   }
+
+   ret = qcom_scm_iommu_secure_ptbl_init(paddr, psize, spare);
+   if (ret) {
+   dev_err(dev, "failed to init iommu pgtable (%d)\n", ret);
+   goto free_mem;
+   }
+
+   allocated = true;
+   return 0;
+
+free_mem:
+   dma_free_attrs(dev, psize, cpu_addr, paddr, attrs);
+   return ret;
+}
+
 static int qcom_iommu_ctx_probe(struct platform_device *pdev)
 {
struct qcom_iommu_ctx *ctx;
@@ -695,6 +740,17 @@ static struct platform_driver qcom_iommu_ctx_driver = {
 };
 module_platform_driver(qcom_iommu_ctx_driver);
 
+static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
+{
+   struct device_node *child;
+
+   for_each_child_of_node(qcom_iommu->dev->of_node, child)
+   if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec"))
+   return true;
+
+   return false;
+}
+
 static int qcom_iommu_device_probe(struct platform_device *pdev)
 {
struct qcom_iommu_dev *qcom_iommu;
@@ -731,6 +787,14 @@ static int qcom_iommu_device_probe(struct platform_device 
*pdev)
return -ENODEV;
}
 
+   if (qcom_iommu_has_secure_context(qcom_iommu)) {
+   ret = qcom_iommu_sec_ptbl_init(dev);
+   if (ret) {
+   dev_err(dev, "cannot init secure pg table(%d)\n", ret);
+   return ret;
+   }
+   }
+
platform_set_drvdata(pdev, qcom_iommu);
 
/* register context bank devices, which are child nodes: */
-- 
2.9.3

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/4] Docs: dt: document qcom iommu bindings

2017-05-04 Thread Rob Clark
Cc: devicet...@vger.kernel.org
Signed-off-by: Rob Clark 
---
 .../devicetree/bindings/iommu/qcom,iommu.txt   | 121 +
 1 file changed, 121 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/qcom,iommu.txt

diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt 
b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
new file mode 100644
index 000..0d50f84
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
@@ -0,0 +1,121 @@
+* QCOM IOMMU v1 Implementation
+
+Qualcomm "B" family devices which are not compatible with arm-smmu have
+a similar looking IOMMU but without access to the global register space,
+and optionally requiring additional configuration to route context irqs
+to non-secure vs secure interrupt line.
+
+** Required properties:
+
+- compatible   : Should be one of:
+
+"qcom,msm8916-iommu"
+
+ Followed by "qcom,msm-iommu-v1".
+
+- clock-names  : Should be a pair of "iface" (required for IOMMUs
+ register group access) and "bus" (required for
+ the IOMMUs underlying bus access).
+
+- clocks   : Phandles for respective clocks described by
+ clock-names.
+
+- #address-cells   : must be 1.
+
+- #size-cells  : must be 1.
+
+- #iommu-cells : Must be 1.
+
+- ranges   : Base address and size of the iommu context banks.
+
+- qcom,iommu-secure-id  : secure-id.
+
+- List of sub-nodes, one per translation context bank.  Each sub-node
+  has the following required properties:
+
+  - compatible : Should be one of:
+- "qcom,msm-iommu-v1-ns"  : non-secure context bank
+- "qcom,msm-iommu-v1-sec" : secure context bank
+  - reg: Base address and size of context bank within the iommu
+  - interrupts : The context fault irq.
+
+** Optional properties:
+
+- reg  : Base address and size of the SMMU local base, should
+ be only specified if the iommu requires configuration
+ for routing of context bank irq's to secure vs non-
+ secure lines.  (Ie. if the iommu contains secure
+ context banks)
+
+
+** Examples:
+
+   apps_iommu: iommu@1e2 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   #iommu-cells = <1>;
+   compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1";
+   ranges = <0 0x1e2 0x4>;
+   reg = <0x1ef 0x3000>;
+   clocks = < GCC_SMMU_CFG_CLK>,
+< GCC_APSS_TCU_CLK>;
+   clock-names = "iface", "bus";
+   qcom,iommu-secure-id = <17>;
+
+   // mdp_0:
+   iommu-ctx@4000 {
+   compatible = "qcom,msm-iommu-v1-ns";
+   reg = <0x4000 0x1000>;
+   interrupts = ;
+   };
+
+   // venus_ns:
+   iommu-ctx@5000 {
+   compatible = "qcom,msm-iommu-v1-sec";
+   reg = <0x5000 0x1000>;
+   interrupts = ;
+   };
+   };
+
+   gpu_iommu: iommu@1f08000 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   #iommu-cells = <1>;
+   compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1";
+   ranges = <0 0x1f08000 0x1>;
+   clocks = < GCC_SMMU_CFG_CLK>,
+< GCC_GFX_TCU_CLK>;
+   clock-names = "iface", "bus";
+   qcom,iommu-secure-id = <18>;
+
+   // gfx3d_user:
+   iommu-ctx@1f09000 {
+   compatible = "qcom,msm-iommu-v1-ns";
+   reg = <0x1000 0x1000>;
+   interrupts = ;
+   };
+
+   // gfx3d_priv:
+   iommu-ctx@1f0a000 {
+   compatible = "qcom,msm-iommu-v1-ns";
+   reg = <0x2000 0x1000>;
+   interrupts = ;
+   };
+   };
+
+   ...
+
+   venus: video-codec@1d0 {
+   ...
+   iommus = <_iommu 5>;
+   };
+
+   mdp: mdp@1a01000 {
+   ...
+   iommus = <_iommu 4>;
+   };
+
+   gpu@01c0 {
+   ...
+   iommus = <_iommu 1>, <_iommu 2>;
+   };
-- 
2.9.3

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/4] iommu: arm-smmu: split out register defines

2017-05-04 Thread Rob Clark
I want to re-use some of these for qcom_iommu, which has (roughly) the
same context-bank registers.

Signed-off-by: Rob Clark 
---
 drivers/iommu/arm-smmu-regs.h | 227 ++
 drivers/iommu/arm-smmu.c  | 203 +
 2 files changed, 228 insertions(+), 202 deletions(-)
 create mode 100644 drivers/iommu/arm-smmu-regs.h

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
new file mode 100644
index 000..87589c8
--- /dev/null
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -0,0 +1,227 @@
+/*
+ * IOMMU API for ARM architected SMMU implementations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2013 ARM Limited
+ *
+ * Author: Will Deacon 
+ */
+
+#ifndef _ARM_SMMU_REGS_H
+#define _ARM_SMMU_REGS_H
+
+/* Configuration registers */
+#define ARM_SMMU_GR0_sCR0  0x0
+#define sCR0_CLIENTPD  (1 << 0)
+#define sCR0_GFRE  (1 << 1)
+#define sCR0_GFIE  (1 << 2)
+#define sCR0_EXIDENABLE(1 << 3)
+#define sCR0_GCFGFRE   (1 << 4)
+#define sCR0_GCFGFIE   (1 << 5)
+#define sCR0_USFCFG(1 << 10)
+#define sCR0_VMIDPNE   (1 << 11)
+#define sCR0_PTM   (1 << 12)
+#define sCR0_FB(1 << 13)
+#define sCR0_VMID16EN  (1 << 31)
+#define sCR0_BSU_SHIFT 14
+#define sCR0_BSU_MASK  0x3
+
+/* Auxiliary Configuration register */
+#define ARM_SMMU_GR0_sACR  0x10
+
+/* Identification registers */
+#define ARM_SMMU_GR0_ID0   0x20
+#define ARM_SMMU_GR0_ID1   0x24
+#define ARM_SMMU_GR0_ID2   0x28
+#define ARM_SMMU_GR0_ID3   0x2c
+#define ARM_SMMU_GR0_ID4   0x30
+#define ARM_SMMU_GR0_ID5   0x34
+#define ARM_SMMU_GR0_ID6   0x38
+#define ARM_SMMU_GR0_ID7   0x3c
+#define ARM_SMMU_GR0_sGFSR 0x48
+#define ARM_SMMU_GR0_sGFSYNR0  0x50
+#define ARM_SMMU_GR0_sGFSYNR1  0x54
+#define ARM_SMMU_GR0_sGFSYNR2  0x58
+
+#define ID0_S1TS   (1 << 30)
+#define ID0_S2TS   (1 << 29)
+#define ID0_NTS(1 << 28)
+#define ID0_SMS(1 << 27)
+#define ID0_ATOSNS (1 << 26)
+#define ID0_PTFS_NO_AARCH32(1 << 25)
+#define ID0_PTFS_NO_AARCH32S   (1 << 24)
+#define ID0_CTTW   (1 << 14)
+#define ID0_NUMIRPT_SHIFT  16
+#define ID0_NUMIRPT_MASK   0xff
+#define ID0_NUMSIDB_SHIFT  9
+#define ID0_NUMSIDB_MASK   0xf
+#define ID0_EXIDS  (1 << 8)
+#define ID0_NUMSMRG_SHIFT  0
+#define ID0_NUMSMRG_MASK   0xff
+
+#define ID1_PAGESIZE   (1 << 31)
+#define ID1_NUMPAGENDXB_SHIFT  28
+#define ID1_NUMPAGENDXB_MASK   7
+#define ID1_NUMS2CB_SHIFT  16
+#define ID1_NUMS2CB_MASK   0xff
+#define ID1_NUMCB_SHIFT0
+#define ID1_NUMCB_MASK 0xff
+
+#define ID2_OAS_SHIFT  4
+#define ID2_OAS_MASK   0xf
+#define ID2_IAS_SHIFT  0
+#define ID2_IAS_MASK   0xf
+#define ID2_UBS_SHIFT  8
+#define ID2_UBS_MASK   0xf
+#define ID2_PTFS_4K(1 << 12)
+#define ID2_PTFS_16K   (1 << 13)
+#define ID2_PTFS_64K   (1 << 14)
+#define ID2_VMID16 (1 << 15)
+
+#define ID7_MAJOR_SHIFT4
+#define ID7_MAJOR_MASK 0xf
+
+/* Global TLB invalidation */
+#define ARM_SMMU_GR0_TLBIVMID  0x64
+#define ARM_SMMU_GR0_TLBIALLNSNH   0x68
+#define ARM_SMMU_GR0_TLBIALLH  0x6c
+#define ARM_SMMU_GR0_sTLBGSYNC 0x70
+#define ARM_SMMU_GR0_sTLBGSTATUS   0x74
+#define sTLBGSTATUS_GSACTIVE   (1 << 0)
+#define TLB_LOOP_TIMEOUT   100 /* 1s! */
+#define TLB_SPIN_COUNT 10
+
+/* Stream mapping registers */
+#define ARM_SMMU_GR0_SMR(n)(0x800 + ((n) << 2))
+#define SMR_VALID 

[PATCH 3/4] iommu: add qcom_iommu

2017-05-04 Thread Rob Clark
An iommu driver for Qualcomm "B" family devices which do not completely
implement the ARM SMMU spec.  These devices have context-bank register
layout that is similar to ARM SMMU, but no global register space (or at
least not one that is accessible).

Signed-off-by: Rob Clark 
Signed-off-by: Stanimir Varbanov 
---
 drivers/iommu/Kconfig  |  10 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/qcom_iommu.c | 825 +
 3 files changed, 836 insertions(+)
 create mode 100644 drivers/iommu/qcom_iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 37e204f..400a404 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -359,4 +359,14 @@ config MTK_IOMMU_V1
 
  if unsure, say N here.
 
+config QCOM_IOMMU
+   bool "Qualcomm IOMMU Support"
+   depends on ARM || ARM64
+   depends on ARCH_QCOM || COMPILE_TEST
+   select IOMMU_API
+   select IOMMU_IO_PGTABLE_LPAE
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMU on certain Qualcomm SoCs.
+
 endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 195f7b9..b910aea 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
+obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
new file mode 100644
index 000..1cf7c8e
--- /dev/null
+++ b/drivers/iommu/qcom_iommu.c
@@ -0,0 +1,825 @@
+/*
+ * IOMMU API for QCOM secure IOMMUs.  Somewhat based on arm-smmu.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2013 ARM Limited
+ * Copyright (C) 2017 Red Hat
+ */
+
+#define pr_fmt(fmt) "qcom-iommu: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "io-pgtable.h"
+#include "arm-smmu-regs.h"
+
+#define SMMU_INTR_SEL_NS 0x2000
+
+struct qcom_iommu_dev {
+   /* IOMMU core code handle */
+   struct iommu_device  iommu;
+   struct device   *dev;
+   struct clk  *iface_clk;
+   struct clk  *bus_clk;
+   void __iomem*local_base;
+   u32  sec_id;
+   struct list_head context_list;   /* list of qcom_iommu_context 
*/
+};
+
+struct qcom_iommu_ctx {
+   struct device   *dev;
+   void __iomem*base;
+   unsigned int irq;
+   bool secure_init;
+   u32  asid;  /* asid and ctx bank # are 1:1 */
+   struct iommu_group  *group;
+   struct list_head node;  /* head in 
qcom_iommu_device::context_list */
+};
+
+struct qcom_iommu_domain {
+   struct io_pgtable_ops   *pgtbl_ops;
+   spinlock_t   pgtbl_lock;
+   struct mutex init_mutex; /* Protects iommu pointer */
+   struct iommu_domain  domain;
+   struct qcom_iommu_dev   *iommu;
+};
+
+static struct qcom_iommu_domain *to_qcom_iommu_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct qcom_iommu_domain, domain);
+}
+
+static const struct iommu_ops qcom_iommu_ops;
+
+static struct qcom_iommu_dev * __to_iommu(struct iommu_fwspec *fwspec)
+{
+   if (!fwspec || fwspec->ops != _iommu_ops)
+   return NULL;
+   return fwspec->iommu_priv;
+}
+
+static struct qcom_iommu_dev * to_iommu(struct iommu_fwspec *fwspec)
+{
+   struct qcom_iommu_dev *qcom_iommu = __to_iommu(fwspec);
+   WARN_ON(!qcom_iommu);
+   return qcom_iommu;
+}
+
+static struct qcom_iommu_ctx * to_ctx(struct iommu_fwspec *fwspec, unsigned 
asid)
+{
+   struct qcom_iommu_dev *qcom_iommu = to_iommu(fwspec);
+   struct qcom_iommu_ctx *ctx;
+
+   if (!qcom_iommu)
+   return NULL;
+
+   list_for_each_entry(ctx, _iommu->context_list, node)
+   if (ctx->asid == asid)
+   return ctx;
+
+   WARN(1, "no 

[PATCH 0/4] iommu: add qcom_iommu for early "B" family devices (v3)

2017-05-04 Thread Rob Clark
An iommu driver for Qualcomm "B" family devices which do not completely
implement the ARM SMMU spec.  These devices have context-bank register
layout that is similar to ARM SMMU, but no global register space (or at
least not one that is accessible).

At this point, all the dependencies have landed for v4.12, so please
review.  An iommu driver is the last remaining piece of the puzzle to
have the gpu working out of the box on 8x16 (dragonboard 410c, for
example).  There are only minimal changes since v2:

  * small dt doc change suggested by Rob H.
  * fix for WARN_ON() splats reported by Archit

Rob Clark (3):
  Docs: dt: document qcom iommu bindings
  iommu: arm-smmu: split out register defines
  iommu: add qcom_iommu

Stanimir Varbanov (1):
  iommu: qcom: initialize secure page table

 .../devicetree/bindings/iommu/qcom,iommu.txt   | 121 +++
 drivers/iommu/Kconfig  |  10 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/arm-smmu-regs.h  | 227 ++
 drivers/iommu/arm-smmu.c   | 203 +
 drivers/iommu/qcom_iommu.c | 889 +
 6 files changed, 1249 insertions(+), 202 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iommu/qcom,iommu.txt
 create mode 100644 drivers/iommu/arm-smmu-regs.h
 create mode 100644 drivers/iommu/qcom_iommu.c

-- 
2.9.3

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH] iommu/dma: Setup iova_domain granule for IOMMU_DMA_MSI cookies

2017-05-04 Thread Bharat Bhushan
Hi Robin,

I faced same issue on our platform and debugged to get the root cause of the 
issue. Also fixed in somewhat similar way, cleared iova_off and not change size 
for if cookie->type is  IOMMU_DMA_MSI_COOKIE. Anyways that was not as good as 
below changes.

While just now I saw this was already discussed and solved. Should have looked 
earlier to save time, but the debugging was some learning experience  

I have tested your below change and it works fine on NXP platform.

Thanks
-Bharat

> -Original Message-
> From: iommu-boun...@lists.linux-foundation.org [mailto:iommu-
> boun...@lists.linux-foundation.org] On Behalf Of Shanker Donthineni
> Sent: Thursday, April 13, 2017 8:00 PM
> To: Robin Murphy ; Nate Watterson
> ; Joerg Roedel ;
> iommu@lists.linux-foundation.org; linux-ker...@vger.kernel.org
> Subject: Re: [PATCH] iommu/dma: Setup iova_domain granule for
> IOMMU_DMA_MSI cookies
> 
> Hi Robin,
> 
> I tested your changes and the device pass-through feature works fine on
> QDF2400 server platform. Maybe Nate comments on the patch contents but
> it fixes the problem.
> 
> 
> @@ -317,13 +317,13 @@ static void iommu_dma_free_iova(struct
> iommu_dma_cookie *cookie,
> dma_addr_t iova, size_t size)  {
> struct iova_domain *iovad = >iovad;
> -   unsigned long shift = iova_shift(iovad);
> 
> /* The MSI case is only ever cleaning up its most recent allocation */
> if (cookie->type == IOMMU_DMA_MSI_COOKIE)
> cookie->msi_iova -= size;
> else
> -   free_iova_fast(iovad, iova >> shift, size >> shift);
> +   free_iova_fast(iovad, iova_pfn(iovad, iova),
> +  size >> iova_shift(iovad));
>  }
> 
>  static void __iommu_dma_unmap(struct iommu_domain *domain,
> dma_addr_t dma_addr, @@ -538,11 +538,14 @@ static dma_addr_t
> __iommu_dma_map(struct device *dev, phys_addr_t phys,  {
> struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> struct iommu_dma_cookie *cookie = domain->iova_cookie;
> -   struct iova_domain *iovad = >iovad;
> -   size_t iova_off = iova_offset(iovad, phys);
> +   size_t iova_off = 0;
> dma_addr_t iova;
> 
> -   size = iova_align(iovad, size + iova_off);
> +   if (cookie->type == IOMMU_DMA_IOVA_COOKIE) {
> +   iova_off = iova_offset(>iovad, phys);
> +   size = iova_align(>iovad, size + iova_off);
> +   }
> 
> 
> On 04/13/2017 06:21 AM, Robin Murphy wrote:
> > Hi Nate,
> >
> > On 13/04/17 09:55, Nate Watterson wrote:
> >> Currently, the __iommu_dma_{map/free} functions call
> >> iova_{offset/align} making them unsuitable for use with iommu_domains
> >> having an IOMMU_DMA_MSI cookie since the cookie's iova_domain
> member, iovad, is uninitialized.
> >>
> >> Now that iommu_dma_get_msi_page() calls __iommu_dma_map()
> regardless
> >> of cookie type, failures are being seen when mapping MSI target
> >> addresses for devices attached to UNMANAGED domains. To work
> around
> >> this issue, the iova_domain granule for IOMMU_DMA_MSI cookies is
> >> initialized to the value returned by cookie_msi_granule().
> > Oh bum. Thanks for the report.
> >
> > However, I really don't like bodging around it with deliberate
> > undefined behaviour. Fixing things properly doesn't seem too hard:
> >
> > ->8-
> > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> > index 8348f366ddd1..62618e77bedc 100644
> > --- a/drivers/iommu/dma-iommu.c
> > +++ b/drivers/iommu/dma-iommu.c
> > @@ -396,13 +396,13 @@ static void iommu_dma_free_iova(struct
> > iommu_dma_cookie *cookie,
> > dma_addr_t iova, size_t size)  {
> > struct iova_domain *iovad = >iovad;
> > -   unsigned long shift = iova_shift(iovad);
> >
> > /* The MSI case is only ever cleaning up its most recent
> > allocation */
> > if (cookie->type == IOMMU_DMA_MSI_COOKIE)
> > cookie->msi_iova -= size;
> > else
> > -   free_iova_fast(iovad, iova >> shift, size >> shift);
> > +   free_iova_fast(iovad, iova_pfn(iovad, iova),
> > +   size >> iova_shift(iovad));
> >  }
> >
> >  static void __iommu_dma_unmap(struct iommu_domain *domain,
> dma_addr_t
> > dma_addr, @@ -617,11 +617,14 @@ static dma_addr_t
> > __iommu_dma_map(struct device *dev, phys_addr_t phys,  {
> > struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> > struct iommu_dma_cookie *cookie = domain->iova_cookie;
> > -   struct iova_domain *iovad = >iovad;
> > -   size_t iova_off = iova_offset(iovad, phys);
> > +   size_t iova_off = 0;
> > dma_addr_t iova;
> >
> > -   size = iova_align(iovad, size + iova_off);
> > +   if (cookie->type == IOMMU_DMA_IOVA_COOKIE) {
> > +   iova_off = iova_offset(>iovad, phys);
> > +   size = 

[PATCH v2 4/7] iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY option for ThunderX2 SMMUv3 implementation.

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

Enable PAGE0_REGS_ONLY option for Cavium ThunderX2 SMMUv3 model.

Signed-off-by: Linu Cherian 
Signed-off-by: Geetha Sowjanya 
---
 drivers/iommu/arm-smmu-v3.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index f027676..8f7d8ad 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2625,6 +2625,14 @@ static int arm_smmu_device_hw_probe(struct 
arm_smmu_device *smmu)
 }
 
 #ifdef CONFIG_ACPI
+static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu)
+{
+   if (model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
+   smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY;
+
+   dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options);
+}
+
 static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
  struct arm_smmu_device *smmu)
 {
@@ -2637,6 +2645,8 @@ static int arm_smmu_device_acpi_probe(struct 
platform_device *pdev,
/* Retrieve SMMUv3 specific data */
iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
 
+   acpi_smmu_get_options(iort_smmu->model, smmu);
+
if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
smmu->features |= ARM_SMMU_FEAT_COHERENCY;
 
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 7/7] arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

Add Cavium ThunderX2 SMMUv3 erratas to the errata list.

Signed-off-by: Linu Cherian 
Signed-off-by: Geetha Sowjanya 
---
 Documentation/arm64/silicon-errata.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.txt 
b/Documentation/arm64/silicon-errata.txt
index 10f2ddd..42422f6 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -62,6 +62,8 @@ stable kernels.
 | Cavium | ThunderX GICv3  | #23154  | CAVIUM_ERRATUM_23154
|
 | Cavium | ThunderX Core   | #27456  | CAVIUM_ERRATUM_27456
|
 | Cavium | ThunderX SMMUv2 | #27704  | N/A 
|
+| Cavium | ThunderX2 SMMUv3| #74 | N/A 
|
+| Cavium | ThunderX2 SMMUv3| #126| N/A 
|
 || | | 
|
 | Freescale/NXP  | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 
|
 || | | 
|
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 3/7] ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

Add SMMUv3 model definition for ThunderX2.

Signed-off-by: Linu Cherian 
Signed-off-by: Geetha Sowjanya 
---
 include/acpi/actbl2.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index faa9f2c..76a6f5d 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -779,6 +779,8 @@ struct acpi_iort_smmu {
 #define ACPI_IORT_SMMU_CORELINK_MMU400  0x0002 /* ARM Corelink MMU-400 
*/
 #define ACPI_IORT_SMMU_CORELINK_MMU500  0x0003 /* ARM Corelink MMU-500 
*/
 
+#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x0002 /* Cavium ThunderX2 SMMUv3 
*/
+
 /* Masks for Flags field above */
 
 #define ACPI_IORT_SMMU_DVM_SUPPORTED(1)
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 5/7] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

Cavium ThunderX2 implementation doesn't support second page in SMMU
register space. Hence, resource size is set as 64k for this model.

Signed-off-by: Linu Cherian 
Signed-off-by: Geetha Sowjanya 
---
 drivers/acpi/arm64/iort.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..23c5350 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct 
resource *res,
 {
struct acpi_iort_smmu_v3 *smmu;
int num_res = 0;
+   unsigned long size = SZ_128K;
 
/* Retrieve SMMUv3 specific data */
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
 
+   /*
+* Override the size, for Cavium ThunderX2 implementation
+* which doesn't support the page 1 SMMU register space.
+*/
+   if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
+   size = SZ_64K;
+
res[num_res].start = smmu->base_address;
-   res[num_res].end = smmu->base_address + SZ_128K - 1;
+   res[num_res].end = smmu->base_address + size - 1;
res[num_res].flags = IORESOURCE_MEM;
 
num_res++;
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 6/7] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126

2017-05-04 Thread Geetha sowjanya
From: Geetha Sowjanya 

Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq
lines for gerror, eventq and cmdq-sync.

This patch addresses the issue by checking if any interrupt sources are
using same irq number, then they are registered as shared irqs.

Signed-off-by: Geetha Sowjanya 
---
 drivers/iommu/arm-smmu-v3.c | 32 
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 016b702..46428e7 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2236,10 +2236,30 @@ static void arm_smmu_setup_msis(struct arm_smmu_device 
*smmu)
devm_add_action(dev, arm_smmu_free_msis, dev);
 }
 
+static int get_irq_flags(struct arm_smmu_device *smmu, int irq)
+{
+   int match_count = 0;
+
+   if (irq == smmu->evtq.q.irq)
+   match_count++;
+   if (irq == smmu->cmdq.q.irq)
+   match_count++;
+   if (irq == smmu->gerr_irq)
+   match_count++;
+   if (irq == smmu->priq.q.irq)
+   match_count++;
+
+   if (match_count > 1)
+   return IRQF_SHARED | IRQF_ONESHOT;
+
+   return 0;
+}
+
 static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 {
int ret, irq;
u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
+   u32 irqflags = 0;
 
/* Disable IRQs first */
ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
@@ -2254,9 +2274,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device 
*smmu)
/* Request interrupt lines */
irq = smmu->evtq.q.irq;
if (irq) {
+   irqflags = get_irq_flags(smmu, irq);
ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
arm_smmu_evtq_thread,
-   IRQF_ONESHOT,
+   IRQF_ONESHOT | irqflags,
"arm-smmu-v3-evtq", smmu);
if (ret < 0)
dev_warn(smmu->dev, "failed to enable evtq irq\n");
@@ -2264,8 +2285,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device 
*smmu)
 
irq = smmu->cmdq.q.irq;
if (irq) {
+   irqflags = get_irq_flags(smmu, irq);
ret = devm_request_irq(smmu->dev, irq,
-  arm_smmu_cmdq_sync_handler, 0,
+  arm_smmu_cmdq_sync_handler, irqflags,
   "arm-smmu-v3-cmdq-sync", smmu);
if (ret < 0)
dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n");
@@ -2273,8 +2295,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device 
*smmu)
 
irq = smmu->gerr_irq;
if (irq) {
+   irqflags = get_irq_flags(smmu, irq);
ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler,
-  0, "arm-smmu-v3-gerror", smmu);
+  irqflags, "arm-smmu-v3-gerror", smmu);
if (ret < 0)
dev_warn(smmu->dev, "failed to enable gerror irq\n");
}
@@ -2282,9 +2305,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device 
*smmu)
if (smmu->features & ARM_SMMU_FEAT_PRI) {
irq = smmu->priq.q.irq;
if (irq) {
+   irqflags = get_irq_flags(smmu, irq);
ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
arm_smmu_priq_thread,
-   IRQF_ONESHOT,
+   IRQF_ONESHOT | irqflags,
"arm-smmu-v3-priq",
smmu);
if (ret < 0)
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 2/7] iommu/arm-smmu-v3: Do resource size checks based on SMMU

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

With implementations supporting only page 0 register space,
resource size can be 64k as well and hence perform size checks
based on SMMU option PAGE0_REGS_ONLY.

For this, arm_smmu_device_dt_probe/acpi_probe has been moved before
platform_get_resource call, so that SMMU options are set beforehand.

Signed-off-by:  Linu Cherian 
Signed-off-by:  Geetha Sowjanya 
---
 drivers/iommu/arm-smmu-v3.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 107b4a6..f027676 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2672,6 +2672,14 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
return ret;
 }
 
+static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu)
+{
+   if (ARM_SMMU_PAGE0_REGS_ONLY(smmu))
+   return SZ_64K;
+   else
+   return SZ_128K;
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
int irq, ret;
@@ -2688,9 +2696,17 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
}
smmu->dev = dev;
 
+   if (dev->of_node) {
+   ret = arm_smmu_device_dt_probe(pdev, smmu);
+   } else {
+   ret = arm_smmu_device_acpi_probe(pdev, smmu);
+   if (ret == -ENODEV)
+   return ret;
+   }
+
/* Base address */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (resource_size(res) + 1 < SZ_128K) {
+   if (resource_size(res) + 1 < arm_smmu_resource_size(smmu)) {
dev_err(dev, "MMIO region too small (%pr)\n", res);
return -EINVAL;
}
@@ -2717,14 +2733,6 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (irq > 0)
smmu->gerr_irq = irq;
 
-   if (dev->of_node) {
-   ret = arm_smmu_device_dt_probe(pdev, smmu);
-   } else {
-   ret = arm_smmu_device_acpi_probe(pdev, smmu);
-   if (ret == -ENODEV)
-   return ret;
-   }
-
/* Set bypass mode according to firmware probing result */
bypass = !!ret;
 
-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 0/7] Cavium ThunderX2 SMMUv3 errata workarounds

2017-05-04 Thread Geetha sowjanya
From: Linu Cherian 

Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas.
1. Errata ID #74
   SMMU register alias Page 1 is not implemented
2. Errata ID #126
   SMMU doesnt support unique IRQ lines and also MSI for gerror, 
   eventq and cmdq-sync

The following patchset does software workaround for these two erratas.

This series is based on patchset. 
https://www.spinics.net/lists/arm-kernel/msg578443.html

Changes from v1:
 Since the use of MIDR register is rejected and SMMU_IIDR is broken on this 
 silicon, as suggested by Will Deacon modified the patches to use ThunderX2 
 SMMUv3 IORT model number to enable errata workaround.


Geetha Sowjanya (1):
  iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126

Linu Cherian (6):
  iommu/arm-smmu-v3: Introduce smmu option PAGE0_REGS_ONLY for ThunderX2
errata#74.
  iommu/arm-smmu-v3: Do resource size checks based on SMMU option
PAGE0_REGS_ONLY
  ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.
  iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY
option for ThunderX2 SMMUv3 implementations.
  ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3
model
  arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas

 Documentation/arm64/silicon-errata.txt |   2 +
 drivers/acpi/arm64/iort.c  |  10 ++-
 drivers/iommu/arm-smmu-v3.c| 122 ++---
 include/acpi/actbl2.h  |   2 +
 4 files changed, 110 insertions(+), 26 deletions(-)

-- 
1.8.3.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Joerg Roedel
On Thu, May 04, 2017 at 12:21:51PM +0300, Andy Shevchenko wrote:
> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> index cbf7763d8091..420d51b286ad 100644
> --- a/drivers/iommu/dmar.c
> +++ b/drivers/iommu/dmar.c
> @@ -1808,10 +1808,9 @@ IOMMU_INIT_POST(detect_intel_iommu);
>   * for Directed-IO Architecture Specifiction, Rev 2.2, Section 8.8
>   * "Remapping Hardware Unit Hot Plug".
>   */
> -static u8 dmar_hp_uuid[] = {
> - /*  */0xA6, 0xA3, 0xC1, 0xD8, 0x9B, 0xBE, 0x9B, 0x4C,
> - /* 0008 */0x91, 0xBF, 0xC3, 0xCB, 0x81, 0xFC, 0x5D, 0xAF
> -};
> +static uuid_le dmar_hp_uuid =
> + UUID_LE(0xD8C1A3A6, 0xBE9B, 0x4C9B,
> + 0x91, 0xBF, 0xC3, 0xCB, 0x81, 0xFC, 0x5D, 0xAF);
>  
>  /*
>   * Currently there's only one revision and BIOS will not check the revision 
> id,
> @@ -1824,7 +1823,7 @@ static u8 dmar_hp_uuid[] = {
>  
>  static inline bool dmar_detect_dsm(acpi_handle handle, int func)
>  {
> - return acpi_check_dsm(handle, dmar_hp_uuid, DMAR_DSM_REV_ID, 1 << func);
> + return acpi_check_dsm(handle, _hp_uuid, DMAR_DSM_REV_ID, 1 << 
> func);
>  }
>  
>  static int dmar_walk_dsm_resource(acpi_handle handle, int func,
> @@ -1843,7 +1842,7 @@ static int dmar_walk_dsm_resource(acpi_handle handle, 
> int func,
>   if (!dmar_detect_dsm(handle, func))
>   return 0;
>  
> - obj = acpi_evaluate_dsm_typed(handle, dmar_hp_uuid, DMAR_DSM_REV_ID,
> + obj = acpi_evaluate_dsm_typed(handle, _hp_uuid, DMAR_DSM_REV_ID,
> func, NULL, ACPI_TYPE_BUFFER);
>   if (!obj)
>   return -ENODEV;

DMAR part is

Acked-by: Joerg Roedel 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Heikki Krogerus
On Thu, May 04, 2017 at 12:21:51PM +0300, Andy Shevchenko wrote:
> acpi_evaluate_dsm() and friends take a pointer to a raw buffer of 16
> bytes. Instead we convert them to use uuid_le type. At the same time we
> convert current users.
> 
> acpi_str_to_uuid() becomes useless after the conversion and it's safe to
> get rid of it.
> 
> The conversion fixes a potential bug in int340x_thermal as well since
> we have to use memcmp() on binary data.
> 
> Cc: Rafael J. Wysocki 
> Cc: Mika Westerberg 
> Cc: Borislav Petkov 
> Cc: Dan Williams 
> Cc: Amir Goldstein 
> Cc: Jarkko Sakkinen 
> Cc: Jani Nikula 
> Cc: Ben Skeggs 
> Cc: Benjamin Tissoires 
> Cc: Joerg Roedel 
> Cc: Adrian Hunter 
> Cc: Yisen Zhuang 
> Cc: Bjorn Helgaas 
> Cc: Zhang Rui 
> Cc: Felipe Balbi 
> Cc: Mathias Nyman 
> Cc: Heikki Krogerus 
> Cc: Liam Girdwood 
> Cc: Mark Brown 
> Signed-off-by: Andy Shevchenko 

OK by me, FWIW:

Reviewed-by: Heikki Krogerus 


Thanks,

-- 
heikki
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 12/32] x86/mm: Insure that boot memory areas are mapped properly

2017-05-04 Thread Borislav Petkov
On Tue, Apr 18, 2017 at 04:18:22PM -0500, Tom Lendacky wrote:
> The boot data and command line data are present in memory in a decrypted
> state and are copied early in the boot process.  The early page fault
> support will map these areas as encrypted, so before attempting to copy
> them, add decrypted mappings so the data is accessed properly when copied.
> 
> For the initrd, encrypt this data in place. Since the future mapping of the
> initrd area will be mapped as encrypted the data will be accessed properly.
> 
> Signed-off-by: Tom Lendacky 
> ---
>  arch/x86/include/asm/mem_encrypt.h |   11 +
>  arch/x86/include/asm/pgtable.h |3 +
>  arch/x86/kernel/head64.c   |   30 --
>  arch/x86/kernel/setup.c|   10 +
>  arch/x86/mm/mem_encrypt.c  |   77 
> 
>  5 files changed, 127 insertions(+), 4 deletions(-)

...

> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 603a166..a95800b 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -115,6 +115,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /*
>   * max_low_pfn_mapped: highest direct mapped pfn under 4GB
> @@ -374,6 +375,15 @@ static void __init reserve_initrd(void)
>   !ramdisk_image || !ramdisk_size)
>   return; /* No initrd provided by bootloader */
>  
> + /*
> +  * If SME is active, this memory will be marked encrypted by the
> +  * kernel when it is accessed (including relocation). However, the
> +  * ramdisk image was loaded decrypted by the bootloader, so make
> +  * sure that it is encrypted before accessing it.
> +  */
> + if (sme_active())

That test is not needed here because __sme_early_enc_dec() already tests
sme_me_mask. There you should change that test to sme_active() instead.

> + sme_early_encrypt(ramdisk_image, ramdisk_end - ramdisk_image);
> +
>   initrd_start = 0;
>  
>   mapped_size = memblock_mem_size(max_pfn_mapped);

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Jani Nikula
On Thu, 04 May 2017, Andy Shevchenko  wrote:
> diff --git a/drivers/gpu/drm/i915/intel_acpi.c 
> b/drivers/gpu/drm/i915/intel_acpi.c
> index eb638a1e69d2..72bfe6ceadf8 100644
> --- a/drivers/gpu/drm/i915/intel_acpi.c
> +++ b/drivers/gpu/drm/i915/intel_acpi.c
> @@ -15,13 +15,9 @@ static struct intel_dsm_priv {
>   acpi_handle dhandle;
>  } intel_dsm_priv;
>  
> -static const u8 intel_dsm_guid[] = {
> - 0xd3, 0x73, 0xd8, 0x7e,
> - 0xd0, 0xc2,
> - 0x4f, 0x4e,
> - 0xa8, 0x54,
> - 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
> -};
> +static const uuid_le intel_dsm_guid =
> + UUID_LE(0x7ed873d3, 0xc2d0, 0x4e4f,
> + 0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c);
>  
>  static char *intel_dsm_port_name(u8 id)
>  {
> @@ -80,7 +76,7 @@ static void intel_dsm_platform_mux_info(void)
>   int i;
>   union acpi_object *pkg, *connector_count;
>  
> - pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
> + pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, _dsm_guid,
>   INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
>   NULL, ACPI_TYPE_PACKAGE);
>   if (!pkg) {
> @@ -118,7 +114,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev)
>   if (!dhandle)
>   return false;
>  
> - if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID,
> + if (!acpi_check_dsm(dhandle, _dsm_guid, INTEL_DSM_REVISION_ID,
>   1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
>   DRM_DEBUG_KMS("no _DSM method for intel device\n");
>   return false;

The drm/i915 hunk above is

Reviewed-by: Jani Nikula 

and acked for merging via whichever tree is suitable.


BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1] ACPI: Switch to use generic UUID API

2017-05-04 Thread Andy Shevchenko
acpi_evaluate_dsm() and friends take a pointer to a raw buffer of 16
bytes. Instead we convert them to use uuid_le type. At the same time we
convert current users.

acpi_str_to_uuid() becomes useless after the conversion and it's safe to
get rid of it.

The conversion fixes a potential bug in int340x_thermal as well since
we have to use memcmp() on binary data.

Cc: Rafael J. Wysocki 
Cc: Mika Westerberg 
Cc: Borislav Petkov 
Cc: Dan Williams 
Cc: Amir Goldstein 
Cc: Jarkko Sakkinen 
Cc: Jani Nikula 
Cc: Ben Skeggs 
Cc: Benjamin Tissoires 
Cc: Joerg Roedel 
Cc: Adrian Hunter 
Cc: Yisen Zhuang 
Cc: Bjorn Helgaas 
Cc: Zhang Rui 
Cc: Felipe Balbi 
Cc: Mathias Nyman 
Cc: Heikki Krogerus 
Cc: Liam Girdwood 
Cc: Mark Brown 
Signed-off-by: Andy Shevchenko 
---
 drivers/acpi/acpi_extlog.c | 10 +++---
 drivers/acpi/bus.c | 29 ++--
 drivers/acpi/nfit/core.c   | 40 +++---
 drivers/acpi/nfit/nfit.h   |  3 +-
 drivers/acpi/utils.c   |  4 +--
 drivers/char/tpm/tpm_crb.c |  9 +++--
 drivers/char/tpm/tpm_ppi.c | 20 +--
 drivers/gpu/drm/i915/intel_acpi.c  | 14 +++-
 drivers/gpu/drm/nouveau/nouveau_acpi.c | 20 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c |  9 +++--
 drivers/hid/i2c-hid/i2c-hid.c  |  9 +++--
 drivers/iommu/dmar.c   | 11 +++---
 drivers/mmc/host/sdhci-pci-core.c  |  9 +++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 15 
 drivers/pci/pci-acpi.c | 11 +++---
 drivers/pci/pci-label.c|  4 +--
 drivers/thermal/int340x_thermal/int3400_thermal.c  |  8 ++---
 drivers/usb/dwc3/dwc3-pci.c|  6 ++--
 drivers/usb/host/xhci-pci.c|  9 +++--
 drivers/usb/misc/ucsi.c|  2 +-
 drivers/usb/typec/typec_wcove.c|  4 +--
 include/acpi/acpi_bus.h|  9 ++---
 include/linux/acpi.h   |  4 +--
 include/linux/pci-acpi.h   |  2 +-
 sound/soc/intel/skylake/skl-nhlt.c |  7 ++--
 tools/testing/nvdimm/test/iomap.c  |  2 +-
 tools/testing/nvdimm/test/nfit.c   |  2 +-
 27 files changed, 116 insertions(+), 156 deletions(-)

diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 502ea4dc2080..69d6140b6afa 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -182,17 +182,17 @@ static int extlog_print(struct notifier_block *nb, 
unsigned long val,
 
 static bool __init extlog_get_l1addr(void)
 {
-   u8 uuid[16];
+   uuid_le uuid;
acpi_handle handle;
union acpi_object *obj;
 
-   acpi_str_to_uuid(extlog_dsm_uuid, uuid);
-
+   if (uuid_le_to_bin(extlog_dsm_uuid, ))
+   return false;
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", )))
return false;
-   if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR))
+   if (!acpi_check_dsm(handle, , EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR))
return false;
-   obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV,
+   obj = acpi_evaluate_dsm_typed(handle, , EXTLOG_DSM_REV,
  EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER);
if (!obj) {
return false;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 784bda663d16..e8130a4873e9 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -196,42 +196,19 @@ static void acpi_print_osc_error(acpi_handle handle,
pr_debug("\n");
 }
 
-acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
-{
-   int i;
-   static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
-   24, 26, 28, 30, 32, 34};
-
-   if (strlen(str) != 36)
-   return AE_BAD_PARAMETER;
-   for (i = 0; i < 36; i++) {
-   if (i == 8 || i == 13 || i == 18 || i == 23) {
-   if (str[i] != '-')
-   return AE_BAD_PARAMETER;
-   } else if (!isxdigit(str[i]))
-   return AE_BAD_PARAMETER;
-   }
-   for (i = 0; i < 16; i++) {
-   uuid[i] =