linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
@ 2020-02-20 19:44 Yonghyun Hwang
  2020-02-20 19:50 ` Moritz Fischer
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Yonghyun Hwang @ 2020-02-20 19:44 UTC (permalink / raw)
  To: David Woodhouse, Lu Baolu, Joerg Roedel
  Cc: iommu, linux-kernel, Havard Skinnemoen, Deepa Dinamani,
	Moritz Fischer, Yonghyun Hwang

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 <yonghyun@google.com>
---

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, &level);
 	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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-20 19:44 [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Yonghyun Hwang
@ 2020-02-20 19:50 ` Moritz Fischer
  2020-02-22 13:05 ` Lu Baolu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Moritz Fischer @ 2020-02-20 19:50 UTC (permalink / raw)
  To: Yonghyun Hwang
  Cc: David Woodhouse, Lu Baolu, Joerg Roedel, iommu, linux-kernel,
	Havard Skinnemoen, Deepa Dinamani, Moritz Fischer

Hi Yonghyun,

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.
> 
D'oh I meant to add a Cc: stable@vger.kernel.org here ... :)
> Signed-off-by: Yonghyun Hwang <yonghyun@google.com>
> ---
> 
> 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, &level);
>  	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
> 

Cheers,
Moritz

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-20 19:44 [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Yonghyun Hwang
  2020-02-20 19:50 ` Moritz Fischer
@ 2020-02-22 13:05 ` Lu Baolu
  2020-02-22 13:08   ` Lu Baolu
  2020-02-24 14:05   ` Lu Baolu
  2020-02-22 19:02 ` Moritz Fischer
  2020-02-25  5:53 ` Lu Baolu
  3 siblings, 2 replies; 7+ messages in thread
From: Lu Baolu @ 2020-02-22 13:05 UTC (permalink / raw)
  To: Yonghyun Hwang, David Woodhouse, Joerg Roedel
  Cc: baolu.lu, iommu, linux-kernel, Havard Skinnemoen, Deepa Dinamani,
	Moritz Fischer

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 <yonghyun@google.com>

This fix looks good to me.

Cc: <stable@kernel.org> # As far back as possible
Acked-by: Lu Baolu <baolu.lu@linux.intel.com>

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, &level);
>   	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;
>   }
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-22 13:05 ` Lu Baolu
@ 2020-02-22 13:08   ` Lu Baolu
  2020-02-24 14:05   ` Lu Baolu
  1 sibling, 0 replies; 7+ messages in thread
From: Lu Baolu @ 2020-02-22 13:08 UTC (permalink / raw)
  To: Yonghyun Hwang, David Woodhouse, Joerg Roedel
  Cc: baolu.lu, iommu, linux-kernel, Havard Skinnemoen, Deepa Dinamani,
	Moritz Fischer

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 <yonghyun@google.com>
> 
> This fix looks good to me.
> 
> Cc: <stable@kernel.org> # As far back as possible

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

Sorry about the typo.

Best regards,
baolu

> Acked-by: Lu Baolu <baolu.lu@linux.intel.com>
> 
> 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, &level);
>>       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;
>>   }
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-20 19:44 [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Yonghyun Hwang
  2020-02-20 19:50 ` Moritz Fischer
  2020-02-22 13:05 ` Lu Baolu
@ 2020-02-22 19:02 ` Moritz Fischer
  2020-02-25  5:53 ` Lu Baolu
  3 siblings, 0 replies; 7+ messages in thread
From: Moritz Fischer @ 2020-02-22 19:02 UTC (permalink / raw)
  To: Yonghyun Hwang
  Cc: David Woodhouse, Lu Baolu, Joerg Roedel, iommu, linux-kernel,
	Havard Skinnemoen, Deepa Dinamani, 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 <yonghyun@google.com>
Reviewed-by: Moritz Fischer <mdf@kernel.org>
> ---
> 
> 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, &level);
>  	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
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-22 13:05 ` Lu Baolu
  2020-02-22 13:08   ` Lu Baolu
@ 2020-02-24 14:05   ` Lu Baolu
  1 sibling, 0 replies; 7+ messages in thread
From: Lu Baolu @ 2020-02-24 14:05 UTC (permalink / raw)
  To: Yonghyun Hwang, David Woodhouse, Joerg Roedel
  Cc: baolu.lu, iommu, linux-kernel, Havard Skinnemoen, Deepa Dinamani,
	Moritz Fischer

Hi Joerg and Yonghyun,

I found a problem in the test. I am still working on this. Please hold
on for a while.

Best regards,
baolu

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 <yonghyun@google.com>
> 
> This fix looks good to me.
> 
> Cc: <stable@kernel.org> # As far back as possible
> Acked-by: Lu Baolu <baolu.lu@linux.intel.com>
> 
> 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, &level);
>>       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;
>>   }
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page
  2020-02-20 19:44 [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Yonghyun Hwang
                   ` (2 preceding siblings ...)
  2020-02-22 19:02 ` Moritz Fischer
@ 2020-02-25  5:53 ` Lu Baolu
  3 siblings, 0 replies; 7+ messages in thread
From: Lu Baolu @ 2020-02-25  5:53 UTC (permalink / raw)
  To: Yonghyun Hwang, David Woodhouse, Joerg Roedel
  Cc: baolu.lu, iommu, linux-kernel, Havard Skinnemoen, Deepa Dinamani,
	Moritz Fischer

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 <yonghyun@google.com>
> ---
> 
> 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, &level);
>   	if (pte)

Need to check whether the pte is present here. Otherwise, the returned
level makes no sense.

Increased change looks like:

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 61c7ef2f33b4..33593fea0250 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5700,7 +5700,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct 
iommu_domain *domain,
         u64 phys = 0;

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

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

Best regards,
baolu

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-02-25  5:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-20 19:44 [PATCH v2] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Yonghyun Hwang
2020-02-20 19:50 ` Moritz Fischer
2020-02-22 13:05 ` Lu Baolu
2020-02-22 13:08   ` Lu Baolu
2020-02-24 14:05   ` Lu Baolu
2020-02-22 19:02 ` Moritz Fischer
2020-02-25  5:53 ` Lu Baolu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).