aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/amd_iommu_proto.h10
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h17
-rw-r--r--arch/x86/kernel/amd_iommu_init.c24
3 files changed, 48 insertions, 3 deletions
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h
index 1223c0fe03f5..a4ae6c3875eb 100644
--- a/arch/x86/include/asm/amd_iommu_proto.h
+++ b/arch/x86/include/asm/amd_iommu_proto.h
@@ -19,7 +19,7 @@
19#ifndef _ASM_X86_AMD_IOMMU_PROTO_H 19#ifndef _ASM_X86_AMD_IOMMU_PROTO_H
20#define _ASM_X86_AMD_IOMMU_PROTO_H 20#define _ASM_X86_AMD_IOMMU_PROTO_H
21 21
22struct amd_iommu; 22#include <asm/amd_iommu_types.h>
23 23
24extern int amd_iommu_init_dma_ops(void); 24extern int amd_iommu_init_dma_ops(void);
25extern int amd_iommu_init_passthrough(void); 25extern int amd_iommu_init_passthrough(void);
@@ -42,4 +42,12 @@ static inline bool is_rd890_iommu(struct pci_dev *pdev)
42 (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); 42 (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
43} 43}
44 44
45static inline bool iommu_feature(struct amd_iommu *iommu, u64 f)
46{
47 if (!(iommu->cap & (1 << IOMMU_CAP_EFR)))
48 return false;
49
50 return !!(iommu->features & f);
51}
52
45#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ 53#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 878ae008eb04..5c24e4652347 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -68,12 +68,25 @@
68#define MMIO_CONTROL_OFFSET 0x0018 68#define MMIO_CONTROL_OFFSET 0x0018
69#define MMIO_EXCL_BASE_OFFSET 0x0020 69#define MMIO_EXCL_BASE_OFFSET 0x0020
70#define MMIO_EXCL_LIMIT_OFFSET 0x0028 70#define MMIO_EXCL_LIMIT_OFFSET 0x0028
71#define MMIO_EXT_FEATURES 0x0030
71#define MMIO_CMD_HEAD_OFFSET 0x2000 72#define MMIO_CMD_HEAD_OFFSET 0x2000
72#define MMIO_CMD_TAIL_OFFSET 0x2008 73#define MMIO_CMD_TAIL_OFFSET 0x2008
73#define MMIO_EVT_HEAD_OFFSET 0x2010 74#define MMIO_EVT_HEAD_OFFSET 0x2010
74#define MMIO_EVT_TAIL_OFFSET 0x2018 75#define MMIO_EVT_TAIL_OFFSET 0x2018
75#define MMIO_STATUS_OFFSET 0x2020 76#define MMIO_STATUS_OFFSET 0x2020
76 77
78
79/* Extended Feature Bits */
80#define FEATURE_PREFETCH (1ULL<<0)
81#define FEATURE_PPR (1ULL<<1)
82#define FEATURE_X2APIC (1ULL<<2)
83#define FEATURE_NX (1ULL<<3)
84#define FEATURE_GT (1ULL<<4)
85#define FEATURE_IA (1ULL<<6)
86#define FEATURE_GA (1ULL<<7)
87#define FEATURE_HE (1ULL<<8)
88#define FEATURE_PC (1ULL<<9)
89
77/* MMIO status bits */ 90/* MMIO status bits */
78#define MMIO_STATUS_COM_WAIT_INT_MASK 0x04 91#define MMIO_STATUS_COM_WAIT_INT_MASK 0x04
79 92
@@ -227,6 +240,7 @@
227/* IOMMU capabilities */ 240/* IOMMU capabilities */
228#define IOMMU_CAP_IOTLB 24 241#define IOMMU_CAP_IOTLB 24
229#define IOMMU_CAP_NPCACHE 26 242#define IOMMU_CAP_NPCACHE 26
243#define IOMMU_CAP_EFR 27
230 244
231#define MAX_DOMAIN_ID 65536 245#define MAX_DOMAIN_ID 65536
232 246
@@ -371,6 +385,9 @@ struct amd_iommu {
371 /* flags read from acpi table */ 385 /* flags read from acpi table */
372 u8 acpi_flags; 386 u8 acpi_flags;
373 387
388 /* Extended features */
389 u64 features;
390
374 /* 391 /*
375 * Capability pointer. There could be more than one IOMMU per PCI 392 * Capability pointer. There could be more than one IOMMU per PCI
376 * device function if there are more than one AMD IOMMU capability 393 * device function if there are more than one AMD IOMMU capability
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 8848dda808e2..047905dc3e14 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -299,9 +299,23 @@ static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
299/* Function to enable the hardware */ 299/* Function to enable the hardware */
300static void iommu_enable(struct amd_iommu *iommu) 300static void iommu_enable(struct amd_iommu *iommu)
301{ 301{
302 printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n", 302 static const char * const feat_str[] = {
303 "PreF", "PPR", "X2APIC", "NX", "GT", "[5]",
304 "IA", "GA", "HE", "PC", NULL
305 };
306 int i;
307
308 printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx",
303 dev_name(&iommu->dev->dev), iommu->cap_ptr); 309 dev_name(&iommu->dev->dev), iommu->cap_ptr);
304 310
311 if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
312 printk(KERN_CONT " extended features: ");
313 for (i = 0; feat_str[i]; ++i)
314 if (iommu_feature(iommu, (1ULL << i)))
315 printk(KERN_CONT " %s", feat_str[i]);
316 }
317 printk(KERN_CONT "\n");
318
305 iommu_feature_enable(iommu, CONTROL_IOMMU_EN); 319 iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
306} 320}
307 321
@@ -657,7 +671,7 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
657static void __init init_iommu_from_pci(struct amd_iommu *iommu) 671static void __init init_iommu_from_pci(struct amd_iommu *iommu)
658{ 672{
659 int cap_ptr = iommu->cap_ptr; 673 int cap_ptr = iommu->cap_ptr;
660 u32 range, misc; 674 u32 range, misc, low, high;
661 int i, j; 675 int i, j;
662 676
663 pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET, 677 pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
@@ -673,6 +687,12 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
673 MMIO_GET_LD(range)); 687 MMIO_GET_LD(range));
674 iommu->evt_msi_num = MMIO_MSI_NUM(misc); 688 iommu->evt_msi_num = MMIO_MSI_NUM(misc);
675 689
690 /* read extended feature bits */
691 low = readl(iommu->mmio_base + MMIO_EXT_FEATURES);
692 high = readl(iommu->mmio_base + MMIO_EXT_FEATURES + 4);
693
694 iommu->features = ((u64)high << 32) | low;
695
676 if (!is_rd890_iommu(iommu->dev)) 696 if (!is_rd890_iommu(iommu->dev))
677 return; 697 return;
678 698