Linux IOMMU Development
 help / color / mirror / Atom feed
From: Vasant Hegde <vasant.hegde@amd.com>
To: Klara Modin <klarasmodin@gmail.com>,
	iommu@lists.linux.dev, joro@8bytes.org
Cc: suravee.suthikulpanit@amd.com, wei.huang2@amd.com,
	jsnitsel@redhat.com, jgg@ziepe.ca,
	Jason Gunthorpe <jgg@nvidia.com>
Subject: Re: [PATCH v8 07/15] iommu/amd: Setup GCR3 table in advance if domain is SVA capable
Date: Mon, 6 May 2024 13:01:46 +0530	[thread overview]
Message-ID: <3488f733-c920-4e2a-86f7-05dc1779685e@amd.com> (raw)
In-Reply-To: <333e6eb6-361c-4afb-8107-2573324bf689@gmail.com>

Hi Klara,


On 5/2/2024 6:46 PM, Klara Modin wrote:
> Hi,
> 
> On 2024-04-18 12:33, Vasant Hegde wrote:
>> SVA can be supported if domain is in passthrough mode or paging domain
>> with v2 page table. Current code sets up GCR3 table for domain with v2
>> page table only. Setup GCR3 table for all SVA capable domains.
>>
>>    - Move GCR3 init/destroy to separate function.
>>
>>    - Change default GCR3 table to use MAX supported PASIDs. Ideally it
>>      should use 1 level PASID table as its using PASID zero only. But we
>>      don't have support to extend PASID table yet. We will fix this later.
>>
>>    - When domain is configured with passthrough mode, allocate default GCR3
>>      table only if device is SVA capable.
>>
>> Note that in attach_device() path it will not know whether device will use
>> SVA or not. If device is attached to passthrough domain and if it doesn't
>> use SVA then GCR3 table will never be used. We will endup wasting memory
>> allocated for GCR3 table. This is done to avoid DTE update when
>> attaching PASID to device.
>>
>> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
>> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
>> ---
>>   drivers/iommu/amd/iommu.c | 86 ++++++++++++++++++++++++++++++++-------
>>   1 file changed, 71 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
>> index 7daf6d75d964..288cf7485306 100644
>> --- a/drivers/iommu/amd/iommu.c
>> +++ b/drivers/iommu/amd/iommu.c
>> @@ -89,6 +89,21 @@ static inline bool pdom_is_v2_pgtbl_mode(struct
>> protection_domain *pdom)
>>       return (pdom && (pdom->pd_mode == PD_MODE_V2));
>>   }
>>   +static inline bool pdom_is_in_pt_mode(struct protection_domain *pdom)
>> +{
>> +    return (pdom->domain.type == IOMMU_DOMAIN_IDENTITY);
>> +}
>> +
>> +/*
>> + * We cannot support PASID w/ existing v1 page table in the same domain
>> + * since it will be nested. However, existing domain w/ v2 page table
>> + * or passthrough mode can be used for PASID.
>> + */
>> +static inline bool pdom_is_sva_capable(struct protection_domain *pdom)
>> +{
>> +    return pdom_is_v2_pgtbl_mode(pdom) || pdom_is_in_pt_mode(pdom);
>> +}
>> +
>>   static inline int get_acpihid_device_id(struct device *dev,
>>                       struct acpihid_map_entry **entry)
>>   {
>> @@ -1964,6 +1979,58 @@ void amd_iommu_dev_update_dte(struct iommu_dev_data
>> *dev_data, bool set)
>>       iommu_completion_wait(iommu);
>>   }
>>   +/*
>> + * If domain is SVA capable then initialize GCR3 table. Also if domain is
>> + * in v2 page table mode then update GCR3[0].
>> + */
>> +static int init_gcr3_table(struct iommu_dev_data *dev_data,
>> +               struct protection_domain *pdom)
>> +{
>> +    struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
>> +    int max_pasids = dev_data->max_pasids;
>> +    int ret = 0;
>> +
>> +     /*
>> +      * If domain is in pt mode then setup GCR3 table only if device
>> +      * is PASID capable
>> +      */
>> +    if (pdom_is_in_pt_mode(pdom) && !pdev_pasid_supported(dev_data))
>> +        return ret;
>> +
>> +    /*
>> +     * By default, setup GCR3 table to support MAX PASIDs
>> +     * supported by the device/IOMMU.
>> +     */
>> +    ret = setup_gcr3_table(&dev_data->gcr3_info, iommu,
>> +                   max_pasids > 0 ?  max_pasids : 1);
>> +    if (ret)
>> +        return ret;
>> +
>> +    /* Setup GCR3[0] only if domain is setup with v2 page table mode */
>> +    if (!pdom_is_v2_pgtbl_mode(pdom))
>> +        return ret;
>> +
>> +    ret = update_gcr3(dev_data, 0, iommu_virt_to_phys(pdom->iop.pgd), true);
>> +    if (ret)
>> +        free_gcr3_table(&dev_data->gcr3_info);
>> +
>> +    return ret;
>> +}
>> +
>> +static void destroy_gcr3_table(struct iommu_dev_data *dev_data,
>> +                   struct protection_domain *pdom)
>> +{
>> +    struct gcr3_tbl_info *gcr3_info = &dev_data->gcr3_info;
>> +
>> +    if (pdom_is_v2_pgtbl_mode(pdom))
>> +        update_gcr3(dev_data, 0, 0, false);
>> +
>> +    if (gcr3_info->gcr3_tbl == NULL)
>> +        return;
>> +
>> +    free_gcr3_table(gcr3_info);
>> +}
>> +
>>   static int do_attach(struct iommu_dev_data *dev_data,
>>                struct protection_domain *domain)
>>   {
>> @@ -1982,19 +2049,10 @@ static int do_attach(struct iommu_dev_data *dev_data,
>>       domain->dev_iommu[iommu->index] += 1;
>>       domain->dev_cnt                 += 1;
>>   -    /* Init GCR3 table and update device table */
>> -    if (domain->pd_mode == PD_MODE_V2) {
>> -        /* By default, setup GCR3 table to support single PASID */
>> -        ret = setup_gcr3_table(&dev_data->gcr3_info, iommu, 1);
>> +    if (pdom_is_sva_capable(domain)) {
>> +        ret = init_gcr3_table(dev_data, domain);
>>           if (ret)
>>               return ret;
>> -
>> -        ret = update_gcr3(dev_data, 0,
>> -                  iommu_virt_to_phys(domain->iop.pgd), true);
>> -        if (ret) {
>> -            free_gcr3_table(&dev_data->gcr3_info);
>> -            return ret;
>> -        }
>>       }
>>         /* Update device table */
>> @@ -2009,10 +2067,8 @@ static void do_detach(struct iommu_dev_data *dev_data)
>>       struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
>>         /* Clear GCR3 table */
>> -    if (domain->pd_mode == PD_MODE_V2) {
>> -        update_gcr3(dev_data, 0, 0, false);
>> -        free_gcr3_table(&dev_data->gcr3_info);
>> -    }
>> +    if (pdom_is_sva_capable(domain))
>> +        destroy_gcr3_table(dev_data, domain);
>>         /* Update data structures */
>>       dev_data->domain = NULL;
> 
> This change seems to interact poorly with the amdgpu driver. It fails to
> initialize properly (monitors go to sleep).
> 
> The full log is attached, this snippet happens immediately before the first
> warning:
> amdgpu 0000:2d:00.0: amdgpu: STB initialized to 2048 entries
> [drm] Loading DMUB firmware via PSP: version=0x02020020
> [drm] use_doorbell being set to: [true]
> [drm] use_doorbell being set to: [true]
> [drm] Found VCN firmware Version ENC: 1.30 DEC: 3 VEP: 0 Revision: 4
> amdgpu 0000:2d:00.0: amdgpu: Will use PSP to load VCN firmware
> iommu ivhd0: AMD-Vi: Event logged [ILLEGAL_DEV_TABLE_ENTRY device=0000:2d:00.0
> pasid=0x00000 address=0x11c300000 flags=0x0080]
> AMD-Vi: DTE[0]: 7d80000000000003
> AMD-Vi: DTE[1]: 0000100011700014
> AMD-Vi: DTE[2]: 0000000000000000
> AMD-Vi: DTE[3]: 0000000000000000
> r8169 0000:05:00.0 enp5s0: Link is Up - 1Gbps/Full - flow control rx/tx
> amdgpu 0000:2d:00.0: amdgpu: PSP load kdb failed!
> [drm:psp_v11_0_ring_destroy [amdgpu]] *ERROR* Fail to stop psp ring
> [drm:amdgpu_fill_buffer [amdgpu]] *ERROR* Trying to clear memory with ring
> turned off.
> 
> Please let me know if this is the wrong place to report this or there's anything
> else you need.

Thanks for the report.

Looking into the attached dmesg :

2024-04-29T10:35:05+02:00 soda.int.kasm.eu kernel: AMD-Vi: Using global IVHD
EFR:0x0, EFR2:0x0

--> This means BIOS didn't setup the EFR flags in ACPI IVRS table (its BIOS issue).

Commit 8e0179733172 (iommu/amd: Enable Guest Translation before registering
devices) changed GT feature enablement in control register.

Now it tries to enable CONTROL[GT] flag before reading IOMMU feature register
(late_iommu_features_init()).

In attach device path, it assumed GT is supported (based on IOMMU EFR register
value) and enabled DTE[GV]. Hence we hit ILLEGAL_DEV_TABLE_ENTRY error.


Can you please try below fix?


-Vasant

---


diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index fd3e76e43699..b292181995b7 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2046,6 +2046,8 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
 			amd_iommu_max_glx_val = glxval;
 		else
 			amd_iommu_max_glx_val = min(amd_iommu_max_glx_val, glxval);
+
+		iommu_enable_gt(iommu);
 	}

 	if (check_feature(FEATURE_PPR) && amd_iommu_alloc_ppr_log(iommu))
@@ -2732,7 +2734,6 @@ static void early_enable_iommu(struct amd_iommu *iommu)
 	iommu_enable_command_buffer(iommu);
 	iommu_enable_event_buffer(iommu);
 	iommu_set_exclusion_range(iommu);
-	iommu_enable_gt(iommu);
 	iommu_enable_ga(iommu);
 	iommu_enable_xt(iommu);
 	iommu_enable_irtcachedis(iommu);
@@ -2789,7 +2790,6 @@ static void early_enable_iommus(void)
 			iommu_disable_irtcachedis(iommu);
 			iommu_enable_command_buffer(iommu);
 			iommu_enable_event_buffer(iommu);
-			iommu_enable_gt(iommu);
 			iommu_enable_ga(iommu);
 			iommu_enable_xt(iommu);
 			iommu_enable_irtcachedis(iommu);

  parent reply	other threads:[~2024-05-06  7:32 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-18 10:33 [PATCH v8 00/15] iommu/amd: SVA Support (Part 4) - SVA and IOPF Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 01/15] iommu/amd: Rename amd_iommu_v2_supported() as amd_iommu_pasid_supported() Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 02/15] iommu/amd: Introduce per device DTE update function Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 03/15] iommu/amd: Add support for enabling/disabling IOMMU features Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 04/15] iommu/amd: Move PPR-related functions into ppr.c Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 05/15] iommu/amd: Fix PPR interrupt processing logic Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 06/15] iommu/amd: Introduce iommu_dev_data.max_pasids Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 07/15] iommu/amd: Setup GCR3 table in advance if domain is SVA capable Vasant Hegde
2024-05-02 13:16   ` Klara Modin
2024-05-03 10:26     ` Joerg Roedel
2024-05-06  6:42       ` Vasant Hegde
2024-05-06  7:31     ` Vasant Hegde [this message]
2024-05-06  7:47       ` Klara Modin
2024-05-06  8:15         ` Joerg Roedel
2024-05-06  8:25           ` Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 08/15] iommu/amd: Enable PCI features based on attached domain capability Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 09/15] iommu/amd: Define per-IOMMU iopf_queue Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 10/15] iommu/amd: Add support for page response Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 11/15] iommu/amd: Add IO page fault notifier handler Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 12/15] iommu/amd: Add support for enable/disable IOPF Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 13/15] iommu/amd: Initial SVA support for AMD IOMMU Vasant Hegde
2024-04-18 10:33 ` [PATCH v8 14/15] iommu: Add ops->domain_alloc_sva() Vasant Hegde
2024-04-18 10:34 ` [PATCH v8 15/15] iommu/amd: Add SVA domain support Vasant Hegde
2024-04-26 10:57 ` [PATCH v8 00/15] iommu/amd: SVA Support (Part 4) - SVA and IOPF Joerg Roedel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3488f733-c920-4e2a-86f7-05dc1779685e@amd.com \
    --to=vasant.hegde@amd.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@nvidia.com \
    --cc=jgg@ziepe.ca \
    --cc=joro@8bytes.org \
    --cc=jsnitsel@redhat.com \
    --cc=klarasmodin@gmail.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=wei.huang2@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox