Skip to content

Commit 8bda0cf

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Detect and initialize guest vAPIC log
This patch adds support to detect and initialize IOMMU Guest vAPIC log (GALOG). By default, it also enable GALog interrupt to notify IOMMU driver when GA Log entry is created. Signed-off-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 77bdab4 commit 8bda0cf

File tree

2 files changed

+133
-7
lines changed

2 files changed

+133
-7
lines changed

drivers/iommu/amd_iommu_init.c

Lines changed: 105 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#define ACPI_DEVFLAG_LINT1 0x80
8585
#define ACPI_DEVFLAG_ATSDIS 0x10000000
8686

87+
#define LOOP_TIMEOUT 100000
8788
/*
8889
* ACPI table definitions
8990
*
@@ -388,6 +389,10 @@ static void iommu_disable(struct amd_iommu *iommu)
388389
iommu_feature_disable(iommu, CONTROL_EVT_INT_EN);
389390
iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
390391

392+
/* Disable IOMMU GA_LOG */
393+
iommu_feature_disable(iommu, CONTROL_GALOG_EN);
394+
iommu_feature_disable(iommu, CONTROL_GAINT_EN);
395+
391396
/* Disable IOMMU hardware itself */
392397
iommu_feature_disable(iommu, CONTROL_IOMMU_EN);
393398
}
@@ -673,6 +678,99 @@ static void __init free_ppr_log(struct amd_iommu *iommu)
673678
free_pages((unsigned long)iommu->ppr_log, get_order(PPR_LOG_SIZE));
674679
}
675680

681+
static void free_ga_log(struct amd_iommu *iommu)
682+
{
683+
#ifdef CONFIG_IRQ_REMAP
684+
if (iommu->ga_log)
685+
free_pages((unsigned long)iommu->ga_log,
686+
get_order(GA_LOG_SIZE));
687+
if (iommu->ga_log_tail)
688+
free_pages((unsigned long)iommu->ga_log_tail,
689+
get_order(8));
690+
#endif
691+
}
692+
693+
static int iommu_ga_log_enable(struct amd_iommu *iommu)
694+
{
695+
#ifdef CONFIG_IRQ_REMAP
696+
u32 status, i;
697+
698+
if (!iommu->ga_log)
699+
return -EINVAL;
700+
701+
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
702+
703+
/* Check if already running */
704+
if (status & (MMIO_STATUS_GALOG_RUN_MASK))
705+
return 0;
706+
707+
iommu_feature_enable(iommu, CONTROL_GAINT_EN);
708+
iommu_feature_enable(iommu, CONTROL_GALOG_EN);
709+
710+
for (i = 0; i < LOOP_TIMEOUT; ++i) {
711+
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
712+
if (status & (MMIO_STATUS_GALOG_RUN_MASK))
713+
break;
714+
}
715+
716+
if (i >= LOOP_TIMEOUT)
717+
return -EINVAL;
718+
#endif /* CONFIG_IRQ_REMAP */
719+
return 0;
720+
}
721+
722+
#ifdef CONFIG_IRQ_REMAP
723+
static int iommu_init_ga_log(struct amd_iommu *iommu)
724+
{
725+
u64 entry;
726+
727+
if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
728+
return 0;
729+
730+
iommu->ga_log = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
731+
get_order(GA_LOG_SIZE));
732+
if (!iommu->ga_log)
733+
goto err_out;
734+
735+
iommu->ga_log_tail = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
736+
get_order(8));
737+
if (!iommu->ga_log_tail)
738+
goto err_out;
739+
740+
entry = (u64)virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
741+
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
742+
&entry, sizeof(entry));
743+
entry = ((u64)virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL;
744+
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
745+
&entry, sizeof(entry));
746+
writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
747+
writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);
748+
749+
return 0;
750+
err_out:
751+
free_ga_log(iommu);
752+
return -EINVAL;
753+
}
754+
#endif /* CONFIG_IRQ_REMAP */
755+
756+
static int iommu_init_ga(struct amd_iommu *iommu)
757+
{
758+
int ret = 0;
759+
760+
#ifdef CONFIG_IRQ_REMAP
761+
/* Note: We have already checked GASup from IVRS table.
762+
* Now, we need to make sure that GAMSup is set.
763+
*/
764+
if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) &&
765+
!iommu_feature(iommu, FEATURE_GAM_VAPIC))
766+
amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
767+
768+
ret = iommu_init_ga_log(iommu);
769+
#endif /* CONFIG_IRQ_REMAP */
770+
771+
return ret;
772+
}
773+
676774
static void iommu_enable_gt(struct amd_iommu *iommu)
677775
{
678776
if (!iommu_feature(iommu, FEATURE_GT))
@@ -1146,6 +1244,7 @@ static void __init free_iommu_one(struct amd_iommu *iommu)
11461244
free_command_buffer(iommu);
11471245
free_event_buffer(iommu);
11481246
free_ppr_log(iommu);
1247+
free_ga_log(iommu);
11491248
iommu_unmap_mmio_space(iommu);
11501249
}
11511250

@@ -1438,6 +1537,7 @@ static int iommu_init_pci(struct amd_iommu *iommu)
14381537
{
14391538
int cap_ptr = iommu->cap_ptr;
14401539
u32 range, misc, low, high;
1540+
int ret;
14411541

14421542
iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid),
14431543
iommu->devid & 0xff);
@@ -1494,13 +1594,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
14941594
if (iommu_feature(iommu, FEATURE_PPR) && alloc_ppr_log(iommu))
14951595
return -ENOMEM;
14961596

1497-
/* Note: We have already checked GASup from IVRS table.
1498-
* Now, we need to make sure that GAMSup is set.
1499-
*/
1500-
if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) &&
1501-
!iommu_feature(iommu, FEATURE_GAM_VAPIC))
1502-
amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
1503-
1597+
ret = iommu_init_ga(iommu);
1598+
if (ret)
1599+
return ret;
15041600

15051601
if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
15061602
amd_iommu_np_cache = true;
@@ -1667,6 +1763,8 @@ static int iommu_init_msi(struct amd_iommu *iommu)
16671763
if (iommu->ppr_log != NULL)
16681764
iommu_feature_enable(iommu, CONTROL_PPFINT_EN);
16691765

1766+
iommu_ga_log_enable(iommu);
1767+
16701768
return 0;
16711769
}
16721770

drivers/iommu/amd_iommu_types.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,17 @@
7070
#define MMIO_EXCL_LIMIT_OFFSET 0x0028
7171
#define MMIO_EXT_FEATURES 0x0030
7272
#define MMIO_PPR_LOG_OFFSET 0x0038
73+
#define MMIO_GA_LOG_BASE_OFFSET 0x00e0
74+
#define MMIO_GA_LOG_TAIL_OFFSET 0x00e8
7375
#define MMIO_CMD_HEAD_OFFSET 0x2000
7476
#define MMIO_CMD_TAIL_OFFSET 0x2008
7577
#define MMIO_EVT_HEAD_OFFSET 0x2010
7678
#define MMIO_EVT_TAIL_OFFSET 0x2018
7779
#define MMIO_STATUS_OFFSET 0x2020
7880
#define MMIO_PPR_HEAD_OFFSET 0x2030
7981
#define MMIO_PPR_TAIL_OFFSET 0x2038
82+
#define MMIO_GA_HEAD_OFFSET 0x2040
83+
#define MMIO_GA_TAIL_OFFSET 0x2048
8084
#define MMIO_CNTR_CONF_OFFSET 0x4000
8185
#define MMIO_CNTR_REG_OFFSET 0x40000
8286
#define MMIO_REG_END_OFFSET 0x80000
@@ -112,6 +116,9 @@
112116
#define MMIO_STATUS_EVT_INT_MASK (1 << 1)
113117
#define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2)
114118
#define MMIO_STATUS_PPR_INT_MASK (1 << 6)
119+
#define MMIO_STATUS_GALOG_RUN_MASK (1 << 8)
120+
#define MMIO_STATUS_GALOG_OVERFLOW_MASK (1 << 9)
121+
#define MMIO_STATUS_GALOG_INT_MASK (1 << 10)
115122

116123
/* event logging constants */
117124
#define EVENT_ENTRY_SIZE 0x10
@@ -150,6 +157,8 @@
150157
#define CONTROL_GT_EN 0x10ULL
151158
#define CONTROL_GA_EN 0x11ULL
152159
#define CONTROL_GAM_EN 0x19ULL
160+
#define CONTROL_GALOG_EN 0x1CULL
161+
#define CONTROL_GAINT_EN 0x1DULL
153162

154163
#define CTRL_INV_TO_MASK (7 << CONTROL_INV_TIMEOUT)
155164
#define CTRL_INV_TO_NONE 0
@@ -228,6 +237,19 @@
228237

229238
#define PPR_REQ_FAULT 0x01
230239

240+
/* Constants for GA Log handling */
241+
#define GA_LOG_ENTRIES 512
242+
#define GA_LOG_SIZE_SHIFT 56
243+
#define GA_LOG_SIZE_512 (0x8ULL << GA_LOG_SIZE_SHIFT)
244+
#define GA_ENTRY_SIZE 8
245+
#define GA_LOG_SIZE (GA_ENTRY_SIZE * GA_LOG_ENTRIES)
246+
247+
#define GA_TAG(x) (u32)(x & 0xffffffffULL)
248+
#define GA_DEVID(x) (u16)(((x) >> 32) & 0xffffULL)
249+
#define GA_REQ_TYPE(x) (((x) >> 60) & 0xfULL)
250+
251+
#define GA_GUEST_NR 0x1
252+
231253
#define PAGE_MODE_NONE 0x00
232254
#define PAGE_MODE_1_LEVEL 0x01
233255
#define PAGE_MODE_2_LEVEL 0x02
@@ -501,6 +523,12 @@ struct amd_iommu {
501523
/* Base of the PPR log, if present */
502524
u8 *ppr_log;
503525

526+
/* Base of the GA log, if present */
527+
u8 *ga_log;
528+
529+
/* Tail of the GA log, if present */
530+
u8 *ga_log_tail;
531+
504532
/* true if interrupts for this IOMMU are already enabled */
505533
bool int_enabled;
506534

0 commit comments

Comments
 (0)