[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v5 08/20] intel_iommu: Check stage-1 translation result with
From: |
CLEMENT MATHIEU--DRIF |
Subject: |
Re: [PATCH v5 08/20] intel_iommu: Check stage-1 translation result with interrupt range |
Date: |
Wed, 13 Nov 2024 06:55:42 +0000 |
On 11/11/2024 09:34, Zhenzhong Duan wrote:
> Caution: External email. Do not open attachments or click links, unless this
> email comes from a known sender and you know the content is safe.
>
>
> Per VT-d spec 4.1 section 3.15, "Untranslated requests and translation
> requests that result in an address in the interrupt range will be
> blocked with condition code LGN.4 or SGN.8."
>
> This applies to both stage-1 and stage-2 IOMMU page table, move the
> check from vtd_iova_to_slpte() to vtd_do_iommu_translate() so stage-1
> page table could also be checked.
>
> By this chance, update the comment with correct section number.
>
> Suggested-by: Yi Liu <yi.l.liu@intel.com>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> ---
> hw/i386/intel_iommu.c | 48 ++++++++++++++++++++++---------------------
> 1 file changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 4cc4d668fc..e651401db1 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -1138,7 +1138,6 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s,
> VTDContextEntry *ce,
> uint32_t offset;
> uint64_t slpte;
> uint64_t access_right_check;
> - uint64_t xlat, size;
>
> if (!vtd_iova_sl_range_check(s, iova, ce, aw_bits, pasid)) {
> error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 ","
> @@ -1191,28 +1190,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s,
> VTDContextEntry *ce,
> level--;
> }
>
> - xlat = vtd_get_pte_addr(*slptep, aw_bits);
> - size = ~vtd_pt_level_page_mask(level) + 1;
> -
> - /*
> - * From VT-d spec 3.14: Untranslated requests and translation
> - * requests that result in an address in the interrupt range will be
> - * blocked with condition code LGN.4 or SGN.8.
> - */
> - if ((xlat > VTD_INTERRUPT_ADDR_LAST ||
> - xlat + size - 1 < VTD_INTERRUPT_ADDR_FIRST)) {
> - return 0;
> - } else {
> - error_report_once("%s: xlat address is in interrupt range "
> - "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
> - "slpte=0x%" PRIx64 ", write=%d, "
> - "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ", "
> - "pasid=0x%" PRIx32 ")",
> - __func__, iova, level, slpte, is_write,
> - xlat, size, pasid);
> - return s->scalable_mode ? -VTD_FR_SM_INTERRUPT_ADDR :
> - -VTD_FR_INTERRUPT_ADDR;
> - }
> + return 0;
> }
>
> typedef int (*vtd_page_walk_hook)(const IOMMUTLBEvent *event, void
> *private);
> @@ -2064,6 +2042,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace
> *vtd_as, PCIBus *bus,
> uint8_t access_flags;
> bool rid2pasid = (pasid == PCI_NO_PASID) && s->root_scalable;
> VTDIOTLBEntry *iotlb_entry;
> + uint64_t xlat, size;
>
> /*
> * We have standalone memory region for interrupt addresses, we
> @@ -2173,6 +2152,29 @@ static bool vtd_do_iommu_translate(VTDAddressSpace
> *vtd_as, PCIBus *bus,
> ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level,
> &reads, &writes, s->aw_bits, pasid);
> }
> + if (!ret_fr) {
> + xlat = vtd_get_pte_addr(pte, s->aw_bits);
> + size = ~vtd_pt_level_page_mask(level) + 1;
> +
> + /*
> + * Per VT-d spec 4.1 section 3.15: Untranslated requests and
> translation
> + * requests that result in an address in the interrupt range will be
> + * blocked with condition code LGN.4 or SGN.8.
> + */
> + if ((xlat <= VTD_INTERRUPT_ADDR_LAST &&
> + xlat + size - 1 >= VTD_INTERRUPT_ADDR_FIRST)) {
> + error_report_once("%s: xlat address is in interrupt range "
> + "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
> + "pte=0x%" PRIx64 ", write=%d, "
> + "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ", "
> + "pasid=0x%" PRIx32 ")",
> + __func__, addr, level, pte, is_write,
> + xlat, size, pasid);
Hi Zhenzhong,
Shouldn't we add the pgtt value to this trace as it can now be generated
by both FL and SL?
Thanks
cmd
> + ret_fr = s->scalable_mode ? -VTD_FR_SM_INTERRUPT_ADDR :
> + -VTD_FR_INTERRUPT_ADDR;
> + }
> + }
> +
> if (ret_fr) {
> vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
> addr, is_write, pasid != PCI_NO_PASID, pasid);
> --
> 2.34.1
>
- [PATCH v5 00/20] intel_iommu: Enable stage-1 translation for emulated device, Zhenzhong Duan, 2024/11/11
- [PATCH v5 04/20] intel_iommu: Flush stage-2 cache in PASID-selective PASID-based iotlb invalidation, Zhenzhong Duan, 2024/11/11
- [PATCH v5 01/20] intel_iommu: Use the latest fault reasons defined by spec, Zhenzhong Duan, 2024/11/11
- [PATCH v5 05/20] intel_iommu: Rename slpte to pte, Zhenzhong Duan, 2024/11/11
- [PATCH v5 02/20] intel_iommu: Make pasid entry type check accurate, Zhenzhong Duan, 2024/11/11
- [PATCH v5 07/20] intel_iommu: Check if the input address is canonical, Zhenzhong Duan, 2024/11/11
- [PATCH v5 03/20] intel_iommu: Add a placeholder variable for scalable modern mode, Zhenzhong Duan, 2024/11/11
- [PATCH v5 06/20] intel_iommu: Implement stage-1 translation, Zhenzhong Duan, 2024/11/11
- [PATCH v5 09/20] intel_iommu: Set accessed and dirty bits during stage-1 translation, Zhenzhong Duan, 2024/11/11
- [PATCH v5 08/20] intel_iommu: Check stage-1 translation result with interrupt range, Zhenzhong Duan, 2024/11/11
- Re: [PATCH v5 08/20] intel_iommu: Check stage-1 translation result with interrupt range,
CLEMENT MATHIEU--DRIF <=
- [PATCH v5 10/20] intel_iommu: Flush stage-1 cache in iotlb invalidation, Zhenzhong Duan, 2024/11/11
- [PATCH v5 11/20] intel_iommu: Process PASID-based iotlb invalidation, Zhenzhong Duan, 2024/11/11
- [PATCH v5 15/20] tests/acpi: q35: allow DMAR acpi table changes, Zhenzhong Duan, 2024/11/11
- [PATCH v5 16/20] intel_iommu: Set default aw_bits to 48 starting from QEMU 9.2, Zhenzhong Duan, 2024/11/11
- [PATCH v5 17/20] tests/acpi: q35: Update host address width in DMAR, Zhenzhong Duan, 2024/11/11