Re: [PATCH 2/3] iommu/vt-d: Parse SATC reporting structure

2021-02-02 Thread Lu Baolu

Hi Ashok,

On 2/3/21 12:41 AM, Raj, Ashok wrote:

On Tue, Feb 02, 2021 at 12:40:56PM +0800, Lu Baolu wrote:

From: Yian Chen 

Software should parse every SATC table and all devices in the tables
reported by the BIOS and keep the information in kernel list for further
SATC policy deployment.


The last part seems bit vague? Are you trying to imply,

if kernel is booted with noats for instance, a device listed in SATC table
as "requires ATS" will fail to load?

Otherwise its not clear what the policy enforcement means.



Yes. This is a bit vague. The ATS policy is out of the purpose of this
patch. It only parses the table and keep the device list for further
reference.

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


Re: [PATCH 2/3] iommu/vt-d: Parse SATC reporting structure

2021-02-02 Thread Lu Baolu

Hi Joerg,

On 2/2/21 9:53 PM, Joerg Roedel wrote:

On Tue, Feb 02, 2021 at 12:40:56PM +0800, Lu Baolu wrote:

+   case ACPI_DMAR_TYPE_SATC:
+   satc = container_of(header, struct acpi_dmar_satc, header);
+   pr_info("SATC flags: 0x%x\n", satc->flags);
+   break;


Did the pr_info() slip through or is there a real purpose for having
this information in the kernel log?



Here is just the easiest way for users to know SATC: system has SATC?
ATS is required?

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


Re: [PATCH 2/3] iommu/vt-d: Parse SATC reporting structure

2021-02-02 Thread Raj, Ashok
On Tue, Feb 02, 2021 at 12:40:56PM +0800, Lu Baolu wrote:
> From: Yian Chen 
> 
> Software should parse every SATC table and all devices in the tables
> reported by the BIOS and keep the information in kernel list for further
> SATC policy deployment.
> 
The last part seems bit vague? Are you trying to imply, 

if kernel is booted with noats for instance, a device listed in SATC table
as "requires ATS" will fail to load?

Otherwise its not clear what the policy enforcement means.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/3] iommu/vt-d: Parse SATC reporting structure

2021-02-02 Thread Joerg Roedel
On Tue, Feb 02, 2021 at 12:40:56PM +0800, Lu Baolu wrote:
> + case ACPI_DMAR_TYPE_SATC:
> + satc = container_of(header, struct acpi_dmar_satc, header);
> + pr_info("SATC flags: 0x%x\n", satc->flags);
> + break;

Did the pr_info() slip through or is there a real purpose for having
this information in the kernel log?

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


[PATCH 2/3] iommu/vt-d: Parse SATC reporting structure

2021-02-01 Thread Lu Baolu
From: Yian Chen 

Software should parse every SATC table and all devices in the tables
reported by the BIOS and keep the information in kernel list for further
SATC policy deployment.

Signed-off-by: Yian Chen 
---
 drivers/iommu/intel/dmar.c  |  9 
 drivers/iommu/intel/iommu.c | 89 +
 include/linux/dmar.h|  2 +
 3 files changed, 100 insertions(+)

diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 980e8ae090af..6bd357966d4e 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -526,6 +526,7 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
struct acpi_dmar_reserved_memory *rmrr;
struct acpi_dmar_atsr *atsr;
struct acpi_dmar_rhsa *rhsa;
+   struct acpi_dmar_satc *satc;
 
switch (header->type) {
case ACPI_DMAR_TYPE_HARDWARE_UNIT:
@@ -555,6 +556,11 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header 
*header)
/* We don't print this here because we need to sanity-check
   it first. So print it in dmar_parse_one_andd() instead. */
break;
+   case ACPI_DMAR_TYPE_SATC:
+   satc = container_of(header, struct acpi_dmar_satc, header);
+   pr_info("SATC flags: 0x%x\n", satc->flags);
+   break;
+
}
 }
 
@@ -642,6 +648,7 @@ parse_dmar_table(void)
.cb[ACPI_DMAR_TYPE_ROOT_ATS] = _parse_one_atsr,
.cb[ACPI_DMAR_TYPE_HARDWARE_AFFINITY] = _parse_one_rhsa,
.cb[ACPI_DMAR_TYPE_NAMESPACE] = _parse_one_andd,
+   .cb[ACPI_DMAR_TYPE_SATC] = _parse_one_satc,
};
 
/*
@@ -2077,6 +2084,7 @@ static guid_t dmar_hp_guid =
 #defineDMAR_DSM_FUNC_DRHD  1
 #defineDMAR_DSM_FUNC_ATSR  2
 #defineDMAR_DSM_FUNC_RHSA  3
+#defineDMAR_DSM_FUNC_SATC  4
 
 static inline bool dmar_detect_dsm(acpi_handle handle, int func)
 {
@@ -2094,6 +2102,7 @@ static int dmar_walk_dsm_resource(acpi_handle handle, int 
func,
[DMAR_DSM_FUNC_DRHD] = ACPI_DMAR_TYPE_HARDWARE_UNIT,
[DMAR_DSM_FUNC_ATSR] = ACPI_DMAR_TYPE_ROOT_ATS,
[DMAR_DSM_FUNC_RHSA] = ACPI_DMAR_TYPE_HARDWARE_AFFINITY,
+   [DMAR_DSM_FUNC_SATC] = ACPI_DMAR_TYPE_SATC,
};
 
if (!dmar_detect_dsm(handle, func))
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ecd36e456de3..b20fd305fc60 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -316,8 +316,18 @@ struct dmar_atsr_unit {
u8 include_all:1;   /* include all ports */
 };
 
+struct dmar_satc_unit {
+   struct list_head list;  /* list of SATC units */
+   struct acpi_dmar_header *hdr;   /* ACPI header */
+   struct dmar_dev_scope *devices; /* target devices */
+   struct intel_iommu *iommu;  /* the corresponding iommu */
+   int devices_cnt;/* target device count */
+   u8 atc_required:1;  /* ATS is required */
+};
+
 static LIST_HEAD(dmar_atsr_units);
 static LIST_HEAD(dmar_rmrr_units);
+static LIST_HEAD(dmar_satc_units);
 
 #define for_each_rmrr_units(rmrr) \
list_for_each_entry(rmrr, _rmrr_units, list)
@@ -3736,6 +3746,57 @@ int dmar_check_one_atsr(struct acpi_dmar_header *hdr, 
void *arg)
return 0;
 }
 
+static struct dmar_satc_unit *dmar_find_satc(struct acpi_dmar_satc *satc)
+{
+   struct dmar_satc_unit *satcu;
+   struct acpi_dmar_satc *tmp;
+
+   list_for_each_entry_rcu(satcu, _satc_units, list,
+   dmar_rcu_check()) {
+   tmp = (struct acpi_dmar_satc *)satcu->hdr;
+   if (satc->segment != tmp->segment)
+   continue;
+   if (satc->header.length != tmp->header.length)
+   continue;
+   if (memcmp(satc, tmp, satc->header.length) == 0)
+   return satcu;
+   }
+
+   return NULL;
+}
+
+int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg)
+{
+   struct acpi_dmar_satc *satc;
+   struct dmar_satc_unit *satcu;
+
+   if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
+   return 0;
+
+   satc = container_of(hdr, struct acpi_dmar_satc, header);
+   satcu = dmar_find_satc(satc);
+   if (satcu)
+   return 0;
+
+   satcu = kzalloc(sizeof(*satcu) + hdr->length, GFP_KERNEL);
+   if (!satcu)
+   return -ENOMEM;
+
+   satcu->hdr = (void *)(satcu + 1);
+   memcpy(satcu->hdr, hdr, hdr->length);
+   satcu->atc_required = satc->flags & 0x1;
+   satcu->devices = dmar_alloc_dev_scope((void *)(satc + 1),
+ (void *)satc + 
satc->header.length,
+ >devices_cnt);
+   if (satcu->devices_cnt && !satcu->devices)