Re: [PATCH 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
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
On Thu, May 04, 2017 at 02:28:53PM -0600, Alex Williamson wrote: > On Thu, 27 Apr 2017 18:53:17 +0800 > Peter Xuwrote: > > > 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
On Thu, 27 Apr 2017 18:53:17 +0800 Peter Xuwrote: > 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
On Thu, May 4, 2017 at 11:32 PM, Robin Murphywrote: > [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
On Thu, May 4, 2017 at 11:50 PM, Robin Murphywrote: > 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
On Thu, May 4, 2017 at 11:32 PM, Robin Murphywrote: > [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
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
[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
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
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
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
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
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
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
On Thu, May 4, 2017 at 8:34 AM, Rob Clarkwrote: > 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
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
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
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
On Thu, May 4, 2017 at 4:21 AM, Andy Shevchenkowrote: > 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
From: Stanimir VarbanovThis 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
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
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
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 ClarkSigned-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)
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
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.
From: Linu CherianEnable 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
From: Linu CherianAdd 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.
From: Linu CherianAdd 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
From: Linu CherianCavium 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
From: Geetha SowjanyaCavium 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
From: Linu CherianWith 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
From: Linu CherianCavium 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
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
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
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
On Thu, 04 May 2017, Andy Shevchenkowrote: > 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
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. WysockiCc: 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] =