]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.infradead.org/iommu-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Apr 2009 17:36:57 +0000 (10:36 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Apr 2009 17:36:57 +0000 (10:36 -0700)
* git://git.infradead.org/iommu-2.6:
  intel-iommu: Fix address wrap on 32-bit kernel.
  intel-iommu: Enable DMAR on 32-bit kernel.
  intel-iommu: fix PCI device detach from virtual machine
  intel-iommu: VT-d page table to support snooping control bit
  iommu: Add domain_has_cap iommu_ops
  intel-iommu: Snooping control support

Fixed trivial conflicts in arch/x86/Kconfig and drivers/pci/intel-iommu.c

1  2 
arch/x86/Kconfig
arch/x86/kernel/amd_iommu.c
drivers/base/iommu.c
drivers/pci/intel-iommu.c
include/linux/intel-iommu.h

diff --combined arch/x86/Kconfig
index 748e50a1a15257ac6226eca13869b47e32a59de2,5ff2252ec4752ffe61edd450e175aed483e55b66..3f27e5c0c9c962a3c7e01c5c35ac1bfc23ec84b0
@@@ -5,7 -5,7 +5,7 @@@ mainmenu "Linux Kernel Configuration fo
  config 64BIT
        bool "64-bit kernel" if ARCH = "x86"
        default ARCH = "x86_64"
 -      help
 +      ---help---
          Say yes to build a 64-bit kernel - formerly known as x86_64
          Say no to build a 32-bit kernel - formerly known as i386
  
@@@ -34,16 -34,12 +34,16 @@@ config X8
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 -      select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
 -      select HAVE_ARCH_KGDB if !X86_VOYAGER
 +      select HAVE_KVM
 +      select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_DMA_COHERENT if X86_32
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
        select USER_STACKTRACE_SUPPORT
 +      select HAVE_DMA_API_DEBUG
 +      select HAVE_KERNEL_GZIP
 +      select HAVE_KERNEL_BZIP2
 +      select HAVE_KERNEL_LZMA
  
  config ARCH_DEFCONFIG
        string
@@@ -137,19 -133,18 +137,19 @@@ config ARCH_HAS_CACHE_LINE_SIZ
        def_bool y
  
  config HAVE_SETUP_PER_CPU_AREA
 -      def_bool X86_64_SMP || (X86_SMP && !X86_VOYAGER)
 +      def_bool y
 +
 +config HAVE_DYNAMIC_PER_CPU_AREA
 +      def_bool y
  
  config HAVE_CPUMASK_OF_CPU_MAP
        def_bool X86_64_SMP
  
  config ARCH_HIBERNATION_POSSIBLE
        def_bool y
 -      depends on !SMP || !X86_VOYAGER
  
  config ARCH_SUSPEND_POSSIBLE
        def_bool y
 -      depends on !X86_VOYAGER
  
  config ZONE_DMA32
        bool
@@@ -165,17 -160,11 +165,17 @@@ config AUDIT_ARC
  config ARCH_SUPPORTS_OPTIMIZED_INLINING
        def_bool y
  
 +config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 +      def_bool y
 +
  # Use the generic interrupt handling code in kernel/irq/:
  config GENERIC_HARDIRQS
        bool
        default y
  
 +config GENERIC_HARDIRQS_NO__DO_IRQ
 +       def_bool y
 +
  config GENERIC_IRQ_PROBE
        bool
        default y
@@@ -185,6 -174,11 +185,6 @@@ config GENERIC_PENDING_IR
        depends on GENERIC_HARDIRQS && SMP
        default y
  
 -config X86_SMP
 -      bool
 -      depends on SMP && ((X86_32 && !X86_VOYAGER) || X86_64)
 -      default y
 -
  config USE_GENERIC_SMP_HELPERS
        def_bool y
        depends on SMP
@@@ -200,17 -194,19 +200,17 @@@ config X86_64_SM
  config X86_HT
        bool
        depends on SMP
 -      depends on (X86_32 && !X86_VOYAGER) || X86_64
 -      default y
 -
 -config X86_BIOS_REBOOT
 -      bool
 -      depends on !X86_VOYAGER
        default y
  
  config X86_TRAMPOLINE
        bool
 -      depends on X86_SMP || (X86_VOYAGER && SMP) || (64BIT && ACPI_SLEEP)
 +      depends on SMP || (64BIT && ACPI_SLEEP)
        default y
  
 +config X86_32_LAZY_GS
 +      def_bool y
 +      depends on X86_32 && !CC_STACKPROTECTOR
 +
  config KTIME_SCALAR
        def_bool X86_32
  source "init/Kconfig"
@@@ -248,24 -244,14 +248,24 @@@ config SM
  
          If you don't know what to do here, say N.
  
 -config X86_HAS_BOOT_CPU_ID
 -      def_bool y
 -      depends on X86_VOYAGER
 +config X86_X2APIC
 +      bool "Support x2apic"
 +      depends on X86_LOCAL_APIC && X86_64
 +      ---help---
 +        This enables x2apic support on CPUs that have this feature.
 +
 +        This allows 32-bit apic IDs (so it can support very large systems),
 +        and accesses the local apic via MSRs not via mmio.
 +
 +        ( On certain CPU models you may need to enable INTR_REMAP too,
 +          to get functional x2apic mode. )
 +
 +        If you don't know what to do here, say N.
  
  config SPARSE_IRQ
        bool "Support sparse irq numbering"
        depends on PCI_MSI || HT_IRQ
 -      help
 +      ---help---
          This enables support for sparse irqs. This is useful for distro
          kernels that want to define a high CONFIG_NR_CPUS value but still
          want to have low kernel memory footprint on smaller machines.
@@@ -279,140 -265,114 +279,140 @@@ config NUMA_MIGRATE_IRQ_DES
        bool "Move irq desc when changing irq smp_affinity"
        depends on SPARSE_IRQ && NUMA
        default n
 -      help
 +      ---help---
          This enables moving irq_desc to cpu/node that irq will use handled.
  
          If you don't know what to do here, say N.
  
 -config X86_FIND_SMP_CONFIG
 -      def_bool y
 -      depends on X86_MPPARSE || X86_VOYAGER
 -
  config X86_MPPARSE
        bool "Enable MPS table" if ACPI
        default y
        depends on X86_LOCAL_APIC
 -      help
 +      ---help---
          For old smp systems that do not have proper acpi support. Newer systems
          (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
  
 -choice
 -      prompt "Subarchitecture Type"
 -      default X86_PC
 +config X86_BIGSMP
 +      bool "Support for big SMP systems with more than 8 CPUs"
 +      depends on X86_32 && SMP
 +      ---help---
 +        This option is needed for the systems that have more than 8 CPUs
  
 -config X86_PC
 -      bool "PC-compatible"
 -      help
 -        Choose this option if your computer is a standard PC or compatible.
 +if X86_32
 +config X86_EXTENDED_PLATFORM
 +      bool "Support for extended (non-PC) x86 platforms"
 +      default y
 +      ---help---
 +        If you disable this option then the kernel will only support
 +        standard PC platforms. (which covers the vast majority of
 +        systems out there.)
 +
 +        If you enable this option then you'll be able to select support
 +        for the following (non-PC) 32 bit x86 platforms:
 +              AMD Elan
 +              NUMAQ (IBM/Sequent)
 +              RDC R-321x SoC
 +              SGI 320/540 (Visual Workstation)
 +              Summit/EXA (IBM x440)
 +              Unisys ES7000 IA32 series
 +
 +        If you have one of these systems, or if you want to build a
 +        generic distribution kernel, say Y here - otherwise say N.
 +endif
 +
 +if X86_64
 +config X86_EXTENDED_PLATFORM
 +      bool "Support for extended (non-PC) x86 platforms"
 +      default y
 +      ---help---
 +        If you disable this option then the kernel will only support
 +        standard PC platforms. (which covers the vast majority of
 +        systems out there.)
 +
 +        If you enable this option then you'll be able to select support
 +        for the following (non-PC) 64 bit x86 platforms:
 +              ScaleMP vSMP
 +              SGI Ultraviolet
 +
 +        If you have one of these systems, or if you want to build a
 +        generic distribution kernel, say Y here - otherwise say N.
 +endif
 +# This is an alphabetically sorted list of 64 bit extended platforms
 +# Please maintain the alphabetic order if and when there are additions
 +
 +config X86_VSMP
 +      bool "ScaleMP vSMP"
 +      select PARAVIRT
 +      depends on X86_64 && PCI
 +      depends on X86_EXTENDED_PLATFORM
 +      ---help---
 +        Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
 +        supposed to run on these EM64T-based machines.  Only choose this option
 +        if you have one of these machines.
 +
 +config X86_UV
 +      bool "SGI Ultraviolet"
 +      depends on X86_64
 +      depends on X86_EXTENDED_PLATFORM
 +      select X86_X2APIC
 +      ---help---
 +        This option is needed in order to support SGI Ultraviolet systems.
 +        If you don't have one of these, you should say N here.
 +
 +# Following is an alphabetically sorted list of 32 bit extended platforms
 +# Please maintain the alphabetic order if and when there are additions
  
  config X86_ELAN
        bool "AMD Elan"
        depends on X86_32
 -      help
 +      depends on X86_EXTENDED_PLATFORM
 +      ---help---
          Select this for an AMD Elan processor.
  
          Do not use this option for K6/Athlon/Opteron processors!
  
          If unsure, choose "PC-compatible" instead.
  
 -config X86_VOYAGER
 -      bool "Voyager (NCR)"
 -      depends on X86_32 && (SMP || BROKEN) && !PCI
 -      help
 -        Voyager is an MCA-based 32-way capable SMP architecture proprietary
 -        to NCR Corp.  Machine classes 345x/35xx/4100/51xx are Voyager-based.
 -
 -        *** WARNING ***
 -
 -        If you do not specifically know you have a Voyager based machine,
 -        say N here, otherwise the kernel you build will not be bootable.
 -
 -config X86_GENERICARCH
 -       bool "Generic architecture"
 +config X86_RDC321X
 +      bool "RDC R-321x SoC"
        depends on X86_32
 -       help
 -          This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
 +      depends on X86_EXTENDED_PLATFORM
 +      select M486
 +      select X86_REBOOTFIXUPS
 +      ---help---
 +        This option is needed for RDC R-321x system-on-chip, also known
 +        as R-8610-(G).
 +        If you don't have one of these chips, you should say N here.
 +
 +config X86_32_NON_STANDARD
 +      bool "Support non-standard 32-bit SMP architectures"
 +      depends on X86_32 && SMP
 +      depends on X86_EXTENDED_PLATFORM
 +      ---help---
 +        This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
          subarchitectures.  It is intended for a generic binary kernel.
          if you select them all, kernel will probe it one by one. and will
          fallback to default.
  
 -if X86_GENERICARCH
 +# Alphabetically sorted list of Non standard 32 bit platforms
  
  config X86_NUMAQ
        bool "NUMAQ (IBM/Sequent)"
 -      depends on SMP && X86_32 && PCI && X86_MPPARSE
 +      depends on X86_32_NON_STANDARD
        select NUMA
 -      help
 +      select X86_MPPARSE
 +      ---help---
          This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
          NUMA multiquad box. This changes the way that processors are
          bootstrapped, and uses Clustered Logical APIC addressing mode instead
          of Flat Logical.  You will need a new lynxer.elf file to flash your
          firmware with - send email to <Martin.Bligh@us.ibm.com>.
  
 -config X86_SUMMIT
 -      bool "Summit/EXA (IBM x440)"
 -      depends on X86_32 && SMP
 -      help
 -        This option is needed for IBM systems that use the Summit/EXA chipset.
 -        In particular, it is needed for the x440.
 -
 -config X86_ES7000
 -      bool "Support for Unisys ES7000 IA32 series"
 -      depends on X86_32 && SMP
 -      help
 -        Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
 -        supposed to run on an IA32-based Unisys ES7000 system.
 -
 -config X86_BIGSMP
 -      bool "Support for big SMP systems with more than 8 CPUs"
 -      depends on X86_32 && SMP
 -      help
 -        This option is needed for the systems that have more than 8 CPUs
 -        and if the system is not of any sub-arch type above.
 -
 -endif
 -
 -config X86_VSMP
 -      bool "Support for ScaleMP vSMP"
 -      select PARAVIRT
 -      depends on X86_64 && PCI
 -      help
 -        Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
 -        supposed to run on these EM64T-based machines.  Only choose this option
 -        if you have one of these machines.
 -
 -endchoice
 -
  config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
 -      depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE && PCI_GODIRECT
 -      help
 +      depends on X86_32 && PCI && X86_MPPARSE && PCI_GODIRECT
 +      depends on X86_32_NON_STANDARD
 +      ---help---
          The SGI Visual Workstation series is an IA32-based workstation
          based on SGI systems chips with some legacy PC hardware attached.
  
          A kernel compiled for the Visual Workstation will run on general
          PCs as well. See <file:Documentation/sgi-visws.txt> for details.
  
 -config X86_RDC321X
 -      bool "RDC R-321x SoC"
 -      depends on X86_32
 -      select M486
 -      select X86_REBOOTFIXUPS
 -      help
 -        This option is needed for RDC R-321x system-on-chip, also known
 -        as R-8610-(G).
 -        If you don't have one of these chips, you should say N here.
 +config X86_SUMMIT
 +      bool "Summit/EXA (IBM x440)"
 +      depends on X86_32_NON_STANDARD
 +      ---help---
 +        This option is needed for IBM systems that use the Summit/EXA chipset.
 +        In particular, it is needed for the x440.
 +
 +config X86_ES7000
 +      bool "Unisys ES7000 IA32 series"
 +      depends on X86_32_NON_STANDARD && X86_BIGSMP
 +      ---help---
 +        Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
 +        supposed to run on an IA32-based Unisys ES7000 system.
  
  config SCHED_OMIT_FRAME_POINTER
        def_bool y
        prompt "Single-depth WCHAN output"
        depends on X86
 -      help
 +      ---help---
          Calculate simpler /proc/<PID>/wchan values. If this option
          is disabled then wchan values will recurse back to the
          caller function. This provides more accurate wchan values,
  
  menuconfig PARAVIRT_GUEST
        bool "Paravirtualized guest support"
 -      help
 +      ---help---
          Say Y here to get to see options related to running Linux under
          various hypervisors.  This option alone does not add any kernel code.
  
@@@ -463,7 -419,8 +463,7 @@@ config VM
        bool "VMI Guest support"
        select PARAVIRT
        depends on X86_32
 -      depends on !X86_VOYAGER
 -      help
 +      ---help---
          VMI provides a paravirtualized interface to the VMware ESX server
          (it could be used by other hypervisors in theory too, but is not
          at the moment), by linking the kernel to a GPL-ed ROM module
@@@ -473,7 -430,8 +473,7 @@@ config KVM_CLOC
        bool "KVM paravirtualized clock"
        select PARAVIRT
        select PARAVIRT_CLOCK
 -      depends on !X86_VOYAGER
 -      help
 +      ---help---
          Turning on this option will allow you to run a paravirtualized clock
          when running over the KVM hypervisor. Instead of relying on a PIT
          (or probably other) emulation by the underlying device model, the host
  config KVM_GUEST
        bool "KVM Guest support"
        select PARAVIRT
 -      depends on !X86_VOYAGER
 -      help
 -       This option enables various optimizations for running under the KVM
 -       hypervisor.
 +      ---help---
 +        This option enables various optimizations for running under the KVM
 +        hypervisor.
  
  source "arch/x86/lguest/Kconfig"
  
  config PARAVIRT
        bool "Enable paravirtualization code"
 -      depends on !X86_VOYAGER
 -      help
 +      ---help---
          This changes the kernel so it can modify itself when it is run
          under a hypervisor, potentially improving performance significantly
          over full virtualization.  However, when run without a hypervisor
@@@ -504,51 -464,51 +504,51 @@@ config PARAVIRT_CLOC
  endif
  
  config PARAVIRT_DEBUG
 -       bool "paravirt-ops debugging"
 -       depends on PARAVIRT && DEBUG_KERNEL
 -       help
 -         Enable to debug paravirt_ops internals.  Specifically, BUG if
 -       a paravirt_op is missing when it is called.
 +      bool "paravirt-ops debugging"
 +      depends on PARAVIRT && DEBUG_KERNEL
 +      ---help---
 +        Enable to debug paravirt_ops internals.  Specifically, BUG if
 +        a paravirt_op is missing when it is called.
  
  config MEMTEST
        bool "Memtest"
 -      help
 +      ---help---
          This option adds a kernel parameter 'memtest', which allows memtest
          to be set.
 -              memtest=0, mean disabled; -- default
 -              memtest=1, mean do 1 test pattern;
 -              ...
 -              memtest=4, mean do 4 test patterns.
 +              memtest=0, mean disabled; -- default
 +              memtest=1, mean do 1 test pattern;
 +              ...
 +              memtest=4, mean do 4 test patterns.
          If you are unsure how to answer this question, answer N.
  
  config X86_SUMMIT_NUMA
        def_bool y
 -      depends on X86_32 && NUMA && X86_GENERICARCH
 +      depends on X86_32 && NUMA && X86_32_NON_STANDARD
  
  config X86_CYCLONE_TIMER
        def_bool y
 -      depends on X86_GENERICARCH
 +      depends on X86_32_NON_STANDARD
  
  source "arch/x86/Kconfig.cpu"
  
  config HPET_TIMER
        def_bool X86_64
        prompt "HPET Timer Support" if X86_32
 -      help
 -         Use the IA-PC HPET (High Precision Event Timer) to manage
 -         time in preference to the PIT and RTC, if a HPET is
 -         present.
 -         HPET is the next generation timer replacing legacy 8254s.
 -         The HPET provides a stable time base on SMP
 -         systems, unlike the TSC, but it is more expensive to access,
 -         as it is off-chip.  You can find the HPET spec at
 -         <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
 +      ---help---
 +        Use the IA-PC HPET (High Precision Event Timer) to manage
 +        time in preference to the PIT and RTC, if a HPET is
 +        present.
 +        HPET is the next generation timer replacing legacy 8254s.
 +        The HPET provides a stable time base on SMP
 +        systems, unlike the TSC, but it is more expensive to access,
 +        as it is off-chip.  You can find the HPET spec at
 +        <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
  
 -         You can safely choose Y here.  However, HPET will only be
 -         activated if the platform and the BIOS support this feature.
 -         Otherwise the 8254 will be used for timing services.
 +        You can safely choose Y here.  However, HPET will only be
 +        activated if the platform and the BIOS support this feature.
 +        Otherwise the 8254 will be used for timing services.
  
 -         Choose N to continue using the legacy 8254 timer.
 +        Choose N to continue using the legacy 8254 timer.
  
  config HPET_EMULATE_RTC
        def_bool y
  config DMI
        default y
        bool "Enable DMI scanning" if EMBEDDED
 -      help
 +      ---help---
          Enabled scanning of DMI to identify machine quirks. Say Y
          here unless you have verified that your setup is not
          affected by entries in the DMI blacklist. Required by PNP
@@@ -571,7 -531,7 +571,7 @@@ config GART_IOMM
        select SWIOTLB
        select AGP
        depends on X86_64 && PCI
 -      help
 +      ---help---
          Support for full DMA access of devices with 32bit memory access only
          on systems with more than 3GB. This is usually needed for USB,
          sound, many IDE/SATA chipsets and some other devices.
@@@ -586,7 -546,7 +586,7 @@@ config CALGARY_IOMM
        bool "IBM Calgary IOMMU support"
        select SWIOTLB
        depends on X86_64 && PCI && EXPERIMENTAL
 -      help
 +      ---help---
          Support for hardware IOMMUs in IBM's xSeries x366 and x460
          systems. Needed to run systems with more than 3GB of memory
          properly with 32-bit PCI devices that do not support DAC
@@@ -604,7 -564,7 +604,7 @@@ config CALGARY_IOMMU_ENABLED_BY_DEFAUL
        def_bool y
        prompt "Should Calgary be enabled by default?"
        depends on CALGARY_IOMMU
 -      help
 +      ---help---
          Should Calgary be enabled by default? if you choose 'y', Calgary
          will be used (if it exists). If you choose 'n', Calgary will not be
          used even if it exists. If you choose 'n' and would like to use
@@@ -616,7 -576,7 +616,7 @@@ config AMD_IOMM
        select SWIOTLB
        select PCI_MSI
        depends on X86_64 && PCI && ACPI
 -      help
 +      ---help---
          With this option you can enable support for AMD IOMMU hardware in
          your system. An IOMMU is a hardware component which provides
          remapping of DMA memory accesses from devices. With an AMD IOMMU you
@@@ -631,7 -591,7 +631,7 @@@ config AMD_IOMMU_STAT
        bool "Export AMD IOMMU statistics to debugfs"
        depends on AMD_IOMMU
        select DEBUG_FS
 -      help
 +      ---help---
          This option enables code in the AMD IOMMU driver to collect various
          statistics about whats happening in the driver and exports that
          information to userspace via debugfs.
  # need this always selected by IOMMU for the VIA workaround
  config SWIOTLB
        def_bool y if X86_64
 -      help
 +      ---help---
          Support for software bounce buffers used on x86-64 systems
          which don't have a hardware IOMMU (e.g. the current generation
          of Intel's x86-64 CPUs). Using this PCI devices which can only
@@@ -658,7 -618,7 +658,7 @@@ config MAXSM
        depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
        select CPUMASK_OFFSTACK
        default n
 -      help
 +      ---help---
          Configure maximum number of CPUS and NUMA Nodes for this architecture.
          If unsure, say N.
  
@@@ -669,7 -629,7 +669,7 @@@ config NR_CPU
        default "4096" if MAXSMP
        default "32" if SMP && (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000)
        default "8" if SMP
 -      help
 +      ---help---
          This allows you to specify the maximum number of CPUs which this
          kernel will support.  The maximum supported value is 512 and the
          minimum value which makes sense is 2.
  config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
        depends on X86_HT
 -      help
 +      ---help---
          SMT scheduler support improves the CPU scheduler's decision making
          when dealing with Intel Pentium 4 chips with HyperThreading at a
          cost of slightly increased overhead in some places. If unsure say
@@@ -690,7 -650,7 +690,7 @@@ config SCHED_M
        def_bool y
        prompt "Multi-core scheduler support"
        depends on X86_HT
 -      help
 +      ---help---
          Multi-core scheduler support improves the CPU scheduler's decision
          making when dealing with multi-core CPU chips at a cost of slightly
          increased overhead in some places. If unsure say N here.
@@@ -699,8 -659,8 +699,8 @@@ source "kernel/Kconfig.preempt
  
  config X86_UP_APIC
        bool "Local APIC support on uniprocessors"
 -      depends on X86_32 && !SMP && !(X86_VOYAGER || X86_GENERICARCH)
 -      help
 +      depends on X86_32 && !SMP && !X86_32_NON_STANDARD
 +      ---help---
          A local APIC (Advanced Programmable Interrupt Controller) is an
          integrated interrupt controller in the CPU. If you have a single-CPU
          system which has a processor with a local APIC, you can say Y here to
  config X86_UP_IOAPIC
        bool "IO-APIC support on uniprocessors"
        depends on X86_UP_APIC
 -      help
 +      ---help---
          An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
          SMP-capable replacement for PC-style interrupt controllers. Most
          SMP systems and many recent uniprocessor systems have one.
  
  config X86_LOCAL_APIC
        def_bool y
 -      depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
 +      depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
  
  config X86_IO_APIC
        def_bool y
 -      depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
 +      depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
  
  config X86_VISWS_APIC
        def_bool y
@@@ -738,7 -698,7 +738,7 @@@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQ
        bool "Reroute for broken boot IRQs"
        default n
        depends on X86_IO_APIC
 -      help
 +      ---help---
          This option enables a workaround that fixes a source of
          spurious interrupts. This is recommended when threaded
          interrupt handling is used on systems where the generation of
  
  config X86_MCE
        bool "Machine Check Exception"
 -      depends on !X86_VOYAGER
        ---help---
          Machine Check Exception support allows the processor to notify the
          kernel if it detects a problem (e.g. overheating, component failure).
@@@ -778,7 -739,7 +778,7 @@@ config X86_MCE_INTE
        def_bool y
        prompt "Intel MCE features"
        depends on X86_64 && X86_MCE && X86_LOCAL_APIC
 -      help
 +      ---help---
           Additional support for intel specific MCE features such as
           the thermal monitor.
  
@@@ -786,19 -747,14 +786,19 @@@ config X86_MCE_AM
        def_bool y
        prompt "AMD MCE features"
        depends on X86_64 && X86_MCE && X86_LOCAL_APIC
 -      help
 +      ---help---
           Additional support for AMD specific MCE features such as
           the DRAM Error Threshold.
  
 +config X86_MCE_THRESHOLD
 +      depends on X86_MCE_AMD || X86_MCE_INTEL
 +      bool
 +      default y
 +
  config X86_MCE_NONFATAL
        tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
        depends on X86_32 && X86_MCE
 -      help
 +      ---help---
          Enabling this feature starts a timer that triggers every 5 seconds which
          will look at the machine check registers to see if anything happened.
          Non-fatal problems automatically get corrected (but still logged).
  config X86_MCE_P4THERMAL
        bool "check for P4 thermal throttling interrupt."
        depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP)
 -      help
 +      ---help---
          Enabling this feature will cause a message to be printed when the P4
          enters thermal throttling.
  
@@@ -819,11 -775,11 +819,11 @@@ config VM8
        bool "Enable VM86 support" if EMBEDDED
        default y
        depends on X86_32
 -      help
 -          This option is required by programs like DOSEMU to run 16-bit legacy
 +      ---help---
 +        This option is required by programs like DOSEMU to run 16-bit legacy
          code on X86 processors. It also may be needed by software like
 -          XFree86 to initialize some video cards via BIOS. Disabling this
 -          option saves about 6k.
 +        XFree86 to initialize some video cards via BIOS. Disabling this
 +        option saves about 6k.
  
  config TOSHIBA
        tristate "Toshiba Laptop support"
@@@ -897,33 -853,33 +897,33 @@@ config MICROCOD
          module will be called microcode.
  
  config MICROCODE_INTEL
 -       bool "Intel microcode patch loading support"
 -       depends on MICROCODE
 -       default MICROCODE
 -       select FW_LOADER
 -       --help---
 -         This options enables microcode patch loading support for Intel
 -         processors.
 -
 -         For latest news and information on obtaining all the required
 -         Intel ingredients for this driver, check:
 -         <http://www.urbanmyth.org/microcode/>.
 +      bool "Intel microcode patch loading support"
 +      depends on MICROCODE
 +      default MICROCODE
 +      select FW_LOADER
 +      ---help---
 +        This options enables microcode patch loading support for Intel
 +        processors.
 +
 +        For latest news and information on obtaining all the required
 +        Intel ingredients for this driver, check:
 +        <http://www.urbanmyth.org/microcode/>.
  
  config MICROCODE_AMD
 -       bool "AMD microcode patch loading support"
 -       depends on MICROCODE
 -       select FW_LOADER
 -       --help---
 -         If you select this option, microcode patch loading support for AMD
 -       processors will be enabled.
 +      bool "AMD microcode patch loading support"
 +      depends on MICROCODE
 +      select FW_LOADER
 +      ---help---
 +        If you select this option, microcode patch loading support for AMD
 +        processors will be enabled.
  
 -   config MICROCODE_OLD_INTERFACE
 +config MICROCODE_OLD_INTERFACE
        def_bool y
        depends on MICROCODE
  
  config X86_MSR
        tristate "/dev/cpu/*/msr - Model-specific register support"
 -      help
 +      ---help---
          This device gives privileged processes access to the x86
          Model-Specific Registers (MSRs).  It is a character device with
          major 202 and minors 0 to 31 for /dev/cpu/0/msr to /dev/cpu/31/msr.
  
  config X86_CPUID
        tristate "/dev/cpu/*/cpuid - CPU information support"
 -      help
 +      ---help---
          This device gives processes access to the x86 CPUID instruction to
          be executed on a specific processor.  It is a character device
          with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
          /dev/cpu/31/cpuid.
  
 +config X86_CPU_DEBUG
 +      tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
 +      ---help---
 +        If you select this option, this will provide various x86 CPUs
 +        information through debugfs.
 +
  choice
        prompt "High Memory Support"
        default HIGHMEM4G if !X86_NUMAQ
@@@ -990,7 -940,7 +990,7 @@@ config NOHIGHME
  config HIGHMEM4G
        bool "4GB"
        depends on !X86_NUMAQ
 -      help
 +      ---help---
          Select this if you have a 32-bit processor and between 1 and 4
          gigabytes of physical RAM.
  
@@@ -998,7 -948,7 +998,7 @@@ config HIGHMEM64
        bool "64GB"
        depends on !M386 && !M486
        select X86_PAE
 -      help
 +      ---help---
          Select this if you have a 32-bit processor and more than 4
          gigabytes of physical RAM.
  
@@@ -1009,7 -959,7 +1009,7 @@@ choic
        prompt "Memory split" if EMBEDDED
        default VMSPLIT_3G
        depends on X86_32
 -      help
 +      ---help---
          Select the desired split between kernel and user memory.
  
          If the address range available to the kernel is less than the
@@@ -1055,20 -1005,20 +1055,20 @@@ config HIGHME
  config X86_PAE
        bool "PAE (Physical Address Extension) Support"
        depends on X86_32 && !HIGHMEM4G
 -      help
 +      ---help---
          PAE is required for NX support, and furthermore enables
          larger swapspace support for non-overcommit purposes. It
          has the cost of more pagetable lookup overhead, and also
          consumes more pagetable space per process.
  
  config ARCH_PHYS_ADDR_T_64BIT
 -       def_bool X86_64 || X86_PAE
 +      def_bool X86_64 || X86_PAE
  
  config DIRECT_GBPAGES
        bool "Enable 1GB pages for kernel pagetables" if EMBEDDED
        default y
        depends on X86_64
 -      help
 +      ---help---
          Allow the kernel linear mapping to use 1GB pages on CPUs that
          support it. This can improve the kernel's performance a tiny bit by
          reducing TLB pressure. If in doubt, say "Y".
@@@ -1078,8 -1028,9 +1078,8 @@@ config NUM
        bool "Numa Memory Allocation and Scheduler Support"
        depends on SMP
        depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && EXPERIMENTAL)
 -      default n if X86_PC
        default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP)
 -      help
 +      ---help---
          Enable NUMA (Non Uniform Memory Access) support.
  
          The kernel will try to allocate memory used by a CPU on the
@@@ -1102,19 -1053,19 +1102,19 @@@ config K8_NUM
        def_bool y
        prompt "Old style AMD Opteron NUMA detection"
        depends on X86_64 && NUMA && PCI
 -      help
 -       Enable K8 NUMA node topology detection.  You should say Y here if
 -       you have a multi processor AMD K8 system. This uses an old
 -       method to read the NUMA configuration directly from the builtin
 -       Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
 -       instead, which also takes priority if both are compiled in.
 +      ---help---
 +        Enable K8 NUMA node topology detection.  You should say Y here if
 +        you have a multi processor AMD K8 system. This uses an old
 +        method to read the NUMA configuration directly from the builtin
 +        Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
 +        instead, which also takes priority if both are compiled in.
  
  config X86_64_ACPI_NUMA
        def_bool y
        prompt "ACPI NUMA detection"
        depends on X86_64 && NUMA && ACPI && PCI
        select ACPI_NUMA
 -      help
 +      ---help---
          Enable ACPI SRAT based node topology detection.
  
  # Some NUMA nodes have memory ranges that span
@@@ -1129,24 -1080,24 +1129,24 @@@ config NODES_SPAN_OTHER_NODE
  config NUMA_EMU
        bool "NUMA emulation"
        depends on X86_64 && NUMA
 -      help
 +      ---help---
          Enable NUMA emulation. A flat machine will be split
          into virtual nodes when booted with "numa=fake=N", where N is the
          number of nodes. This is only useful for debugging.
  
  config NODES_SHIFT
        int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
 -      range 1 9   if X86_64
 +      range 1 9
        default "9" if MAXSMP
        default "6" if X86_64
        default "4" if X86_NUMAQ
        default "3"
        depends on NEED_MULTIPLE_NODES
 -      help
 +      ---help---
          Specify the maximum number of NUMA Nodes available on the target
          system.  Increases memory reserved to accomodate various tables.
  
 -config HAVE_ARCH_BOOTMEM_NODE
 +config HAVE_ARCH_BOOTMEM
        def_bool y
        depends on X86_32 && NUMA
  
@@@ -1180,7 -1131,7 +1180,7 @@@ config ARCH_SPARSEMEM_DEFAUL
  
  config ARCH_SPARSEMEM_ENABLE
        def_bool y
 -      depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) || X86_GENERICARCH
 +      depends on X86_64 || NUMA || (EXPERIMENTAL && X86_32) || X86_32_NON_STANDARD
        select SPARSEMEM_STATIC if X86_32
        select SPARSEMEM_VMEMMAP_ENABLE if X86_64
  
@@@ -1197,61 -1148,61 +1197,61 @@@ source "mm/Kconfig
  config HIGHPTE
        bool "Allocate 3rd-level pagetables from highmem"
        depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
 -      help
 +      ---help---
          The VM uses one page table entry for each page of physical memory.
          For systems with a lot of RAM, this can be wasteful of precious
          low memory.  Setting this option will put user-space page table
          entries in high memory.
  
  config X86_CHECK_BIOS_CORRUPTION
 -        bool "Check for low memory corruption"
 -      help
 -       Periodically check for memory corruption in low memory, which
 -       is suspected to be caused by BIOS.  Even when enabled in the
 -       configuration, it is disabled at runtime.  Enable it by
 -       setting "memory_corruption_check=1" on the kernel command
 -       line.  By default it scans the low 64k of memory every 60
 -       seconds; see the memory_corruption_check_size and
 -       memory_corruption_check_period parameters in
 -       Documentation/kernel-parameters.txt to adjust this.
 -
 -       When enabled with the default parameters, this option has
 -       almost no overhead, as it reserves a relatively small amount
 -       of memory and scans it infrequently.  It both detects corruption
 -       and prevents it from affecting the running system.
 -
 -       It is, however, intended as a diagnostic tool; if repeatable
 -       BIOS-originated corruption always affects the same memory,
 -       you can use memmap= to prevent the kernel from using that
 -       memory.
 +      bool "Check for low memory corruption"
 +      ---help---
 +        Periodically check for memory corruption in low memory, which
 +        is suspected to be caused by BIOS.  Even when enabled in the
 +        configuration, it is disabled at runtime.  Enable it by
 +        setting "memory_corruption_check=1" on the kernel command
 +        line.  By default it scans the low 64k of memory every 60
 +        seconds; see the memory_corruption_check_size and
 +        memory_corruption_check_period parameters in
 +        Documentation/kernel-parameters.txt to adjust this.
 +
 +        When enabled with the default parameters, this option has
 +        almost no overhead, as it reserves a relatively small amount
 +        of memory and scans it infrequently.  It both detects corruption
 +        and prevents it from affecting the running system.
 +
 +        It is, however, intended as a diagnostic tool; if repeatable
 +        BIOS-originated corruption always affects the same memory,
 +        you can use memmap= to prevent the kernel from using that
 +        memory.
  
  config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
 -        bool "Set the default setting of memory_corruption_check"
 +      bool "Set the default setting of memory_corruption_check"
        depends on X86_CHECK_BIOS_CORRUPTION
        default y
 -      help
 -       Set whether the default state of memory_corruption_check is
 -       on or off.
 +      ---help---
 +        Set whether the default state of memory_corruption_check is
 +        on or off.
  
  config X86_RESERVE_LOW_64K
 -        bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
 +      bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
        default y
 -      help
 -       Reserve the first 64K of physical RAM on BIOSes that are known
 -       to potentially corrupt that memory range. A numbers of BIOSes are
 -       known to utilize this area during suspend/resume, so it must not
 -       be used by the kernel.
 +      ---help---
 +        Reserve the first 64K of physical RAM on BIOSes that are known
 +        to potentially corrupt that memory range. A numbers of BIOSes are
 +        known to utilize this area during suspend/resume, so it must not
 +        be used by the kernel.
  
 -       Set this to N if you are absolutely sure that you trust the BIOS
 -       to get all its memory reservations and usages right.
 +        Set this to N if you are absolutely sure that you trust the BIOS
 +        to get all its memory reservations and usages right.
  
 -       If you have doubts about the BIOS (e.g. suspend/resume does not
 -       work or there's kernel crashes after certain hardware hotplug
 -       events) and it's not AMI or Phoenix, then you might want to enable
 -       X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
 -       corruption patterns.
 +        If you have doubts about the BIOS (e.g. suspend/resume does not
 +        work or there's kernel crashes after certain hardware hotplug
 +        events) and it's not AMI or Phoenix, then you might want to enable
 +        X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
 +        corruption patterns.
  
 -       Say Y if unsure.
 +        Say Y if unsure.
  
  config MATH_EMULATION
        bool
@@@ -1317,7 -1268,7 +1317,7 @@@ config MTRR_SANITIZE
        def_bool y
        prompt "MTRR cleanup support"
        depends on MTRR
 -      help
 +      ---help---
          Convert MTRR layout from continuous to discrete, so X drivers can
          add writeback entries.
  
@@@ -1332,7 -1283,7 +1332,7 @@@ config MTRR_SANITIZER_ENABLE_DEFAUL
        range 0 1
        default "0"
        depends on MTRR_SANITIZER
 -      help
 +      ---help---
          Enable mtrr cleanup default value
  
  config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
        range 0 7
        default "1"
        depends on MTRR_SANITIZER
 -      help
 +      ---help---
          mtrr cleanup spare entries default, it can be changed via
          mtrr_spare_reg_nr=N on the kernel command line.
  
@@@ -1348,7 -1299,7 +1348,7 @@@ config X86_PA
        bool
        prompt "x86 PAT support"
        depends on MTRR
 -      help
 +      ---help---
          Use PAT attributes to setup page level cache control.
  
          PATs are the modern equivalents of MTRRs and are much more
@@@ -1363,20 -1314,20 +1363,20 @@@ config EF
        bool "EFI runtime service support"
        depends on ACPI
        ---help---
 -      This enables the kernel to use EFI runtime services that are
 -      available (such as the EFI variable services).
 +        This enables the kernel to use EFI runtime services that are
 +        available (such as the EFI variable services).
  
 -      This option is only useful on systems that have EFI firmware.
 -      In addition, you should use the latest ELILO loader available
 -      at <http://elilo.sourceforge.net> in order to take advantage
 -      of EFI runtime services. However, even with this option, the
 -      resultant kernel should continue to boot on existing non-EFI
 -      platforms.
 +        This option is only useful on systems that have EFI firmware.
 +        In addition, you should use the latest ELILO loader available
 +        at <http://elilo.sourceforge.net> in order to take advantage
 +        of EFI runtime services. However, even with this option, the
 +        resultant kernel should continue to boot on existing non-EFI
 +        platforms.
  
  config SECCOMP
        def_bool y
        prompt "Enable seccomp to safely compute untrusted bytecode"
 -      help
 +      ---help---
          This kernel feature is useful for number crunching applications
          that may need to compute untrusted bytecode during their
          execution. By using pipes or other transports made available to
  
          If unsure, say Y. Only embedded should say N here.
  
 +config CC_STACKPROTECTOR_ALL
 +      bool
 +
  config CC_STACKPROTECTOR
        bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
 -      depends on X86_64 && EXPERIMENTAL && BROKEN
 -      help
 -         This option turns on the -fstack-protector GCC feature. This
 -        feature puts, at the beginning of critical functions, a canary
 -        value on the stack just before the return address, and validates
 +      select CC_STACKPROTECTOR_ALL
 +      ---help---
 +        This option turns on the -fstack-protector GCC feature. This
 +        feature puts, at the beginning of functions, a canary value on
 +        the stack just before the return address, and validates
          the value just before actually returning.  Stack based buffer
          overflows (that need to overwrite this return address) now also
          overwrite the canary, which gets detected and the attack is then
  
          This feature requires gcc version 4.2 or above, or a distribution
          gcc with the feature backported. Older versions are automatically
 -        detected and for those versions, this configuration option is ignored.
 -
 -config CC_STACKPROTECTOR_ALL
 -      bool "Use stack-protector for all functions"
 -      depends on CC_STACKPROTECTOR
 -      help
 -        Normally, GCC only inserts the canary value protection for
 -        functions that use large-ish on-stack buffers. By enabling
 -        this option, GCC will be asked to do this for ALL functions.
 +        detected and for those versions, this configuration option is
 +        ignored. (and a warning is printed during bootup)
  
  source kernel/Kconfig.hz
  
  config KEXEC
        bool "kexec system call"
 -      depends on X86_BIOS_REBOOT
 -      help
 +      ---help---
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
          but it is independent of the system firmware.   And like a reboot
  config CRASH_DUMP
        bool "kernel crash dumps"
        depends on X86_64 || (X86_32 && HIGHMEM)
 -      help
 +      ---help---
          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
          which are loaded in the main kernel with kexec-tools into
  config KEXEC_JUMP
        bool "kexec jump (EXPERIMENTAL)"
        depends on EXPERIMENTAL
 -      depends on KEXEC && HIBERNATION && X86_32
 -      help
 +      depends on KEXEC && HIBERNATION
 +      ---help---
          Jump between original kernel and kexeced kernel and invoke
          code in physical address mode via KEXEC
  
@@@ -1454,7 -1410,7 +1454,7 @@@ config PHYSICAL_STAR
        default "0x1000000" if X86_NUMAQ
        default "0x200000" if X86_64
        default "0x100000"
 -      help
 +      ---help---
          This gives the physical address where the kernel is loaded.
  
          If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
  config RELOCATABLE
        bool "Build a relocatable kernel (EXPERIMENTAL)"
        depends on EXPERIMENTAL
 -      help
 +      ---help---
          This builds a kernel image that retains relocation information
          so it can be loaded someplace besides the default 1MB.
          The relocations tend to make the kernel binary about 10% larger,
@@@ -1515,7 -1471,7 +1515,7 @@@ config PHYSICAL_ALIG
        default "0x100000" if X86_32
        default "0x200000" if X86_64
        range 0x2000 0x400000
 -      help
 +      ---help---
          This value puts the alignment restrictions on physical address
          where kernel is loaded and run from. Kernel is compiled for an
          address which meets above alignment restriction.
  
  config HOTPLUG_CPU
        bool "Support for hot-pluggable CPUs"
 -      depends on SMP && HOTPLUG && !X86_VOYAGER
 +      depends on SMP && HOTPLUG
        ---help---
          Say Y here to allow turning CPUs off and on. CPUs can be
          controlled through /sys/devices/system/cpu.
@@@ -1548,7 -1504,7 +1548,7 @@@ config COMPAT_VDS
        def_bool y
        prompt "Compat VDSO support"
        depends on X86_32 || IA32_EMULATION
 -      help
 +      ---help---
          Map the 32-bit VDSO to the predictable old-style address too.
        ---help---
          Say N here if you are running a sufficiently recent glibc
  config CMDLINE_BOOL
        bool "Built-in kernel command line"
        default n
 -      help
 +      ---help---
          Allow for specifying boot arguments to the kernel at
          build time.  On some systems (e.g. embedded ones), it is
          necessary or convenient to provide some or all of the
@@@ -1578,7 -1534,7 +1578,7 @@@ config CMDLIN
        string "Built-in kernel command string"
        depends on CMDLINE_BOOL
        default ""
 -      help
 +      ---help---
          Enter arguments here that should be compiled into the kernel
          image and used at boot time.  If the boot loader provides a
          command line at boot time, it is appended to this string to
@@@ -1595,7 -1551,7 +1595,7 @@@ config CMDLINE_OVERRID
        bool "Built-in command line overrides boot loader arguments"
        default n
        depends on CMDLINE_BOOL
 -      help
 +      ---help---
          Set this option to 'Y' to have the kernel ignore the boot loader
          command line, and use ONLY the built-in command line.
  
@@@ -1617,6 -1573,7 +1617,6 @@@ config HAVE_ARCH_EARLY_PFN_TO_NI
        depends on NUMA
  
  menu "Power management and ACPI options"
 -      depends on !X86_VOYAGER
  
  config ARCH_HIBERNATION_HEADER
        def_bool y
@@@ -1694,7 -1651,7 +1694,7 @@@ if AP
  
  config APM_IGNORE_USER_SUSPEND
        bool "Ignore USER SUSPEND"
 -      help
 +      ---help---
          This option will ignore USER SUSPEND requests. On machines with a
          compliant APM BIOS, you want to say N. However, on the NEC Versa M
          series notebooks, it is necessary to say Y because of a BIOS bug.
@@@ -1718,7 -1675,7 +1718,7 @@@ config APM_DO_ENABL
  
  config APM_CPU_IDLE
        bool "Make CPU Idle calls when idle"
 -      help
 +      ---help---
          Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
          On some machines, this can activate improved power savings, such as
          a slowed CPU clock rate, when the machine is idle. These idle calls
  
  config APM_DISPLAY_BLANK
        bool "Enable console blanking using APM"
 -      help
 +      ---help---
          Enable console blanking using the APM. Some laptops can use this to
          turn off the LCD backlight when the screen blanker of the Linux
          virtual console blanks the screen. Note that this is only used by
  
  config APM_ALLOW_INTS
        bool "Allow interrupts during APM BIOS calls"
 -      help
 +      ---help---
          Normally we disable external interrupts while we are making calls to
          the APM BIOS as a measure to lessen the effects of a badly behaving
          BIOS implementation.  The BIOS should reenable interrupts if it
@@@ -1767,7 -1724,7 +1767,7 @@@ config PC
        bool "PCI support"
        default y
        select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
 -      help
 +      ---help---
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
          your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
@@@ -1837,8 -1794,8 +1837,8 @@@ config PCI_MMCONFI
  
  config DMAR
        bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
-       depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
-       ---help---
+       depends on PCI_MSI && ACPI && EXPERIMENTAL
+       help
          DMA remapping (DMAR) devices support enables independent address
          translations for Direct Memory Access (DMA) from devices.
          These DMA remapping devices are reported via ACPI tables
@@@ -1860,30 -1817,29 +1860,30 @@@ config DMAR_GFX_W
        def_bool y
        prompt "Support for Graphics workaround"
        depends on DMAR
 -      help
 -       Current Graphics drivers tend to use physical address
 -       for DMA and avoid using DMA APIs. Setting this config
 -       option permits the IOMMU driver to set a unity map for
 -       all the OS-visible memory. Hence the driver can continue
 -       to use physical addresses for DMA.
 +      ---help---
 +        Current Graphics drivers tend to use physical address
 +        for DMA and avoid using DMA APIs. Setting this config
 +        option permits the IOMMU driver to set a unity map for
 +        all the OS-visible memory. Hence the driver can continue
 +        to use physical addresses for DMA.
  
  config DMAR_FLOPPY_WA
        def_bool y
        depends on DMAR
 -      help
 -       Floppy disk drivers are know to bypass DMA API calls
 -       thereby failing to work when IOMMU is enabled. This
 -       workaround will setup a 1:1 mapping for the first
 -       16M to make floppy (an ISA device) work.
 +      ---help---
 +        Floppy disk drivers are know to bypass DMA API calls
 +        thereby failing to work when IOMMU is enabled. This
 +        workaround will setup a 1:1 mapping for the first
 +        16M to make floppy (an ISA device) work.
  
  config INTR_REMAP
        bool "Support for Interrupt Remapping (EXPERIMENTAL)"
        depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
 -      help
 -       Supports Interrupt remapping for IO-APIC and MSI devices.
 -       To use x2apic mode in the CPU's which support x2APIC enhancements or
 -       to support platforms with CPU's having > 8 bit APIC ID, say Y.
 +      select X86_X2APIC
 +      ---help---
 +        Supports Interrupt remapping for IO-APIC and MSI devices.
 +        To use x2apic mode in the CPU's which support x2APIC enhancements or
 +        to support platforms with CPU's having > 8 bit APIC ID, say Y.
  
  source "drivers/pci/pcie/Kconfig"
  
@@@ -1897,7 -1853,8 +1897,7 @@@ if X86_3
  
  config ISA
        bool "ISA support"
 -      depends on !X86_VOYAGER
 -      help
 +      ---help---
          Find out whether you have ISA slots on your motherboard.  ISA is the
          name of a bus system, i.e. the way the CPU talks to the other stuff
          inside your box.  Other bus systems are PCI, EISA, MicroChannel
@@@ -1923,8 -1880,9 +1923,8 @@@ config EIS
  source "drivers/eisa/Kconfig"
  
  config MCA
 -      bool "MCA support" if !X86_VOYAGER
 -      default y if X86_VOYAGER
 -      help
 +      bool "MCA support"
 +      ---help---
          MicroChannel Architecture is found in some IBM PS/2 machines and
          laptops.  It is a bus system similar to PCI or ISA. See
          <file:Documentation/mca.txt> (and especially the web page given
@@@ -1934,7 -1892,8 +1934,7 @@@ source "drivers/mca/Kconfig
  
  config SCx200
        tristate "NatSemi SCx200 support"
 -      depends on !X86_VOYAGER
 -      help
 +      ---help---
          This provides basic support for National Semiconductor's
          (now AMD's) Geode processors.  The driver probes for the
          PCI-IDs of several on-chip devices, so its a good dependency
@@@ -1946,7 -1905,7 +1946,7 @@@ config SCx200HR_TIME
        tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
        depends on SCx200 && GENERIC_TIME
        default y
 -      help
 +      ---help---
          This driver provides a clocksource built upon the on-chip
          27MHz high-resolution timer.  Its also a workaround for
          NSC Geode SC-1100's buggy TSC, which loses time when the
@@@ -1957,7 -1916,7 +1957,7 @@@ config GEODE_MFGPT_TIME
        def_bool y
        prompt "Geode Multi-Function General Purpose Timer (MFGPT) events"
        depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
 -      help
 +      ---help---
          This driver provides a clock event source based on the MFGPT
          timer(s) in the CS5535 and CS5536 companion chip for the geode.
          MFGPTs have a better resolution and max interval than the
  config OLPC
        bool "One Laptop Per Child support"
        default n
 -      help
 +      ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
  
@@@ -1991,16 -1950,16 +1991,16 @@@ config IA32_EMULATIO
        bool "IA32 Emulation"
        depends on X86_64
        select COMPAT_BINFMT_ELF
 -      help
 +      ---help---
          Include code to run 32-bit programs under a 64-bit kernel. You should
          likely turn this on, unless you're 100% sure that you don't have any
          32-bit programs left.
  
  config IA32_AOUT
 -       tristate "IA32 a.out support"
 -       depends on IA32_EMULATION
 -       help
 -         Support old a.out binaries in the 32bit emulation.
 +      tristate "IA32 a.out support"
 +      depends on IA32_EMULATION
 +      ---help---
 +        Support old a.out binaries in the 32bit emulation.
  
  config COMPAT
        def_bool y
index c5962fe3796fbabe71024e3892354e8297d23a5f,65c9b58655ff202584df7a6280468fa1f5e222a8..a97db99dad52fedd4bbcf6fe9d46bed8784f5e1f
  #include <linux/bitops.h>
  #include <linux/debugfs.h>
  #include <linux/scatterlist.h>
 +#include <linux/dma-mapping.h>
  #include <linux/iommu-helper.h>
 -#ifdef CONFIG_IOMMU_API
  #include <linux/iommu.h>
 -#endif
  #include <asm/proto.h>
  #include <asm/iommu.h>
  #include <asm/gart.h>
@@@ -1296,10 -1297,8 +1296,10 @@@ static void __unmap_single(struct amd_i
  /*
   * The exported map_single function for dma_ops.
   */
 -static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
 -                           size_t size, int dir)
 +static dma_addr_t map_page(struct device *dev, struct page *page,
 +                         unsigned long offset, size_t size,
 +                         enum dma_data_direction dir,
 +                         struct dma_attrs *attrs)
  {
        unsigned long flags;
        struct amd_iommu *iommu;
        u16 devid;
        dma_addr_t addr;
        u64 dma_mask;
 +      phys_addr_t paddr = page_to_phys(page) + offset;
  
        INC_STATS_COUNTER(cnt_map_single);
  
@@@ -1342,8 -1340,8 +1342,8 @@@ out
  /*
   * The exported unmap_single function for dma_ops.
   */
 -static void unmap_single(struct device *dev, dma_addr_t dma_addr,
 -                       size_t size, int dir)
 +static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
 +                     enum dma_data_direction dir, struct dma_attrs *attrs)
  {
        unsigned long flags;
        struct amd_iommu *iommu;
@@@ -1392,8 -1390,7 +1392,8 @@@ static int map_sg_no_iommu(struct devic
   * lists).
   */
  static int map_sg(struct device *dev, struct scatterlist *sglist,
 -                int nelems, int dir)
 +                int nelems, enum dma_data_direction dir,
 +                struct dma_attrs *attrs)
  {
        unsigned long flags;
        struct amd_iommu *iommu;
@@@ -1460,8 -1457,7 +1460,8 @@@ unmap
   * lists).
   */
  static void unmap_sg(struct device *dev, struct scatterlist *sglist,
 -                   int nelems, int dir)
 +                   int nelems, enum dma_data_direction dir,
 +                   struct dma_attrs *attrs)
  {
        unsigned long flags;
        struct amd_iommu *iommu;
@@@ -1648,11 -1644,11 +1648,11 @@@ static void prealloc_protection_domains
        }
  }
  
 -static struct dma_mapping_ops amd_iommu_dma_ops = {
 +static struct dma_map_ops amd_iommu_dma_ops = {
        .alloc_coherent = alloc_coherent,
        .free_coherent = free_coherent,
 -      .map_single = map_single,
 -      .unmap_single = unmap_single,
 +      .map_page = map_page,
 +      .unmap_page = unmap_page,
        .map_sg = map_sg,
        .unmap_sg = unmap_sg,
        .dma_supported = amd_iommu_dma_supported,
@@@ -1928,6 -1924,12 +1928,12 @@@ static phys_addr_t amd_iommu_iova_to_ph
        return paddr;
  }
  
+ static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
+                                   unsigned long cap)
+ {
+       return 0;
+ }
  static struct iommu_ops amd_iommu_ops = {
        .domain_init = amd_iommu_domain_init,
        .domain_destroy = amd_iommu_domain_destroy,
        .map = amd_iommu_map_range,
        .unmap = amd_iommu_unmap_range,
        .iova_to_phys = amd_iommu_iova_to_phys,
+       .domain_has_cap = amd_iommu_domain_has_cap,
  };
  
diff --combined drivers/base/iommu.c
index c2d1eed903767484304b1f3208c27719b5ec3195,c314f144825faf669d1f91281f072d7e4a7fa6c2..9f0e672f4be84ff35489b8f5e8724898ec3d9f12
@@@ -31,7 -31,7 +31,7 @@@ void register_iommu(struct iommu_ops *o
        iommu_ops = ops;
  }
  
 -bool iommu_found()
 +bool iommu_found(void)
  {
        return iommu_ops != NULL;
  }
@@@ -98,3 -98,10 +98,10 @@@ phys_addr_t iommu_iova_to_phys(struct i
        return iommu_ops->iova_to_phys(domain, iova);
  }
  EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+ int iommu_domain_has_cap(struct iommu_domain *domain,
+                        unsigned long cap)
+ {
+       return iommu_ops->domain_has_cap(domain, cap);
+ }
+ EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
index 9dbd5066acafee0594b7d20938822d6f7a3f3dbd,002c8b95edf8f75d5f70a99fb42ec4593693b5ff..23e56a564e05056a208ac41d98828d32987865b7
@@@ -164,7 -164,8 +164,8 @@@ static inline void context_clear_entry(
   * 1: writable
   * 2-6: reserved
   * 7: super page
-  * 8-11: available
+  * 8-10: available
+  * 11: snoop behavior
   * 12-63: Host physcial address
   */
  struct dma_pte {
@@@ -186,6 -187,11 +187,11 @@@ static inline void dma_set_pte_writable
        pte->val |= DMA_PTE_WRITE;
  }
  
+ static inline void dma_set_pte_snp(struct dma_pte *pte)
+ {
+       pte->val |= DMA_PTE_SNP;
+ }
  static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
  {
        pte->val = (pte->val & ~3) | (prot & 3);
@@@ -231,6 -237,7 +237,7 @@@ struct dmar_domain 
        int             flags;          /* flags to find out type of domain */
  
        int             iommu_coherency;/* indicate coherency of iommu access */
+       int             iommu_snooping; /* indicate snooping control feature*/
        int             iommu_count;    /* reference count of iommu */
        spinlock_t      iommu_lock;     /* protect iommu set in domain */
        u64             max_addr;       /* maximum mapped address */
@@@ -421,7 -428,6 +428,6 @@@ static struct intel_iommu *domain_get_i
        return g_iommus[iommu_id];
  }
  
- /* "Coherency" capability may be different across iommus */
  static void domain_update_iommu_coherency(struct dmar_domain *domain)
  {
        int i;
        }
  }
  
+ static void domain_update_iommu_snooping(struct dmar_domain *domain)
+ {
+       int i;
+       domain->iommu_snooping = 1;
+       i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+       for (; i < g_num_of_iommus; ) {
+               if (!ecap_sc_support(g_iommus[i]->ecap)) {
+                       domain->iommu_snooping = 0;
+                       break;
+               }
+               i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+       }
+ }
+ /* Some capabilities may be different across iommus */
+ static void domain_update_iommu_cap(struct dmar_domain *domain)
+ {
+       domain_update_iommu_coherency(domain);
+       domain_update_iommu_snooping(domain);
+ }
  static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
  {
        struct dmar_drhd_unit *drhd = NULL;
@@@ -689,15 -718,17 +718,17 @@@ static void dma_pte_clear_one(struct dm
  static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
  {
        int addr_width = agaw_to_width(domain->agaw);
+       int npages;
  
        start &= (((u64)1) << addr_width) - 1;
        end &= (((u64)1) << addr_width) - 1;
        /* in case it's partial page */
        start = PAGE_ALIGN(start);
        end &= PAGE_MASK;
+       npages = (end - start) / VTD_PAGE_SIZE;
  
        /* we don't need lock here, nobody else touches the iova range */
-       while (start < end) {
+       while (npages--) {
                dma_pte_clear_one(domain, start);
                start += VTD_PAGE_SIZE;
        }
@@@ -1004,6 -1035,194 +1035,6 @@@ static int iommu_disable_translation(st
        return 0;
  }
  
 -/* iommu interrupt handling. Most stuff are MSI-like. */
 -
 -static const char *fault_reason_strings[] =
 -{
 -      "Software",
 -      "Present bit in root entry is clear",
 -      "Present bit in context entry is clear",
 -      "Invalid context entry",
 -      "Access beyond MGAW",
 -      "PTE Write access is not set",
 -      "PTE Read access is not set",
 -      "Next page table ptr is invalid",
 -      "Root table address invalid",
 -      "Context table ptr is invalid",
 -      "non-zero reserved fields in RTP",
 -      "non-zero reserved fields in CTP",
 -      "non-zero reserved fields in PTE",
 -};
 -#define MAX_FAULT_REASON_IDX  (ARRAY_SIZE(fault_reason_strings) - 1)
 -
 -const char *dmar_get_fault_reason(u8 fault_reason)
 -{
 -      if (fault_reason > MAX_FAULT_REASON_IDX)
 -              return "Unknown";
 -      else
 -              return fault_reason_strings[fault_reason];
 -}
 -
 -void dmar_msi_unmask(unsigned int irq)
 -{
 -      struct intel_iommu *iommu = get_irq_data(irq);
 -      unsigned long flag;
 -
 -      /* unmask it */
 -      spin_lock_irqsave(&iommu->register_lock, flag);
 -      writel(0, iommu->reg + DMAR_FECTL_REG);
 -      /* Read a reg to force flush the post write */
 -      readl(iommu->reg + DMAR_FECTL_REG);
 -      spin_unlock_irqrestore(&iommu->register_lock, flag);
 -}
 -
 -void dmar_msi_mask(unsigned int irq)
 -{
 -      unsigned long flag;
 -      struct intel_iommu *iommu = get_irq_data(irq);
 -
 -      /* mask it */
 -      spin_lock_irqsave(&iommu->register_lock, flag);
 -      writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
 -      /* Read a reg to force flush the post write */
 -      readl(iommu->reg + DMAR_FECTL_REG);
 -      spin_unlock_irqrestore(&iommu->register_lock, flag);
 -}
 -
 -void dmar_msi_write(int irq, struct msi_msg *msg)
 -{
 -      struct intel_iommu *iommu = get_irq_data(irq);
 -      unsigned long flag;
 -
 -      spin_lock_irqsave(&iommu->register_lock, flag);
 -      writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
 -      writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
 -      writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
 -      spin_unlock_irqrestore(&iommu->register_lock, flag);
 -}
 -
 -void dmar_msi_read(int irq, struct msi_msg *msg)
 -{
 -      struct intel_iommu *iommu = get_irq_data(irq);
 -      unsigned long flag;
 -
 -      spin_lock_irqsave(&iommu->register_lock, flag);
 -      msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
 -      msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
 -      msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
 -      spin_unlock_irqrestore(&iommu->register_lock, flag);
 -}
 -
 -static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
 -              u8 fault_reason, u16 source_id, unsigned long long addr)
 -{
 -      const char *reason;
 -
 -      reason = dmar_get_fault_reason(fault_reason);
 -
 -      printk(KERN_ERR
 -              "DMAR:[%s] Request device [%02x:%02x.%d] "
 -              "fault addr %llx \n"
 -              "DMAR:[fault reason %02d] %s\n",
 -              (type ? "DMA Read" : "DMA Write"),
 -              (source_id >> 8), PCI_SLOT(source_id & 0xFF),
 -              PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
 -      return 0;
 -}
 -
 -#define PRIMARY_FAULT_REG_LEN (16)
 -static irqreturn_t iommu_page_fault(int irq, void *dev_id)
 -{
 -      struct intel_iommu *iommu = dev_id;
 -      int reg, fault_index;
 -      u32 fault_status;
 -      unsigned long flag;
 -
 -      spin_lock_irqsave(&iommu->register_lock, flag);
 -      fault_status = readl(iommu->reg + DMAR_FSTS_REG);
 -
 -      /* TBD: ignore advanced fault log currently */
 -      if (!(fault_status & DMA_FSTS_PPF))
 -              goto clear_overflow;
 -
 -      fault_index = dma_fsts_fault_record_index(fault_status);
 -      reg = cap_fault_reg_offset(iommu->cap);
 -      while (1) {
 -              u8 fault_reason;
 -              u16 source_id;
 -              u64 guest_addr;
 -              int type;
 -              u32 data;
 -
 -              /* highest 32 bits */
 -              data = readl(iommu->reg + reg +
 -                              fault_index * PRIMARY_FAULT_REG_LEN + 12);
 -              if (!(data & DMA_FRCD_F))
 -                      break;
 -
 -              fault_reason = dma_frcd_fault_reason(data);
 -              type = dma_frcd_type(data);
 -
 -              data = readl(iommu->reg + reg +
 -                              fault_index * PRIMARY_FAULT_REG_LEN + 8);
 -              source_id = dma_frcd_source_id(data);
 -
 -              guest_addr = dmar_readq(iommu->reg + reg +
 -                              fault_index * PRIMARY_FAULT_REG_LEN);
 -              guest_addr = dma_frcd_page_addr(guest_addr);
 -              /* clear the fault */
 -              writel(DMA_FRCD_F, iommu->reg + reg +
 -                      fault_index * PRIMARY_FAULT_REG_LEN + 12);
 -
 -              spin_unlock_irqrestore(&iommu->register_lock, flag);
 -
 -              iommu_page_fault_do_one(iommu, type, fault_reason,
 -                              source_id, guest_addr);
 -
 -              fault_index++;
 -              if (fault_index > cap_num_fault_regs(iommu->cap))
 -                      fault_index = 0;
 -              spin_lock_irqsave(&iommu->register_lock, flag);
 -      }
 -clear_overflow:
 -      /* clear primary fault overflow */
 -      fault_status = readl(iommu->reg + DMAR_FSTS_REG);
 -      if (fault_status & DMA_FSTS_PFO)
 -              writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
 -
 -      spin_unlock_irqrestore(&iommu->register_lock, flag);
 -      return IRQ_HANDLED;
 -}
 -
 -int dmar_set_interrupt(struct intel_iommu *iommu)
 -{
 -      int irq, ret;
 -
 -      irq = create_irq();
 -      if (!irq) {
 -              printk(KERN_ERR "IOMMU: no free vectors\n");
 -              return -EINVAL;
 -      }
 -
 -      set_irq_data(irq, iommu);
 -      iommu->irq = irq;
 -
 -      ret = arch_setup_dmar_msi(irq);
 -      if (ret) {
 -              set_irq_data(irq, NULL);
 -              iommu->irq = 0;
 -              destroy_irq(irq);
 -              return 0;
 -      }
 -
 -      /* Force fault register is cleared */
 -      iommu_page_fault(irq, iommu);
 -
 -      ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
 -      if (ret)
 -              printk(KERN_ERR "IOMMU: can't request irq\n");
 -      return ret;
 -}
  
  static int iommu_init_domains(struct intel_iommu *iommu)
  {
@@@ -1241,6 -1460,11 +1272,11 @@@ static int domain_init(struct dmar_doma
        else
                domain->iommu_coherency = 0;
  
+       if (ecap_sc_support(iommu->ecap))
+               domain->iommu_snooping = 1;
+       else
+               domain->iommu_snooping = 0;
        domain->iommu_count = 1;
  
        /* always allocate the top pgd */
@@@ -1369,7 -1593,7 +1405,7 @@@ static int domain_context_mapping_one(s
        spin_lock_irqsave(&domain->iommu_lock, flags);
        if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
                domain->iommu_count++;
-               domain_update_iommu_coherency(domain);
+               domain_update_iommu_cap(domain);
        }
        spin_unlock_irqrestore(&domain->iommu_lock, flags);
        return 0;
@@@ -1469,6 -1693,8 +1505,8 @@@ domain_page_mapping(struct dmar_domain 
                BUG_ON(dma_pte_addr(pte));
                dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
                dma_set_pte_prot(pte, prot);
+               if (prot & DMA_PTE_SNP)
+                       dma_set_pte_snp(pte);
                domain_flush_cache(domain, pte, sizeof(*pte));
                start_pfn++;
                index++;
@@@ -1782,7 -2008,7 +1820,7 @@@ static inline void iommu_prepare_isa(vo
        ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
  
        if (ret)
 -              printk("IOMMU: Failed to create 0-64M identity map, "
 +              printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
                        "floppy might not work\n");
  
  }
@@@ -1799,7 -2025,7 +1837,7 @@@ static int __init init_dmars(void
        struct dmar_rmrr_unit *rmrr;
        struct pci_dev *pdev;
        struct intel_iommu *iommu;
 -      int i, ret, unit = 0;
 +      int i, ret;
  
        /*
         * for each drhd
                }
        }
  
 +      /*
 +       * Start from the sane iommu hardware state.
 +       */
        for_each_drhd_unit(drhd) {
                if (drhd->ignored)
                        continue;
  
                iommu = drhd->iommu;
 +
 +              /*
 +               * If the queued invalidation is already initialized by us
 +               * (for example, while enabling interrupt-remapping) then
 +               * we got the things already rolling from a sane state.
 +               */
 +              if (iommu->qi)
 +                      continue;
 +
 +              /*
 +               * Clear any previous faults.
 +               */
 +              dmar_fault(-1, iommu);
 +              /*
 +               * Disable queued invalidation if supported and already enabled
 +               * before OS handover.
 +               */
 +              dmar_disable_qi(iommu);
 +      }
 +
 +      for_each_drhd_unit(drhd) {
 +              if (drhd->ignored)
 +                      continue;
 +
 +              iommu = drhd->iommu;
 +
                if (dmar_enable_qi(iommu)) {
                        /*
                         * Queued Invalidate not enabled, use Register Based
                if (drhd->ignored)
                        continue;
                iommu = drhd->iommu;
 -              sprintf (iommu->name, "dmar%d", unit++);
  
                iommu_flush_write_buffer(iommu);
  
@@@ -2119,18 -2317,16 +2157,18 @@@ static dma_addr_t __intel_map_single(st
  error:
        if (iova)
                __free_iova(&domain->iovad, iova);
-       printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+       printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
                pci_name(pdev), size, (unsigned long long)paddr, dir);
        return 0;
  }
  
 -dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr,
 -                          size_t size, int dir)
 +static dma_addr_t intel_map_page(struct device *dev, struct page *page,
 +                               unsigned long offset, size_t size,
 +                               enum dma_data_direction dir,
 +                               struct dma_attrs *attrs)
  {
 -      return __intel_map_single(hwdev, paddr, size, dir,
 -                                to_pci_dev(hwdev)->dma_mask);
 +      return __intel_map_single(dev, page_to_phys(page) + offset, size,
 +                                dir, to_pci_dev(dev)->dma_mask);
  }
  
  static void flush_unmaps(void)
@@@ -2194,9 -2390,8 +2232,9 @@@ static void add_unmap(struct dmar_domai
        spin_unlock_irqrestore(&async_umap_flush_lock, flags);
  }
  
 -void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
 -                      int dir)
 +static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
 +                           size_t size, enum dma_data_direction dir,
 +                           struct dma_attrs *attrs)
  {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct dmar_domain *domain;
        start_addr = iova->pfn_lo << PAGE_SHIFT;
        size = aligned_size((u64)dev_addr, size);
  
-       pr_debug("Device %s unmapping: %lx@%llx\n",
+       pr_debug("Device %s unmapping: %zx@%llx\n",
                pci_name(pdev), size, (unsigned long long)start_addr);
  
        /*  clear the whole page */
        }
  }
  
 -void *intel_alloc_coherent(struct device *hwdev, size_t size,
 -                         dma_addr_t *dma_handle, gfp_t flags)
 +static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
 +                             int dir)
 +{
 +      intel_unmap_page(dev, dev_addr, size, dir, NULL);
 +}
 +
 +static void *intel_alloc_coherent(struct device *hwdev, size_t size,
 +                                dma_addr_t *dma_handle, gfp_t flags)
  {
        void *vaddr;
        int order;
        return NULL;
  }
  
 -void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 -                       dma_addr_t dma_handle)
 +static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 +                              dma_addr_t dma_handle)
  {
        int order;
  
        free_pages((unsigned long)vaddr, order);
  }
  
- #define SG_ENT_VIRT_ADDRESS(sg)       (sg_virt((sg)))
 -void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
 -                  int nelems, int dir)
 +static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
 +                         int nelems, enum dma_data_direction dir,
 +                         struct dma_attrs *attrs)
  {
        int i;
        struct pci_dev *pdev = to_pci_dev(hwdev);
        unsigned long start_addr;
        struct iova *iova;
        size_t size = 0;
-       void *addr;
+       phys_addr_t addr;
        struct scatterlist *sg;
        struct intel_iommu *iommu;
  
        if (!iova)
                return;
        for_each_sg(sglist, sg, nelems, i) {
-               addr = SG_ENT_VIRT_ADDRESS(sg);
+               addr = page_to_phys(sg_page(sg)) + sg->offset;
                size += aligned_size((u64)addr, sg->length);
        }
  
@@@ -2337,16 -2523,16 +2373,16 @@@ static int intel_nontranslate_map_sg(st
  
        for_each_sg(sglist, sg, nelems, i) {
                BUG_ON(!sg_page(sg));
-               sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+               sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
                sg->dma_length = sg->length;
        }
        return nelems;
  }
  
 -int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
 -               int dir)
 +static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
 +                      enum dma_data_direction dir, struct dma_attrs *attrs)
  {
-       void *addr;
+       phys_addr_t addr;
        int i;
        struct pci_dev *pdev = to_pci_dev(hwdev);
        struct dmar_domain *domain;
        iommu = domain_get_iommu(domain);
  
        for_each_sg(sglist, sg, nelems, i) {
-               addr = SG_ENT_VIRT_ADDRESS(sg);
-               addr = (void *)virt_to_phys(addr);
+               addr = page_to_phys(sg_page(sg)) + sg->offset;
                size += aligned_size((u64)addr, sg->length);
        }
  
        start_addr = iova->pfn_lo << PAGE_SHIFT;
        offset = 0;
        for_each_sg(sglist, sg, nelems, i) {
-               addr = SG_ENT_VIRT_ADDRESS(sg);
-               addr = (void *)virt_to_phys(addr);
+               addr = page_to_phys(sg_page(sg)) + sg->offset;
                size = aligned_size((u64)addr, sg->length);
                ret = domain_page_mapping(domain, start_addr + offset,
                        ((u64)addr) & PAGE_MASK,
        return nelems;
  }
  
 -static struct dma_mapping_ops intel_dma_ops = {
 +static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
 +{
 +      return !dma_addr;
 +}
 +
 +struct dma_map_ops intel_dma_ops = {
        .alloc_coherent = intel_alloc_coherent,
        .free_coherent = intel_free_coherent,
 -      .map_single = intel_map_single,
 -      .unmap_single = intel_unmap_single,
        .map_sg = intel_map_sg,
        .unmap_sg = intel_unmap_sg,
 +      .map_page = intel_map_page,
 +      .unmap_page = intel_unmap_page,
 +      .mapping_error = intel_mapping_error,
  };
  
  static inline int iommu_domain_cache_init(void)
@@@ -2628,6 -2806,33 +2662,33 @@@ static int vm_domain_add_dev_info(struc
        return 0;
  }
  
+ static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+                                          struct pci_dev *pdev)
+ {
+       struct pci_dev *tmp, *parent;
+       if (!iommu || !pdev)
+               return;
+       /* dependent device detach */
+       tmp = pci_find_upstream_pcie_bridge(pdev);
+       /* Secondary interface's bus number and devfn 0 */
+       if (tmp) {
+               parent = pdev->bus->self;
+               while (parent != tmp) {
+                       iommu_detach_dev(iommu, parent->bus->number,
+                               parent->devfn);
+                       parent = parent->bus->self;
+               }
+               if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+                       iommu_detach_dev(iommu,
+                               tmp->subordinate->number, 0);
+               else /* this is a legacy PCI bridge */
+                       iommu_detach_dev(iommu,
+                               tmp->bus->number, tmp->devfn);
+       }
+ }
  static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
                                          struct pci_dev *pdev)
  {
                        spin_unlock_irqrestore(&device_domain_lock, flags);
  
                        iommu_detach_dev(iommu, info->bus, info->devfn);
+                       iommu_detach_dependent_devices(iommu, pdev);
                        free_devinfo_mem(info);
  
                        spin_lock_irqsave(&device_domain_lock, flags);
                spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
                clear_bit(iommu->seq_id, &domain->iommu_bmp);
                domain->iommu_count--;
-               domain_update_iommu_coherency(domain);
+               domain_update_iommu_cap(domain);
                spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
        }
  
@@@ -2702,15 -2908,16 +2764,16 @@@ static void vm_domain_remove_all_dev_in
  
                iommu = device_to_iommu(info->bus, info->devfn);
                iommu_detach_dev(iommu, info->bus, info->devfn);
+               iommu_detach_dependent_devices(iommu, info->dev);
  
                /* clear this iommu in iommu_bmp, update iommu count
-                * and coherency
+                * and capabilities
                 */
                spin_lock_irqsave(&domain->iommu_lock, flags2);
                if (test_and_clear_bit(iommu->seq_id,
                                       &domain->iommu_bmp)) {
                        domain->iommu_count--;
-                       domain_update_iommu_coherency(domain);
+                       domain_update_iommu_cap(domain);
                }
                spin_unlock_irqrestore(&domain->iommu_lock, flags2);
  
@@@ -2933,6 -3140,8 +2996,8 @@@ static int intel_iommu_map_range(struc
                prot |= DMA_PTE_READ;
        if (iommu_prot & IOMMU_WRITE)
                prot |= DMA_PTE_WRITE;
+       if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+               prot |= DMA_PTE_SNP;
  
        max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
        if (dmar_domain->max_addr < max_addr) {
@@@ -2986,6 -3195,17 +3051,17 @@@ static phys_addr_t intel_iommu_iova_to_
        return phys;
  }
  
+ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+                                     unsigned long cap)
+ {
+       struct dmar_domain *dmar_domain = domain->priv;
+       if (cap == IOMMU_CAP_CACHE_COHERENCY)
+               return dmar_domain->iommu_snooping;
+       return 0;
+ }
  static struct iommu_ops intel_iommu_ops = {
        .domain_init    = intel_iommu_domain_init,
        .domain_destroy = intel_iommu_domain_destroy,
        .map            = intel_iommu_map_range,
        .unmap          = intel_iommu_unmap_range,
        .iova_to_phys   = intel_iommu_iova_to_phys,
+       .domain_has_cap = intel_iommu_domain_has_cap,
  };
  
  static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
index 1d6c71d96edeac0d730fb178e91120bebe695300,3ad89400493816286998f05267cda312bbca17ce..77214ead1a36343ee4267647c00fd9bd9e3d28c8
@@@ -123,7 -123,7 +123,7 @@@ static inline void dmar_writeq(void __i
  #define ecap_eim_support(e)   ((e >> 4) & 0x1)
  #define ecap_ir_support(e)    ((e >> 3) & 0x1)
  #define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
+ #define ecap_sc_support(e)    ((e >> 7) & 0x1) /* Snooping Control */
  
  /* IOTLB_REG */
  #define DMA_TLB_FLUSH_GRANU_OFFSET  60
@@@ -292,8 -292,6 +292,8 @@@ struct intel_iommu 
        spinlock_t      register_lock; /* protect register handling */
        int             seq_id; /* sequence id of the iommu */
        int             agaw; /* agaw of this iommu */
 +      unsigned int    irq;
 +      unsigned char   name[13];    /* Device Name */
  
  #ifdef CONFIG_DMAR
        unsigned long   *domain_ids; /* bitmap of domains */
        spinlock_t      lock; /* protect context, domain ids */
        struct root_entry *root_entry; /* virtual address */
  
 -      unsigned int irq;
 -      unsigned char name[7];    /* Device Name */
        struct iommu_flush flush;
  #endif
        struct q_inval  *qi;            /* Queued invalidation info */
@@@ -321,7 -321,6 +321,7 @@@ extern struct dmar_drhd_unit * dmar_fin
  extern int alloc_iommu(struct dmar_drhd_unit *drhd);
  extern void free_iommu(struct intel_iommu *iommu);
  extern int dmar_enable_qi(struct intel_iommu *iommu);
 +extern void dmar_disable_qi(struct intel_iommu *iommu);
  extern void qi_global_iec(struct intel_iommu *iommu);
  
  extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
@@@ -332,4 -331,11 +332,4 @@@ extern int qi_flush_iotlb(struct intel_
  
  extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
  
 -extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
 -extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t);
 -extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int);
 -extern void intel_unmap_single(struct device *, dma_addr_t, size_t, int);
 -extern int intel_map_sg(struct device *, struct scatterlist *, int, int);
 -extern void intel_unmap_sg(struct device *, struct scatterlist *, int, int);
 -
  #endif