Support for Intel Virtualization Technology for Directed I/O
Subsystems (5)
cover Support for Intel Virtualization Technology for Directed I/O
Hi,
Pleased to announce support for Intel(R) Virtualization Technology for Directed I/O use as an IOMMU in Linux.
This is a series of patches to support the same.
A brief description of the patches follows.
1. Support for ACPI framework to parse and work with DMA Remapping Tables.
2. Add support for PCI infrastructure to search parent relationships.
3. Hardware support for providing DMA remapping support for Intel Chipsets.
4. Supporting Zero Length Reads on DMAR's not able to support ZLR.
5. Graphics driver workarounds to provide unity map since they dont use dma api.
6. Updates to Documentation area for startup options and some basics.
7. Workaround to provide unity map for ISA bridge device to enable floppy disk.
8. Ability to preserve some mappings for devices not able to address entire range.
Please help review and provide feedback.
Cheers,
Ashok Raj & Shaohua Li
PATCH 2/8 Some generic search functions required to lookup device relationships.
PCI support functions for DMAR, to find parent bridge.
When devices are under a p2p bridge, upstream
transactions get replaced by the device id of the bridge as it owns the PCIE transaction. Hence its necessary to setup translations on behalf of the bridge as well. Due to this limitation all devices under a p2p share the same domain in a DMAR.
We just cache the type of device, if its a native PCIe device or not for later use.
-------------------------------------------------
drivers/pci/pci.h +1 -0
@@ -90,3 +90,4 @@return NULL ; } +struct pci_dev *pci_find_upstream_pcie_bridge (struct pci_dev *pdev);
drivers/pci/probe.c +14 -0
@@ -822,6 +822,19 @@kfree (pci_dev); } +static void set_pcie_port_type (struct pci_dev *pdev) +{ +int pos; +u16 reg16; + + pos =pci_find_capability (pdev,PCI_CAP_ID_EXP ); +if (!pos) +return ; + pdev->is_pcie =1 ; +pci_read_config_word (pdev, pos +PCI_EXP_FLAGS , ®16); + pdev->pcie_type = (reg16 &PCI_EXP_FLAGS_TYPE ) >>4 ; +} +/** * pci_cfg_space_size - get the configuration space size of the PCI device. * @dev: PCI device
@@ -919,6 +932,7 @@ dev->device = (l >>16 ) &0xffff ; dev->cfg_size =pci_cfg_space_size (dev); dev->error_state = pci_channel_io_normal; +set_pcie_port_type (dev);/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */
drivers/pci/search.c +30 -0
@@ -14,6 +14,36 @@#include "pci.h" DECLARE_RWSEM (pci_bus_sem); +/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) { + tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ +BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}static struct pci_bus *pci_do_find_bus (struct pci_bus * bus,unsigned char busnr)
include/linux/pci.h +2 -0
@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */
@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;atomic_t enable_cnt;/* pci_enable_device has been called */ u32 saved_config_space[16 ];/* config space saved at suspend time */
PATCH 4/8 Supporting Zero Length Reads in Intel IOMMU.
In reply to Ashok RajPCI specs permit zero length reads (ZLR) even if the mapping for that region is write only. Support for this feature is indicated by the presence of a bit in the DMAR capability. If a particular DMAR does not support this capability we map write-only regions as read-write.
This option can also provides a workaround for some drivers that request a write-only mapping when they really should request a read-write. (We ran into one such case in eepro100.c in handling rx_ring_dma)
----------------------------------
drivers/pci/intel-iommu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/pci/intel-iommu.c +10 -2
@@ -84,7 +84,7 @@struct sys_device sysdev; }; -static int dmar_disabled; +static int dmar_disabled, dmar_force_rw;static char *get_fault_reason (u8 fault_reason) {
@@ -102,6 +102,9 @@if (!strncmp (str,"off" ,3 )) { dmar_disabled =1 ;printk (KERN_INFO "Intel-IOMMU: disabled\n" ); + }else if (!strncmp (str,"forcerw" ,7 )) { + dmar_force_rw =1 ; +printk (KERN_INFO "Intel-IOMMU: force R/W for W/O mapping\n" ); } str +=strcspn (str,"," );while (*str ==',' )
@@ -1668,7 +1671,12 @@ goto error; } -if (dir ==DMA_TO_DEVICE || dir ==DMA_BIDIRECTIONAL ) +/* +* Check if DMAR supports zero-length reads on write only +* mappings.. +*/ +if (dir ==DMA_TO_DEVICE || dir ==DMA_BIDIRECTIONAL || \ + !cap_zlr (domain->iommu->cap) || dmar_force_rw) prot |=DMA_PTE_READ ;if (dir ==DMA_FROM_DEVICE || dir ==DMA_BIDIRECTIONAL ) prot |=DMA_PTE_WRITE ;
include/linux/intel-iommu.h +1 -0
@@ -79,6 +79,7 @@#define cap_max_fault_reg_offset (c) \ (cap_fault_reg_offset(c) + cap_num_fault_regs(c) * 16) +#define cap_zlr (c) (((c) >> 22) & 1)#define cap_isoch (c) (((c) >> 23) & 1)#define cap_mgaw (c) ((((c) >> 16) & 0x3f) + 1)#define cap_sagaw (c) (((c) >> 8) & 0x1f)
PATCH 5/8 Graphics driver workarounds to provide unity map
In reply to Ashok RajMost GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer, Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
Once graphics devices are converted over to use the DMA-API's this entire patch can be removed...
a. intel_iommu=igfx_off. With this option, DMAR who has just gfx devices
under it will be ignored. This mostly affect intergated gfx devices. If the DMAR is ignored, gfx device under it will get physical address for DMA.
b. intel_iommu=gfx_workaround. With this option, we will setup 1:1 mapping
for whole memory for gfx devices, that is physical address equals to virtual address.In this way, gfx will use physical address for DMA, this is primarily for add-in card GFX device.
arch/x86_64/kernel/e820.c +19 -0
@@ -730,3 +730,22 @@printk (KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n" , pci_mem_start, gapstart, gapsize); } + +int __init arch_get_ram_range (int slot,u64 *addr,u64 *size) +{ +int i; + +if (slot <0 || slot >= e820.nr_map) +return -1 ; +for (i = slot; i < e820.nr_map; i++) { +if (e820.map[i].type !=E820_RAM ) +continue ; +break ; + } +if (i == e820.nr_map || e820.map[i].addr > (max_pfn <<PAGE_SHIFT )) +return -1 ; + *addr = e820.map[i].addr; + *size =min_t (u64, e820.map[i].size + e820.map[i].addr, + max_pfn <<PAGE_SHIFT ) - *addr; +return i +1 ; +}
drivers/pci/intel-iommu.c +119 -0
226 lines not on this page · raw message
include/acpi/dmar.h +1 -0
@@ -32,6 +32,7 @@int devices_cnt; u8 include_all:1;struct iommu *iommu; + int ignored:1; /* the drhd should be ignored */ };struct acpi_rmrr_unit {
include/linux/intel-iommu.h +2 -0
@@ -262,6 +262,8 @@extern void dmar_msi_write (int irq,struct msi_msg *msg);extern int arch_setup_dmar_msi (unsigned int irq); +extern int arch_get_ram_range (int slot,u64 *addr,u64 *size); +extern int init_dmars (void );extern void detect_intel_iommu (void );extern int early_dmar_detect (void );
PATCH 6/8 Doc updates for Intel Virtualization Technology for Directed I/O.
In reply to Ashok RajDocument Intel IOMMU driver boot option.
Documentation/Intel-IOMMU.txt new file +119 -0
@@ -0,0 +1,119 @@ +Linux IOMMU Support +=================== + +The architecture spec can be obtained from the below location. + +http://www.intel.com/technology/virtualization/ + +This guide gives a quick cheat sheet for some basic understanding. + +Some Keywords + +DMAR - DMA remapping +DRHD - DMA Engine Reporting Structure +RMRR - Reserved memory Region Reporting Structure +ZLR - Zero length reads from PCI devices +IOVA - IO Virtual address. + +Basic stuff +----------- + +ACPI enumerates and lists the different DMA engines in the platform, and +device scope relationships between PCI devices and which DMA engine controls +them. + +What is RMRR? +------------- + +There are some devices the BIOS controls, for e.g USB devices to perform +PS2 emulation. The regions of memory used for these devices are marked +reserved in the e820 map. When we turn on DMA translation, DMA to those +regions will fail. Hence BIOS uses RMRR to specify these regions along with +devices that need to access these regions. OS is expected to setup +unity mappings for these regions for these devices to access these regions. + +How is IOVA generated? +--------------------- + +Well behaved drivers call pci_map_*() calls before sending command to device +that needs to perform DMA. Once DMA is completed and mapping is no longer +required, device performs a pci_unmap_*() calls to unmap the region. + +The Intel IOMMU driver allocates a virtual address per domain. Each PCIE +device has its own domain (hence protection). Devices under p2p bridges +share the virtual address with all devices under the p2p bridge due to +transaction id aliasing for p2p bridges. + +IOVA generation is pretty generic. We used the same technique as vmalloc() +but these are not global address spaces, but separate for each domain. +Different DMA engines may support different number of domains. + +We also allocate gaurd pages with each mapping, so we can attempt to catch +any overflow that might happen. + + +Graphics Problems? +------------------ +If you encounter issues with graphics devices, you can try adding +option intel_iommu=igfx_off to turn off the integrated graphics engine. + +If it happens to be a PCI device included in the INCLUDE_ALL Engine, +then try the intel_iommu=gfx_workaround to setup a 1-1 map. We hear +graphics drivers may be in process of using DMA api's in the near +future.... + +Some exceptions to IOVA +----------------------- +Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff). +The same is true for peer to peer transactions. Hence we reserve the +address from PCI MMIO ranges so they are not allocated for IOVA addresses. + + +Fault reporting +--------------- +When errors are reported, the DMA engine signals via an interrupt. The fault +reason and device that caused it with fault reason is printed on console. + +See below for sample. + + +Boot Message Sample +------------------- + +Something like this gets printed indicating presence of DMAR tables +in ACPI. + +ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0 + +When DMAR is being processed and initialized by ACPI, prints DMAR locations +and any RMRR's processed. + +ACPI DMAR:Host address width 36 +ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000 +ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000 +ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000 +ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff +ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff + +When DMAR is enabled for use, you will notice.. + +PCI-DMA: Using DMAR IOMMU + +Fault reporting +--------------- + +DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000 +DMAR:[fault reason 05] PTE Write access is not set +DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000 +DMAR:[fault reason 05] PTE Write access is not set + +TBD +---- + +- No Performance tuning / analysis yet. +- sysfs needs useful data to be populated. + DMAR info, device scope, stats could be exposed to some extent. +- Add support to Firmware Developer Kit to test ACPI tables for DMAR. +- For compatibility testing, could use unity map domain for all devices, just + provide a 1-1 for all useful memory under a single domain for all devices. +- API for paravirt ops for abstracting functionlity for VMM folks.
Documentation/kernel-parameters.txt +20 -0
@@ -710,6 +710,26 @@ inttest= [IA64] + intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option + off + Disable intel iommu driver. + forcerw + Some drivers might incorrectly map DMA buffers as + write-only even when the device, requires read/write + mapping. This option works around the issue in IOMMU + driver by making all write-only map as read/write. + Default is off. + igfx_off [Default Off] + By default, gfx is mapped as normal device. If a gfx + device has a dedicated DMAR unit, the DMAR unit is + bypassed with this option. In this case, gfx device + will use physical address for DMA. + gfx_workaround [Default Off] + gfx devices tend to use physical address for DMA and + avoid using DMA api's. Setting this option permits + the IOMMU driver to set a unity map for all OS + visible memory. Hence the driver can continue to use + physical addresses for DMA. io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c.
PATCH 8/8 Preserve some Virtual Address when devices cannot address entire range.
In reply to Ashok RajSome devices may not support entire 64bit DMA. In a situation where such devices are co-located in a shared domain, we need to ensure there is some address space reserved for such devices without the low addresses getting depleted by other devices capable of handling high dma addresses.
Documentation/kernel-parameters.txt +5 -0
@@ -735,6 +735,11 @@ first 16M. The floppy disk could be modified to use the DMA api's but thats a lot of pain for very small gain. This option is turned on by default. + preserve_{1g/2g/4g/512m/256m/16m} + If a device is sharing a domain with other devices + and the device mask doesnt cover the 64bit range, + use this option to let the iommu code preserve some + virtual addr for such devices. io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c.
drivers/pci/intel-iommu.c +26 -2
@@ -90,6 +90,7 @@static int dmar_disabled, dmar_force_rw;static int dmar_map_gfx =1 , dmar_no_gfx_identity_map =1 ;static int dmar_fix_isa =1 ; +static u64 dmar_preserve_iova_mask;static char *get_fault_reason (u8 fault_reason) {
@@ -119,6 +120,28 @@ }else if (!strncmp (str,"noisamap" ,8 )) { dmar_fix_isa =0 ;printk (KERN_INFO "Intel-IOMMU: Turning off 16M unity map for LPC\n" ); + }else if (!strncmp (str,"preserve_" ,9 )) { +if (!strncmp (str +9 ,"4g" ,2 ) || + !strncmp (str +9 ,"4G" ,2 )) + dmar_preserve_iova_mask =DMA_32BIT_MASK ; +else if (!strncmp (str +9 ,"2g" ,2 ) || + !strncmp (str +9 ,"2G" ,2 )) + dmar_preserve_iova_mask =DMA_31BIT_MASK ; +else if (!strncmp (str +9 ,"1g" ,2 ) || + !strncmp (str +9 ,"1G" ,2 )) + dmar_preserve_iova_mask =DMA_30BIT_MASK ; +else if (!strncmp (str +9 ,"512m" ,2 ) || + !strncmp (str +9 ,"512M" ,2 )) + dmar_preserve_iova_mask =DMA_29BIT_MASK ; +else if (!strncmp (str +9 ,"256m" ,4 ) || + !strncmp (str +9 ,"256M" ,4 )) + dmar_preserve_iova_mask =DMA_28BIT_MASK ; +else if (!strncmp (str +9 ,"16m" ,3 ) || + !strncmp (str +9 ,"16M" ,3 )) + dmar_preserve_iova_mask =DMA_24BIT_MASK ; +printk (KERN_INFO +"DMAR: Preserved IOVA mask 0x%Lx for devices " +"sharing domain\n" , dmar_preserve_iova_mask); } str +=strcspn (str,"," );
@@ -1726,9 +1749,10 @@* leave rooms for other devices */ if ((domain->flags &DOMAIN_FLAG_MULTIPLE_DEVICES ) && - pdev->dma_mask >DMA_32BIT_MASK ) + dmar_preserve_iova_mask && + pdev->dma_mask > dmar_preserve_iova_mask) iova =alloc_iova (domain, addr, size, -DMA_32BIT_MASK +1 , pdev->dma_mask); + dmar_preserve_iova_mask +1 , pdev->dma_mask);else iova =alloc_iova (domain, addr, size,IOVA_START_ADDR , pdev->dma_mask);
PATCH 3/8 Generic hardware support for Intel IOMMU.
In reply to Ashok RajActual intel IOMMU driver. Hardware spec can be found at:
http://www.intel.com/technology/virtualization
The current version of spec is slightly outdated, but an updated version of spec is in works and comming very soon. I will send a note to the list when new updated spec is available. For the most part existing spec should be good for basic understanding of the mechanics of the IOMMU.
This driver sets X86_64 'dma_ops', so hook into standard DMA APIs. In this way, PCI driver will get virtual DMA address. This change is transparent to PCI drivers.
arch/x86_64/kernel/io_apic.c +58 -1
@@ -32,6 +32,7 @@#include <linux/sysdev.h> #include <linux/msi.h> #include <linux/htirq.h> +#include <linux/intel-iommu.h> #ifdef CONFIG_ACPI #include <acpi/acpi_bus.h> #endif
@@ -2002,8 +2003,64 @@destroy_irq (irq); } -#endif /* CONFIG_PCI_MSI */ +#ifdef CONFIG_DMAR +#ifdef CONFIG_SMP +static void dmar_msi_set_affinity (unsigned int irq,cpumask_t mask) +{ +struct irq_cfg *cfg = irq_cfg + irq; +struct msi_msg msg; +unsigned int dest; +cpumask_t tmp; + +cpus_and (tmp, mask, cpu_online_map); +if (cpus_empty (tmp)) +return ; + +if (assign_irq_vector (irq, mask)) +return ; + +cpus_and (tmp, cfg->domain, mask); + dest =cpu_mask_to_apicid (tmp); + +dmar_msi_read (irq, &msg); + + msg.data &= ~MSI_DATA_VECTOR_MASK ; + msg.data |=MSI_DATA_VECTOR (cfg->vector); + msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK ; + msg.address_lo |=MSI_ADDR_DEST_ID (dest); + +dmar_msi_write (irq, &msg); + irq_desc[irq].affinity = mask; +} +#endif /* CONFIG_SMP */ + +struct irq_chip dmar_msi_type = { + .name ="DMAR_MSI" , + .unmask = dmar_msi_unmask, + .mask = dmar_msi_mask, + .ack = ack_apic_edge, +#ifdef CONFIG_SMP + .set_affinity = dmar_msi_set_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +int arch_setup_dmar_msi (unsigned int irq) +{ +int ret; +struct msi_msg msg; + + ret =msi_compose_msg (NULL , irq, &msg); +if (ret <0 ) +return ret; +dmar_msi_write (irq, &msg); +set_irq_chip_and_handler_name (irq, &dmar_msi_type, handle_edge_irq, +"edge" ); +return 0 ; +} +#endif +#endif /* CONFIG_PCI_MSI */ /* * Hypertransport interrupt support */
arch/x86_64/kernel/pci-dma.c +9 -0
@@ -7,6 +7,7 @@#include <linux/string.h> #include <linux/pci.h> #include <linux/module.h> +#include <linux/intel-iommu.h> #include <asm/io.h> #include <asm/proto.h> #include <asm/calgary.h>
@@ -303,6 +304,10 @@detect_calgary ();#endif +#ifdef CONFIG_DMAR +detect_intel_iommu (); +#endif +#ifdef CONFIG_SWIOTLB pci_swiotlb_init ();#endif
@@ -314,6 +319,10 @@calgary_iommu_init ();#endif +#ifdef CONFIG_DMAR +intel_iommu_init (); +#endif +#ifdef CONFIG_IOMMU gart_iommu_init ();#endif
arch/x86_64/mm/pageattr.c +3 -3
@@ -61,10 +61,10 @@return base; } -static void cache_flush_page (void *adr) +void clflush_cache_range (void *adr,int size) {int i; -for (i =0 ; i <PAGE_SIZE ; i += boot_cpu_data.x86_clflush_size) +for (i =0 ; i < size; i += boot_cpu_data.x86_clflush_size) asmvolatile ("clflush (%0)" ::"r" (adr + i)); }
@@ -80,7 +80,7 @@list_for_each_entry (pg, l, lru) {void *adr =page_address (pg);if (cpu_has_clflush) -cache_flush_page (adr); +clflush_cache_range (adr,PAGE_SIZE );__flush_tlb_one (adr); } }
drivers/pci/Makefile +3 -0
@@ -20,6 +20,9 @@ # Build the Hypertransport interrupt support obj-$(CONFIG_HT_IRQ) += htirq.o +# Build DMAR if configured +obj-$(CONFIG_DMAR) += intel-iommu.o iova.o + # # Some architectures use the generic PCI setup functions #
drivers/pci/intel-iommu.c new file +2015 -0
2,015 lines not on this page · raw message
drivers/pci/iova.c new file +269 -0
269 lines not on this page · raw message
drivers/pci/iova.h new file +56 -0
56 lines not on this page · raw message
include/asm-x86_64/cacheflush.h +1 -0
@@ -27,6 +27,7 @@void global_flush_tlb (void );int change_page_attr (struct page *page,int numpages,pgprot_t prot);int change_page_attr_addr (unsigned long addr,int numpages,pgprot_t prot); +void clflush_cache_range (void *addr,int size);#ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro (void );
include/linux/intel-iommu.h new file +268 -0
268 lines not on this page · raw message
PATCH 7/8 Support for legacy ISA devices
In reply to Ashok RajFloppy disk drivers dont work well with DMA remapping. Its possible to extend the current use for x86_64, but the gain is very little. If someone feels compelled to clean this up, its up for grabs. Since these use 16M, we just provide a unity map for the ISA bridge device.
------------------------------------
Documentation/kernel-parameters.txt +5 -0
@@ -730,6 +730,11 @@ the IOMMU driver to set a unity map for all OS visible memory. Hence the driver can continue to use physical addresses for DMA. + noisamap + This option is required to setup identify map for + first 16M. The floppy disk could be modified to use + the DMA api's but thats a lot of pain for very small + gain. This option is turned on by default. io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c.
drivers/pci/intel-iommu.c +26 -0
@@ -37,6 +37,8 @@#include "pci.h" #define IS_GFX_DEVICE (pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) +#define IS_ISA_DEVICE (pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) +#define IOAPIC_RANGE_START (0xfee00000)#define IOAPIC_RANGE_END (0xfeefffff)#define IOAPIC_RANGE_SIZE (IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1)
@@ -87,6 +89,7 @@static int dmar_disabled, dmar_force_rw;static int dmar_map_gfx =1 , dmar_no_gfx_identity_map =1 ; +static int dmar_fix_isa =1 ;static char *get_fault_reason (u8 fault_reason) {
@@ -113,6 +116,9 @@ }else if (!strncmp (str,"gfx_workaround" ,14 )) { dmar_no_gfx_identity_map =0 ;printk (KERN_INFO "Intel-IOMMU: do 1-1 mapping whole physical memory for GFX device\n" ); + }else if (!strncmp (str,"noisamap" ,8 )) { + dmar_fix_isa =0 ; +printk (KERN_INFO "Intel-IOMMU: Turning off 16M unity map for LPC\n" ); } str +=strcspn (str,"," );
@@ -1575,6 +1581,25 @@ } } +static void iommu_prepare_isa (void ) +{ +struct pci_dev *pdev =NULL ; +int ret; + +if (!dmar_fix_isa) +return ; + + pdev =pci_get_class (PCI_CLASS_BRIDGE_ISA <<8 ,NULL ); +if (!pdev) +return ; + +printk (KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n" ); + ret =iommu_prepare_identity_map (pdev,0 ,16 *1024 *1024 ); + +if (ret) +printk ("IOMMU: Failed to create 0-64M identity map, Floppy might not work\n" ); + +}int __init init_dmars (void ) {struct acpi_drhd_unit *drhd;
@@ -1631,6 +1656,7 @@end_for_each_rmrr_device (rmrr, pdev)iommu_prepare_gfx_mapping (); +iommu_prepare_isa ();/* * for each drhd
PATCH 1/8 ACPI support for Intel Virtualization Technology for Directed I/O
In reply to Ashok RajThis patch contains basic ACPI parsing and enumeration support.
arch/x86_64/Kconfig +8 -0
@@ -687,6 +687,14 @@ bool "Support mmconfig PCI config space access" depends on PCI && ACPI +config DMAR + bool "Support for DMA Remapping Devices (EXPERIMENTAL)" + depends on PCI_MSI && ACPI && EXPERIMENTAL + help + Support DMA Remapping Devices. The devices are reported via + ACPI tables and includes pci device scope under each DMA + remapping device. + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig"
drivers/acpi/Makefile +1 -0
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o +obj-$(CONFIG_DMAR) += dmar.o
drivers/acpi/dmar.c new file +344 -0
344 lines not on this page · raw message
include/acpi/actbl1.h +37 -29
103 lines not on this page · raw message
include/acpi/dmar.h new file +60 -0
60 lines not on this page · raw message
Len Brown
reviewerRe: [patch 1/8] [Intel IOMMU] ACPI support for Intel Virtualization Technology for Directed I/O
Quoted 1 line · Ashok Raj
This patch contains basic ACPI parsing and enumeration support.
AFAICS, ACPI supplies the envelope which delivers the table,
and ACPI has some convenience structure definitions for that
table in include/acpi/actbl1.h (primarily for the acpixtract table dis-assembler), but ACPI is otherwise not involved in IOMMU support.
Indeed, one might argue that all new functions in this patch series with "acpi..." would more appropriately be called "pci...", since a cursory scan of the IOMMU spec seems to suggest it is specific to PCI.
So on first blush, it looks like the only call to a function that begins with "acpi" in this patch series should be acpi_get_table() from some IOMMU specific file outside of drivers/acpi,
and the only modification to any code with an "acpi" in the file path or filename should be any updates to the convenience structure definitions in acpitbl1.h
thanks,
-Len
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Ashok RajQuoted 20 lines · Ashok Raj
drivers/pci/search.c +20
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) {
drivers/pci/search.c line 46
Quoted 10 lines
drivers/pci/search.c +10
-0+ tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ +BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}
No locking while you walk up the bus list?
Quoted 11 lines
include/linux/pci.h +1
-0@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */
include/linux/pci.h line 172
Quoted 4 lines
include/linux/pci.h +1
-0@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;
Do you really need both fields? Wouldn't just the pcie_type one work (with some NOT_PCIE type being set for it if it isn't I suppose.)
thanks,
greg k-h
Quoted 1 line · On Monday 09 April 2007 23:55:52 Ashok Raj wrote:
Please help review and provide feedback.
High level question: how did you solve the "user X server needs IOMMU bypass" problem?
-Andi
Quoted 6 lines · Andi Kleen
Quoted 1 line · On Monday 09 April 2007 23:55:52 Ashok Raj wrote:
Please help review and provide feedback.
High level question: how did you solve the "user X server needs IOMMU bypass" problem?
Please see patch 5. We have two workarounds for graphics. One is completely bypass dma remapping for gfx, this option only works for gfx card with dedicated dma remapping engine. The other is doing 1-1 mapping for whole physical memory address, then virtual dma address will equal to physical address, so gfx can ignore iommu in the case.
Thanks,
Shaohua
Quoted 5 lines · Shaohua Li
Quoted 4 lines · Andi Kleen
Quoted 1 line · On Monday 09 April 2007 23:55:52 Ashok Raj wrote:
Please help review and provide feedback.
Quoted 8 lines
Quoted 2 lines
High level question: how did you solve the "user X server needs IOMMU bypass" problem?
Please see patch 5. We have two workarounds for graphics. One is completely bypass dma remapping for gfx, this option only works for gfx card with dedicated dma remapping engine. The other is doing 1-1 mapping for whole physical memory address, then virtual dma address will equal to physical address, so gfx can ignore iommu in the case.
Apologies but I've not had a chance to review the patches yet. Do you special case the BDF of the graphics adpater (via PCI ID?), or does the user need to provide a command line option to specify the graphics adapter?
Cheers,
Muli
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Greg KHQuoted 25 lines · Greg KH
Quoted 24 lines · Ashok Raj
drivers/pci/search.c +24
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) { + tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */
Quoted 8 lines
drivers/pci/search.c line 46
Quoted 6 lines
drivers/pci/search.c +6
-0+BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}No locking while you walk up the bus list?
hmm, iommu driver didn't support pci hotplug in current stage. But we can add lock here.
Quoted 10 lines
Quoted 10 lines
include/linux/pci.h +1
-0@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */
Quoted 8 lines
include/linux/pci.h line 172
Quoted 5 lines
include/linux/pci.h +1
-0@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;Do you really need both fields? Wouldn't just the
pcie_typeone work (with someNOT_PCIEtype being set for it if it isn't I suppose.)
There are some encodings are reserved for future. Just don't want to use reserved bits, as we don't know which one is proper for NOT_PCIE.
Thanks,
Shaohua
Quoted 9 lines · Ashok Raj
1. Support for ACPI framework to parse and work with DMA Remapping Tables.
2. Add support for PCI infrastructure to search parent relationships.
3. Hardware support for providing DMA remapping support for Intel Chipsets.
4. Supporting Zero Length Reads on DMAR's not able to support ZLR.
5. Graphics driver workarounds to provide unity map since they dont use dma api.
6. Updates to Documentation area for startup options and some basics.
7. Workaround to provide unity map for ISA bridge device to enable floppy disk.
8. Ability to preserve some mappings for devices not able to address entire range.
I really think it would be best to avoid ACPI for something as critical as DMA remapping!
Jeff
Quoted 15 lines · Muli Ben-Yehuda
Quoted 5 lines · Shaohua Li
Quoted 4 lines · Andi Kleen
Quoted 1 line · On Monday 09 April 2007 23:55:52 Ashok Raj wrote:
Please help review and provide feedback.
Quoted 8 lines
Quoted 2 lines
High level question: how did you solve the "user X server needs IOMMU bypass" problem?
Please see patch 5. We have two workarounds for graphics. One is completely bypass dma remapping for gfx, this option only works for gfx card with dedicated dma remapping engine. The other is doing 1-1 mapping for whole physical memory address, then virtual dma address will equal to physical address, so gfx can ignore iommu in the case.
Quoted 4 lines
Apologies but I've not had a chance to review the patches yet. Do you special case the BDF of the graphics adpater (via PCI ID?), or does the user need to provide a command line option to specify the graphics adapter?
Not understand what you ask. The PCI device's type can tell us if it's a gfx device.
Thanks,
shaohua
Quoted 11 lines · Jeff Garzik
Quoted 9 lines · Ashok Raj
1. Support for ACPI framework to parse and work with DMA Remapping Tables.
2. Add support for PCI infrastructure to search parent relationships.
3. Hardware support for providing DMA remapping support for Intel Chipsets.
4. Supporting Zero Length Reads on DMAR's not able to support ZLR.
5. Graphics driver workarounds to provide unity map since they dont use dma api.
6. Updates to Documentation area for startup options and some basics.
7. Workaround to provide unity map for ISA bridge device to enable floppy disk.
8. Ability to preserve some mappings for devices not able to address entire range.
Quoted 2 lines
I really think it would be best to avoid ACPI for something as critical as DMA remapping!
DMA remapping just uses ACPI table to tell which dma remapping engine a pci device is controlled by at boot time. At run time, DMA remapping hasn't any interactive with ACPI.
Thanks,
Shaohua
Re: [patch 5/8] [Intel IOMMU] Graphics driver workarounds to provide unity map
In reply to Ashok RajQuoted 3 lines · Ashok Raj
Most GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer, Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
All drm drivers do it. If the usual out of tree crap vendors are too stupid for their own sake it's their fault.
So NACK to this patch.
Quoted 3 lines · Shaohua Li
DMA remapping just uses ACPI table to tell which dma remapping engine a pci device is controlled by at boot time. At run time, DMA remapping hasn't any interactive with ACPI.
The Linux kernel _really_ wants a non-ACPI way to detect this.
Just use the hardware registers themselves, you don't need an ACPI table.
Jeff
Re: [patch 5/8] [Intel IOMMU] Graphics driver workarounds to provide unity map
In reply to Christoph HellwigFrom: Christoph Hellwig <[email protected]>
Date: Tue, 10 Apr 2007 09:33:51 +0100
Quoted 9 lines · Ashok Raj
Quoted 3 lines
Most GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer, Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
All drm drivers do it. If the usual out of tree crap vendors are too stupid for their own sake it's their fault.
So NACK to this patch.
That's my feeling as well, everything we care about should be using the proper APIs or else what is the point of them...
Re: [patch 5/8] [Intel IOMMU] Graphics driver workarounds to provide unity map
Quoted 8 lines · On Tuesday 10 April 2007 11:07:02 David Miller wrote:
From: Christoph Hellwig <[email protected]>
Date: Tue, 10 Apr 2007 09:33:51 +0100Quoted 5 lines · Ashok Raj
Quoted 3 lines
Most GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer, Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
Quoted 7 lines
Quoted 4 lines
All drm drivers do it. If the usual out of tree crap vendors are too stupid for their own sake it's their fault.
So NACK to this patch.
That's my feeling as well, everything we care about should be using the proper APIs or else what is the point of them...
They can't. There is no proper API to do IOMMU mappings from user space. And that is how Xorg on x86 works.
I had some hackish patches to enable mapping on /sys/bus/pci/.../coherent_mem, but you need ioctls to pass out the translated address and it wasn't exactly pretty. Still also not sure that's the right way.
-Andi
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Shaohua LiQuoted 34 lines · Shaohua Li
Quoted 25 lines · Greg KH
Quoted 24 lines · Ashok Raj
drivers/pci/search.c +24
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) { + tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ Quoted 8 lines
drivers/pci/search.c line 46
Quoted 6 lines
drivers/pci/search.c +6
-0+BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}No locking while you walk up the bus list?
Quoted 2 lines
hmm, iommu driver didn't support pci hotplug in current stage. But we can add lock here.
Please do, as PCI-E hotplug is much more common than PCI hotplug these days (think ExpressCard in millions of laptops...)
Quoted 18 lines
Quoted 10 lines
Quoted 10 lines
include/linux/pci.h +1
-0@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */ Quoted 8 lines
include/linux/pci.h line 172
Quoted 5 lines
include/linux/pci.h +1
-0@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;Do you really need both fields? Wouldn't just the
pcie_typeone work (with someNOT_PCIEtype being set for it if it isn't I suppose.)
Quoted 2 lines
There are some encodings are reserved for future. Just don't want to use reserved bits, as we don't know which one is proper for
NOT_PCIE.
What are the current encodings? I don't have my copy of the pci spec availble at the moment...
thanks,
greg k-h
Re: [patch 1/8] [Intel IOMMU] ACPI support for Intel Virtualization Technology for Directed I/O
In reply to Len BrownQuoted 11 lines · Len Brown
Quoted 1 line · Ashok Raj
This patch contains basic ACPI parsing and enumeration support.
AFAICS, ACPI supplies the envelope which delivers the table,
and ACPI has some convenience structure definitions for that
table ininclude/acpi/actbl1.h(primarily for the acpixtract table dis-assembler), but ACPI is otherwise not involved in IOMMU support.Indeed, one might argue that all new functions in this patch series with "acpi..." would more appropriately be called "pci...", since a cursory scan of the IOMMU spec seems to suggest it is specific to PCI.
Think we can migrate some of the code to make the core part just perform the get-table. We will do that in the next respin.
Quoted 9 lines
So on first blush, it looks like the only call to a function that begins with "acpi" in this patch series should be
acpi_get_table()from some IOMMU specific file outside ofdrivers/acpi,
and the only modification to any code with an "acpi" in the file path or filename should be any updates to the convenience structure definitions inacpitbl1.hthanks,
-Len
Re: [patch 5/8] [Intel IOMMU] Graphics driver workarounds to provide unity map
In reply to David MillerQuoted 6 lines · David Miller
From: Christoph Hellwig <[email protected]>
Date: Tue, 10 Apr 2007 09:33:51 +0100Quoted 3 lines · Ashok Raj
Quoted 2 lines
Most GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer,
Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
Quoted 7 lines
Quoted 4 lines
All drm drivers do it. If the usual out of tree crap vendors are too stupid for their own sake it's their fault.
So NACK to this patch.
That's my feeling as well, everything we care about should be using the proper APIs or else what is the point of them...
that's too simple; X uses /dev/mem as well, even with something as open as the Intel drivers.
Sad but true ;(
(it's getting resolved on the X side but existing X is like this)
Quoted 6 lines · Andi Kleen
Quoted 1 line · On Monday 09 April 2007 23:55:52 Ashok Raj wrote:
Please help review and provide feedback.
High level question: how did you solve the "user X server needs IOMMU bypass" problem?
There is no special consideration for user space. Since all useful memeory is mapped 1-1, guess user space would work as is. Unless iam missing something here.. so yes.. there is no protection with 1-1, but guess its like compatibility mode until the code gets converted over.
Keith: cced says some of the user space side also is getting converted over with some driver support possibly. So this is an interim problem until X catches up with it.
Quoted 2 lines
-Andi
Quoted 10 lines · Jeff Garzik
Quoted 3 lines · Shaohua Li
DMA remapping just uses ACPI table to tell which dma remapping engine a pci device is controlled by at boot time. At run time, DMA remapping hasn't any interactive with ACPI.
The Linux kernel _really_ wants a non-ACPI way to detect this.
Just use the hardware registers themselves, you don't need an ACPI table.
Jeff
ACPI is required just not for identifying the DMA remapping hardware in the system. We also need them to identify which engines control which pci devices.
Also there are some reserved sections that BIOS uses for its purpose that it needs identity map.. say for legacy emulation via usb etc that needs to be passed to the OS.
not sure we can get away from using ACPI that easily.. its just only for setup information, once the identification is complete we dont bother ACPI anymore.
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Greg KHQuoted 59 lines · Greg KH
Quoted 34 lines · Shaohua Li
Quoted 25 lines · Greg KH
Quoted 24 lines · Ashok Raj
drivers/pci/search.c +24
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) { + tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ Quoted 8 lines
drivers/pci/search.c line 46
Quoted 6 lines
drivers/pci/search.c +6
-0+BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}No locking while you walk up the bus list?
Quoted 2 lines
hmm, iommu driver didn't support pci hotplug in current stage. But we can add lock here.
Please do, as PCI-E hotplug is much more common than PCI hotplug these days (think ExpressCard in millions of laptops...)
Quoted 18 lines
Quoted 18 lines
Quoted 11 lines
include/linux/pci.h +1
-0@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */ include/linux/pci.h line 172
Quoted 4 lines
include/linux/pci.h +1
-0@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;Do you really need both fields? Wouldn't just the
pcie_typeone work (with someNOT_PCIEtype being set for it if it isn't I suppose.)
Quoted 5 lines
Quoted 2 lines
There are some encodings are reserved for future. Just don't want to use reserved bits, as we don't know which one is proper for
NOT_PCIE.What are the current encodings? I don't have my copy of the pci spec availble at the moment...
0 - 1010b is defined. Other bits are reserved. How about the pcie_type's highest bit determines NOT_PCIE? the pcie spec just use 4 bits for pcie type.
Thanks,
Shaohua
Re: [patch 5/8] [Intel IOMMU] Graphics driver workarounds to provide unity map
In reply to Andi KleenQuoted 13 lines · Andi Kleen
Quoted 5 lines
Quoted 5 lines · Ashok Raj
Quoted 3 lines
Most GFX drivers don't call standard PCI DMA APIs to allocate DMA buffer, Such drivers will be broken with IOMMU enabled. To workaround this issue, we added two options.
Quoted 7 lines
Quoted 4 lines
All drm drivers do it. If the usual out of tree crap vendors are too stupid for their own sake it's their fault.
So NACK to this patch.
That's my feeling as well, everything we care about should be using the proper APIs or else what is the point of them...
Quoted 7 lines
They can't. There is no proper API to do IOMMU mappings from user space. And that is how Xorg on x86 works.
I had some hackish patches to enable mapping on
/sys/bus/pci/.../coherent_mem, but you need ioctls to pass out the translated address and it wasn't exactly pretty. Still also not sure that's the right way.
For agpgart based gfx driver, we need to enable dma mapping on agpgart module, which would work in the IOMMU case. I attach my current patches to do this. Dave, how do you think about it?
drivers/char/agp/agp.h +3 -0
@@ -115,6 +115,9 @@ struct agp_bridge_driver {void *(*agp_alloc_page)(struct agp_bridge_data *);void (*agp_destroy_page)(void *);int (*agp_type_to_mask_type) (struct agp_bridge_data *,int ); +int (*agp_map_dma_pages)(struct agp_bridge_data *,struct agp_memory *); +void (*agp_unmap_dma_pages)(struct agp_bridge_data *, +struct agp_memory *); };struct agp_bridge_data {
drivers/char/agp/generic.c +89 -5
146 lines not on this page · raw message
include/linux/agp_backend.h +5 -0
@@ -79,6 +79,8 @@ struct agp_memory {struct agp_memory *prev;struct agp_bridge_data *bridge;unsigned long *memory; +dma_addr_t *dma_memory; +u8 is_dma_mapped;size_t page_count;int key;int num_scratch_pages;
@@ -90,6 +92,9 @@ struct agp_memory {u8 vmalloc_flag; }; +#define AGP_MEMORY_VMALLOC 1 +#define AGP_DMA_MEMORY_VMALLOC 2 +#define AGP_NORMAL_MEMORY 0#define AGP_USER_TYPES (1 << 16)
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Shaohua LiQuoted 60 lines · Shaohua Li
Quoted 59 lines · Greg KH
Quoted 34 lines · Shaohua Li
Quoted 25 lines · Greg KH
Quoted 24 lines · Ashok Raj
drivers/pci/search.c +24
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) { + tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ Quoted 8 lines
drivers/pci/search.c line 46
Quoted 6 lines
drivers/pci/search.c +6
-0+BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}No locking while you walk up the bus list?
Quoted 2 lines
hmm, iommu driver didn't support pci hotplug in current stage. But we can add lock here.
Please do, as PCI-E hotplug is much more common than PCI hotplug these days (think ExpressCard in millions of laptops...)
Quoted 18 lines
Quoted 18 lines
Quoted 11 lines
include/linux/pci.h +1
-0@@ -126,6 +126,7 @@unsigned short subsystem_device;unsigned int class;/* 3 bytes: (base,sub,prog-if) */ u8 hdr_type;/* PCI header type (`multi' flag masked out) */ +u8 pcie_type;/* PCI-E device/port type */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */ include/linux/pci.h line 172
Quoted 4 lines
include/linux/pci.h +1
-0@@ -168,6 +169,7 @@ unsigned int msi_enabled:1; unsigned int msix_enabled:1; unsigned int is_managed:1; + unsigned int is_pcie:1;Do you really need both fields? Wouldn't just the
pcie_typeone work (with someNOT_PCIEtype being set for it if it isn't I suppose.)
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
There are some encodings are reserved for future. Just don't want to use reserved bits, as we don't know which one is proper for
NOT_PCIE.What are the current encodings? I don't have my copy of the pci spec availble at the moment...
0 - 1010b is defined. Other bits are reserved. How about the pcie_type's highest bit determines
NOT_PCIE? the pcie spec just use 4 bits for pcie type.
No, nevermind, it's fine to use two variables, it would just be too messy to put them in the same one with no real benifit.
thanks,
greg k-h
Re: [patch 2/8] [Intel IOMMU] Some generic search functions required to lookup device relationships.
In reply to Greg KHQuoted 35 lines · Greg KH
Quoted 34 lines · Shaohua Li
Quoted 33 lines · Greg KH
Quoted 20 lines · Ashok Raj
drivers/pci/search.c +20
-0+/* +* find the upstream PCIE-to-PCI bridge of a PCI device +* if the device is PCIE, return NULL +* if the device isn't connected to a PCIE bridge (that is its parent is a +* legacy PCI bridge and the bridge is directly connected to bus 0), return its +* parent +*/ +struct pci_dev * +pci_find_upstream_pcie_bridge (struct pci_dev *pdev) +{ +struct pci_dev *tmp =NULL ; + +if (pdev->is_pcie) +return NULL ; +while (1 ) { +if (!pdev->bus->self) +break ; + pdev = pdev->bus->self; +/* a p2p bridge */ +if (!pdev->is_pcie) {drivers/pci/search.c line 46
Quoted 10 lines
drivers/pci/search.c +10
-0+ tmp = pdev; +continue ; + } +/* PCI device should connect to a PCIE bridge */ +BUG_ON (pdev->pcie_type !=PCI_EXP_TYPE_PCI_BRIDGE ); +return pdev; + } + +return tmp; +}No locking while you walk up the bus list?
Quoted 5 lines
Quoted 2 lines
hmm, iommu driver didn't support pci hotplug in current stage. But we can add lock here.
Please do, as PCI-E hotplug is much more common than PCI hotplug these days (think ExpressCard in millions of laptops...)
Sounds we can't add lock here. pci_bus_sem is a semaphore, but the api can be called within a spinlock and maybe with interrupt disabled. On the other hand, there is no hotplug risk here. The pdev is in use (the driver is doing dma buf allocation) when the api is called, so it's parent can't be hotpluged too. If you feel others misuse the api, we could move it to intel_iommu.c.
Thanks,
Shaohua