iommu/amd: Restore GA log/tail pointer on host resume
authorMaxim Levitsky <mlevitsk@redhat.com>
Tue, 23 Nov 2021 16:10:34 +0000 (18:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 10:04:13 +0000 (11:04 +0100)
[ Upstream commit a8d4a37d1bb93608501d0d0545f902061152669a ]

This will give IOMMU GA log a chance to work after resume
from s3/s4.

Fixes: 8bda0cfbdc1a6 ("iommu/amd: Detect and initialize guest vAPIC log")

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20211123161038.48009-2-mlevitsk@redhat.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/iommu/amd/init.c

index 2a822b2..9b12a2f 100644 (file)
@@ -804,16 +804,27 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
 {
 #ifdef CONFIG_IRQ_REMAP
        u32 status, i;
+       u64 entry;
 
        if (!iommu->ga_log)
                return -EINVAL;
 
-       status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
-
        /* Check if already running */
-       if (status & (MMIO_STATUS_GALOG_RUN_MASK))
+       status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
+       if (WARN_ON(status & (MMIO_STATUS_GALOG_RUN_MASK)))
                return 0;
 
+       entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
+       memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
+                   &entry, sizeof(entry));
+       entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
+                (BIT_ULL(52)-1)) & ~7ULL;
+       memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
+                   &entry, sizeof(entry));
+       writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
+       writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);
+
+
        iommu_feature_enable(iommu, CONTROL_GAINT_EN);
        iommu_feature_enable(iommu, CONTROL_GALOG_EN);
 
@@ -823,7 +834,7 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
                        break;
        }
 
-       if (i >= LOOP_TIMEOUT)
+       if (WARN_ON(i >= LOOP_TIMEOUT))
                return -EINVAL;
 #endif /* CONFIG_IRQ_REMAP */
        return 0;
@@ -832,8 +843,6 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
 static int iommu_init_ga_log(struct amd_iommu *iommu)
 {
 #ifdef CONFIG_IRQ_REMAP
-       u64 entry;
-
        if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
                return 0;
 
@@ -847,16 +856,6 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)
        if (!iommu->ga_log_tail)
                goto err_out;
 
-       entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
-       memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
-                   &entry, sizeof(entry));
-       entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
-                (BIT_ULL(52)-1)) & ~7ULL;
-       memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
-                   &entry, sizeof(entry));
-       writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
-       writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);
-
        return 0;
 err_out:
        free_ga_log(iommu);