[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vtd: consolidate VT-d quirks into a single file quirks.c
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1288344554 -3600 # Node ID b48d8f27fca251c2df0222d195ffcb772d6a1128 # Parent 2d5e8f4ac43a120bbb5d4c52d08f6980848f0166 vtd: consolidate VT-d quirks into a single file quirks.c Consolidate VT-d quirks into a single file - quirks.c. This includes quirks to workaround OEM BIOS issue with VT-d enabling in IGD, Cantiga VT-d buffer flush issue, Cantiga IGD Vt-d low power related errata, and a quirk to workaround issues related to wifi direct assignment. Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx> Reviewed-by: Jan Beulich <JBeulich@xxxxxxxxxx> --- xen/drivers/passthrough/vtd/Makefile | 1 xen/drivers/passthrough/vtd/dmar.c | 31 ++-- xen/drivers/passthrough/vtd/extern.h | 31 +++- xen/drivers/passthrough/vtd/iommu.c | 85 +++++++---- xen/drivers/passthrough/vtd/iommu.h | 1 xen/drivers/passthrough/vtd/quirks.c | 257 ++++++++++++++++++++++++++++++++++ xen/drivers/passthrough/vtd/vtd.h | 18 -- xen/drivers/passthrough/vtd/x86/vtd.c | 1 xen/include/asm-x86/fixmap.h | 1 9 files changed, 365 insertions(+), 61 deletions(-) diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/Makefile --- a/xen/drivers/passthrough/vtd/Makefile Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/Makefile Fri Oct 29 10:29:14 2010 +0100 @@ -6,3 +6,4 @@ obj-y += utils.o obj-y += utils.o obj-y += qinval.o obj-y += intremap.o +obj-y += quirks.o diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/dmar.c Fri Oct 29 10:29:14 2010 +0100 @@ -242,7 +242,7 @@ struct acpi_rhsa_unit * drhd_to_rhsa(str int is_igd_drhd(struct acpi_drhd_unit *drhd) { - return ( drhd->address == igd_drhd_address ? 1 : 0); + return drhd && (drhd->address == igd_drhd_address); } /* @@ -278,8 +278,7 @@ static int scope_device_count(void *star static int __init acpi_parse_dev_scope(void *start, void *end, - void *acpi_entry, int type, - int *igd) + void *acpi_entry, int type) { struct dmar_scope *scope = acpi_entry; struct acpi_ioapic_unit *acpi_ioapic_unit; @@ -340,8 +339,15 @@ static int __init acpi_parse_dev_scope(v if ( iommu_verbose ) dprintk(VTDPREFIX, " endpoint: %x:%x.%x\n", bus, path->dev, path->fn); - if ( (bus == 0) && (path->dev == 2) && (path->fn == 0) ) - *igd = 1; + + if ( type == DMAR_TYPE ) + { + struct acpi_drhd_unit *drhd = acpi_entry; + + if ( (bus == 0) && (path->dev == 2) && (path->fn == 0) ) + igd_drhd_address = drhd->address; + } + break; case ACPI_DEV_IOAPIC: @@ -388,7 +394,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent struct acpi_table_drhd * drhd = (struct acpi_table_drhd *)header; void *dev_scope_start, *dev_scope_end; struct acpi_drhd_unit *dmaru; - int ret, igd = 0; + int ret; static int include_all = 0; if ( (ret = acpi_dmar_check_length(header, sizeof(*drhd))) != 0 ) @@ -413,10 +419,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent dev_scope_start = (void *)(drhd + 1); dev_scope_end = ((void *)drhd) + header->length; ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end, - dmaru, DMAR_TYPE, &igd); - - if ( igd ) - igd_drhd_address = dmaru->address; + dmaru, DMAR_TYPE); if ( dmaru->include_all ) { @@ -504,7 +507,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent struct acpi_rmrr_unit *rmrru; void *dev_scope_start, *dev_scope_end; u64 base_addr = rmrr->base_address, end_addr = rmrr->end_address; - int ret, igd = 0; + int ret; if ( (ret = acpi_dmar_check_length(header, sizeof(*rmrr))) != 0 ) return ret; @@ -536,7 +539,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent dev_scope_start = (void *)(rmrr + 1); dev_scope_end = ((void *)rmrr) + header->length; ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end, - rmrru, RMRR_TYPE, &igd); + rmrru, RMRR_TYPE); if ( ret || (rmrru->scope.devices_cnt == 0) ) xfree(rmrru); @@ -601,7 +604,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent { struct acpi_table_atsr *atsr = (struct acpi_table_atsr *)header; struct acpi_atsr_unit *atsru; - int ret, igd = 0; + int ret; static int all_ports; void *dev_scope_start, *dev_scope_end; @@ -622,7 +625,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent dev_scope_start = (void *)(atsr + 1); dev_scope_end = ((void *)atsr) + header->length; ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end, - atsru, ATSR_TYPE, &igd); + atsru, ATSR_TYPE); } else { diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/extern.h --- a/xen/drivers/passthrough/vtd/extern.h Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/extern.h Fri Oct 29 10:29:14 2010 +0100 @@ -26,6 +26,7 @@ extern int qinval_enabled; extern int ats_enabled; +extern bool_t rwbf_quirk; void print_iommu_regs(struct acpi_drhd_unit *drhd); void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn); @@ -35,6 +36,12 @@ void disable_qinval(struct iommu *iommu) void disable_qinval(struct iommu *iommu); int enable_intremap(struct iommu *iommu, int eim); void disable_intremap(struct iommu *iommu); + +void iommu_flush_cache_entry(void *addr, unsigned int size); +void iommu_flush_cache_page(void *addr, unsigned long npages); +int iommu_alloc(struct acpi_drhd_unit *drhd); +void iommu_free(struct acpi_drhd_unit *drhd); + int queue_invalidate_context(struct iommu *iommu, u16 did, u16 source_id, u8 function_mask, u8 granu); int queue_invalidate_iotlb(struct iommu *iommu, @@ -45,18 +52,40 @@ int iommu_flush_iec_global(struct iommu int iommu_flush_iec_global(struct iommu *iommu); int iommu_flush_iec_index(struct iommu *iommu, u8 im, u16 iidx); void clear_fault_bits(struct iommu *iommu); + struct iommu * ioapic_to_iommu(unsigned int apic_id); struct acpi_drhd_unit * ioapic_to_drhd(unsigned int apic_id); struct acpi_drhd_unit * iommu_to_drhd(struct iommu *iommu); struct acpi_rhsa_unit * drhd_to_rhsa(struct acpi_drhd_unit *drhd); +struct acpi_drhd_unit * find_ats_dev_drhd(struct iommu *iommu); + int ats_device(int seg, int bus, int devfn); int enable_ats_device(int seg, int bus, int devfn); int disable_ats_device(int seg, int bus, int devfn); int invalidate_ats_tcs(struct iommu *iommu); + int qinval_device_iotlb(struct iommu *iommu, u32 max_invs_pend, u16 sid, u16 size, u64 addr); int dev_invalidate_iotlb(struct iommu *iommu, u16 did, u64 addr, unsigned int size_order, u64 type); -struct acpi_drhd_unit * find_ats_dev_drhd(struct iommu *iommu); + +unsigned int get_cache_line_size(void); +void cacheline_flush(char *); +void flush_all_cache(void); + +u64 alloc_pgtable_maddr(struct acpi_drhd_unit *drhd, unsigned long npages); +void free_pgtable_maddr(u64 maddr); +void *map_vtd_domain_page(u64 maddr); +void unmap_vtd_domain_page(void *va); +int domain_context_mapping_one(struct domain *domain, struct iommu *iommu, + u8 bus, u8 devfn); +int domain_context_unmap_one(struct domain *domain, struct iommu *iommu, + u8 bus, u8 devfn); + +int is_igd_vt_enabled_quirk(void); +void __init platform_quirks_init(void); +void vtd_ops_preamble_quirk(struct iommu* iommu); +void vtd_ops_postamble_quirk(struct iommu* iommu); +void me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map); #endif // _VTD_EXTERN_H_ diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/iommu.c Fri Oct 29 10:29:14 2010 +0100 @@ -44,7 +44,6 @@ #endif int nr_iommus; -static bool_t rwbf_quirk; static void setup_dom0_devices(struct domain *d); static void setup_dom0_rmrr(struct domain *d); @@ -482,16 +481,36 @@ static int inline iommu_flush_iotlb_glob int flush_non_present_entry, int flush_dev_iotlb) { struct iommu_flush *flush = iommu_get_flush(iommu); - return flush->iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH, + int status; + + /* apply platform specific errata workarounds */ + vtd_ops_preamble_quirk(iommu); + + status = flush->iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH, flush_non_present_entry, flush_dev_iotlb); + + /* undo platform specific errata workarounds */ + vtd_ops_postamble_quirk(iommu); + + return status; } static int inline iommu_flush_iotlb_dsi(struct iommu *iommu, u16 did, int flush_non_present_entry, int flush_dev_iotlb) { struct iommu_flush *flush = iommu_get_flush(iommu); - return flush->iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH, + int status; + + /* apply platform specific errata workarounds */ + vtd_ops_preamble_quirk(iommu); + + status = flush->iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH, flush_non_present_entry, flush_dev_iotlb); + + /* undo platform specific errata workarounds */ + vtd_ops_postamble_quirk(iommu); + + return status; } static int inline get_alignment(u64 base, unsigned int size) @@ -515,6 +534,7 @@ static int inline iommu_flush_iotlb_psi( { unsigned int align; struct iommu_flush *flush = iommu_get_flush(iommu); + int status; ASSERT(!(addr & (~PAGE_MASK_4K))); ASSERT(pages > 0); @@ -535,8 +555,16 @@ static int inline iommu_flush_iotlb_psi( addr >>= PAGE_SHIFT_4K + align; addr <<= PAGE_SHIFT_4K + align; - return flush->iotlb(iommu, did, addr, align, DMA_TLB_PSI_FLUSH, + /* apply platform specific errata workarounds */ + vtd_ops_preamble_quirk(iommu); + + status = flush->iotlb(iommu, did, addr, align, DMA_TLB_PSI_FLUSH, flush_non_present_entry, flush_dev_iotlb); + + /* undo platform specific errata workarounds */ + vtd_ops_postamble_quirk(iommu); + + return status; } static void iommu_flush_all(void) @@ -689,24 +717,13 @@ static int iommu_set_root_entry(struct i return 0; } -#define GGC 0x52 -#define GGC_MEMORY_VT_ENABLED (0x8 << 8) -static int is_igd_vt_enabled(void) -{ - unsigned short ggc; - - /* integrated graphics on Intel platforms is located at 0:2.0 */ - ggc = pci_conf_read16(0, 2, 0, GGC); - return ( ggc & GGC_MEMORY_VT_ENABLED ? 1 : 0 ); -} - static void iommu_enable_translation(struct acpi_drhd_unit *drhd) { u32 sts; unsigned long flags; struct iommu *iommu = drhd->iommu; - if ( !is_igd_vt_enabled() && is_igd_drhd(drhd) ) + if ( is_igd_drhd(drhd) && !is_igd_vt_enabled_quirk() ) { if ( force_iommu ) panic("BIOS did not enable IGD for VT properly, crash Xen for security purpose!\n"); @@ -717,6 +734,9 @@ static void iommu_enable_translation(str return; } } + + /* apply platform specific errata workarounds */ + vtd_ops_preamble_quirk(iommu); if ( iommu_verbose ) dprintk(VTDPREFIX, @@ -730,6 +750,9 @@ static void iommu_enable_translation(str (sts & DMA_GSTS_TES), sts); spin_unlock_irqrestore(&iommu->register_lock, flags); + /* undo platform specific errata workarounds */ + vtd_ops_postamble_quirk(iommu); + /* Disable PMRs when VT-d engine takes effect per spec definition */ disable_pmr(iommu); } @@ -738,6 +761,9 @@ static void iommu_disable_translation(st { u32 sts; unsigned long flags; + + /* apply platform specific errata workarounds */ + vtd_ops_preamble_quirk(iommu); spin_lock_irqsave(&iommu->register_lock, flags); sts = dmar_readl(iommu->reg, DMAR_GSTS_REG); @@ -747,6 +773,9 @@ static void iommu_disable_translation(st IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl, !(sts & DMA_GSTS_TES), sts); spin_unlock_irqrestore(&iommu->register_lock, flags); + + /* undo platform specific errata workarounds */ + vtd_ops_postamble_quirk(iommu); } enum faulttype { @@ -1090,6 +1119,7 @@ int __init iommu_alloc(struct acpi_drhd_ xfree(iommu); return -ENOMEM; } + iommu->intel->drhd = drhd; iommu->reg = map_to_nocache_virt(nr_iommus, drhd->address); iommu->index = nr_iommus++; @@ -1222,7 +1252,7 @@ static void intel_iommu_dom0_init(struct } } -static int domain_context_mapping_one( +int domain_context_mapping_one( struct domain *domain, struct iommu *iommu, u8 bus, u8 devfn) @@ -1324,6 +1354,8 @@ static int domain_context_mapping_one( unmap_vtd_domain_page(context_entries); + me_wifi_quirk(domain, bus, devfn, MAP_ME_PHANTOM_FUNC); + return 0; } @@ -1405,7 +1437,7 @@ static int domain_context_mapping(struct return ret; } -static int domain_context_unmap_one( +int domain_context_unmap_one( struct domain *domain, struct iommu *iommu, u8 bus, u8 devfn) @@ -1452,6 +1484,8 @@ static int domain_context_unmap_one( spin_unlock(&iommu->lock); unmap_vtd_domain_page(context_entries); + + me_wifi_quirk(domain, bus, devfn, UNMAP_ME_PHANTOM_FUNC); return 0; } @@ -1951,19 +1985,6 @@ static void setup_dom0_rmrr(struct domai spin_unlock(&pcidevs_lock); } -static void __init platform_quirks(void) -{ - u32 id; - - /* Mobile 4 Series Chipset neglects to set RWBF capability. */ - id = pci_conf_read32(0, 0, 0, 0); - if ( id == 0x2a408086 ) - { - dprintk(XENLOG_INFO VTDPREFIX, "DMAR: Forcing write-buffer flush\n"); - rwbf_quirk = 1; - } -} - int __init intel_vtd_setup(void) { struct acpi_drhd_unit *drhd; @@ -1972,7 +1993,7 @@ int __init intel_vtd_setup(void) if ( list_empty(&acpi_drhd_units) ) return -ENODEV; - platform_quirks(); + platform_quirks_init(); irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs); BUG_ON(!irq_to_iommu); diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/iommu.h --- a/xen/drivers/passthrough/vtd/iommu.h Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/iommu.h Fri Oct 29 10:29:14 2010 +0100 @@ -501,6 +501,7 @@ struct intel_iommu { struct qi_ctrl qi_ctrl; struct ir_ctrl ir_ctrl; struct iommu_flush flush; + struct acpi_drhd_unit *drhd; }; #endif diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/quirks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/passthrough/vtd/quirks.c Fri Oct 29 10:29:14 2010 +0100 @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Author: Allen Kay <allen.m.kay@xxxxxxxxx> + */ + +#include <xen/irq.h> +#include <xen/sched.h> +#include <xen/xmalloc.h> +#include <xen/domain_page.h> +#include <xen/iommu.h> +#include <asm/hvm/iommu.h> +#include <xen/numa.h> +#include <xen/softirq.h> +#include <xen/time.h> +#include <xen/pci.h> +#include <xen/pci_regs.h> +#include <xen/keyhandler.h> +#include <asm/msi.h> +#include <asm/irq.h> +#include <mach_apic.h> +#include "iommu.h" +#include "dmar.h" +#include "extern.h" +#include "vtd.h" + +#define IGD_BAR_MASK 0xFFFFFFFFFFFF0000 +#define GGC 0x52 +#define GGC_MEMORY_VT_ENABLED (0x8 << 8) + +#define IS_CTG(id) (id == 0x2a408086) +#define IS_ILK(id) (id == 0x00408086 || id == 0x00448086 || id== 0x00628086 || id == 0x006A8086) +#define IS_CPT(id) (id == 0x01008086 || id == 0x01048086) + +u32 dev0_id; +bool_t rwbf_quirk; +static int is_cantiga_b3; +static u8 *igd_reg_va; + +/* + * QUIRK to workaround Xen boot issue on Calpella/Ironlake OEM BIOS + * not enabling VT-d properly in IGD. The workaround is to not enabling + * IGD VT-d translation if VT is not enabled in IGD. + */ +int is_igd_vt_enabled_quirk(void) +{ + u16 ggc; + + if ( !IS_ILK(dev0_id) ) + return 1; + + /* integrated graphics on Intel platforms is located at 0:2.0 */ + ggc = pci_conf_read16(0, INTEL_IGD_DEV, 0, GGC); + return ( ggc & GGC_MEMORY_VT_ENABLED ? 1 : 0 ); +} + +/* + * QUIRK to workaround cantiga VT-d buffer flush issue. + * The workaround is to force write buffer flush even if + * VT-d capability indicates it is not required. + */ +static void cantiga_b3_errata_init(void) +{ + u16 vid; + u8 did_hi, rid; + + vid = pci_conf_read16(0, INTEL_IGD_DEV, 0, 0); + if ( vid != 0x8086 ) + return; + + did_hi = pci_conf_read8(0, INTEL_IGD_DEV, 0, 3); + rid = pci_conf_read8(0, INTEL_IGD_DEV, 0, 8); + + if ( (did_hi == 0x2A) && (rid == 0x7) ) + is_cantiga_b3 = 1; +} + +/* + * QUIRK to workaround Cantiga IGD VT-d low power errata. + * This errata impacts IGD assignment on Cantiga systems + * and can potentially cause VT-d operations to hang. + * The workaround is to access an IGD PCI config register + * to get IGD out of low power state before VT-d translation + * enable/disable and IOTLB flushes. + */ + +/* + * map IGD MMIO+0x2000 page to allow Xen access to IGD 3D register. + */ +static void map_igd_reg(void) +{ + u64 igd_mmio, igd_reg; + + if ( !is_cantiga_b3 || igd_reg_va != NULL ) + return; + + /* get IGD mmio address in PCI BAR */ + igd_mmio = ((u64)pci_conf_read32(0, INTEL_IGD_DEV, 0, 0x14) << 32) + + pci_conf_read32(0, INTEL_IGD_DEV, 0, 0x10); + + /* offset of IGD regster we want to access is in 0x2000 range */ + igd_reg = (igd_mmio & IGD_BAR_MASK) + 0x2000; + + /* ioremap this physical page */ + set_fixmap_nocache(FIX_IGD_MMIO, igd_reg); + igd_reg_va = (u8 *)fix_to_virt(FIX_IGD_MMIO); +} + +/* + * force IGD to exit low power mode by accessing a IGD 3D regsiter. + */ +static int cantiga_vtd_ops_preamble(struct iommu* iommu) +{ + struct intel_iommu *intel = iommu->intel; + struct acpi_drhd_unit *drhd = intel ? intel->drhd : NULL; + + if ( !is_igd_drhd(drhd) || !is_cantiga_b3 ) + return 0; + + /* + * read IGD register at IGD MMIO + 0x20A4 to force IGD + * to exit low power state. Since map_igd_reg() + * already mapped page starting 0x2000, we just need to + * add page offset 0x0A4 to virtual address base. + */ + return ( *((volatile int *)(igd_reg_va + 0x0A4)) ); +} + +/* + * call before VT-d translation enable and IOTLB flush operations. + */ +void vtd_ops_preamble_quirk(struct iommu* iommu) +{ + cantiga_vtd_ops_preamble(iommu); +} + +/* + * call after VT-d translation enable and IOTLB flush operations. + */ +void vtd_ops_postamble_quirk(struct iommu* iommu) +{ + return; +} + +/* initialize platform identification flags */ +void __init platform_quirks_init(void) +{ + dev0_id = pci_conf_read32(0, 0, 0, 0); + + /* Mobile 4 Series Chipset neglects to set RWBF capability. */ + if ( dev0_id == 0x2a408086 ) + { + dprintk(XENLOG_INFO VTDPREFIX, "DMAR: Forcing write-buffer flush\n"); + rwbf_quirk = 1; + } + + /* initialize cantiga B3 identification */ + cantiga_b3_errata_init(); + + /* ioremap IGD MMIO+0x2000 page */ + map_igd_reg(); +} + +/* + * QUIRK to workaround wifi direct assignment issue. This issue + * impacts only cases where Intel integrated wifi device is directly + * is directly assigned to a guest. + * + * The workaround is to map ME phantom device 0:3.7 or 0:22.7 + * to the ME vt-d engine if detect the user is trying to directly + * assigning Intel integrated wifi device to a guest. + */ + +static void map_me_phantom_function(struct domain *domain, u32 dev, int map) +{ + struct acpi_drhd_unit *drhd; + struct pci_dev *pdev; + + /* find ME VT-d engine base on a real ME device */ + pdev = pci_get_pdev(0, PCI_DEVFN(dev, 0)); + drhd = acpi_find_matched_drhd_unit(pdev); + + /* map or unmap ME phantom function */ + if ( map ) + domain_context_mapping_one(domain, drhd->iommu, 0, + PCI_DEVFN(dev, 7)); + else + domain_context_unmap_one(domain, drhd->iommu, 0, + PCI_DEVFN(dev, 7)); +} + +void me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map) +{ + u32 id; + + id = pci_conf_read32(0, 0, 0, 0); + if ( IS_CTG(id) ) + { + /* quit if ME does not exist */ + if ( pci_conf_read32(0, 3, 0, 0) == 0xffffffff ) + return; + + /* if device is WLAN device, map ME phantom device 0:3.7 */ + id = pci_conf_read32(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0); + switch (id) + { + case 0x42328086: + case 0x42358086: + case 0x42368086: + case 0x42378086: + case 0x423a8086: + case 0x423b8086: + case 0x423c8086: + case 0x423d8086: + map_me_phantom_function(domain, 3, map); + break; + default: + break; + } + } + else if ( IS_ILK(id) || IS_CPT(id) ) + { + /* quit if ME does not exist */ + if ( pci_conf_read32(0, 22, 0, 0) == 0xffffffff ) + return; + + /* if device is WLAN device, map ME phantom device 0:22.7 */ + id = pci_conf_read32(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0); + switch (id) + { + case 0x00878086: + case 0x00898086: + case 0x00828086: + case 0x00858086: + case 0x42388086: + case 0x422b8086: + map_me_phantom_function(domain, 22, map); + break; + default: + break; + } + + } +} diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/vtd.h --- a/xen/drivers/passthrough/vtd/vtd.h Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/vtd.h Fri Oct 29 10:29:14 2010 +0100 @@ -22,6 +22,10 @@ #define _VTD_H_ #include <xen/iommu.h> + +#define INTEL_IGD_DEV 0 +#define MAP_ME_PHANTOM_FUNC 1 +#define UNMAP_ME_PHANTOM_FUNC 0 /* Accomodate both IOAPIC and IOSAPIC. */ struct IO_xAPIC_route_entry { @@ -97,18 +101,4 @@ struct msi_msg_remap_entry { u32 data; /* msi message data */ }; -unsigned int get_cache_line_size(void); -void cacheline_flush(char *); -void flush_all_cache(void); -u64 alloc_pgtable_maddr(struct acpi_drhd_unit *drhd, unsigned long npages); -void free_pgtable_maddr(u64 maddr); -void *map_vtd_domain_page(u64 maddr); -void unmap_vtd_domain_page(void *va); - -void iommu_flush_cache_entry(void *addr, unsigned int size); -void iommu_flush_cache_page(void *addr, unsigned long npages); - -int iommu_alloc(struct acpi_drhd_unit *drhd); -void iommu_free(struct acpi_drhd_unit *drhd); - #endif // _VTD_H_ diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/drivers/passthrough/vtd/x86/vtd.c --- a/xen/drivers/passthrough/vtd/x86/vtd.c Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/drivers/passthrough/vtd/x86/vtd.c Fri Oct 29 10:29:14 2010 +0100 @@ -28,6 +28,7 @@ #include "../iommu.h" #include "../dmar.h" #include "../vtd.h" +#include "../extern.h" /* * iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0 diff -r 2d5e8f4ac43a -r b48d8f27fca2 xen/include/asm-x86/fixmap.h --- a/xen/include/asm-x86/fixmap.h Fri Oct 29 10:20:33 2010 +0100 +++ b/xen/include/asm-x86/fixmap.h Fri Oct 29 10:29:14 2010 +0100 @@ -55,6 +55,7 @@ enum fixed_addresses { FIX_TBOOT_MAP_ADDRESS, FIX_APEI_RANGE_BASE, FIX_APEI_RANGE_END = FIX_APEI_RANGE_BASE + FIX_APEI_RANGE_MAX -1, + FIX_IGD_MMIO, __end_of_fixed_addresses }; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |