Re: [PATCH V2 2/5] iommu/vt-d: Rename device_def_domain_type() to intel_iommu_dev_def_domain_type()

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/23 7:59, Prakhya, Sai Praneeth wrote:


On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:

The functionality needed for iommu_ops->dev_def_domain_type() is
already provided by device_def_domain_type() in intel_iommu.c. But,
every call back function in intel_iommu_ops starts with intel_iommu
prefix, hence rename
device_def_domain_type() to intel_iommu_dev_def_domain_type() so that
it follows the same semantics.


How about keep device_def_domain_type() and call it in the new
intel_iommu_dev_def_domain_type()?


Sure! I could but could you please explain the advantages we might get by doing 
so?
Less number of changes is what I could think of.. any other reasons?



device_def_domain_type() is a quirk list for devices that must use a
specified domain type. intel_iommu_dev_def_domain_type() tells the upper
layer whether the device could switch to another type of domain. Put
them in separated functions will make it easier for maintenance.

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


Re: [PATCH V2 5/5] iommu: Document usage of "/sys/kernel/iommu_groups//type" file

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:

The default domain type of an iommu group can be changed using file
"/sys/kernel/iommu_groups//type". Hence, document it's usage and
more importantly spell out it's limitations.

Cc: Christoph Hellwig 
Cc: Joerg Roedel 
Cc: Ashok Raj 
Cc: Will Deacon 
Cc: Lu Baolu 
Cc: Sohil Mehta 
Cc: Robin Murphy 
Cc: Jacob Pan 
Signed-off-by: Sai Praneeth Prakhya 
---
  .../ABI/testing/sysfs-kernel-iommu_groups  | 29 ++
  1 file changed, 29 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-kernel-iommu_groups 
b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
index 017f5bc3920c..808a9507b281 100644
--- a/Documentation/ABI/testing/sysfs-kernel-iommu_groups
+++ b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
@@ -33,3 +33,32 @@ Description:In case an RMRR is used only by graphics or 
USB devices
it is now exposed as "direct-relaxable" instead of "direct".
In device assignment use case, for instance, those RMRR
are considered to be relaxable and safe.
+
+What:  /sys/kernel/iommu_groups//type
+Date:  February 2020
+KernelVersion: v5.6
+Contact:   Sai Praneeth Prakhya 
+Description:   Lets the user know the type of default domain in use by iommu
+   for this group. A privileged user could request kernel to change


Let the users know the default domain type of the IOMMU group by
reading this file. A privileged user could request to change it by
writing to this file.


+   the group type by writing to this file. Presently, only three
+   types are supported
+   1. DMA: All the DMA transactions from the devices in this group
+   are translated by the iommu.
+   2. identity: All the DMA transactions from the devices in this
+group are *not* translated by the iommu.
+   3. auto: Kernel decides one among DMA/identity mode and hence
+when the user reads the file he would never see "auto".


Just out of curiosity, when could a user reads "auto" from this file?


+This is just a write only value.
+   Note:
+   -
+   A group type could be modified only when *all* the devices in


group's default domain type (not group type).


+   the group are not binded to any device driver. So, the user has


bound


+   to first unbind the appropriate drivers and then change the
+   default domain type.
+   Caution:
+   
+   Unbinding a device driver will take away the drivers control
+   over the device and if done on devices that host root file
+   system could lead to catastrophic effects (the user might
+   need to reboot the machine to get it to normal state). So, it's
+   expected that the user understands what he is doing.



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


Re: [PATCH V2 3/5] iommu: Add support to change default domain of an iommu_group

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:

Presently, the default domain of an iommu_group is allocated during boot
time (i.e. when a device is being added to a group) and it cannot be
changed later. So, the device would typically be either in identity (also
known as pass_through) mode (controlled by "iommu=pt" kernel command line


The default domain type is initialized according to the kernel build
option, and could be overrided by several kernel commands like iommu=pt
and iommu.passthrough.


argument) or the device would be in DMA mode as long as the machine is up
and running. There is no way to change the default domain type dynamically
i.e. after booting, a device cannot switch between identity mode and DMA
mode.

But, assume a use case wherein the user trusts the device and also believes
that the OS is secure enough and hence wants *only* this device to bypass
IOMMU (so that it could be high performing) whereas all the other devices
to go through IOMMU (so that the system is protected). Presently, this use
case is not supported. Hence it will be helpful if there is some way to
change the default domain of a B:D.F dynamically. Since, linux iommu
subsystem prefers to deal at iommu_group level instead of B:D.F level, it
might be helpful if there is some way to change the default domain of a
*iommu_group* dynamically. Hence, add such support.

A privileged user could request the kernel to change the default domain
type of a iommu_group by writing to
"/sys/kernel/iommu_groups//type"
file. Presently, only three values are supported
1. identity: all the DMA transactions from the devices in this group are
 *not* translated by the iommu
2. DMA: all the DMA transactions from the devices in this group are
translated by the iommu
3. auto: kernel decides one among DMA/identity

Also please note that a group type could be modified only when *all* the
devices in the group are not binded to any device driver. Please see
"Documentation/ABI/testing/sysfs-kernel-iommu_groups" for more information.

Cc: Christoph Hellwig 
Cc: Joerg Roedel 
Cc: Ashok Raj 
Cc: Will Deacon 
Cc: Lu Baolu 
Cc: Sohil Mehta 
Cc: Robin Murphy 
Cc: Jacob Pan 
Signed-off-by: Sai Praneeth Prakhya 
---
  drivers/iommu/iommu.c | 227 +-
  1 file changed, 226 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3e3528436e0b..56a29076871f 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -225,6 +225,8 @@ static int __iommu_attach_group(struct iommu_domain *domain,
struct iommu_group *group);
  static void __iommu_detach_group(struct iommu_domain *domain,
 struct iommu_group *group);
+static ssize_t iommu_group_store_type(struct iommu_group *group,
+ const char *buf, size_t count);
  
  static int __init iommu_set_def_domain_type(char *str)

  {
@@ -448,7 +450,8 @@ static IOMMU_GROUP_ATTR(name, S_IRUGO, 
iommu_group_show_name, NULL);
  static IOMMU_GROUP_ATTR(reserved_regions, 0444,
iommu_group_show_resv_regions, NULL);
  
-static IOMMU_GROUP_ATTR(type, 0444, iommu_group_show_type, NULL);

+static IOMMU_GROUP_ATTR(type, 0644, iommu_group_show_type,
+   iommu_group_store_type);
  
  static void iommu_group_release(struct kobject *kobj)

  {
@@ -2654,3 +2657,225 @@ int iommu_sva_get_pasid(struct iommu_sva *handle)
return ops->sva_get_pasid(handle);
  }
  EXPORT_SYMBOL_GPL(iommu_sva_get_pasid);
+
+/*
+ * Changes the default domain of a group
+ *
+ * @group: The group for which the default domain should be changed
+ * @prv_dom: The previous domain that is being switched from


The previous domain is still kept in group->default_domain, so it's
unnecessary to pass it as a parameter, right?


+ * @type: The type of the new default domain that gets associated with the 
group
+ *
+ * Returns 0 on success and error code on failure
+ */
+static int iommu_group_change_def_domain(struct iommu_group *group,
+struct iommu_domain *prv_dom,
+int type)
+{
+   struct group_device *grp_dev, *temp;
+   struct iommu_domain *new_domain;
+   int ret;
+
+   /*
+* iommu_domain_alloc() takes "struct bus_type" as an argument which is
+* a member in "struct device". Changing a group's default domain type
+* deals at iommu_group level rather than device level and hence there
+* is no straight forward way to get "bus_type" of an iommu_group that
+* could be passed to iommu_domain_alloc(). So, instead of directly
+* calling iommu_domain_alloc(), use iommu_ops from previous default
+* domain.
+*/
+   if (!prv_dom || !prv_dom->ops || !prv_dom->ops->domain_alloc || !type)
+   return -EINVAL;
+
+   /* Allocate a new domain of 

RE: [PATCH V2 2/5] iommu/vt-d: Rename device_def_domain_type() to intel_iommu_dev_def_domain_type()

2020-02-22 Thread Prakhya, Sai Praneeth
> 
> On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:
> > The functionality needed for iommu_ops->dev_def_domain_type() is
> > already provided by device_def_domain_type() in intel_iommu.c. But,
> > every call back function in intel_iommu_ops starts with intel_iommu
> > prefix, hence rename
> > device_def_domain_type() to intel_iommu_dev_def_domain_type() so that
> > it follows the same semantics.
> 
> How about keep device_def_domain_type() and call it in the new
> intel_iommu_dev_def_domain_type()?

Sure! I could but could you please explain the advantages we might get by doing 
so?
Less number of changes is what I could think of.. any other reasons?

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


Re: [PATCH V2 2/5] iommu/vt-d: Rename device_def_domain_type() to intel_iommu_dev_def_domain_type()

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:

The functionality needed for iommu_ops->dev_def_domain_type() is already
provided by device_def_domain_type() in intel_iommu.c. But, every call back
function in intel_iommu_ops starts with intel_iommu prefix, hence rename
device_def_domain_type() to intel_iommu_dev_def_domain_type() so that it
follows the same semantics.


How about keep device_def_domain_type() and call it in the new
intel_iommu_dev_def_domain_type()?

Best regards,
baolu



Cc: Christoph Hellwig 
Cc: Joerg Roedel 
Cc: Ashok Raj 
Cc: Will Deacon 
Cc: Lu Baolu 
Cc: Sohil Mehta 
Cc: Robin Murphy 
Cc: Jacob Pan 
Signed-off-by: Sai Praneeth Prakhya 
---
  drivers/iommu/intel-iommu.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 64ddccf1d5fe..68f10d271ac0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3034,7 +3034,7 @@ static bool device_is_rmrr_locked(struct device *dev)
   *  - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
   *  - 0: both identity and dynamic domains work for this device
   */
-static int device_def_domain_type(struct device *dev)
+static int intel_iommu_dev_def_domain_type(struct device *dev)
  {
if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);
@@ -5796,7 +5796,8 @@ static int intel_iommu_add_device(struct device *dev)
domain = iommu_get_domain_for_dev(dev);
dmar_domain = to_dmar_domain(domain);
if (domain->type == IOMMU_DOMAIN_DMA) {
-   if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) {
+   if (intel_iommu_dev_def_domain_type(dev) ==
+   IOMMU_DOMAIN_IDENTITY) {
ret = iommu_request_dm_for_dev(dev);
if (ret) {
dmar_remove_one_dev_info(dev);
@@ -5807,7 +5808,7 @@ static int intel_iommu_add_device(struct device *dev)
}
}
} else {
-   if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
+   if (intel_iommu_dev_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
ret = iommu_request_dma_domain_for_dev(dev);
if (ret) {
dmar_remove_one_dev_info(dev);
@@ -6194,6 +6195,7 @@ const struct iommu_ops intel_iommu_ops = {
.dev_enable_feat= intel_iommu_dev_enable_feat,
.dev_disable_feat   = intel_iommu_dev_disable_feat,
.is_attach_deferred = intel_iommu_is_attach_deferred,
+   .dev_def_domain_type= intel_iommu_dev_def_domain_type,
.pgsize_bitmap  = INTEL_IOMMU_PGSIZES,
  };
  


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


RE: [PATCH V2 0/5] iommu: Add support to change default domain of a group

2020-02-22 Thread Prakhya, Sai Praneeth
Hi Joerg,

> Presently, the default domain of a group is allocated during boot time and it
> cannot be changed later. So, the device would typically be either in identity
> (pass_through) mode or the device would be in DMA mode as long as the system
> is up and running. There is no way to change the default domain type
> dynamically i.e. after booting, a device cannot switch between identity mode
> and DMA mode.
> 
> Assume a use case wherein the privileged user would want to use the device in
> pass-through mode when the device is used for host so that it would be high
> performing. Presently, this is not supported. Hence add support to change the
> default domain of a group dynamically.
> 
> Support this through a sysfs file, namely
> "/sys/kernel/iommu_groups//type".
> 
> Hi Joerg,
> Sorry! for _huge_ delay in posting a V2 of this patch set. Was stuck with some
> internal PoC work. Will be consistent from now.
> 
> Changes from V1:
> 
> 1. V1 patch set wasn't updating dma_ops for some vendors (Eg: AMD), hence,
>change the logic of updating default domain as below (because adding a
> device
>to iommu_group automatically updates dma_ops)
>a. Allocate a new domain
>b. For every device in the group
>   i. Remove the device from the group
>   ii. Add the device back to the group
>c. Free previous domain
> 2. Drop 1st patch of V1 (iommu/vt-d: Modify device_def_domain_type() to use
> at
>runtime) because "iommu=pt" has no effect on this function anymore.
> 3. Added a patch to take/release lock while reading iommu_group-
> >default_domain->type
>because it can be changed any time by user.
> 4. Before changing default domain type of a group, check if the group is
>directly assigned for user level access. If so, abort.
> 5. Sanitize return path (using ternary operator) in iommu_group_store_type() 
> 6.
> Split 2nd patch of V1 (iommu: Add device_def_domain_type() call back function
>to iommu_ops) into two patches such that iommu generic changes are now in
> 1st
>patch of V2 and vt-d specific changes are in 2nd patch of V2.
> 7. Rename device_def_domain_type() to dev_def_domain_type() 8. Remove
> example from documentation 9. Change the value written to file
> "/sys/kernel/iommu_groups//type"
>from "dma" to "DMA".

Just a gentle reminder, could you please review this patch set and let me know 
your comments?

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


RE: [PATCH V2 1/5] iommu: Add dev_def_domain_type() call back function to iommu_ops

2020-02-22 Thread Prakhya, Sai Praneeth
> 
> On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:
> > When user requests kernel to change the default domain type of a group
> > through sysfs, kernel has to make sure that it's ok to change the
> > domain type of every device in the group to the requested domain
> > (every device may not support both the domain types i.e. DMA and
> > identity). Hence, add a call back function that could be implemented
> > per architecture that performs the above check.
> >
> > Cc: Christoph Hellwig 
> > Cc: Joerg Roedel 
> > Cc: Ashok Raj 
> > Cc: Will Deacon 
> > Cc: Lu Baolu 
> > Cc: Sohil Mehta 
> > Cc: Robin Murphy 
> > Cc: Jacob Pan 
> > Signed-off-by: Sai Praneeth Prakhya 
> > ---
> >   include/linux/iommu.h | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h index
> > d1b5f4d98569..3f4aaad0aeb7 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -248,6 +248,7 @@ struct iommu_iotlb_gather {
> >* @cache_invalidate: invalidate translation caches
> >* @sva_bind_gpasid: bind guest pasid and mm
> >* @sva_unbind_gpasid: unbind guest pasid and mm
> > + * @dev_def_domain_type: Return the required default domain type for
> > + a device
> 
> Can you please define the return value of this callback?

Sure! I will add it in the next version

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


Re: [PATCH V2 1/5] iommu: Add dev_def_domain_type() call back function to iommu_ops

2020-02-22 Thread Lu Baolu

Hi Sai,

On 2020/2/17 5:57, Sai Praneeth Prakhya wrote:

When user requests kernel to change the default domain type of a group
through sysfs, kernel has to make sure that it's ok to change the domain
type of every device in the group to the requested domain (every device may
not support both the domain types i.e. DMA and identity). Hence, add a call
back function that could be implemented per architecture that performs the
above check.

Cc: Christoph Hellwig 
Cc: Joerg Roedel 
Cc: Ashok Raj 
Cc: Will Deacon 
Cc: Lu Baolu 
Cc: Sohil Mehta 
Cc: Robin Murphy 
Cc: Jacob Pan 
Signed-off-by: Sai Praneeth Prakhya 
---
  include/linux/iommu.h | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d1b5f4d98569..3f4aaad0aeb7 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -248,6 +248,7 @@ struct iommu_iotlb_gather {
   * @cache_invalidate: invalidate translation caches
   * @sva_bind_gpasid: bind guest pasid and mm
   * @sva_unbind_gpasid: unbind guest pasid and mm
+ * @dev_def_domain_type: Return the required default domain type for a device


Can you please define the return value of this callback?

Best regards,
baolu


   * @pgsize_bitmap: bitmap of all possible supported page sizes
   * @owner: Driver module providing these ops
   */
@@ -318,6 +319,8 @@ struct iommu_ops {
  
  	int (*sva_unbind_gpasid)(struct device *dev, int pasid);
  
+	int (*dev_def_domain_type)(struct device *dev);

+
unsigned long pgsize_bitmap;
struct module *owner;
  };


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


Re: [PATCH 2/2] virtio: let virtio use DMA API when guest RAM is protected

2020-02-22 Thread Michael S. Tsirkin
On Fri, Feb 21, 2020 at 03:33:40PM +0100, Halil Pasic wrote:
> AFAIU you have a positive attitude towards the idea, that 
> !F_VIRTIO_PLATFORM implies 'no DMA API is used by virtio' 
> should be scrapped. 
> 
> I would like to accomplish that without adverse effects to virtio-ccw
> (because caring for virtio-ccw is a part of job description).
> 
> Regards,
> Halil

It is possible, in theory. IIRC the main challenge is that DMA API
has overhead of indirect function calls even when all it
does it return back the PA without changes. So that will lead to
a measureable performance degradation. That might be fixable,
possibly using some kind of logic along the lines of
if (iova is pa)
return pa
else
indirect call

and for unmapping, we might need an API that says "unmap
is a nop, safe to skip" so we don't maintain the
dma address until unmap.


-- 
MST

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


Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page

2020-02-22 Thread Moritz Fischer
On Thu, Feb 20, 2020 at 11:44:31AM -0800, Yonghyun Hwang wrote:
> intel_iommu_iova_to_phys() has a bug when it translates an IOVA for a huge
> page onto its corresponding physical address. This commit fixes the bug by
> accomodating the level of page entry for the IOVA and adds IOVA's lower
> address to the physical address.
> 
> Signed-off-by: Yonghyun Hwang 
Reviewed-by: Moritz Fischer 
> ---
> 
> Changes from v1:
> - level cannot be 0. So, the condition, "if (level > 1)", is removed, which 
> results in a simple code.
> - a macro, BIT_MASK, is used to have a bit mask
> 
> ---
>  drivers/iommu/intel-iommu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 932267f49f9a..4fd5c6287b6d 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -5554,7 +5554,9 @@ static phys_addr_t intel_iommu_iova_to_phys(struct 
> iommu_domain *domain,
>  
>   pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, );
>   if (pte)
> - phys = dma_pte_addr(pte);
> + phys = dma_pte_addr(pte) +
> + (iova & (BIT_MASK(level_to_offset_bits(level) +
> + VTD_PAGE_SHIFT) - 1));
>  
>   return phys;
>  }
> -- 
> 2.25.0.265.gbab2e86ba0-goog
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/22 21:05, Lu Baolu wrote:

Hi,

On 2020/2/21 3:44, Yonghyun Hwang wrote:
intel_iommu_iova_to_phys() has a bug when it translates an IOVA for a 
huge
page onto its corresponding physical address. This commit fixes the 
bug by

accomodating the level of page entry for the IOVA and adds IOVA's lower
address to the physical address.

Signed-off-by: Yonghyun Hwang 


This fix looks good to me.

Cc:  # As far back as possible


The email address should be: sta...@vger.kernel.org.

Sorry about the typo.

Best regards,
baolu


Acked-by: Lu Baolu 

Best regards,
baolu


---

Changes from v1:
- level cannot be 0. So, the condition, "if (level > 1)", is removed, 
which results in a simple code.

- a macro, BIT_MASK, is used to have a bit mask

---
  drivers/iommu/intel-iommu.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 932267f49f9a..4fd5c6287b6d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5554,7 +5554,9 @@ static phys_addr_t 
intel_iommu_iova_to_phys(struct iommu_domain *domain,

  pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, );
  if (pte)
-    phys = dma_pte_addr(pte);
+    phys = dma_pte_addr(pte) +
+    (iova & (BIT_MASK(level_to_offset_bits(level) +
+    VTD_PAGE_SHIFT) - 1));
  return phys;
  }


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

Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page

2020-02-22 Thread Lu Baolu

Hi,

On 2020/2/21 3:44, Yonghyun Hwang wrote:

intel_iommu_iova_to_phys() has a bug when it translates an IOVA for a huge
page onto its corresponding physical address. This commit fixes the bug by
accomodating the level of page entry for the IOVA and adds IOVA's lower
address to the physical address.

Signed-off-by: Yonghyun Hwang 


This fix looks good to me.

Cc:  # As far back as possible
Acked-by: Lu Baolu 

Best regards,
baolu


---

Changes from v1:
- level cannot be 0. So, the condition, "if (level > 1)", is removed, which 
results in a simple code.
- a macro, BIT_MASK, is used to have a bit mask

---
  drivers/iommu/intel-iommu.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 932267f49f9a..4fd5c6287b6d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5554,7 +5554,9 @@ static phys_addr_t intel_iommu_iova_to_phys(struct 
iommu_domain *domain,
  
  	pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, );

if (pte)
-   phys = dma_pte_addr(pte);
+   phys = dma_pte_addr(pte) +
+   (iova & (BIT_MASK(level_to_offset_bits(level) +
+   VTD_PAGE_SHIFT) - 1));
  
  	return phys;

  }


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