Commit a8d4a37d authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Joerg Roedel
Browse files

iommu/amd: Restore GA log/tail pointer on host resume



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

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

Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20211123161038.48009-2-mlevitsk@redhat.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 0fcfb00b
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -806,16 +806,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);

@@ -825,7 +836,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;
@@ -834,8 +845,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;

@@ -849,16 +858,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);