[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241016135232.GM3559746@nvidia.com>
Date: Wed, 16 Oct 2024 10:52:32 -0300
From: Jason Gunthorpe <jgg@...dia.com>
To: Suravee Suthikulpanit <suravee.suthikulpanit@....com>
Cc: linux-kernel@...r.kernel.org, iommu@...ts.linux.dev, joro@...tes.org,
robin.murphy@....com, vasant.hegde@....com, kevin.tian@...el.com,
jon.grimm@....com, santosh.shukla@....com, pandoh@...gle.com,
kumaranand@...gle.com
Subject: Re: [PATCH v6 5/9] iommu/amd: Modify set_dte_entry() to use 256-bit
DTE helpers
On Wed, Oct 16, 2024 at 05:17:52AM +0000, Suravee Suthikulpanit wrote:
> +static void set_dte_gcr3_table(struct amd_iommu *iommu,
> + struct iommu_dev_data *dev_data,
> + struct dev_table_entry *target)
> +{
> + struct gcr3_tbl_info *gcr3_info = &dev_data->gcr3_info;
> + u64 tmp, gcr3;
> +
> + if (!gcr3_info->gcr3_tbl)
> + return;
> +
> + pr_debug("%s: devid=%#x, glx=%#x, gcr3_tbl=%#llx\n",
> + __func__, dev_data->devid, gcr3_info->glx,
> + (unsigned long long)gcr3_info->gcr3_tbl);
> +
> + tmp = gcr3_info->glx;
> + target->data[0] |= (tmp & DTE_GLX_MASK) << DTE_GLX_SHIFT;
> + if (pdom_is_v2_pgtbl_mode(dev_data->domain))
> + target->data[0] |= DTE_FLAG_GIOV;
> + target->data[0] |= DTE_FLAG_GV;
> +
> +
> + gcr3 = iommu_virt_to_phys(gcr3_info->gcr3_tbl);
> +
> + /* Encode GCR3 table into DTE */
> + tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A;
> + target->data[0] |= tmp;
> + tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B;
> + tmp |= DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C;
> + target->data[1] |= tmp;
> +
> + /* Guest page table can only support 4 and 5 levels */
> + if (amd_iommu_gpt_level == PAGE_MODE_5_LEVEL)
> + target->data[2] |= ((u64)GUEST_PGTABLE_5_LEVEL << DTE_GPT_LEVEL_SHIFT);
> +}
This looks OK but suggest to use the new macros and things, it is much
more readable:
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 53e129835b2668..fbae0803bceaa0 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -409,8 +409,7 @@
#define DTE_FLAG_HAD (3ULL << 7)
#define DTE_FLAG_GIOV BIT_ULL(54)
#define DTE_FLAG_GV BIT_ULL(55)
-#define DTE_GLX_SHIFT (56)
-#define DTE_GLX_MASK (3)
+#define DTE_GLX GENMASK_ULL(57, 56)
#define DTE_FLAG_IR BIT_ULL(61)
#define DTE_FLAG_IW BIT_ULL(62)
@@ -418,15 +417,10 @@
#define DTE_FLAG_MASK (0x3ffULL << 32)
#define DEV_DOMID_MASK 0xffffULL
-#define DTE_GCR3_VAL_A(x) (((x) >> 12) & 0x00007ULL)
-#define DTE_GCR3_VAL_B(x) (((x) >> 15) & 0x0ffffULL)
-#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0x1fffffULL)
+#define DTE_GCR3_14_12 GENMASK_ULL(57, 56)
+#define DTE_GCR3_30_15 GENMASK_ULL(31, 16)
+#define DTE_GCR3_51_31 GENMASK_ULL(63, 43)
-#define DTE_GCR3_SHIFT_A 58
-#define DTE_GCR3_SHIFT_B 16
-#define DTE_GCR3_SHIFT_C 43
-
-#define DTE_GPT_LEVEL_SHIFT 54
#define DTE_GPT_LEVEL_MASK GENMASK_ULL(55, 54)
#define GCR3_VALID 0x01ULL
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index caea101df7b93d..b0d2174583dbc9 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2012,7 +2012,7 @@ static void set_dte_gcr3_table(struct amd_iommu *iommu,
struct dev_table_entry *target)
{
struct gcr3_tbl_info *gcr3_info = &dev_data->gcr3_info;
- u64 tmp, gcr3;
+ u64 gcr3;
if (!gcr3_info->gcr3_tbl)
return;
@@ -2021,25 +2021,24 @@ static void set_dte_gcr3_table(struct amd_iommu *iommu,
__func__, dev_data->devid, gcr3_info->glx,
(unsigned long long)gcr3_info->gcr3_tbl);
- tmp = gcr3_info->glx;
- target->data[0] |= (tmp & DTE_GLX_MASK) << DTE_GLX_SHIFT;
- if (pdom_is_v2_pgtbl_mode(dev_data->domain))
- target->data[0] |= DTE_FLAG_GIOV;
- target->data[0] |= DTE_FLAG_GV;
-
-
gcr3 = iommu_virt_to_phys(gcr3_info->gcr3_tbl);
- /* Encode GCR3 table into DTE */
- tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A;
- target->data[0] |= tmp;
- tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B;
- tmp |= DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C;
- target->data[1] |= tmp;
+ target->data[0] |= DTE_FLAG_GV |
+ FIELD_PREP(DTE_GLX, gcr3_info->glx) |
+ FIELD_PREP(DTE_GCR3_14_12, gcr3 >> 12);
+ if (pdom_is_v2_pgtbl_mode(dev_data->domain))
+ target->data[0] |= DTE_FLAG_GIOV;
+
+ target->data[1] |= FIELD_PREP(DTE_GCR3_30_15, gcr3 >> 15) |
+ FIELD_PREP(DTE_GCR3_51_31, gcr3 >> 31);
/* Guest page table can only support 4 and 5 levels */
if (amd_iommu_gpt_level == PAGE_MODE_5_LEVEL)
- target->data[2] |= ((u64)GUEST_PGTABLE_5_LEVEL << DTE_GPT_LEVEL_SHIFT);
+ target->data[2] |=
+ FIELD_PREP(DTE_GPT_LEVEL_MASK, GUEST_PGTABLE_5_LEVEL);
+ else
+ target->data[2] |=
+ FIELD_PREP(DTE_GPT_LEVEL_MASK, GUEST_PGTABLE_4_LEVEL);
}
static void set_dte_entry(struct amd_iommu *iommu,
Powered by blists - more mailing lists