All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-20  8:17 ` Lu Baolu
  0 siblings, 0 replies; 31+ messages in thread
From: Lu Baolu @ 2022-06-20  8:17 UTC (permalink / raw)
  To: Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: Chenyi Qiang, Liu Yi L, Jacob jun Pan, iommu, linux-kernel,
	Lu Baolu, stable

The IOMMU driver shares the pasid table for PCI alias devices. When the
RID2PASID entry of the shared pasid table has been filled by the first
device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
failed" failure as the pasid entry has already been marke as present. As
the result, the IOMMU probing process will be aborted.

This fixes it by skipping RID2PASID setting if the pasid entry has been
populated. This works because the IOMMU core ensures that only the same
IOMMU domain can be attached to all PCI alias devices at the same time.
Therefore the subsequent devices just try to setup the RID2PASID entry
with the same domain, which is negligible.

Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID support")
Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/iommu/intel/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..b9966c01a2a2 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
 			ret = intel_pasid_setup_second_level(iommu, domain,
 					dev, PASID_RID2PASID);
 		spin_unlock_irqrestore(&iommu->lock, flags);
-		if (ret) {
+		if (ret && ret != -EBUSY) {
 			dev_err(dev, "Setup RID2PASID failed\n");
 			dmar_remove_one_dev_info(dev);
 			return ret;
-- 
2.25.1


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

* [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-20  8:17 ` Lu Baolu
  0 siblings, 0 replies; 31+ messages in thread
From: Lu Baolu @ 2022-06-20  8:17 UTC (permalink / raw)
  To: Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: linux-kernel, stable, Chenyi Qiang, iommu, Jacob jun Pan

The IOMMU driver shares the pasid table for PCI alias devices. When the
RID2PASID entry of the shared pasid table has been filled by the first
device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
failed" failure as the pasid entry has already been marke as present. As
the result, the IOMMU probing process will be aborted.

This fixes it by skipping RID2PASID setting if the pasid entry has been
populated. This works because the IOMMU core ensures that only the same
IOMMU domain can be attached to all PCI alias devices at the same time.
Therefore the subsequent devices just try to setup the RID2PASID entry
with the same domain, which is negligible.

Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID support")
Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/iommu/intel/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 44016594831d..b9966c01a2a2 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
 			ret = intel_pasid_setup_second_level(iommu, domain,
 					dev, PASID_RID2PASID);
 		spin_unlock_irqrestore(&iommu->lock, flags);
-		if (ret) {
+		if (ret && ret != -EBUSY) {
 			dev_err(dev, "Setup RID2PASID failed\n");
 			dmar_remove_one_dev_info(dev);
 			return ret;
-- 
2.25.1

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

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-20  8:17 ` Lu Baolu
@ 2022-06-20  8:31   ` Yi Liu
  -1 siblings, 0 replies; 31+ messages in thread
From: Yi Liu @ 2022-06-20  8:31 UTC (permalink / raw)
  To: Lu Baolu, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: Chenyi Qiang, Jacob jun Pan, iommu, linux-kernel, stable

Hi Baolu,

On 2022/6/20 16:17, Lu Baolu wrote:
> The IOMMU driver shares the pasid table for PCI alias devices. When the
> RID2PASID entry of the shared pasid table has been filled by the first
> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
> failed" failure as the pasid entry has already been marke as present. As

s/marke/marked/

> the result, the IOMMU probing process will be aborted.
> 
> This fixes it by skipping RID2PASID setting if the pasid entry has been
> populated. This works because the IOMMU core ensures that only the same
> IOMMU domain can be attached to all PCI alias devices at the same time.

nit. this sentence is a little bit to interpret. :-) I guess what you want
to describe is the PCI alias devices should be attached to the same domain
instead of different domain. right?

also, does it apply to all domain types? e.g. the SVA domains introduced in 
"iommu: SVA and IOPF refactoring"

> Therefore the subsequent devices just try to setup the RID2PASID entry
> with the same domain, which is negligible.
> 
> Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID support")
> Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>   drivers/iommu/intel/iommu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 44016594831d..b9966c01a2a2 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
>   			ret = intel_pasid_setup_second_level(iommu, domain,
>   					dev, PASID_RID2PASID);
>   		spin_unlock_irqrestore(&iommu->lock, flags);
> -		if (ret) {
> +		if (ret && ret != -EBUSY) {
>   			dev_err(dev, "Setup RID2PASID failed\n");
>   			dmar_remove_one_dev_info(dev);
>   			return ret;

-- 
Regards,
Yi Liu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-20  8:31   ` Yi Liu
  0 siblings, 0 replies; 31+ messages in thread
From: Yi Liu @ 2022-06-20  8:31 UTC (permalink / raw)
  To: Lu Baolu, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: linux-kernel, iommu, Chenyi Qiang, stable, Jacob jun Pan

Hi Baolu,

On 2022/6/20 16:17, Lu Baolu wrote:
> The IOMMU driver shares the pasid table for PCI alias devices. When the
> RID2PASID entry of the shared pasid table has been filled by the first
> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
> failed" failure as the pasid entry has already been marke as present. As

s/marke/marked/

> the result, the IOMMU probing process will be aborted.
> 
> This fixes it by skipping RID2PASID setting if the pasid entry has been
> populated. This works because the IOMMU core ensures that only the same
> IOMMU domain can be attached to all PCI alias devices at the same time.

nit. this sentence is a little bit to interpret. :-) I guess what you want
to describe is the PCI alias devices should be attached to the same domain
instead of different domain. right?

also, does it apply to all domain types? e.g. the SVA domains introduced in 
"iommu: SVA and IOPF refactoring"

> Therefore the subsequent devices just try to setup the RID2PASID entry
> with the same domain, which is negligible.
> 
> Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID support")
> Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>   drivers/iommu/intel/iommu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 44016594831d..b9966c01a2a2 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
>   			ret = intel_pasid_setup_second_level(iommu, domain,
>   					dev, PASID_RID2PASID);
>   		spin_unlock_irqrestore(&iommu->lock, flags);
> -		if (ret) {
> +		if (ret && ret != -EBUSY) {
>   			dev_err(dev, "Setup RID2PASID failed\n");
>   			dmar_remove_one_dev_info(dev);
>   			return ret;

-- 
Regards,
Yi Liu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-20  8:31   ` Yi Liu
@ 2022-06-20  8:57     ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-20  8:57 UTC (permalink / raw)
  To: Yi Liu, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: linux-kernel, stable, Chenyi Qiang, iommu, Jacob jun Pan

On 2022/6/20 16:31, Yi Liu wrote:
> Hi Baolu,
> 
> On 2022/6/20 16:17, Lu Baolu wrote:
>> The IOMMU driver shares the pasid table for PCI alias devices. When the
>> RID2PASID entry of the shared pasid table has been filled by the first
>> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
>> failed" failure as the pasid entry has already been marke as present. As
> 
> s/marke/marked/

Updated. Thanks!

>> the result, the IOMMU probing process will be aborted.
>>
>> This fixes it by skipping RID2PASID setting if the pasid entry has been
>> populated. This works because the IOMMU core ensures that only the same
>> IOMMU domain can be attached to all PCI alias devices at the same time.
> 
> nit. this sentence is a little bit to interpret. :-) I guess what you want
> to describe is the PCI alias devices should be attached to the same domain
> instead of different domain. right?

Yes.

> 
> also, does it apply to all domain types? e.g. the SVA domains introduced 
> in "iommu: SVA and IOPF refactoring"

No. Only about the RID2PASID.

> 
>> Therefore the subsequent devices just try to setup the RID2PASID entry
>> with the same domain, which is negligible.
>>
>> Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID 
>> support")
>> Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
>> ---
>>   drivers/iommu/intel/iommu.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
>> index 44016594831d..b9966c01a2a2 100644
>> --- a/drivers/iommu/intel/iommu.c
>> +++ b/drivers/iommu/intel/iommu.c
>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct 
>> dmar_domain *domain, struct device *dev)
>>               ret = intel_pasid_setup_second_level(iommu, domain,
>>                       dev, PASID_RID2PASID);
>>           spin_unlock_irqrestore(&iommu->lock, flags);
>> -        if (ret) {
>> +        if (ret && ret != -EBUSY) {
>>               dev_err(dev, "Setup RID2PASID failed\n");
>>               dmar_remove_one_dev_info(dev);
>>               return ret;
> 

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

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-20  8:57     ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-20  8:57 UTC (permalink / raw)
  To: Yi Liu, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: baolu.lu, Chenyi Qiang, Jacob jun Pan, iommu, linux-kernel, stable

On 2022/6/20 16:31, Yi Liu wrote:
> Hi Baolu,
> 
> On 2022/6/20 16:17, Lu Baolu wrote:
>> The IOMMU driver shares the pasid table for PCI alias devices. When the
>> RID2PASID entry of the shared pasid table has been filled by the first
>> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
>> failed" failure as the pasid entry has already been marke as present. As
> 
> s/marke/marked/

Updated. Thanks!

>> the result, the IOMMU probing process will be aborted.
>>
>> This fixes it by skipping RID2PASID setting if the pasid entry has been
>> populated. This works because the IOMMU core ensures that only the same
>> IOMMU domain can be attached to all PCI alias devices at the same time.
> 
> nit. this sentence is a little bit to interpret. :-) I guess what you want
> to describe is the PCI alias devices should be attached to the same domain
> instead of different domain. right?

Yes.

> 
> also, does it apply to all domain types? e.g. the SVA domains introduced 
> in "iommu: SVA and IOPF refactoring"

No. Only about the RID2PASID.

> 
>> Therefore the subsequent devices just try to setup the RID2PASID entry
>> with the same domain, which is negligible.
>>
>> Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID 
>> support")
>> Reported-by: Chenyi Qiang <chenyi.qiang@intel.com>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
>> ---
>>   drivers/iommu/intel/iommu.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
>> index 44016594831d..b9966c01a2a2 100644
>> --- a/drivers/iommu/intel/iommu.c
>> +++ b/drivers/iommu/intel/iommu.c
>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct 
>> dmar_domain *domain, struct device *dev)
>>               ret = intel_pasid_setup_second_level(iommu, domain,
>>                       dev, PASID_RID2PASID);
>>           spin_unlock_irqrestore(&iommu->lock, flags);
>> -        if (ret) {
>> +        if (ret && ret != -EBUSY) {
>>               dev_err(dev, "Setup RID2PASID failed\n");
>>               dmar_remove_one_dev_info(dev);
>>               return ret;
> 

--
Best regards,
baolu

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-20  8:17 ` Lu Baolu
@ 2022-06-21  2:54   ` Tian, Kevin
  -1 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  2:54 UTC (permalink / raw)
  To: Lu Baolu, Joerg Roedel, Raj, Ashok
  Cc: Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu, linux-kernel, stable

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Monday, June 20, 2022 4:17 PM
> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> dmar_domain *domain, struct device *dev)
>  			ret = intel_pasid_setup_second_level(iommu,
> domain,
>  					dev, PASID_RID2PASID);
>  		spin_unlock_irqrestore(&iommu->lock, flags);
> -		if (ret) {
> +		if (ret && ret != -EBUSY) {
>  			dev_err(dev, "Setup RID2PASID failed\n");
>  			dmar_remove_one_dev_info(dev);
>  			return ret;
> --
> 2.25.1

It's cleaner to avoid this error at the first place, i.e. only do the
setup when the first device is attached to the pasid table.

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  2:54   ` Tian, Kevin
  0 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  2:54 UTC (permalink / raw)
  To: Lu Baolu, Joerg Roedel, Raj,  Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Monday, June 20, 2022 4:17 PM
> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> dmar_domain *domain, struct device *dev)
>  			ret = intel_pasid_setup_second_level(iommu,
> domain,
>  					dev, PASID_RID2PASID);
>  		spin_unlock_irqrestore(&iommu->lock, flags);
> -		if (ret) {
> +		if (ret && ret != -EBUSY) {
>  			dev_err(dev, "Setup RID2PASID failed\n");
>  			dmar_remove_one_dev_info(dev);
>  			return ret;
> --
> 2.25.1

It's cleaner to avoid this error at the first place, i.e. only do the
setup when the first device is attached to the pasid table.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  2:54   ` Tian, Kevin
@ 2022-06-21  3:39     ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  3:39 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/21 10:54, Tian, Kevin wrote:
>> From: Lu Baolu <baolu.lu@linux.intel.com>
>> Sent: Monday, June 20, 2022 4:17 PM
>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>> dmar_domain *domain, struct device *dev)
>>   			ret = intel_pasid_setup_second_level(iommu,
>> domain,
>>   					dev, PASID_RID2PASID);
>>   		spin_unlock_irqrestore(&iommu->lock, flags);
>> -		if (ret) {
>> +		if (ret && ret != -EBUSY) {
>>   			dev_err(dev, "Setup RID2PASID failed\n");
>>   			dmar_remove_one_dev_info(dev);
>>   			return ret;
>> --
>> 2.25.1
> 
> It's cleaner to avoid this error at the first place, i.e. only do the
> setup when the first device is attached to the pasid table.

The logic that identifies the first device might introduce additional
unnecessary complexity. Devices that share a pasid table are rare. I
even prefer to give up sharing tables so that the code can be
simpler.:-)

--
Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  3:39     ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  3:39 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/21 10:54, Tian, Kevin wrote:
>> From: Lu Baolu <baolu.lu@linux.intel.com>
>> Sent: Monday, June 20, 2022 4:17 PM
>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>> dmar_domain *domain, struct device *dev)
>>   			ret = intel_pasid_setup_second_level(iommu,
>> domain,
>>   					dev, PASID_RID2PASID);
>>   		spin_unlock_irqrestore(&iommu->lock, flags);
>> -		if (ret) {
>> +		if (ret && ret != -EBUSY) {
>>   			dev_err(dev, "Setup RID2PASID failed\n");
>>   			dmar_remove_one_dev_info(dev);
>>   			return ret;
>> --
>> 2.25.1
> 
> It's cleaner to avoid this error at the first place, i.e. only do the
> setup when the first device is attached to the pasid table.

The logic that identifies the first device might introduce additional
unnecessary complexity. Devices that share a pasid table are rare. I
even prefer to give up sharing tables so that the code can be
simpler.:-)

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

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  3:39     ` Baolu Lu
@ 2022-06-21  3:46       ` Tian, Kevin
  -1 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  3:46 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj, Ashok
  Cc: Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu, linux-kernel, stable

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 11:39 AM
> 
> On 2022/6/21 10:54, Tian, Kevin wrote:
> >> From: Lu Baolu <baolu.lu@linux.intel.com>
> >> Sent: Monday, June 20, 2022 4:17 PM
> >> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >> dmar_domain *domain, struct device *dev)
> >>   			ret = intel_pasid_setup_second_level(iommu,
> >> domain,
> >>   					dev, PASID_RID2PASID);
> >>   		spin_unlock_irqrestore(&iommu->lock, flags);
> >> -		if (ret) {
> >> +		if (ret && ret != -EBUSY) {
> >>   			dev_err(dev, "Setup RID2PASID failed\n");
> >>   			dmar_remove_one_dev_info(dev);
> >>   			return ret;
> >> --
> >> 2.25.1
> >
> > It's cleaner to avoid this error at the first place, i.e. only do the
> > setup when the first device is attached to the pasid table.
> 
> The logic that identifies the first device might introduce additional
> unnecessary complexity. Devices that share a pasid table are rare. I
> even prefer to give up sharing tables so that the code can be
> simpler.:-)
> 

It's not that complex if you simply move device_attach_pasid_table()
out of intel_pasid_alloc_table(). Then do the setup if
list_empty(&pasid_table->dev) and then attach device to the
pasid table in domain_add_dev_info().

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  3:46       ` Tian, Kevin
  0 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  3:46 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj,  Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 11:39 AM
> 
> On 2022/6/21 10:54, Tian, Kevin wrote:
> >> From: Lu Baolu <baolu.lu@linux.intel.com>
> >> Sent: Monday, June 20, 2022 4:17 PM
> >> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >> dmar_domain *domain, struct device *dev)
> >>   			ret = intel_pasid_setup_second_level(iommu,
> >> domain,
> >>   					dev, PASID_RID2PASID);
> >>   		spin_unlock_irqrestore(&iommu->lock, flags);
> >> -		if (ret) {
> >> +		if (ret && ret != -EBUSY) {
> >>   			dev_err(dev, "Setup RID2PASID failed\n");
> >>   			dmar_remove_one_dev_info(dev);
> >>   			return ret;
> >> --
> >> 2.25.1
> >
> > It's cleaner to avoid this error at the first place, i.e. only do the
> > setup when the first device is attached to the pasid table.
> 
> The logic that identifies the first device might introduce additional
> unnecessary complexity. Devices that share a pasid table are rare. I
> even prefer to give up sharing tables so that the code can be
> simpler.:-)
> 

It's not that complex if you simply move device_attach_pasid_table()
out of intel_pasid_alloc_table(). Then do the setup if
list_empty(&pasid_table->dev) and then attach device to the
pasid table in domain_add_dev_info().
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  3:46       ` Tian, Kevin
@ 2022-06-21  4:28         ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  4:28 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/21 11:46, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 11:39 AM
>>
>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>> dmar_domain *domain, struct device *dev)
>>>>    			ret = intel_pasid_setup_second_level(iommu,
>>>> domain,
>>>>    					dev, PASID_RID2PASID);
>>>>    		spin_unlock_irqrestore(&iommu->lock, flags);
>>>> -		if (ret) {
>>>> +		if (ret && ret != -EBUSY) {
>>>>    			dev_err(dev, "Setup RID2PASID failed\n");
>>>>    			dmar_remove_one_dev_info(dev);
>>>>    			return ret;
>>>> --
>>>> 2.25.1
>>>
>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>> setup when the first device is attached to the pasid table.
>>
>> The logic that identifies the first device might introduce additional
>> unnecessary complexity. Devices that share a pasid table are rare. I
>> even prefer to give up sharing tables so that the code can be
>> simpler.:-)
>>
> 
> It's not that complex if you simply move device_attach_pasid_table()
> out of intel_pasid_alloc_table(). Then do the setup if
> list_empty(&pasid_table->dev) and then attach device to the
> pasid table in domain_add_dev_info().

The pasid table is part of the device, hence a better place to
allocate/free the pasid table is in the device probe/release paths.
Things will become more complicated if we change relationship between
device and it's pasid table when attaching/detaching a domain. That's
the reason why I thought it was additional complexity.

--
Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  4:28         ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  4:28 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/21 11:46, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 11:39 AM
>>
>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>> dmar_domain *domain, struct device *dev)
>>>>    			ret = intel_pasid_setup_second_level(iommu,
>>>> domain,
>>>>    					dev, PASID_RID2PASID);
>>>>    		spin_unlock_irqrestore(&iommu->lock, flags);
>>>> -		if (ret) {
>>>> +		if (ret && ret != -EBUSY) {
>>>>    			dev_err(dev, "Setup RID2PASID failed\n");
>>>>    			dmar_remove_one_dev_info(dev);
>>>>    			return ret;
>>>> --
>>>> 2.25.1
>>>
>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>> setup when the first device is attached to the pasid table.
>>
>> The logic that identifies the first device might introduce additional
>> unnecessary complexity. Devices that share a pasid table are rare. I
>> even prefer to give up sharing tables so that the code can be
>> simpler.:-)
>>
> 
> It's not that complex if you simply move device_attach_pasid_table()
> out of intel_pasid_alloc_table(). Then do the setup if
> list_empty(&pasid_table->dev) and then attach device to the
> pasid table in domain_add_dev_info().

The pasid table is part of the device, hence a better place to
allocate/free the pasid table is in the device probe/release paths.
Things will become more complicated if we change relationship between
device and it's pasid table when attaching/detaching a domain. That's
the reason why I thought it was additional complexity.

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

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  4:28         ` Baolu Lu
@ 2022-06-21  5:48           ` Tian, Kevin
  -1 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  5:48 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj, Ashok
  Cc: Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu, linux-kernel, stable

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 12:28 PM
> 
> On 2022/6/21 11:46, Tian, Kevin wrote:
> >> From: Baolu Lu <baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 11:39 AM
> >>
> >> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>> From: Lu Baolu <baolu.lu@linux.intel.com>
> >>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>> dmar_domain *domain, struct device *dev)
> >>>>    			ret = intel_pasid_setup_second_level(iommu,
> >>>> domain,
> >>>>    					dev, PASID_RID2PASID);
> >>>>    		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>> -		if (ret) {
> >>>> +		if (ret && ret != -EBUSY) {
> >>>>    			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>    			dmar_remove_one_dev_info(dev);
> >>>>    			return ret;
> >>>> --
> >>>> 2.25.1
> >>>
> >>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>> setup when the first device is attached to the pasid table.
> >>
> >> The logic that identifies the first device might introduce additional
> >> unnecessary complexity. Devices that share a pasid table are rare. I
> >> even prefer to give up sharing tables so that the code can be
> >> simpler.:-)
> >>
> >
> > It's not that complex if you simply move device_attach_pasid_table()
> > out of intel_pasid_alloc_table(). Then do the setup if
> > list_empty(&pasid_table->dev) and then attach device to the
> > pasid table in domain_add_dev_info().
> 
> The pasid table is part of the device, hence a better place to
> allocate/free the pasid table is in the device probe/release paths.
> Things will become more complicated if we change relationship between
> device and it's pasid table when attaching/detaching a domain. That's
> the reason why I thought it was additional complexity.
> 

If you do want to follow current route it’s still cleaner to check
whether the pasid entry has pointed to the domain in the individual
setup function instead of blindly returning -EBUSY and then ignoring
it even if a real busy condition occurs. The setup functions can
just return zero for this benign alias case.

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  5:48           ` Tian, Kevin
  0 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-21  5:48 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj,  Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 12:28 PM
> 
> On 2022/6/21 11:46, Tian, Kevin wrote:
> >> From: Baolu Lu <baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 11:39 AM
> >>
> >> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>> From: Lu Baolu <baolu.lu@linux.intel.com>
> >>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>> dmar_domain *domain, struct device *dev)
> >>>>    			ret = intel_pasid_setup_second_level(iommu,
> >>>> domain,
> >>>>    					dev, PASID_RID2PASID);
> >>>>    		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>> -		if (ret) {
> >>>> +		if (ret && ret != -EBUSY) {
> >>>>    			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>    			dmar_remove_one_dev_info(dev);
> >>>>    			return ret;
> >>>> --
> >>>> 2.25.1
> >>>
> >>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>> setup when the first device is attached to the pasid table.
> >>
> >> The logic that identifies the first device might introduce additional
> >> unnecessary complexity. Devices that share a pasid table are rare. I
> >> even prefer to give up sharing tables so that the code can be
> >> simpler.:-)
> >>
> >
> > It's not that complex if you simply move device_attach_pasid_table()
> > out of intel_pasid_alloc_table(). Then do the setup if
> > list_empty(&pasid_table->dev) and then attach device to the
> > pasid table in domain_add_dev_info().
> 
> The pasid table is part of the device, hence a better place to
> allocate/free the pasid table is in the device probe/release paths.
> Things will become more complicated if we change relationship between
> device and it's pasid table when attaching/detaching a domain. That's
> the reason why I thought it was additional complexity.
> 

If you do want to follow current route it’s still cleaner to check
whether the pasid entry has pointed to the domain in the individual
setup function instead of blindly returning -EBUSY and then ignoring
it even if a real busy condition occurs. The setup functions can
just return zero for this benign alias case.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  5:48           ` Tian, Kevin
@ 2022-06-21  6:15             ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  6:15 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/21 13:48, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 12:28 PM
>>
>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>> From: Baolu Lu <baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>
>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>     			ret = intel_pasid_setup_second_level(iommu,
>>>>>> domain,
>>>>>>     					dev, PASID_RID2PASID);
>>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>> -		if (ret) {
>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>     			dmar_remove_one_dev_info(dev);
>>>>>>     			return ret;
>>>>>> --
>>>>>> 2.25.1
>>>>>
>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>> setup when the first device is attached to the pasid table.
>>>>
>>>> The logic that identifies the first device might introduce additional
>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>> even prefer to give up sharing tables so that the code can be
>>>> simpler.:-)
>>>>
>>>
>>> It's not that complex if you simply move device_attach_pasid_table()
>>> out of intel_pasid_alloc_table(). Then do the setup if
>>> list_empty(&pasid_table->dev) and then attach device to the
>>> pasid table in domain_add_dev_info().
>>
>> The pasid table is part of the device, hence a better place to
>> allocate/free the pasid table is in the device probe/release paths.
>> Things will become more complicated if we change relationship between
>> device and it's pasid table when attaching/detaching a domain. That's
>> the reason why I thought it was additional complexity.
>>
> 
> If you do want to follow current route it’s still cleaner to check
> whether the pasid entry has pointed to the domain in the individual
> setup function instead of blindly returning -EBUSY and then ignoring
> it even if a real busy condition occurs. The setup functions can
> just return zero for this benign alias case.

Fair enough. Let me improve it.

--
Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  6:15             ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  6:15 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/21 13:48, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 12:28 PM
>>
>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>> From: Baolu Lu <baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>
>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>     			ret = intel_pasid_setup_second_level(iommu,
>>>>>> domain,
>>>>>>     					dev, PASID_RID2PASID);
>>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>> -		if (ret) {
>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>     			dmar_remove_one_dev_info(dev);
>>>>>>     			return ret;
>>>>>> --
>>>>>> 2.25.1
>>>>>
>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>> setup when the first device is attached to the pasid table.
>>>>
>>>> The logic that identifies the first device might introduce additional
>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>> even prefer to give up sharing tables so that the code can be
>>>> simpler.:-)
>>>>
>>>
>>> It's not that complex if you simply move device_attach_pasid_table()
>>> out of intel_pasid_alloc_table(). Then do the setup if
>>> list_empty(&pasid_table->dev) and then attach device to the
>>> pasid table in domain_add_dev_info().
>>
>> The pasid table is part of the device, hence a better place to
>> allocate/free the pasid table is in the device probe/release paths.
>> Things will become more complicated if we change relationship between
>> device and it's pasid table when attaching/detaching a domain. That's
>> the reason why I thought it was additional complexity.
>>
> 
> If you do want to follow current route it’s still cleaner to check
> whether the pasid entry has pointed to the domain in the individual
> setup function instead of blindly returning -EBUSY and then ignoring
> it even if a real busy condition occurs. The setup functions can
> just return zero for this benign alias case.

Fair enough. Let me improve it.

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

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  5:48           ` Tian, Kevin
@ 2022-06-21  9:03             ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  9:03 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/21 13:48, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 12:28 PM
>>
>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>> From: Baolu Lu <baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>
>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>     			ret = intel_pasid_setup_second_level(iommu,
>>>>>> domain,
>>>>>>     					dev, PASID_RID2PASID);
>>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>> -		if (ret) {
>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>     			dmar_remove_one_dev_info(dev);
>>>>>>     			return ret;
>>>>>> --
>>>>>> 2.25.1
>>>>>
>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>> setup when the first device is attached to the pasid table.
>>>>
>>>> The logic that identifies the first device might introduce additional
>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>> even prefer to give up sharing tables so that the code can be
>>>> simpler.:-)
>>>>
>>>
>>> It's not that complex if you simply move device_attach_pasid_table()
>>> out of intel_pasid_alloc_table(). Then do the setup if
>>> list_empty(&pasid_table->dev) and then attach device to the
>>> pasid table in domain_add_dev_info().
>>
>> The pasid table is part of the device, hence a better place to
>> allocate/free the pasid table is in the device probe/release paths.
>> Things will become more complicated if we change relationship between
>> device and it's pasid table when attaching/detaching a domain. That's
>> the reason why I thought it was additional complexity.
>>
> 
> If you do want to follow current route it’s still cleaner to check
> whether the pasid entry has pointed to the domain in the individual
> setup function instead of blindly returning -EBUSY and then ignoring
> it even if a real busy condition occurs. The setup functions can
> just return zero for this benign alias case.

Kevin, how do you like this one?

diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index cb4c1d0cf25c..ecffd0129b2b 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct 
pasid_entry *pte)
  	return 0;
  };

+/*
+ * Return true if @pasid is RID2PASID and the domain @did has already
+ * been setup to the @pte. Otherwise, return false.
+ */
+static inline bool
+rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
+{
+	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) == did;
+}
+
  /*
   * Set up the scalable mode pasid table entry for first only
   * translation type.
@@ -595,9 +605,8 @@ int intel_pasid_setup_first_level(struct intel_iommu 
*iommu,
  	if (WARN_ON(!pte))
  		return -EINVAL;

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);

@@ -698,9 +707,8 @@ int intel_pasid_setup_second_level(struct 
intel_iommu *iommu,
  		return -ENODEV;
  	}

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);
  	pasid_set_domain_id(pte, did);
@@ -738,9 +746,8 @@ int intel_pasid_setup_pass_through(struct 
intel_iommu *iommu,
  		return -ENODEV;
  	}

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);
  	pasid_set_domain_id(pte, did);

--
Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-21  9:03             ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-21  9:03 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/21 13:48, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 12:28 PM
>>
>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>> From: Baolu Lu <baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>
>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>     			ret = intel_pasid_setup_second_level(iommu,
>>>>>> domain,
>>>>>>     					dev, PASID_RID2PASID);
>>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>> -		if (ret) {
>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>     			dmar_remove_one_dev_info(dev);
>>>>>>     			return ret;
>>>>>> --
>>>>>> 2.25.1
>>>>>
>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>> setup when the first device is attached to the pasid table.
>>>>
>>>> The logic that identifies the first device might introduce additional
>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>> even prefer to give up sharing tables so that the code can be
>>>> simpler.:-)
>>>>
>>>
>>> It's not that complex if you simply move device_attach_pasid_table()
>>> out of intel_pasid_alloc_table(). Then do the setup if
>>> list_empty(&pasid_table->dev) and then attach device to the
>>> pasid table in domain_add_dev_info().
>>
>> The pasid table is part of the device, hence a better place to
>> allocate/free the pasid table is in the device probe/release paths.
>> Things will become more complicated if we change relationship between
>> device and it's pasid table when attaching/detaching a domain. That's
>> the reason why I thought it was additional complexity.
>>
> 
> If you do want to follow current route it’s still cleaner to check
> whether the pasid entry has pointed to the domain in the individual
> setup function instead of blindly returning -EBUSY and then ignoring
> it even if a real busy condition occurs. The setup functions can
> just return zero for this benign alias case.

Kevin, how do you like this one?

diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index cb4c1d0cf25c..ecffd0129b2b 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct 
pasid_entry *pte)
  	return 0;
  };

+/*
+ * Return true if @pasid is RID2PASID and the domain @did has already
+ * been setup to the @pte. Otherwise, return false.
+ */
+static inline bool
+rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
+{
+	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) == did;
+}
+
  /*
   * Set up the scalable mode pasid table entry for first only
   * translation type.
@@ -595,9 +605,8 @@ int intel_pasid_setup_first_level(struct intel_iommu 
*iommu,
  	if (WARN_ON(!pte))
  		return -EINVAL;

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);

@@ -698,9 +707,8 @@ int intel_pasid_setup_second_level(struct 
intel_iommu *iommu,
  		return -ENODEV;
  	}

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);
  	pasid_set_domain_id(pte, did);
@@ -738,9 +746,8 @@ int intel_pasid_setup_pass_through(struct 
intel_iommu *iommu,
  		return -ENODEV;
  	}

-	/* Caller must ensure PASID entry is not in use. */
  	if (pasid_pte_is_present(pte))
-		return -EBUSY;
+		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;

  	pasid_clear_entry(pte);
  	pasid_set_domain_id(pte, did);

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

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-20  8:17 ` Lu Baolu
                   ` (2 preceding siblings ...)
  (?)
@ 2022-06-22  2:56 ` Ethan Zhao
  2022-06-22  3:22     ` Baolu Lu
  -1 siblings, 1 reply; 31+ messages in thread
From: Ethan Zhao @ 2022-06-22  2:56 UTC (permalink / raw)
  To: Lu Baolu, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: linux-kernel, stable, Chenyi Qiang, iommu, Jacob jun Pan


[-- Attachment #1.1: Type: text/plain, Size: 3441 bytes --]

Hi,

在 2022/6/20 16:17, Lu Baolu 写道:
> The IOMMU driver shares the pasid table for PCI alias devices. When the
> RID2PASID entry of the shared pasid table has been filled by the first
> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
> failed" failure as the pasid entry has already been marke as present. As
> the result, the IOMMU probing process will be aborted.
>
> This fixes it by skipping RID2PASID setting if the pasid entry has been
> populated. This works because the IOMMU core ensures that only the same
> IOMMU domain can be attached to all PCI alias devices at the same time.
> Therefore the subsequent devices just try to setup the RID2PASID entry
> with the same domain, which is negligible.
     We have two customers reported the issue "DMAR: Setup RID2PASID 
failed",

Two ASPEED devices locate behind one PCIe-PCI bridge and iommu SM, PT 
mode is enabled.  Most

Interesting thing is the second device is only used by BIOS, and BIOS 
left it to OS without shutting down,

and it is useless for OS.  Is there practical case multi devices behind 
PCIe-PCI bridge share the same

PASID entry without any security concern ? these two customer's case is 
not.


Thanks,

Ethan

>
> Fixes: ef848b7e5a6a0 ("iommu/vt-d: Setup pasid entry for RID2PASID support")
> Reported-by: Chenyi Qiang<chenyi.qiang@intel.com>
> Cc:stable@vger.kernel.org
> Signed-off-by: Lu Baolu<baolu.lu@linux.intel.com>
> ---
>   drivers/iommu/intel/iommu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 44016594831d..b9966c01a2a2 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
>   			ret = intel_pasid_setup_second_level(iommu, domain,
>   					dev, PASID_RID2PASID);
>   		spin_unlock_irqrestore(&iommu->lock, flags);
> -		if (ret) {
> +		if (ret && ret != -EBUSY) {
>   			dev_err(dev, "Setup RID2PASID failed\n");
>   			dmar_remove_one_dev_info(dev);
>   			return ret;

-- 
AFAIK = As Far As I Know
AKA = Also Known As
ASAP = As Soon As Possible
BTW = By The Way (used to introduce some piece of information or question that is on a different topic but may be of interest)
COLA = comp.os.linux.announce (newsgroup)
ETA = Estimated Time of Arrival
FAQ = Frequently Asked Question
FUD = Fear, Uncertainty and Doubt
FWIW = For What It's Worth
FYI = For Your Information
IANAL = I Am Not A Lawyer
IIRC = If I Recall Correctly
IMHO = In My Humble Opinion
IMNSHO = In My Not-So-Humble Opinion
IOW = In Other Words
LART = Luser Attitude Readjustment Tool (quoting Al Viro: "Anything you use to forcibly implant the clue into the place where luser's head is")
LUSER = pronounced "loser", a user who is considered to indeed be a loser (idiot, drongo, wanker, dim-wit, fool, etc.)
OTOH = On The Other Hand
PEBKAC = Problem Exists Between Keyboard And Chair
ROTFL = Rolling On The Floor Laughing
RSN = Real Soon Now
RTFM = Read The Fucking Manual (original definition) or Read The Fine Manual (if you want to pretend to be polite)
TANSTAAFL = There Ain't No Such Thing As A Free Lunch (contributed by David Niemi, quoting Robert Heinlein in his science fiction novel 'The Moon is a Harsh Mistress')
THX = Thanks (thank you)
TIA = Thanks In Advance
WIP = Work In Progress
WRT = With Respect To

[-- Attachment #1.2: Type: text/html, Size: 5769 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

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

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-21  9:03             ` Baolu Lu
@ 2022-06-22  3:06               ` Tian, Kevin
  -1 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-22  3:06 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj, Ashok
  Cc: Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu, linux-kernel, stable

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 5:04 PM
> 
> On 2022/6/21 13:48, Tian, Kevin wrote:
> >> From: Baolu Lu <baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 12:28 PM
> >>
> >> On 2022/6/21 11:46, Tian, Kevin wrote:
> >>>> From: Baolu Lu <baolu.lu@linux.intel.com>
> >>>> Sent: Tuesday, June 21, 2022 11:39 AM
> >>>>
> >>>> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
> >>>>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>>>> dmar_domain *domain, struct device *dev)
> >>>>>>     			ret = intel_pasid_setup_second_level(iommu,
> >>>>>> domain,
> >>>>>>     					dev, PASID_RID2PASID);
> >>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>>>> -		if (ret) {
> >>>>>> +		if (ret && ret != -EBUSY) {
> >>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>>>     			dmar_remove_one_dev_info(dev);
> >>>>>>     			return ret;
> >>>>>> --
> >>>>>> 2.25.1
> >>>>>
> >>>>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>>>> setup when the first device is attached to the pasid table.
> >>>>
> >>>> The logic that identifies the first device might introduce additional
> >>>> unnecessary complexity. Devices that share a pasid table are rare. I
> >>>> even prefer to give up sharing tables so that the code can be
> >>>> simpler.:-)
> >>>>
> >>>
> >>> It's not that complex if you simply move device_attach_pasid_table()
> >>> out of intel_pasid_alloc_table(). Then do the setup if
> >>> list_empty(&pasid_table->dev) and then attach device to the
> >>> pasid table in domain_add_dev_info().
> >>
> >> The pasid table is part of the device, hence a better place to
> >> allocate/free the pasid table is in the device probe/release paths.
> >> Things will become more complicated if we change relationship between
> >> device and it's pasid table when attaching/detaching a domain. That's
> >> the reason why I thought it was additional complexity.
> >>
> >
> > If you do want to follow current route it’s still cleaner to check
> > whether the pasid entry has pointed to the domain in the individual
> > setup function instead of blindly returning -EBUSY and then ignoring
> > it even if a real busy condition occurs. The setup functions can
> > just return zero for this benign alias case.
> 
> Kevin, how do you like this one?
> 
> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
> index cb4c1d0cf25c..ecffd0129b2b 100644
> --- a/drivers/iommu/intel/pasid.c
> +++ b/drivers/iommu/intel/pasid.c
> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
> pasid_entry *pte)
>   	return 0;
>   };
> 
> +/*
> + * Return true if @pasid is RID2PASID and the domain @did has already
> + * been setup to the @pte. Otherwise, return false.
> + */
> +static inline bool
> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
> +{
> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
> did;
> +}

better this is not restricted to RID2PASID only, e.g. pasid_pte_match_domain()
and then read pasid from the pte to compare with the pasid argument.

> +
>   /*
>    * Set up the scalable mode pasid table entry for first only
>    * translation type.
> @@ -595,9 +605,8 @@ int intel_pasid_setup_first_level(struct intel_iommu
> *iommu,
>   	if (WARN_ON(!pte))
>   		return -EINVAL;
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
> 
> @@ -698,9 +707,8 @@ int intel_pasid_setup_second_level(struct
> intel_iommu *iommu,
>   		return -ENODEV;
>   	}
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
>   	pasid_set_domain_id(pte, did);
> @@ -738,9 +746,8 @@ int intel_pasid_setup_pass_through(struct
> intel_iommu *iommu,
>   		return -ENODEV;
>   	}
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
>   	pasid_set_domain_id(pte, did);
> 
> --
> Best regards,
> baolu

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-22  3:06               ` Tian, Kevin
  0 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-22  3:06 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj,  Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Tuesday, June 21, 2022 5:04 PM
> 
> On 2022/6/21 13:48, Tian, Kevin wrote:
> >> From: Baolu Lu <baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 12:28 PM
> >>
> >> On 2022/6/21 11:46, Tian, Kevin wrote:
> >>>> From: Baolu Lu <baolu.lu@linux.intel.com>
> >>>> Sent: Tuesday, June 21, 2022 11:39 AM
> >>>>
> >>>> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>>>> From: Lu Baolu <baolu.lu@linux.intel.com>
> >>>>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>>>> dmar_domain *domain, struct device *dev)
> >>>>>>     			ret = intel_pasid_setup_second_level(iommu,
> >>>>>> domain,
> >>>>>>     					dev, PASID_RID2PASID);
> >>>>>>     		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>>>> -		if (ret) {
> >>>>>> +		if (ret && ret != -EBUSY) {
> >>>>>>     			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>>>     			dmar_remove_one_dev_info(dev);
> >>>>>>     			return ret;
> >>>>>> --
> >>>>>> 2.25.1
> >>>>>
> >>>>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>>>> setup when the first device is attached to the pasid table.
> >>>>
> >>>> The logic that identifies the first device might introduce additional
> >>>> unnecessary complexity. Devices that share a pasid table are rare. I
> >>>> even prefer to give up sharing tables so that the code can be
> >>>> simpler.:-)
> >>>>
> >>>
> >>> It's not that complex if you simply move device_attach_pasid_table()
> >>> out of intel_pasid_alloc_table(). Then do the setup if
> >>> list_empty(&pasid_table->dev) and then attach device to the
> >>> pasid table in domain_add_dev_info().
> >>
> >> The pasid table is part of the device, hence a better place to
> >> allocate/free the pasid table is in the device probe/release paths.
> >> Things will become more complicated if we change relationship between
> >> device and it's pasid table when attaching/detaching a domain. That's
> >> the reason why I thought it was additional complexity.
> >>
> >
> > If you do want to follow current route it’s still cleaner to check
> > whether the pasid entry has pointed to the domain in the individual
> > setup function instead of blindly returning -EBUSY and then ignoring
> > it even if a real busy condition occurs. The setup functions can
> > just return zero for this benign alias case.
> 
> Kevin, how do you like this one?
> 
> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
> index cb4c1d0cf25c..ecffd0129b2b 100644
> --- a/drivers/iommu/intel/pasid.c
> +++ b/drivers/iommu/intel/pasid.c
> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
> pasid_entry *pte)
>   	return 0;
>   };
> 
> +/*
> + * Return true if @pasid is RID2PASID and the domain @did has already
> + * been setup to the @pte. Otherwise, return false.
> + */
> +static inline bool
> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
> +{
> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
> did;
> +}

better this is not restricted to RID2PASID only, e.g. pasid_pte_match_domain()
and then read pasid from the pte to compare with the pasid argument.

> +
>   /*
>    * Set up the scalable mode pasid table entry for first only
>    * translation type.
> @@ -595,9 +605,8 @@ int intel_pasid_setup_first_level(struct intel_iommu
> *iommu,
>   	if (WARN_ON(!pte))
>   		return -EINVAL;
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
> 
> @@ -698,9 +707,8 @@ int intel_pasid_setup_second_level(struct
> intel_iommu *iommu,
>   		return -ENODEV;
>   	}
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
>   	pasid_set_domain_id(pte, did);
> @@ -738,9 +746,8 @@ int intel_pasid_setup_pass_through(struct
> intel_iommu *iommu,
>   		return -ENODEV;
>   	}
> 
> -	/* Caller must ensure PASID entry is not in use. */
>   	if (pasid_pte_is_present(pte))
> -		return -EBUSY;
> +		return rid2pasid_domain_valid(pte, pasid, did) ? 0: -EBUSY;
> 
>   	pasid_clear_entry(pte);
>   	pasid_set_domain_id(pte, did);
> 
> --
> Best regards,
> baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-22  2:56 ` Ethan Zhao
@ 2022-06-22  3:22     ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  3:22 UTC (permalink / raw)
  To: Ethan Zhao, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: baolu.lu, Chenyi Qiang, Liu Yi L, Jacob jun Pan, iommu,
	linux-kernel, stable

On 2022/6/22 10:56, Ethan Zhao wrote:
> 在 2022/6/20 16:17, Lu Baolu 写道:
>> The IOMMU driver shares the pasid table for PCI alias devices. When the
>> RID2PASID entry of the shared pasid table has been filled by the first
>> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
>> failed" failure as the pasid entry has already been marke as present. As
>> the result, the IOMMU probing process will be aborted.
>>
>> This fixes it by skipping RID2PASID setting if the pasid entry has been
>> populated. This works because the IOMMU core ensures that only the same
>> IOMMU domain can be attached to all PCI alias devices at the same time.
>> Therefore the subsequent devices just try to setup the RID2PASID entry
>> with the same domain, which is negligible.
>      We have two customers reported the issue "DMAR: Setup RID2PASID 
> failed",
> 
> Two ASPEED devices locate behind one PCIe-PCI bridge and iommu SM, PT 
> mode is enabled.  Most
> 
> Interesting thing is the second device is only used by BIOS, and BIOS 
> left it to OS without shutting down,
> 
> and it is useless for OS.

This sounds odd. Isn't this a bug?


> Is there practical case multi devices behind 
> PCIe-PCI bridge share the same
> 
> PASID entry without any security concern ? these two customer's case is 
> not.

The devices underneath the PCIe-PCI bridge are alias devices of the
bridge. PCI alias devices always sit in the same group (the minimal unit
that IOMMU guarantees isolation) and can only be attached with a same
domain (managed I/O address space). Hence, there's no security concern
if they further share the pasid table.

Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-22  3:22     ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  3:22 UTC (permalink / raw)
  To: Ethan Zhao, Joerg Roedel, Kevin Tian, Ashok Raj
  Cc: linux-kernel, stable, Chenyi Qiang, iommu, Jacob jun Pan

On 2022/6/22 10:56, Ethan Zhao wrote:
> 在 2022/6/20 16:17, Lu Baolu 写道:
>> The IOMMU driver shares the pasid table for PCI alias devices. When the
>> RID2PASID entry of the shared pasid table has been filled by the first
>> device, the subsequent devices will encounter the "DMAR: Setup RID2PASID
>> failed" failure as the pasid entry has already been marke as present. As
>> the result, the IOMMU probing process will be aborted.
>>
>> This fixes it by skipping RID2PASID setting if the pasid entry has been
>> populated. This works because the IOMMU core ensures that only the same
>> IOMMU domain can be attached to all PCI alias devices at the same time.
>> Therefore the subsequent devices just try to setup the RID2PASID entry
>> with the same domain, which is negligible.
>      We have two customers reported the issue "DMAR: Setup RID2PASID 
> failed",
> 
> Two ASPEED devices locate behind one PCIe-PCI bridge and iommu SM, PT 
> mode is enabled.  Most
> 
> Interesting thing is the second device is only used by BIOS, and BIOS 
> left it to OS without shutting down,
> 
> and it is useless for OS.

This sounds odd. Isn't this a bug?


> Is there practical case multi devices behind 
> PCIe-PCI bridge share the same
> 
> PASID entry without any security concern ? these two customer's case is 
> not.

The devices underneath the PCIe-PCI bridge are alias devices of the
bridge. PCI alias devices always sit in the same group (the minimal unit
that IOMMU guarantees isolation) and can only be attached with a same
domain (managed I/O address space). Hence, there's no security concern
if they further share the pasid table.

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

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-22  3:06               ` Tian, Kevin
@ 2022-06-22  3:27                 ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  3:27 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/22 11:06, Tian, Kevin wrote:
>> From: Baolu Lu<baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 5:04 PM
>>
>> On 2022/6/21 13:48, Tian, Kevin wrote:
>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 12:28 PM
>>>>
>>>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>>>
>>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
>>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>>>      			ret = intel_pasid_setup_second_level(iommu,
>>>>>>>> domain,
>>>>>>>>      					dev, PASID_RID2PASID);
>>>>>>>>      		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>>>> -		if (ret) {
>>>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>>>      			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>>>      			dmar_remove_one_dev_info(dev);
>>>>>>>>      			return ret;
>>>>>>>> --
>>>>>>>> 2.25.1
>>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>>>> setup when the first device is attached to the pasid table.
>>>>>> The logic that identifies the first device might introduce additional
>>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>>>> even prefer to give up sharing tables so that the code can be
>>>>>> simpler.:-)
>>>>>>
>>>>> It's not that complex if you simply move device_attach_pasid_table()
>>>>> out of intel_pasid_alloc_table(). Then do the setup if
>>>>> list_empty(&pasid_table->dev) and then attach device to the
>>>>> pasid table in domain_add_dev_info().
>>>> The pasid table is part of the device, hence a better place to
>>>> allocate/free the pasid table is in the device probe/release paths.
>>>> Things will become more complicated if we change relationship between
>>>> device and it's pasid table when attaching/detaching a domain. That's
>>>> the reason why I thought it was additional complexity.
>>>>
>>> If you do want to follow current route it’s still cleaner to check
>>> whether the pasid entry has pointed to the domain in the individual
>>> setup function instead of blindly returning -EBUSY and then ignoring
>>> it even if a real busy condition occurs. The setup functions can
>>> just return zero for this benign alias case.
>> Kevin, how do you like this one?
>>
>> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
>> index cb4c1d0cf25c..ecffd0129b2b 100644
>> --- a/drivers/iommu/intel/pasid.c
>> +++ b/drivers/iommu/intel/pasid.c
>> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
>> pasid_entry *pte)
>>    	return 0;
>>    };
>>
>> +/*
>> + * Return true if @pasid is RID2PASID and the domain @did has already
>> + * been setup to the @pte. Otherwise, return false.
>> + */
>> +static inline bool
>> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
>> +{
>> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
>> did;
>> +}
> better this is not restricted to RID2PASID only, e.g. pasid_pte_match_domain()
> and then read pasid from the pte to compare with the pasid argument.
> 

The pasid value is not encoded in the pasid table entry. This validity
check is only for RID2PASID as alias devices share the single RID2PASID
entry. For other cases, we should always return -EBUSY as what the code
is doing now.

Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-22  3:27                 ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  3:27 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/22 11:06, Tian, Kevin wrote:
>> From: Baolu Lu<baolu.lu@linux.intel.com>
>> Sent: Tuesday, June 21, 2022 5:04 PM
>>
>> On 2022/6/21 13:48, Tian, Kevin wrote:
>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 12:28 PM
>>>>
>>>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>>>
>>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
>>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>>>      			ret = intel_pasid_setup_second_level(iommu,
>>>>>>>> domain,
>>>>>>>>      					dev, PASID_RID2PASID);
>>>>>>>>      		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>>>> -		if (ret) {
>>>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>>>      			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>>>      			dmar_remove_one_dev_info(dev);
>>>>>>>>      			return ret;
>>>>>>>> --
>>>>>>>> 2.25.1
>>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>>>> setup when the first device is attached to the pasid table.
>>>>>> The logic that identifies the first device might introduce additional
>>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>>>> even prefer to give up sharing tables so that the code can be
>>>>>> simpler.:-)
>>>>>>
>>>>> It's not that complex if you simply move device_attach_pasid_table()
>>>>> out of intel_pasid_alloc_table(). Then do the setup if
>>>>> list_empty(&pasid_table->dev) and then attach device to the
>>>>> pasid table in domain_add_dev_info().
>>>> The pasid table is part of the device, hence a better place to
>>>> allocate/free the pasid table is in the device probe/release paths.
>>>> Things will become more complicated if we change relationship between
>>>> device and it's pasid table when attaching/detaching a domain. That's
>>>> the reason why I thought it was additional complexity.
>>>>
>>> If you do want to follow current route it’s still cleaner to check
>>> whether the pasid entry has pointed to the domain in the individual
>>> setup function instead of blindly returning -EBUSY and then ignoring
>>> it even if a real busy condition occurs. The setup functions can
>>> just return zero for this benign alias case.
>> Kevin, how do you like this one?
>>
>> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
>> index cb4c1d0cf25c..ecffd0129b2b 100644
>> --- a/drivers/iommu/intel/pasid.c
>> +++ b/drivers/iommu/intel/pasid.c
>> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
>> pasid_entry *pte)
>>    	return 0;
>>    };
>>
>> +/*
>> + * Return true if @pasid is RID2PASID and the domain @did has already
>> + * been setup to the @pte. Otherwise, return false.
>> + */
>> +static inline bool
>> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
>> +{
>> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
>> did;
>> +}
> better this is not restricted to RID2PASID only, e.g. pasid_pte_match_domain()
> and then read pasid from the pte to compare with the pasid argument.
> 

The pasid value is not encoded in the pasid table entry. This validity
check is only for RID2PASID as alias devices share the single RID2PASID
entry. For other cases, we should always return -EBUSY as what the code
is doing now.

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

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-22  3:27                 ` Baolu Lu
@ 2022-06-22  3:31                   ` Tian, Kevin
  -1 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-22  3:31 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj, Ashok
  Cc: Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu, linux-kernel, stable

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Wednesday, June 22, 2022 11:28 AM
> 
> On 2022/6/22 11:06, Tian, Kevin wrote:
> >> From: Baolu Lu<baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 5:04 PM
> >>
> >> On 2022/6/21 13:48, Tian, Kevin wrote:
> >>>> From: Baolu Lu<baolu.lu@linux.intel.com>
> >>>> Sent: Tuesday, June 21, 2022 12:28 PM
> >>>>
> >>>> On 2022/6/21 11:46, Tian, Kevin wrote:
> >>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
> >>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
> >>>>>>
> >>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
> >>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>>>>>> dmar_domain *domain, struct device *dev)
> >>>>>>>>      			ret = intel_pasid_setup_second_level(iommu,
> >>>>>>>> domain,
> >>>>>>>>      					dev, PASID_RID2PASID);
> >>>>>>>>      		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>>>>>> -		if (ret) {
> >>>>>>>> +		if (ret && ret != -EBUSY) {
> >>>>>>>>      			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>>>>>      			dmar_remove_one_dev_info(dev);
> >>>>>>>>      			return ret;
> >>>>>>>> --
> >>>>>>>> 2.25.1
> >>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>>>>>> setup when the first device is attached to the pasid table.
> >>>>>> The logic that identifies the first device might introduce additional
> >>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
> >>>>>> even prefer to give up sharing tables so that the code can be
> >>>>>> simpler.:-)
> >>>>>>
> >>>>> It's not that complex if you simply move device_attach_pasid_table()
> >>>>> out of intel_pasid_alloc_table(). Then do the setup if
> >>>>> list_empty(&pasid_table->dev) and then attach device to the
> >>>>> pasid table in domain_add_dev_info().
> >>>> The pasid table is part of the device, hence a better place to
> >>>> allocate/free the pasid table is in the device probe/release paths.
> >>>> Things will become more complicated if we change relationship
> between
> >>>> device and it's pasid table when attaching/detaching a domain. That's
> >>>> the reason why I thought it was additional complexity.
> >>>>
> >>> If you do want to follow current route it’s still cleaner to check
> >>> whether the pasid entry has pointed to the domain in the individual
> >>> setup function instead of blindly returning -EBUSY and then ignoring
> >>> it even if a real busy condition occurs. The setup functions can
> >>> just return zero for this benign alias case.
> >> Kevin, how do you like this one?
> >>
> >> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
> >> index cb4c1d0cf25c..ecffd0129b2b 100644
> >> --- a/drivers/iommu/intel/pasid.c
> >> +++ b/drivers/iommu/intel/pasid.c
> >> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
> >> pasid_entry *pte)
> >>    	return 0;
> >>    };
> >>
> >> +/*
> >> + * Return true if @pasid is RID2PASID and the domain @did has already
> >> + * been setup to the @pte. Otherwise, return false.
> >> + */
> >> +static inline bool
> >> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
> >> +{
> >> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
> >> did;
> >> +}
> > better this is not restricted to RID2PASID only, e.g.
> pasid_pte_match_domain()
> > and then read pasid from the pte to compare with the pasid argument.
> >
> 
> The pasid value is not encoded in the pasid table entry. This validity
> check is only for RID2PASID as alias devices share the single RID2PASID
> entry. For other cases, we should always return -EBUSY as what the code
> is doing now.
> 

You are right.

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

* RE: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-22  3:31                   ` Tian, Kevin
  0 siblings, 0 replies; 31+ messages in thread
From: Tian, Kevin @ 2022-06-22  3:31 UTC (permalink / raw)
  To: Baolu Lu, Joerg Roedel, Raj,  Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Wednesday, June 22, 2022 11:28 AM
> 
> On 2022/6/22 11:06, Tian, Kevin wrote:
> >> From: Baolu Lu<baolu.lu@linux.intel.com>
> >> Sent: Tuesday, June 21, 2022 5:04 PM
> >>
> >> On 2022/6/21 13:48, Tian, Kevin wrote:
> >>>> From: Baolu Lu<baolu.lu@linux.intel.com>
> >>>> Sent: Tuesday, June 21, 2022 12:28 PM
> >>>>
> >>>> On 2022/6/21 11:46, Tian, Kevin wrote:
> >>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
> >>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
> >>>>>>
> >>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
> >>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
> >>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
> >>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
> >>>>>>>> dmar_domain *domain, struct device *dev)
> >>>>>>>>      			ret = intel_pasid_setup_second_level(iommu,
> >>>>>>>> domain,
> >>>>>>>>      					dev, PASID_RID2PASID);
> >>>>>>>>      		spin_unlock_irqrestore(&iommu->lock, flags);
> >>>>>>>> -		if (ret) {
> >>>>>>>> +		if (ret && ret != -EBUSY) {
> >>>>>>>>      			dev_err(dev, "Setup RID2PASID failed\n");
> >>>>>>>>      			dmar_remove_one_dev_info(dev);
> >>>>>>>>      			return ret;
> >>>>>>>> --
> >>>>>>>> 2.25.1
> >>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
> >>>>>>> setup when the first device is attached to the pasid table.
> >>>>>> The logic that identifies the first device might introduce additional
> >>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
> >>>>>> even prefer to give up sharing tables so that the code can be
> >>>>>> simpler.:-)
> >>>>>>
> >>>>> It's not that complex if you simply move device_attach_pasid_table()
> >>>>> out of intel_pasid_alloc_table(). Then do the setup if
> >>>>> list_empty(&pasid_table->dev) and then attach device to the
> >>>>> pasid table in domain_add_dev_info().
> >>>> The pasid table is part of the device, hence a better place to
> >>>> allocate/free the pasid table is in the device probe/release paths.
> >>>> Things will become more complicated if we change relationship
> between
> >>>> device and it's pasid table when attaching/detaching a domain. That's
> >>>> the reason why I thought it was additional complexity.
> >>>>
> >>> If you do want to follow current route it’s still cleaner to check
> >>> whether the pasid entry has pointed to the domain in the individual
> >>> setup function instead of blindly returning -EBUSY and then ignoring
> >>> it even if a real busy condition occurs. The setup functions can
> >>> just return zero for this benign alias case.
> >> Kevin, how do you like this one?
> >>
> >> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
> >> index cb4c1d0cf25c..ecffd0129b2b 100644
> >> --- a/drivers/iommu/intel/pasid.c
> >> +++ b/drivers/iommu/intel/pasid.c
> >> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
> >> pasid_entry *pte)
> >>    	return 0;
> >>    };
> >>
> >> +/*
> >> + * Return true if @pasid is RID2PASID and the domain @did has already
> >> + * been setup to the @pte. Otherwise, return false.
> >> + */
> >> +static inline bool
> >> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
> >> +{
> >> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
> >> did;
> >> +}
> > better this is not restricted to RID2PASID only, e.g.
> pasid_pte_match_domain()
> > and then read pasid from the pte to compare with the pasid argument.
> >
> 
> The pasid value is not encoded in the pasid table entry. This validity
> check is only for RID2PASID as alias devices share the single RID2PASID
> entry. For other cases, we should always return -EBUSY as what the code
> is doing now.
> 

You are right.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
  2022-06-22  3:31                   ` Tian, Kevin
@ 2022-06-22  4:39                     ` Baolu Lu
  -1 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  4:39 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: baolu.lu, Qiang, Chenyi, Liu, Yi L, Pan, Jacob jun, iommu,
	linux-kernel, stable

On 2022/6/22 11:31, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Wednesday, June 22, 2022 11:28 AM
>>
>> On 2022/6/22 11:06, Tian, Kevin wrote:
>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 5:04 PM
>>>>
>>>> On 2022/6/21 13:48, Tian, Kevin wrote:
>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>> Sent: Tuesday, June 21, 2022 12:28 PM
>>>>>>
>>>>>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>>>>>
>>>>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
>>>>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>>>>>       			ret = intel_pasid_setup_second_level(iommu,
>>>>>>>>>> domain,
>>>>>>>>>>       					dev, PASID_RID2PASID);
>>>>>>>>>>       		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>>>>>> -		if (ret) {
>>>>>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>>>>>       			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>>>>>       			dmar_remove_one_dev_info(dev);
>>>>>>>>>>       			return ret;
>>>>>>>>>> --
>>>>>>>>>> 2.25.1
>>>>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>>>>>> setup when the first device is attached to the pasid table.
>>>>>>>> The logic that identifies the first device might introduce additional
>>>>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>>>>>> even prefer to give up sharing tables so that the code can be
>>>>>>>> simpler.:-)
>>>>>>>>
>>>>>>> It's not that complex if you simply move device_attach_pasid_table()
>>>>>>> out of intel_pasid_alloc_table(). Then do the setup if
>>>>>>> list_empty(&pasid_table->dev) and then attach device to the
>>>>>>> pasid table in domain_add_dev_info().
>>>>>> The pasid table is part of the device, hence a better place to
>>>>>> allocate/free the pasid table is in the device probe/release paths.
>>>>>> Things will become more complicated if we change relationship
>> between
>>>>>> device and it's pasid table when attaching/detaching a domain. That's
>>>>>> the reason why I thought it was additional complexity.
>>>>>>
>>>>> If you do want to follow current route it’s still cleaner to check
>>>>> whether the pasid entry has pointed to the domain in the individual
>>>>> setup function instead of blindly returning -EBUSY and then ignoring
>>>>> it even if a real busy condition occurs. The setup functions can
>>>>> just return zero for this benign alias case.
>>>> Kevin, how do you like this one?
>>>>
>>>> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
>>>> index cb4c1d0cf25c..ecffd0129b2b 100644
>>>> --- a/drivers/iommu/intel/pasid.c
>>>> +++ b/drivers/iommu/intel/pasid.c
>>>> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
>>>> pasid_entry *pte)
>>>>     	return 0;
>>>>     };
>>>>
>>>> +/*
>>>> + * Return true if @pasid is RID2PASID and the domain @did has already
>>>> + * been setup to the @pte. Otherwise, return false.
>>>> + */
>>>> +static inline bool
>>>> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
>>>> +{
>>>> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
>>>> did;
>>>> +}
>>> better this is not restricted to RID2PASID only, e.g.
>> pasid_pte_match_domain()
>>> and then read pasid from the pte to compare with the pasid argument.
>>>
>>
>> The pasid value is not encoded in the pasid table entry. This validity
>> check is only for RID2PASID as alias devices share the single RID2PASID
>> entry. For other cases, we should always return -EBUSY as what the code
>> is doing now.
>>
> 
> You are right.

Very appreciated for your input. I will update it with a v2.

Best regards,
baolu

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

* Re: [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure
@ 2022-06-22  4:39                     ` Baolu Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Baolu Lu @ 2022-06-22  4:39 UTC (permalink / raw)
  To: Tian, Kevin, Joerg Roedel, Raj, Ashok
  Cc: linux-kernel, stable, Qiang, Chenyi, iommu, Pan, Jacob jun

On 2022/6/22 11:31, Tian, Kevin wrote:
>> From: Baolu Lu <baolu.lu@linux.intel.com>
>> Sent: Wednesday, June 22, 2022 11:28 AM
>>
>> On 2022/6/22 11:06, Tian, Kevin wrote:
>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>> Sent: Tuesday, June 21, 2022 5:04 PM
>>>>
>>>> On 2022/6/21 13:48, Tian, Kevin wrote:
>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>> Sent: Tuesday, June 21, 2022 12:28 PM
>>>>>>
>>>>>> On 2022/6/21 11:46, Tian, Kevin wrote:
>>>>>>>> From: Baolu Lu<baolu.lu@linux.intel.com>
>>>>>>>> Sent: Tuesday, June 21, 2022 11:39 AM
>>>>>>>>
>>>>>>>> On 2022/6/21 10:54, Tian, Kevin wrote:
>>>>>>>>>> From: Lu Baolu<baolu.lu@linux.intel.com>
>>>>>>>>>> Sent: Monday, June 20, 2022 4:17 PM
>>>>>>>>>> @@ -2564,7 +2564,7 @@ static int domain_add_dev_info(struct
>>>>>>>>>> dmar_domain *domain, struct device *dev)
>>>>>>>>>>       			ret = intel_pasid_setup_second_level(iommu,
>>>>>>>>>> domain,
>>>>>>>>>>       					dev, PASID_RID2PASID);
>>>>>>>>>>       		spin_unlock_irqrestore(&iommu->lock, flags);
>>>>>>>>>> -		if (ret) {
>>>>>>>>>> +		if (ret && ret != -EBUSY) {
>>>>>>>>>>       			dev_err(dev, "Setup RID2PASID failed\n");
>>>>>>>>>>       			dmar_remove_one_dev_info(dev);
>>>>>>>>>>       			return ret;
>>>>>>>>>> --
>>>>>>>>>> 2.25.1
>>>>>>>>> It's cleaner to avoid this error at the first place, i.e. only do the
>>>>>>>>> setup when the first device is attached to the pasid table.
>>>>>>>> The logic that identifies the first device might introduce additional
>>>>>>>> unnecessary complexity. Devices that share a pasid table are rare. I
>>>>>>>> even prefer to give up sharing tables so that the code can be
>>>>>>>> simpler.:-)
>>>>>>>>
>>>>>>> It's not that complex if you simply move device_attach_pasid_table()
>>>>>>> out of intel_pasid_alloc_table(). Then do the setup if
>>>>>>> list_empty(&pasid_table->dev) and then attach device to the
>>>>>>> pasid table in domain_add_dev_info().
>>>>>> The pasid table is part of the device, hence a better place to
>>>>>> allocate/free the pasid table is in the device probe/release paths.
>>>>>> Things will become more complicated if we change relationship
>> between
>>>>>> device and it's pasid table when attaching/detaching a domain. That's
>>>>>> the reason why I thought it was additional complexity.
>>>>>>
>>>>> If you do want to follow current route it’s still cleaner to check
>>>>> whether the pasid entry has pointed to the domain in the individual
>>>>> setup function instead of blindly returning -EBUSY and then ignoring
>>>>> it even if a real busy condition occurs. The setup functions can
>>>>> just return zero for this benign alias case.
>>>> Kevin, how do you like this one?
>>>>
>>>> diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
>>>> index cb4c1d0cf25c..ecffd0129b2b 100644
>>>> --- a/drivers/iommu/intel/pasid.c
>>>> +++ b/drivers/iommu/intel/pasid.c
>>>> @@ -575,6 +575,16 @@ static inline int pasid_enable_wpe(struct
>>>> pasid_entry *pte)
>>>>     	return 0;
>>>>     };
>>>>
>>>> +/*
>>>> + * Return true if @pasid is RID2PASID and the domain @did has already
>>>> + * been setup to the @pte. Otherwise, return false.
>>>> + */
>>>> +static inline bool
>>>> +rid2pasid_domain_valid(struct pasid_entry *pte, u32 pasid, u16 did)
>>>> +{
>>>> +	return pasid == PASID_RID2PASID && pasid_get_domain_id(pte) ==
>>>> did;
>>>> +}
>>> better this is not restricted to RID2PASID only, e.g.
>> pasid_pte_match_domain()
>>> and then read pasid from the pte to compare with the pasid argument.
>>>
>>
>> The pasid value is not encoded in the pasid table entry. This validity
>> check is only for RID2PASID as alias devices share the single RID2PASID
>> entry. For other cases, we should always return -EBUSY as what the code
>> is doing now.
>>
> 
> You are right.

Very appreciated for your input. I will update it with a v2.

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

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

end of thread, other threads:[~2022-06-22  4:39 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-20  8:17 [PATCH 1/1] iommu/vt-d: Fix RID2PASID setup failure Lu Baolu
2022-06-20  8:17 ` Lu Baolu
2022-06-20  8:31 ` Yi Liu
2022-06-20  8:31   ` Yi Liu
2022-06-20  8:57   ` Baolu Lu
2022-06-20  8:57     ` Baolu Lu
2022-06-21  2:54 ` Tian, Kevin
2022-06-21  2:54   ` Tian, Kevin
2022-06-21  3:39   ` Baolu Lu
2022-06-21  3:39     ` Baolu Lu
2022-06-21  3:46     ` Tian, Kevin
2022-06-21  3:46       ` Tian, Kevin
2022-06-21  4:28       ` Baolu Lu
2022-06-21  4:28         ` Baolu Lu
2022-06-21  5:48         ` Tian, Kevin
2022-06-21  5:48           ` Tian, Kevin
2022-06-21  6:15           ` Baolu Lu
2022-06-21  6:15             ` Baolu Lu
2022-06-21  9:03           ` Baolu Lu
2022-06-21  9:03             ` Baolu Lu
2022-06-22  3:06             ` Tian, Kevin
2022-06-22  3:06               ` Tian, Kevin
2022-06-22  3:27               ` Baolu Lu
2022-06-22  3:27                 ` Baolu Lu
2022-06-22  3:31                 ` Tian, Kevin
2022-06-22  3:31                   ` Tian, Kevin
2022-06-22  4:39                   ` Baolu Lu
2022-06-22  4:39                     ` Baolu Lu
2022-06-22  2:56 ` Ethan Zhao
2022-06-22  3:22   ` Baolu Lu
2022-06-22  3:22     ` Baolu Lu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.