]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branches 'x86/vt-d', 'arm/omap', 'arm/smmu', 's390', 'core' and 'x86/amd' into...
authorJoerg Roedel <jroedel@suse.de>
Mon, 2 Nov 2015 11:03:34 +0000 (20:03 +0900)
committerJoerg Roedel <jroedel@suse.de>
Mon, 2 Nov 2015 11:03:34 +0000 (20:03 +0900)
Conflicts:
drivers/iommu/amd_iommu_types.h

1  2  3  4  5  6  7 
MAINTAINERS
drivers/iommu/Kconfig
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_types.h
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/intel-iommu.c

diff --combined MAINTAINERS
index 747c65316167a70ec147d1254dc33afe7708c149,9f6685f6c5a97062e7d44d04493afe518fa27ab8,5f467845ef725f42cca522e9f02bf93292c42d4a,5f467845ef725f42cca522e9f02bf93292c42d4a,8dfe79589681336988785817aa40b12acbbeaff0,5f467845ef725f42cca522e9f02bf93292c42d4a,274f85405584e1249c8b089b789f1a4d11973500..4a63bebf9e0fdebe5021475c83c79a0faa8c0e82
@@@@@@@@ -615,8 -615,8 -615,8 -615,8 -615,8 -615,8 -615,9 +615,8 @@@@@@@@ F:    Documentation/hwmon/fam15h_powe
       F:       drivers/hwmon/fam15h_power.c
       
       AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
      -M:       Thomas Dahlmann <dahlmann.thomas@arcor.de>
       L:       linux-geode@lists.infradead.org (moderated for non-subscribers)
      -S:       Supported
      +S:       Orphan
       F:       drivers/usb/gadget/udc/amd5536udc.*
       
       AMD GEODE PROCESSOR/CHIPSET SUPPORT
@@@@@@@@ -807,13 -807,13 -807,13 -807,13 -807,13 -807,13 -808,6 +807,13 @@@@@@@@ S:     Maintaine
       F:       drivers/video/fbdev/arcfb.c
       F:       drivers/video/fbdev/core/fb_defio.c
       
      +ARCNET NETWORK LAYER
      +M:       Michael Grzeschik <m.grzeschik@pengutronix.de>
      +L:       netdev@vger.kernel.org
      +S:       Maintained
      +F:       drivers/net/arcnet/
      +F:       include/uapi/linux/if_arcnet.h
      +
       ARM MFM AND FLOPPY DRIVERS
       M:       Ian Molton <spyro@f2s.com>
       S:       Maintained
@@@@@@@@ -894,12 -894,11 -894,11 -894,11 -894,11 -894,11 -888,11 +894,12 @@@@@@@@ M:    Lennert Buytenhek <kernel@wantstofly
       L:       linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
       S:       Maintained
       
 ------ARM/Allwinner A1X SoC support
 ++++++ARM/Allwinner sunXi SoC support
       M:       Maxime Ripard <maxime.ripard@free-electrons.com>
 ++++++M:       Chen-Yu Tsai <wens@csie.org>
       L:       linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
       S:       Maintained
 ------N:       sun[x4567]i
 ++++++N:       sun[x456789]i
       
       ARM/Allwinner SoC Clock Support
       M:       Emilio López <emilio@elopez.com.ar>
@@@@@@@@ -3401,6 -3400,6 -3400,6 -3400,6 -3400,6 -3400,6 -3394,7 +3401,6 @@@@@@@@ F:    drivers/staging/dgnc
       
       DIGI EPCA PCI PRODUCTS
       M:       Lidza Louina <lidza.louina@gmail.com>
      -M:       Mark Hounschell <markh@compro.net>
       M:       Daeseok Youn <daeseok.youn@gmail.com>
       L:       driverdev-devel@linuxdriverproject.org
       S:       Maintained
@@@@@@@@ -3592,13 -3591,6 -3591,6 -3591,6 -3591,6 -3591,6 -3586,6 +3592,13 @@@@@@@@ F:  drivers/gpu/drm/i915
       F:       include/drm/i915*
       F:       include/uapi/drm/i915*
       
 ++++++DRM DRIVERS FOR ATMEL HLCDC
 ++++++M:       Boris Brezillon <boris.brezillon@free-electrons.com>
 ++++++L:       dri-devel@lists.freedesktop.org
 ++++++S:       Supported
 ++++++F:       drivers/gpu/drm/atmel-hlcdc/
 ++++++F:       Documentation/devicetree/bindings/drm/atmel/
 ++++++
       DRM DRIVERS FOR EXYNOS
       M:       Inki Dae <inki.dae@samsung.com>
       M:       Joonyoung Shim <jy0922.shim@samsung.com>
@@@@@@@@ -3627,14 -3619,6 -3619,6 -3619,6 -3619,6 -3619,6 -3614,6 +3627,14 @@@@@@@@ S:  Maintaine
       F:       drivers/gpu/drm/imx/
       F:       Documentation/devicetree/bindings/drm/imx/
       
 ++++++DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
 ++++++M:       Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
 ++++++L:       dri-devel@lists.freedesktop.org
 ++++++T:       git git://github.com/patjak/drm-gma500
 ++++++S:       Maintained
 ++++++F:       drivers/gpu/drm/gma500
 ++++++F:       include/drm/gma500*
 ++++++
       DRM DRIVERS FOR NVIDIA TEGRA
       M:       Thierry Reding <thierry.reding@gmail.com>
       M:       Terje Bergström <tbergstrom@nvidia.com>
@@@@@@@@ -4019,7 -4003,7 -4003,7 -4003,7 -4003,7 -4003,7 -3998,7 +4019,7 @@@@@@@@ S:    Maintaine
       F:       sound/usb/misc/ua101.c
       
       EXTENSIBLE FIRMWARE INTERFACE (EFI)
 -  - -M:       Matt Fleming <matt.fleming@intel.com>
 +  + +M:       Matt Fleming <matt@codeblueprint.co.uk>
       L:       linux-efi@vger.kernel.org
       T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
       S:       Maintained
@@@@@@@@ -4034,7 -4018,7 -4018,7 -4018,7 -4018,7 -4018,7 -4013,7 +4034,7 @@@@@@@@ F:    include/linux/efi*.
       EFI VARIABLE FILESYSTEM
       M:       Matthew Garrett <matthew.garrett@nebula.com>
       M:       Jeremy Kerr <jk@ozlabs.org>
 -  - -M:       Matt Fleming <matt.fleming@intel.com>
 +  + +M:       Matt Fleming <matt@codeblueprint.co.uk>
       T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
       L:       linux-efi@vger.kernel.org
       S:       Maintained
@@@@@@@@ -4428,14 -4412,6 -4412,6 -4412,6 -4412,6 -4412,6 -4407,6 +4428,14 @@@@@@@@ L:  linuxppc-dev@lists.ozlabs.or
       S:       Maintained
       F:       drivers/net/ethernet/freescale/ucc_geth*
       
 ++++++FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
 ++++++M:       Claudiu Manoil <claudiu.manoil@freescale.com>
 ++++++L:       netdev@vger.kernel.org
 ++++++S:       Maintained
 ++++++F:       drivers/net/ethernet/freescale/gianfar*
 ++++++X:       drivers/net/ethernet/freescale/gianfar_ptp.c
 ++++++F:       Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
 ++++++
       FREESCALE QUICC ENGINE UCC UART DRIVER
       M:       Timur Tabi <timur@tabi.org>
       L:       linuxppc-dev@lists.ozlabs.org
@@@@@@@@ -5981,7 -5957,7 -5957,7 -5957,7 -5957,7 -5957,7 -5952,7 +5981,7 @@@@@@@@ F:    virt/kvm
       KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
       M:       Joerg Roedel <joro@8bytes.org>
       L:       kvm@vger.kernel.org
 -    -W:       http://kvm.qumranet.com
 +    +W:       http://www.linux-kvm.org/
       S:       Maintained
       F:       arch/x86/include/asm/svm.h
       F:       arch/x86/kvm/svm.c
       KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
       M:       Alexander Graf <agraf@suse.com>
       L:       kvm-ppc@vger.kernel.org
 -    -W:       http://kvm.qumranet.com
 +    +W:       http://www.linux-kvm.org/
       T:       git git://github.com/agraf/linux-2.6.git
       S:       Supported
       F:       arch/powerpc/include/asm/kvm*
@@@@@@@@ -6802,6 -6778,7 -6778,7 -6778,7 -6778,7 -6778,7 -6773,7 +6802,6 @@@@@@@@ F:    drivers/scsi/megaraid
       
       MELLANOX ETHERNET DRIVER (mlx4_en)
       M:       Amir Vadai <amirv@mellanox.com>
 ------M:       Ido Shamay <idos@mellanox.com>
       L:       netdev@vger.kernel.org
       S:       Supported
       W:       http://www.mellanox.com
@@@@@@@@ -8528,6 -8505,6 -8505,6 -8505,6 -8505,6 -8505,6 -8500,7 +8528,6 @@@@@@@@ F:    Documentation/networking/LICENSE.qla
       F:       drivers/net/ethernet/qlogic/qla3xxx.*
       
       QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
      -M:       Shahed Shaikh <shahed.shaikh@qlogic.com>
       M:       Dept-GELinuxNICDev@qlogic.com
       L:       netdev@vger.kernel.org
       S:       Supported
@@@@@@@@ -8966,6 -8943,6 -8943,6 -8943,6 -8943,13 -8943,6 -8939,6 +8966,13 @@@@@@@@ F:  drivers/s390/net/*iucv
       F:       include/net/iucv/
       F:       net/iucv/
       
++++ ++S390 IOMMU (PCI)
++++ ++M:       Gerald Schaefer <gerald.schaefer@de.ibm.com>
++++ ++L:       linux-s390@vger.kernel.org
++++ ++W:       http://www.ibm.com/developerworks/linux/linux390/
++++ ++S:       Supported
++++ ++F:       drivers/iommu/s390-iommu.c
++++ ++
       S3C24XX SD/MMC Driver
       M:       Ben Dooks <ben-linux@fluff.org>
       L:       linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@@@@@@ -9124,15 -9101,6 -9101,6 -9101,6 -9108,6 -9101,6 -9097,6 +9131,15 @@@@@@@@ S: Supporte
       F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
       F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
       
 ++++++SYNOPSYS DESIGNWARE I2C DRIVER
 ++++++M:       Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 ++++++M:       Jarkko Nikula <jarkko.nikula@linux.intel.com>
 ++++++M:       Mika Westerberg <mika.westerberg@linux.intel.com>
 ++++++L:       linux-i2c@vger.kernel.org
 ++++++S:       Maintained
 ++++++F:       drivers/i2c/busses/i2c-designware-*
 ++++++F:       include/linux/platform_data/i2c-designware.h
 ++++++
       SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
       M:       Seungwon Jeon <tgih.jun@samsung.com>
       M:       Jaehoon Chung <jh80.chung@samsung.com>
@@@@@@@@ -9940,12 -9908,13 -9908,12 -9908,12 -9915,13 -9908,12 -9904,13 +9947,12 @@@@@@@@ F:    drivers/staging/media/lirc
       STAGING - LUSTRE PARALLEL FILESYSTEM
       M:       Oleg Drokin <oleg.drokin@intel.com>
       M:       Andreas Dilger <andreas.dilger@intel.com>
      -L:       HPDD-discuss@lists.01.org (moderated for non-subscribers)
      -W:       http://lustre.opensfs.org/
      +L:       lustre-devel@lists.lustre.org (moderated for non-subscribers)
      +W:       http://wiki.lustre.org/
       S:       Maintained
       F:       drivers/staging/lustre
       
       STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
 -  - -M:       Julian Andres Klode <jak@jak-linux.org>
       M:       Marc Dietrich <marvin24@gmx.de>
       L:       ac100@lists.launchpad.net (moderated for non-subscribers)
       L:       linux-tegra@vger.kernel.org
@@@@@@@@ -10373,16 -10342,16 -10341,16 -10341,16 -10349,16 -10341,16 -10338,6 +10380,16 @@@@@@@@ F:     include/uapi/linux/thermal.
       F:       include/linux/cpu_cooling.h
       F:       Documentation/devicetree/bindings/thermal/
       
      +THERMAL/CPU_COOLING
      +M:       Amit Daniel Kachhap <amit.kachhap@gmail.com>
      +M:       Viresh Kumar <viresh.kumar@linaro.org>
      +M:       Javi Merino <javi.merino@arm.com>
      +L:       linux-pm@vger.kernel.org
      +S:       Supported
      +F:       Documentation/thermal/cpu-cooling-api.txt
      +F:       drivers/thermal/cpu_cooling.c
      +F:       include/linux/cpu_cooling.h
      +
       THINGM BLINK(1) USB RGB LED DRIVER
       M:       Vivien Didelot <vivien.didelot@savoirfairelinux.com>
       S:       Maintained
@@@@@@@@ -11232,7 -11201,7 -11200,7 -11200,7 -11208,7 -11200,7 -11187,7 +11239,7 @@@@@@@@ F:    drivers/vlynq/vlynq.
       F:       include/linux/vlynq.h
       
       VME SUBSYSTEM
      -M:       Martyn Welch <martyn.welch@ge.com>
      +M:       Martyn Welch <martyn@welchs.me.uk>
       M:       Manohar Vanga <manohar.vanga@gmail.com>
       M:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
       L:       devel@driverdev.osuosl.org
@@@@@@@@ -11284,6 -11253,6 -11252,6 -11252,6 -11260,6 -11252,6 -11239,7 +11291,6 @@@@@@@@ VOLTAGE AND CURRENT REGULATOR FRAMEWOR
       M:       Liam Girdwood <lgirdwood@gmail.com>
       M:       Mark Brown <broonie@kernel.org>
       L:       linux-kernel@vger.kernel.org
      -W:       http://opensource.wolfsonmicro.com/node/15
       W:       http://www.slimlogic.co.uk/?p=48
       T:       git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
       S:       Supported
@@@@@@@@ -11297,7 -11266,7 -11265,7 -11265,7 -11273,7 -11265,7 -11253,6 +11304,7 @@@@@@@@ L:    netdev@vger.kernel.or
       S:       Maintained
       F:       drivers/net/vrf.c
       F:       include/net/vrf.h
      +F:       Documentation/networking/vrf.txt
       
       VT1211 HARDWARE MONITOR DRIVER
       M:       Juerg Haefliger <juergh@gmail.com>
@@@@@@@@ -11409,10 -11378,19 -11377,10 -11377,10 -11385,19 -11377,10 -11364,21 +11416,10 @@@@@@@@ W:    http://oops.ghostprotocols.net:81/bl
       S:       Maintained
       F:       drivers/net/wireless/wl3501*
       
 -  - -WM97XX TOUCHSCREEN DRIVERS
 -  - -M:       Mark Brown <broonie@kernel.org>
 -  - -M:       Liam Girdwood <lrg@slimlogic.co.uk>
 -  - -L:       linux-input@vger.kernel.org
 -  -  W:       https://github.com/CirrusLogic/linux-drivers/wiki
      -T:       git git://opensource.wolfsonmicro.com/linux-2.6-touch
      -W:       http://opensource.wolfsonmicro.com/node/7
 -  - -S:       Supported
 -  - -F:       drivers/input/touchscreen/*wm97*
 -  - -F:       include/linux/wm97xx.h
 -  - -
       WOLFSON MICROELECTRONICS DRIVERS
       L:       patches@opensource.wolfsonmicro.com
      -T:       git git://opensource.wolfsonmicro.com/linux-2.6-asoc
      -T:       git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
      -W:       http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
      +T:       git https://github.com/CirrusLogic/linux-drivers.git
      +W:       https://github.com/CirrusLogic/linux-drivers/wiki
       S:       Supported
       F:       Documentation/hwmon/wm83??
       F:       arch/arm/mach-s3c64xx/mach-crag6410*
@@@@@@@@ -11683,7 -11661,6 -11651,6 -11651,6 -11668,6 -11651,6 -11649,6 +11690,7 @@@@@@@@ F:    drivers/tty/serial/zs.
       ZSMALLOC COMPRESSED SLAB MEMORY ALLOCATOR
       M:       Minchan Kim <minchan@kernel.org>
       M:       Nitin Gupta <ngupta@vflare.org>
 ++++++R:       Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
       L:       linux-mm@kvack.org
       S:       Maintained
       F:       mm/zsmalloc.c
diff --combined drivers/iommu/Kconfig
index cbe6a890a93a0d1448f46e32edbfdc5231ba7098,4664c2a96c67fee361c3476ddc8f9a8e8842d271,d9da766719c863327d4a8563804994c3edfd01c0,cc2dfa572d07c2400bf8c820805a41dc0885b363,5feb70a91a8c1f9e16062defa1b8059e608e160d,7414f33acfbadebd000444e7e955cbf7049c0054,4664c2a96c67fee361c3476ddc8f9a8e8842d271..4d3385bc9112784a32bac6336df4c98684b5480f
@@@@@@@@ -23,7 -23,8 -23,8 -23,8 -23,8 -23,8 -23,8 +23,7 @@@@@@@@ config IOMMU_IO_PGTABL
       config IOMMU_IO_PGTABLE_LPAE
        bool "ARMv7/v8 Long Descriptor Format"
        select IOMMU_IO_PGTABLE
 ------ # SWIOTLB guarantees a dma_to_phys() implementation
 ------ depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
 ++++++ depends on HAS_DMA && (ARM || ARM64 || COMPILE_TEST)
        help
          Enable support for the ARM long descriptor pagetable format.
          This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
@@@@@@@@ -42,12 -43,12 -43,12 -43,12 -43,12 -43,19 -43,12 +42,19 @@@@@@@@ config IOMMU_IO_PGTABLE_LPAE_SELFTES
       endmenu
       
       config IOMMU_IOVA
 -    - bool
 +    + tristate
       
       config OF_IOMMU
              def_bool y
              depends on OF && IOMMU_API
       
+++++ +# IOMMU-agnostic DMA-mapping layer
+++++ +config IOMMU_DMA
+++++ + bool
+++++ + depends on NEED_SG_DMA_LENGTH
+++++ + select IOMMU_API
+++++ + select IOMMU_IOVA
+++++ +
       config FSL_PAMU
        bool "Freescale IOMMU support"
        depends on PPC32
@@@@@@@@ -361,6 -362,6 -362,6 -362,7 -362,6 -369,6 -362,6 +368,7 @@@@@@@@ config ARM_SMMU_V
        depends on ARM64 && PCI
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
+++ +++ select GENERIC_MSI_IRQ_DOMAIN
        help
          Support for implementations of the ARM System MMU architecture
          version 3 providing translation support to a PCIe root complex.
          Say Y here if your system includes an IOMMU device implementing
          the ARM SMMUv3 architecture.
       
++++ ++config S390_IOMMU
++++ ++ def_bool y if S390 && PCI
++++ ++ depends on S390 && PCI
++++ ++ select IOMMU_API
++++ ++ help
++++ ++   Support for the IOMMU API for s390 PCI devices.
++++ ++
       endif # IOMMU_SUPPORT
diff --combined drivers/iommu/Makefile
index c6dcc513d711299b41a6b1f926abbc4f6e3b9286,c6dcc513d711299b41a6b1f926abbc4f6e3b9286,c6dcc513d711299b41a6b1f926abbc4f6e3b9286,c6dcc513d711299b41a6b1f926abbc4f6e3b9286,a2056d35420b5db173bca1be4b4464fbcc551dda,f465cfbdb18378c0ca80fc654fa6f7bb2c093919,c6dcc513d711299b41a6b1f926abbc4f6e3b9286..2393d86f04da9b224a5cd7c35e8ec88b57f933c1
@@@@@@@@ -1,6 -1,6 -1,6 -1,6 -1,6 -1,7 -1,6 +1,7 @@@@@@@@
       obj-$(CONFIG_IOMMU_API) += iommu.o
       obj-$(CONFIG_IOMMU_API) += iommu-traces.o
       obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+++++ +obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
       obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
       obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
       obj-$(CONFIG_IOMMU_IOVA) += iova.o
@@@@@@@@ -23,3 -23,3 -23,3 -23,3 -23,4 -24,3 -23,3 +24,4 @@@@@@@@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-io
       obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o
       obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o
       obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
++++ ++obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
index 532e2a211fe1cf9b3d7ff71d36cbcfde49bd29df,f82060e778a23bb7a8901ef2356d42b5363d93a6,f82060e778a23bb7a8901ef2356d42b5363d93a6,f82060e778a23bb7a8901ef2356d42b5363d93a6,f82060e778a23bb7a8901ef2356d42b5363d93a6,8d74e38914ddfdaa1cd052059493c00905f769a6,02b8ad76160027585d25bc74db2925c89625fe47..0d533bba4ad18097e447be3dca3fa41e5d9abeab
@@@@@@@@ -89,8 -89,8 -89,8 -89,8 -89,8 -89,8 -89,6 +89,6 @@@@@@@@ static struct dma_map_ops amd_iommu_dma
       struct iommu_dev_data {
        struct list_head list;            /* For domain->dev_list */
        struct list_head dev_data_list;   /* For global dev_data_list */
------  struct list_head alias_list;      /* Link alias-groups together */
------  struct iommu_dev_data *alias_data;/* The alias dev_data */
        struct protection_domain *domain; /* Domain the device is bound to */
        u16 devid;                        /* PCI Device ID */
        bool iommu_v2;                    /* Device can make use of IOMMUv2 */
@@@@@@@@ -136,8 -136,8 -136,8 -136,8 -136,8 -136,8 -134,6 +134,6 @@@@@@@@ static struct iommu_dev_data *alloc_dev
        if (!dev_data)
                return NULL;
       
------  INIT_LIST_HEAD(&dev_data->alias_list);
------ 
        dev_data->devid = devid;
       
        spin_lock_irqsave(&dev_data_list_lock, flags);
        return dev_data;
       }
       
------ static void free_dev_data(struct iommu_dev_data *dev_data)
------ {
------  unsigned long flags;
------ 
------  spin_lock_irqsave(&dev_data_list_lock, flags);
------  list_del(&dev_data->dev_data_list);
------  spin_unlock_irqrestore(&dev_data_list_lock, flags);
------ 
------  kfree(dev_data);
------ }
------ 
       static struct iommu_dev_data *search_dev_data(u16 devid)
       {
        struct iommu_dev_data *dev_data;
        iommu_group_put(group);
       }
       
------ static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
------ {
------  *(u16 *)data = alias;
------  return 0;
------ }
------ 
------ static u16 get_alias(struct device *dev)
------ {
------  struct pci_dev *pdev = to_pci_dev(dev);
------  u16 devid, ivrs_alias, pci_alias;
------ 
------  devid = get_device_id(dev);
------  ivrs_alias = amd_iommu_alias_table[devid];
------  pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
------ 
------  if (ivrs_alias == pci_alias)
------          return ivrs_alias;
------ 
------  /*
------   * DMA alias showdown
------   *
------   * The IVRS is fairly reliable in telling us about aliases, but it
------   * can't know about every screwy device.  If we don't have an IVRS
------   * reported alias, use the PCI reported alias.  In that case we may
------   * still need to initialize the rlookup and dev_table entries if the
------   * alias is to a non-existent device.
------   */
------  if (ivrs_alias == devid) {
------          if (!amd_iommu_rlookup_table[pci_alias]) {
------                  amd_iommu_rlookup_table[pci_alias] =
------                          amd_iommu_rlookup_table[devid];
------                  memcpy(amd_iommu_dev_table[pci_alias].data,
------                         amd_iommu_dev_table[devid].data,
------                         sizeof(amd_iommu_dev_table[pci_alias].data));
------          }
------ 
------          return pci_alias;
------  }
------ 
------  pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "
------          "for device %s[%04x:%04x], kernel reported alias "
------          "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
------          PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
------          PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
------          PCI_FUNC(pci_alias));
------ 
------  /*
------   * If we don't have a PCI DMA alias and the IVRS alias is on the same
------   * bus, then the IVRS table may know about a quirk that we don't.
------   */
------  if (pci_alias == devid &&
------      PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
------          pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
------          pdev->dma_alias_devfn = ivrs_alias & 0xff;
------          pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",
------                  PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
------                  dev_name(dev));
------  }
------ 
------  return ivrs_alias;
------ }
------ 
       static int iommu_init_device(struct device *dev)
       {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct iommu_dev_data *dev_data;
------  u16 alias;
       
        if (dev->archdata.iommu)
                return 0;
        if (!dev_data)
                return -ENOMEM;
       
------  alias = get_alias(dev);
------ 
------  if (alias != dev_data->devid) {
------          struct iommu_dev_data *alias_data;
------ 
------          alias_data = find_dev_data(alias);
------          if (alias_data == NULL) {
------                  pr_err("AMD-Vi: Warning: Unhandled device %s\n",
------                                  dev_name(dev));
------                  free_dev_data(dev_data);
------                  return -ENOTSUPP;
------          }
------          dev_data->alias_data = alias_data;
------ 
------          /* Add device to the alias_list */
------          list_add(&dev_data->alias_list, &alias_data->alias_list);
------  }
------ 
        if (pci_iommuv2_capable(pdev)) {
                struct amd_iommu *iommu;
       
@@@@@@@@ -445,9 -445,9 -445,9 -445,9 -445,9 -445,9 -349,6 +349,6 @@@@@@@@ static void iommu_uninit_device(struct 
       
        iommu_group_remove_device(dev);
       
------  /* Unlink from alias, it may change if another device is re-plugged */
------  dev_data->alias_data = NULL;
------ 
        /* Remove dma-ops */
        dev->archdata.dma_ops = NULL;
       
@@@@@@@@ -633,7 -633,7 -633,7 -633,7 -633,7 -633,7 -534,7 +534,7 @@@@@@@@ static void iommu_poll_events(struct am
       
        while (head != tail) {
                iommu_print_event(iommu, iommu->evt_buf + head);
------          head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
++++++          head = (head + EVENT_ENTRY_SIZE) % EVT_BUFFER_SIZE;
        }
       
        writel(head, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
@@@@@@@@ -783,7 -783,7 -783,7 -783,7 -783,7 -783,7 -684,7 +684,7 @@@@@@@@ static void copy_cmd_to_buffer(struct a
        u8 *target;
       
        target = iommu->cmd_buf + tail;
------  tail   = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
++++++  tail   = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;
       
        /* Copy command to buffer */
        memcpy(target, cmd, sizeof(*cmd));
@@@@@@@@ -950,15 -950,15 -950,15 -950,15 -950,15 -950,15 -851,13 +851,13 @@@@@@@@ static int iommu_queue_command_sync(str
        u32 left, tail, head, next_tail;
        unsigned long flags;
       
------  WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
------ 
       again:
        spin_lock_irqsave(&iommu->lock, flags);
       
        head      = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
        tail      = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
------  next_tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
------  left      = (head - next_tail) % iommu->cmd_buf_size;
++++++  next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;
++++++  left      = (head - next_tail) % CMD_BUFFER_SIZE;
       
        if (left <= 2) {
                struct iommu_cmd sync_cmd;
@@@@@@@@ -1114,11 -1114,11 -1114,11 -1114,11 -1114,11 -1114,11 -1013,15 +1013,15 @@@@@@@@ static int device_flush_iotlb(struct io
       static int device_flush_dte(struct iommu_dev_data *dev_data)
       {
        struct amd_iommu *iommu;
++++++  u16 alias;
        int ret;
       
        iommu = amd_iommu_rlookup_table[dev_data->devid];
++++++  alias = amd_iommu_alias_table[dev_data->devid];
       
        ret = iommu_flush_dte(iommu, dev_data->devid);
++++++  if (!ret && alias != dev_data->devid)
++++++          ret = iommu_flush_dte(iommu, alias);
        if (ret)
                return ret;
       
@@@@@@@@ -1974,8 -1974,8 -1974,8 -1974,8 -1974,8 -1974,8 -1877,8 +1877,8 @@@@@@@@ static void set_dte_entry(u16 devid, st
       static void clear_dte_entry(u16 devid)
       {
        /* remove entry from the device table seen by the hardware */
 ------ amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
 ------ amd_iommu_dev_table[devid].data[1] = 0;
 ++++++ amd_iommu_dev_table[devid].data[0]  = IOMMU_PTE_P | IOMMU_PTE_TV;
 ++++++ amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK;
       
        amd_iommu_apply_erratum_63(devid);
       }
@@@@@@@@ -1984,38 -1984,29 -1984,29 -1984,29 -1984,29 -1984,29 -1887,36 +1887,45 @@@@@@@@ static void do_attach(struct iommu_dev_
                      struct protection_domain *domain)
       {
        struct amd_iommu *iommu;
++++++  u16 alias;
        bool ats;
       
        iommu = amd_iommu_rlookup_table[dev_data->devid];
++++++  alias = amd_iommu_alias_table[dev_data->devid];
        ats   = dev_data->ats.enabled;
       
        /* Update data structures */
        dev_data->domain = domain;
        list_add(&dev_data->list, &domain->dev_list);
------  set_dte_entry(dev_data->devid, domain, ats);
       
        /* Do reference counting */
        domain->dev_iommu[iommu->index] += 1;
        domain->dev_cnt                 += 1;
       
------  /* Flush the DTE entry */
++++++  /* Update device table */
++++++  set_dte_entry(dev_data->devid, domain, ats);
++++++  if (alias != dev_data->devid)
++++++          set_dte_entry(dev_data->devid, domain, ats);
++++++ 
        device_flush_dte(dev_data);
       }
       
       static void do_detach(struct iommu_dev_data *dev_data)
       {
        struct amd_iommu *iommu;
++++++  u16 alias;
 +++++ 
 ++++++ /*
 ++++++  * First check if the device is still attached. It might already
 ++++++  * be detached from its domain because the generic
 ++++++  * iommu_detach_group code detached it and we try again here in
 ++++++  * our alias handling.
 ++++++  */
 ++++++ if (!dev_data->domain)
 ++++++         return;
      +
        iommu = amd_iommu_rlookup_table[dev_data->devid];
++++++  alias = amd_iommu_alias_table[dev_data->devid];
       
        /* decrease reference counters */
        dev_data->domain->dev_iommu[iommu->index] -= 1;
        dev_data->domain = NULL;
        list_del(&dev_data->list);
        clear_dte_entry(dev_data->devid);
++++++  if (alias != dev_data->devid)
++++++          clear_dte_entry(alias);
       
        /* Flush the DTE entry */
        device_flush_dte(dev_data);
       static int __attach_device(struct iommu_dev_data *dev_data,
                           struct protection_domain *domain)
       {
------  struct iommu_dev_data *head, *entry;
        int ret;
       
++++++  /*
++++++   * Must be called with IRQs disabled. Warn here to detect early
++++++   * when its not.
++++++   */
++++++  WARN_ON(!irqs_disabled());
++++++ 
        /* lock domain */
        spin_lock(&domain->lock);
       
------  head = dev_data;
------ 
------  if (head->alias_data != NULL)
------          head = head->alias_data;
------ 
------  /* Now we have the root of the alias group, if any */
------ 
        ret = -EBUSY;
------  if (head->domain != NULL)
++++++  if (dev_data->domain != NULL)
                goto out_unlock;
       
        /* Attach alias group root */
------  do_attach(head, domain);
------ 
------  /* Attach other devices in the alias group */
------  list_for_each_entry(entry, &head->alias_list, alias_list)
------          do_attach(entry, domain);
++++++  do_attach(dev_data, domain);
       
        ret = 0;
       
@@@@@@@@ -2209,26 -2200,26 -2200,26 -2200,26 -2200,26 -2200,26 -2106,24 +2115,24 @@@@@@@@ static int attach_device(struct device 
        */
       static void __detach_device(struct iommu_dev_data *dev_data)
       {
------  struct iommu_dev_data *head, *entry;
        struct protection_domain *domain;
------  unsigned long flags;
       
------  BUG_ON(!dev_data->domain);
------ 
------  domain = dev_data->domain;
++++++  /*
++++++   * Must be called with IRQs disabled. Warn here to detect early
++++++   * when its not.
++++++   */
++++++  WARN_ON(!irqs_disabled());
       
------  spin_lock_irqsave(&domain->lock, flags);
++++++  if (WARN_ON(!dev_data->domain))
++++++          return;
       
------  head = dev_data;
------  if (head->alias_data != NULL)
------          head = head->alias_data;
++++++  domain = dev_data->domain;
       
------  list_for_each_entry(entry, &head->alias_list, alias_list)
------          do_detach(entry);
++++++  spin_lock(&domain->lock);
       
------  do_detach(head);
++++++  do_detach(dev_data);
       
------  spin_unlock_irqrestore(&domain->lock, flags);
++++++  spin_unlock(&domain->lock);
       }
       
       /*
@@@@@@@@ -3198,6 -3189,6 -3189,6 -3189,6 -3189,6 -3189,7 -3093,6 +3102,7 @@@@@@@@ static const struct iommu_ops amd_iommu
        .iova_to_phys = amd_iommu_iova_to_phys,
        .add_device = amd_iommu_add_device,
        .remove_device = amd_iommu_remove_device,
+++++ + .device_group = pci_device_group,
        .get_dm_regions = amd_iommu_get_dm_regions,
        .put_dm_regions = amd_iommu_put_dm_regions,
        .pgsize_bitmap  = AMD_IOMMU_PGSIZES,
index 1b066e7d144d6fdc0043cfbfa340ce2e7a209c50,5ef347a13cb5d54789c07869b0527d81cb24365e,5ef347a13cb5d54789c07869b0527d81cb24365e,5ef347a13cb5d54789c07869b0527d81cb24365e,5ef347a13cb5d54789c07869b0527d81cb24365e,5ef347a13cb5d54789c07869b0527d81cb24365e,dd92a8d8f0ca1c55da1afb2f966ff4c0e2811910..a7cc3996d3b6d6e5e7978b61b8939dafd433a4f7
@@@@@@@@ -407,20 -407,20 -407,20 -407,20 -407,20 -407,20 -407,6 +407,6 @@@@@@@@ static inline int ivhd_entry_length(u8 
        return 0x04 << (*ivhd >> 6);
       }
       
------ /*
------  * This function reads the last device id the IOMMU has to handle from the PCI
------  * capability header for this IOMMU
------  */
------ static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr)
------ {
------  u32 cap;
------ 
------  cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET);
------  update_last_devid(PCI_DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap)));
------ 
------  return 0;
------ }
------ 
       /*
        * After reading the highest device id from the IOMMU PCI capability header
        * this function looks if there is a higher device id defined in the ACPI table
@@@@@@@@ -433,14 -433,14 -433,14 -433,14 -433,14 -433,14 -419,13 +419,13 @@@@@@@@ static int __init find_last_devid_from_
        p += sizeof(*h);
        end += h->length;
       
------  find_last_devid_on_pci(PCI_BUS_NUM(h->devid),
------                  PCI_SLOT(h->devid),
------                  PCI_FUNC(h->devid),
------                  h->cap_ptr);
------ 
        while (p < end) {
                dev = (struct ivhd_entry *)p;
                switch (dev->type) {
++++++          case IVHD_DEV_ALL:
++++++                  /* Use maximum BDF value for DEV_ALL */
++++++                  update_last_devid(0xffff);
++++++                  break;
                case IVHD_DEV_SELECT:
                case IVHD_DEV_RANGE_END:
                case IVHD_DEV_ALIAS:
@@@@@@@@ -513,17 -513,17 -513,17 -513,17 -513,17 -513,17 -498,12 +498,12 @@@@@@@@ static int __init find_last_devid_acpi(
        * write commands to that buffer later and the IOMMU will execute them
        * asynchronously
        */
------ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
++++++ static int __init alloc_command_buffer(struct amd_iommu *iommu)
       {
------  u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
------                  get_order(CMD_BUFFER_SIZE));
------ 
------  if (cmd_buf == NULL)
------          return NULL;
------ 
------  iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
++++++  iommu->cmd_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
++++++                                            get_order(CMD_BUFFER_SIZE));
       
------  return cmd_buf;
++++++  return iommu->cmd_buf ? 0 : -ENOMEM;
       }
       
       /*
@@@@@@@@ -557,27 -557,27 -557,27 -557,27 -557,27 -557,27 -537,20 +537,20 @@@@@@@@ static void iommu_enable_command_buffer
                    &entry, sizeof(entry));
       
        amd_iommu_reset_cmd_buffer(iommu);
------  iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
       }
       
       static void __init free_command_buffer(struct amd_iommu *iommu)
       {
------  free_pages((unsigned long)iommu->cmd_buf,
------             get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
++++++  free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE));
       }
       
       /* allocates the memory where the IOMMU will log its events to */
------ static u8 * __init alloc_event_buffer(struct amd_iommu *iommu)
++++++ static int __init alloc_event_buffer(struct amd_iommu *iommu)
       {
------  iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
------                                          get_order(EVT_BUFFER_SIZE));
++++++  iommu->evt_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
++++++                                            get_order(EVT_BUFFER_SIZE));
       
------  if (iommu->evt_buf == NULL)
------          return NULL;
------ 
------  iommu->evt_buf_size = EVT_BUFFER_SIZE;
------ 
------  return iommu->evt_buf;
++++++  return iommu->evt_buf ? 0 : -ENOMEM;
       }
       
       static void iommu_enable_event_buffer(struct amd_iommu *iommu)
@@@@@@@@ -604,15 -604,15 -604,15 -604,15 -604,15 -604,15 -577,12 +577,12 @@@@@@@@ static void __init free_event_buffer(st
       }
       
       /* allocates the memory where the IOMMU will log its events to */
------ static u8 * __init alloc_ppr_log(struct amd_iommu *iommu)
++++++ static int __init alloc_ppr_log(struct amd_iommu *iommu)
       {
------  iommu->ppr_log = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
------                                          get_order(PPR_LOG_SIZE));
 ----- 
 -----  if (iommu->ppr_log == NULL)
 -----          return NULL;
++++++  iommu->ppr_log = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
++++++                                            get_order(PPR_LOG_SIZE));
       
-       if (iommu->ppr_log == NULL)
-               return NULL;
-      
------  return iommu->ppr_log;
++++++  return iommu->ppr_log ? 0 : -ENOMEM;
       }
       
       static void iommu_enable_ppr_log(struct amd_iommu *iommu)
@@@@@@@@ -835,20 -835,20 -835,20 -835,20 -835,20 -835,20 -805,10 +805,10 @@@@@@@@ static int __init init_iommu_from_acpi(
                switch (e->type) {
                case IVHD_DEV_ALL:
       
------                  DUMP_printk("  DEV_ALL\t\t\t first devid: %02x:%02x.%x"
------                              " last device %02x:%02x.%x flags: %02x\n",
------                              PCI_BUS_NUM(iommu->first_device),
------                              PCI_SLOT(iommu->first_device),
------                              PCI_FUNC(iommu->first_device),
------                              PCI_BUS_NUM(iommu->last_device),
------                              PCI_SLOT(iommu->last_device),
------                              PCI_FUNC(iommu->last_device),
------                              e->flags);
++++++                  DUMP_printk("  DEV_ALL\t\t\tflags: %02x\n", e->flags);
       
------                  for (dev_i = iommu->first_device;
------                                  dev_i <= iommu->last_device; ++dev_i)
------                          set_dev_entry_from_acpi(iommu, dev_i,
------                                                  e->flags, 0);
++++++                  for (dev_i = 0; dev_i <= amd_iommu_last_bdf; ++dev_i)
++++++                          set_dev_entry_from_acpi(iommu, dev_i, e->flags, 0);
                        break;
                case IVHD_DEV_SELECT:
       
        return 0;
       }
       
------ /* Initializes the device->iommu mapping for the driver */
------ static int __init init_iommu_devices(struct amd_iommu *iommu)
------ {
------  u32 i;
------ 
------  for (i = iommu->first_device; i <= iommu->last_device; ++i)
------          set_iommu_for_device(iommu, i);
------ 
------  return 0;
------ }
------ 
       static void __init free_iommu_one(struct amd_iommu *iommu)
       {
        free_command_buffer(iommu);
@@@@@@@@ -1111,12 -1111,12 -1111,12 -1111,12 -1111,12 -1111,12 -1060,10 +1060,10 @@@@@@@@ static int __init init_iommu_one(struc
        if (!iommu->mmio_base)
                return -ENOMEM;
       
------  iommu->cmd_buf = alloc_command_buffer(iommu);
------  if (!iommu->cmd_buf)
++++++  if (alloc_command_buffer(iommu))
                return -ENOMEM;
       
------  iommu->evt_buf = alloc_event_buffer(iommu);
------  if (!iommu->evt_buf)
++++++  if (alloc_event_buffer(iommu))
                return -ENOMEM;
       
        iommu->int_enabled = false;
         */
        amd_iommu_rlookup_table[iommu->devid] = NULL;
       
------  init_iommu_devices(iommu);
------ 
        return 0;
       }
       
@@@@@@@@ -1256,9 -1256,6 -1256,6 -1256,6 -1256,6 -1256,6 -1201,6 +1201,9 @@@@@@@@ static int iommu_init_pci(struct amd_io
        if (!iommu->dev)
                return -ENODEV;
       
 ++++++ /* Prevent binding other PCI device drivers to IOMMU devices */
 ++++++ iommu->dev->match_driver = false;
 ++++++
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
                              &iommu->cap);
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_RANGE_OFFSET,
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET,
                              &misc);
       
------  iommu->first_device = PCI_DEVID(MMIO_GET_BUS(range),
------                                   MMIO_GET_FD(range));
------  iommu->last_device = PCI_DEVID(MMIO_GET_BUS(range),
------                                  MMIO_GET_LD(range));
------ 
        if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
                amd_iommu_iotlb_sup = false;
       
                amd_iommu_v2_present = true;
        }
       
------  if (iommu_feature(iommu, FEATURE_PPR)) {
------          iommu->ppr_log = alloc_ppr_log(iommu);
------          if (!iommu->ppr_log)
------                  return -ENOMEM;
------  }
++++++  if (iommu_feature(iommu, FEATURE_PPR) && alloc_ppr_log(iommu))
++++++          return -ENOMEM;
       
        if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
                amd_iommu_np_cache = true;
@@@@@@@@ -1758,11 -1755,11 -1755,11 -1755,11 -1755,11 -1755,11 -1692,8 +1695,8 @@@@@@@@ static void __init free_on_init_error(v
        free_pages((unsigned long)irq_lookup_table,
                   get_order(rlookup_table_size));
       
------  if (amd_iommu_irq_cache) {
------          kmem_cache_destroy(amd_iommu_irq_cache);
------          amd_iommu_irq_cache = NULL;
------ 
------  }
++++++  kmem_cache_destroy(amd_iommu_irq_cache);
++++++  amd_iommu_irq_cache = NULL;
       
        free_pages((unsigned long)amd_iommu_rlookup_table,
                   get_order(rlookup_table_size));
@@@@@@@@ -2201,7 -2198,7 -2198,7 -2198,7 -2198,7 -2198,7 -2132,7 +2135,7 @@@@@@@@ int __init amd_iommu_detect(void
        iommu_detected = 1;
        x86_init.iommu.iommu_init = amd_iommu_init;
       
------  return 0;
++++++  return 1;
       }
       
       /****************************************************************************
index c9b64722f62309d76e56ad52c5a3691737ffd6ac,f65908841be0184db61f049bc8e2b5a622ca2fbe,f65908841be0184db61f049bc8e2b5a622ca2fbe,f65908841be0184db61f049bc8e2b5a622ca2fbe,f65908841be0184db61f049bc8e2b5a622ca2fbe,f65908841be0184db61f049bc8e2b5a622ca2fbe,fc9501dc706750a934399c628b0cc8686ae2c266..08166ae3b6a4b3c6170e70d7cd3e23353e2ba6ab
       #define IOMMU_PTE_IR (1ULL << 61)
       #define IOMMU_PTE_IW (1ULL << 62)
       
 ----- #define DTE_FLAG_IOTLB   (0x01UL << 32)
 ----- #define DTE_FLAG_GV      (0x01ULL << 55)
++++++ #define DTE_FLAG_IOTLB   (1ULL << 32)
++++++ #define DTE_FLAG_GV      (1ULL << 55)
 ++++++#define DTE_FLAG_MASK    (0x3ffULL << 32)
-      #define DTE_FLAG_IOTLB   (0x01UL << 32)
-      #define DTE_FLAG_GV      (0x01ULL << 55)
       #define DTE_GLX_SHIFT    (56)
       #define DTE_GLX_MASK     (3)
       
@@@@@@@@ -517,11 -516,11 -516,11 -516,11 -516,11 -516,11 -516,6 +517,6 @@@@@@@@ struct amd_iommu 
        /* pci domain of this IOMMU */
        u16 pci_seg;
       
------  /* first device this IOMMU handles. read from PCI */
------  u16 first_device;
------  /* last device this IOMMU handles. read from PCI */
------  u16 last_device;
------ 
        /* start of exclusion range of that IOMMU */
        u64 exclusion_start;
        /* length of exclusion range of that IOMMU */
       
        /* command buffer virtual address */
        u8 *cmd_buf;
------  /* size of command buffer */
------  u32 cmd_buf_size;
       
------  /* size of event buffer */
------  u32 evt_buf_size;
        /* event buffer virtual address */
        u8 *evt_buf;
       
index 286e890e7d64caa31867044f568e3a3cf6ce2ba9,dafaf59dc3b82833fb78d55e8f194ff728999d35,dafaf59dc3b82833fb78d55e8f194ff728999d35,5a36ef70f6f4be31511ee879bdda403a34dce0b4,dafaf59dc3b82833fb78d55e8f194ff728999d35,fbd4fedd5162d1c58d6775084a0f5e356a0b0d59,dafaf59dc3b82833fb78d55e8f194ff728999d35..4e5118a4cd305ee4fa9ae6613d9e9615b1570082
       #include <linux/iommu.h>
       #include <linux/iopoll.h>
       #include <linux/module.h>
+++ +++#include <linux/msi.h>
       #include <linux/of.h>
       #include <linux/of_address.h>
+++ +++#include <linux/of_platform.h>
       #include <linux/pci.h>
       #include <linux/platform_device.h>
       
       #define IDR0_TTF_SHIFT                   2
       #define IDR0_TTF_MASK                    0x3
       #define IDR0_TTF_AARCH64         (2 << IDR0_TTF_SHIFT)
 ++++++#define IDR0_TTF_AARCH32_64              (3 << IDR0_TTF_SHIFT)
       #define IDR0_S1P                 (1 << 1)
       #define IDR0_S2P                 (1 << 0)
       
       #define CMDQ_TLBI_0_VMID_SHIFT           32
       #define CMDQ_TLBI_0_ASID_SHIFT           48
       #define CMDQ_TLBI_1_LEAF         (1UL << 0)
 ------#define CMDQ_TLBI_1_ADDR_MASK            ~0xfffUL
 ++++++#define CMDQ_TLBI_1_VA_MASK              ~0xfffUL
 ++++++#define CMDQ_TLBI_1_IPA_MASK             0xfffffffff000UL
       
       #define CMDQ_PRI_0_SSID_SHIFT            12
       #define CMDQ_PRI_0_SSID_MASK             0xfffffUL
@@@@@@@@ -403,6 -401,6 -401,6 -403,31 -401,6 -401,6 -401,6 +405,31 @@@@@@@@ enum pri_resp 
        PRI_RESP_SUCC,
       };
       
+++ +++enum arm_smmu_msi_index {
+++ +++ EVTQ_MSI_INDEX,
+++ +++ GERROR_MSI_INDEX,
+++ +++ PRIQ_MSI_INDEX,
+++ +++ ARM_SMMU_MAX_MSIS,
+++ +++};
+++ +++
+++ +++static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
+++ +++ [EVTQ_MSI_INDEX] = {
+++ +++         ARM_SMMU_EVTQ_IRQ_CFG0,
+++ +++         ARM_SMMU_EVTQ_IRQ_CFG1,
+++ +++         ARM_SMMU_EVTQ_IRQ_CFG2,
+++ +++ },
+++ +++ [GERROR_MSI_INDEX] = {
+++ +++         ARM_SMMU_GERROR_IRQ_CFG0,
+++ +++         ARM_SMMU_GERROR_IRQ_CFG1,
+++ +++         ARM_SMMU_GERROR_IRQ_CFG2,
+++ +++ },
+++ +++ [PRIQ_MSI_INDEX] = {
+++ +++         ARM_SMMU_PRIQ_IRQ_CFG0,
+++ +++         ARM_SMMU_PRIQ_IRQ_CFG1,
+++ +++         ARM_SMMU_PRIQ_IRQ_CFG2,
+++ +++ },
+++ +++};
+++ +++
       struct arm_smmu_cmdq_ent {
        /* Common fields */
        u8                              opcode;
@@@@@@@@ -570,7 -568,7 -568,7 -595,6 -568,7 -568,7 -568,7 +597,6 @@@@@@@@ struct arm_smmu_device 
        unsigned int                    sid_bits;
       
        struct arm_smmu_strtab_cfg      strtab_cfg;
--- --- struct list_head                list;
       };
       
       /* SMMU private data for an IOMMU group */
@@@@@@@@ -605,10 -603,10 -603,10 -629,6 -603,10 -603,10 -603,10 +631,6 @@@@@@@@ struct arm_smmu_domain 
        struct iommu_domain             domain;
       };
       
--- ---/* Our list of SMMU instances */
--- ---static DEFINE_SPINLOCK(arm_smmu_devices_lock);
--- ---static LIST_HEAD(arm_smmu_devices);
--- ---
       struct arm_smmu_option_prop {
        u32 opt;
        const char *prop;
@@@@@@@@ -772,13 -770,11 -770,11 -792,11 -770,11 -770,11 -770,11 +794,13 @@@@@@@@ static int arm_smmu_cmdq_build_cmd(u64 
                break;
        case CMDQ_OP_TLBI_NH_VA:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
 ------         /* Fallthrough */
 ++++++         cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
 ++++++         cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
 ++++++         break;
        case CMDQ_OP_TLBI_S2_IPA:
                cmd[0] |= (u64)ent->tlbi.vmid << CMDQ_TLBI_0_VMID_SHIFT;
                cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
 ------         cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_ADDR_MASK;
 ++++++         cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_IPA_MASK;
                break;
        case CMDQ_OP_TLBI_NH_ASID:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
@@@@@@@@ -1427,7 -1423,7 -1423,7 -1445,7 -1423,7 -1423,7 -1423,7 +1449,7 @@@@@@@@ static int arm_smmu_domain_finalise_s1(
                                       struct io_pgtable_cfg *pgtbl_cfg)
       {
        int ret;
--- --- u16 asid;
+++ +++ int asid;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
        struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
       
                                         &cfg->cdptr_dma, GFP_KERNEL);
        if (!cfg->cdptr) {
                dev_warn(smmu->dev, "failed to allocate context descriptor\n");
+++ +++         ret = -ENOMEM;
                goto out_free_asid;
        }
       
--- --- cfg->cd.asid    = asid;
+++ +++ cfg->cd.asid    = (u16)asid;
        cfg->cd.ttbr    = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
        cfg->cd.tcr     = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
        cfg->cd.mair    = pgtbl_cfg->arm_lpae_s1_cfg.mair[0];
@@@@@@@@ -1456,7 -1452,7 -1452,7 -1475,7 -1452,7 -1452,7 -1452,7 +1479,7 @@@@@@@@ out_free_asid
       static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
                                       struct io_pgtable_cfg *pgtbl_cfg)
       {
--- --- u16 vmid;
+++ +++ int vmid;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
        struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
       
        if (IS_ERR_VALUE(vmid))
                return vmid;
       
--- --- cfg->vmid       = vmid;
+++ +++ cfg->vmid       = (u16)vmid;
        cfg->vttbr      = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
        cfg->vtcr       = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
        return 0;
@@@@@@@@ -1726,7 -1722,7 -1722,7 -1745,8 -1722,7 -1722,7 -1722,7 +1749,8 @@@@@@@@ static void __arm_smmu_release_pci_iomm
       static struct arm_smmu_device *arm_smmu_get_for_pci_dev(struct pci_dev *pdev)
       {
        struct device_node *of_node;
--- --- struct arm_smmu_device *curr, *smmu = NULL;
+++ +++ struct platform_device *smmu_pdev;
+++ +++ struct arm_smmu_device *smmu = NULL;
        struct pci_bus *bus = pdev->bus;
       
        /* Walk up to the root bus */
                return NULL;
       
        /* See if we can find an SMMU corresponding to the phandle */
--- --- spin_lock(&arm_smmu_devices_lock);
--- --- list_for_each_entry(curr, &arm_smmu_devices, list) {
--- ---         if (curr->dev->of_node == of_node) {
--- ---                 smmu = curr;
--- ---                 break;
--- ---         }
--- --- }
--- --- spin_unlock(&arm_smmu_devices_lock);
+++ +++ smmu_pdev = of_find_device_by_node(of_node);
+++ +++ if (smmu_pdev)
+++ +++         smmu = platform_get_drvdata(smmu_pdev);
+++ +++
        of_node_put(of_node);
        return smmu;
       }
@@@@@@@@ -1902,6 -1898,6 -1898,6 -1918,6 -1898,6 -1898,7 -1898,6 +1922,7 @@@@@@@@ static struct iommu_ops arm_smmu_ops = 
        .iova_to_phys           = arm_smmu_iova_to_phys,
        .add_device             = arm_smmu_add_device,
        .remove_device          = arm_smmu_remove_device,
+++++ + .device_group           = pci_device_group,
        .domain_get_attr        = arm_smmu_domain_get_attr,
        .domain_set_attr        = arm_smmu_domain_set_attr,
        .pgsize_bitmap          = -1UL, /* Restricted during device attach */
@@@@@@@@ -2186,6 -2182,6 -2182,6 -2202,72 -2182,6 -2183,6 -2182,6 +2207,72 @@@@@@@@ static int arm_smmu_write_reg_sync(stru
                                          1, ARM_SMMU_POLL_TIMEOUT_US);
       }
       
+++ +++static void arm_smmu_free_msis(void *data)
+++ +++{
+++ +++ struct device *dev = data;
+++ +++ platform_msi_domain_free_irqs(dev);
+++ +++}
+++ +++
+++ +++static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+++ +++{
+++ +++ phys_addr_t doorbell;
+++ +++ struct device *dev = msi_desc_to_dev(desc);
+++ +++ struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+++ +++ phys_addr_t *cfg = arm_smmu_msi_cfg[desc->platform.msi_index];
+++ +++
+++ +++ doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
+++ +++ doorbell &= MSI_CFG0_ADDR_MASK << MSI_CFG0_ADDR_SHIFT;
+++ +++
+++ +++ writeq_relaxed(doorbell, smmu->base + cfg[0]);
+++ +++ writel_relaxed(msg->data, smmu->base + cfg[1]);
+++ +++ writel_relaxed(MSI_CFG2_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);
+++ +++}
+++ +++
+++ +++static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
+++ +++{
+++ +++ struct msi_desc *desc;
+++ +++ int ret, nvec = ARM_SMMU_MAX_MSIS;
+++ +++ struct device *dev = smmu->dev;
+++ +++
+++ +++ /* Clear the MSI address regs */
+++ +++ writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);
+++ +++ writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);
+++ +++
+++ +++ if (smmu->features & ARM_SMMU_FEAT_PRI)
+++ +++         writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);
+++ +++ else
+++ +++         nvec--;
+++ +++
+++ +++ if (!(smmu->features & ARM_SMMU_FEAT_MSI))
+++ +++         return;
+++ +++
+++ +++ /* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */
+++ +++ ret = platform_msi_domain_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);
+++ +++ if (ret) {
+++ +++         dev_warn(dev, "failed to allocate MSIs\n");
+++ +++         return;
+++ +++ }
+++ +++
+++ +++ for_each_msi_entry(desc, dev) {
+++ +++         switch (desc->platform.msi_index) {
+++ +++         case EVTQ_MSI_INDEX:
+++ +++                 smmu->evtq.q.irq = desc->irq;
+++ +++                 break;
+++ +++         case GERROR_MSI_INDEX:
+++ +++                 smmu->gerr_irq = desc->irq;
+++ +++                 break;
+++ +++         case PRIQ_MSI_INDEX:
+++ +++                 smmu->priq.q.irq = desc->irq;
+++ +++                 break;
+++ +++         default:        /* Unknown */
+++ +++                 continue;
+++ +++         }
+++ +++ }
+++ +++
+++ +++ /* Add callback to free MSIs on teardown */
+++ +++ devm_add_action(dev, arm_smmu_free_msis, dev);
+++ +++}
+++ +++
       static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
       {
        int ret, irq;
                return ret;
        }
       
--- --- /* Clear the MSI address regs */
--- --- writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);
--- --- writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);
+++ +++ arm_smmu_setup_msis(smmu);
       
--- --- /* Request wired interrupt lines */
+++ +++ /* Request interrupt lines */
        irq = smmu->evtq.q.irq;
        if (irq) {
                ret = devm_request_threaded_irq(smmu->dev, irq,
        }
       
        if (smmu->features & ARM_SMMU_FEAT_PRI) {
--- ---         writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);
--- ---
                irq = smmu->priq.q.irq;
                if (irq) {
                        ret = devm_request_threaded_irq(smmu->dev, irq,
@@@@@@@@ -2464,13 -2460,7 -2460,7 -2542,7 -2460,7 -2461,7 -2460,7 +2547,13 @@@@@@@@ static int arm_smmu_device_probe(struc
        }
       
        /* We only support the AArch64 table format at present */
 ------ if ((reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) < IDR0_TTF_AARCH64) {
 ++++++ switch (reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) {
 ++++++ case IDR0_TTF_AARCH32_64:
 ++++++         smmu->ias = 40;
 ++++++         /* Fallthrough */
 ++++++ case IDR0_TTF_AARCH64:
 ++++++         break;
 ++++++ default:
                dev_err(smmu->dev, "AArch64 table format not supported!\n");
                return -ENXIO;
        }
                dev_warn(smmu->dev,
                         "failed to set DMA mask for table walker\n");
       
 ------ if (!smmu->ias)
 ------         smmu->ias = smmu->oas;
 ++++++ smmu->ias = max(smmu->ias, smmu->oas);
       
        dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
                 smmu->ias, smmu->oas, smmu->features);
@@@@@@@@ -2612,16 -2603,16 -2603,16 -2685,14 -2603,16 -2604,16 -2603,16 +2695,14 @@@@@@@@ static int arm_smmu_device_dt_probe(str
        if (ret)
                return ret;
       
+++ +++ /* Record our private device structure */
+++ +++ platform_set_drvdata(pdev, smmu);
+++ +++
        /* Reset the device */
        ret = arm_smmu_device_reset(smmu);
        if (ret)
                goto out_free_structures;
       
--- --- /* Record our private device structure */
--- --- INIT_LIST_HEAD(&smmu->list);
--- --- spin_lock(&arm_smmu_devices_lock);
--- --- list_add(&smmu->list, &arm_smmu_devices);
--- --- spin_unlock(&arm_smmu_devices_lock);
        return 0;
       
       out_free_structures:
       
       static int arm_smmu_device_remove(struct platform_device *pdev)
       {
--- --- struct arm_smmu_device *curr, *smmu = NULL;
--- --- struct device *dev = &pdev->dev;
--- ---
--- --- spin_lock(&arm_smmu_devices_lock);
--- --- list_for_each_entry(curr, &arm_smmu_devices, list) {
--- ---         if (curr->dev == dev) {
--- ---                 smmu = curr;
--- ---                 list_del(&smmu->list);
--- ---                 break;
--- ---         }
--- --- }
--- --- spin_unlock(&arm_smmu_devices_lock);
--- ---
--- --- if (!smmu)
--- ---         return -ENODEV;
+++ +++ struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
       
        arm_smmu_device_disable(smmu);
        arm_smmu_free_structures(smmu);
diff --combined drivers/iommu/arm-smmu.c
index 48a39dfa977795deb8271dc5b34a7b3e0be002d0,48a39dfa977795deb8271dc5b34a7b3e0be002d0,48a39dfa977795deb8271dc5b34a7b3e0be002d0,7c20a68b5a95937f5e339ed603e8cc5119d703b0,48a39dfa977795deb8271dc5b34a7b3e0be002d0,b4c0629d7f7d96170cafaf47884c3c5b4742fc72,48a39dfa977795deb8271dc5b34a7b3e0be002d0..47dc7a793f5cf070c50a2f2f98c15058582bb9ee
                ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)       \
                        ? 0x400 : 0))
       
+++ +++#ifdef CONFIG_64BIT
+++ +++#define smmu_writeq      writeq_relaxed
+++ +++#else
+++ +++#define smmu_writeq(reg64, addr)                         \
+++ +++ do {                                                    \
+++ +++         u64 __val = (reg64);                            \
+++ +++         void __iomem *__addr = (addr);                  \
+++ +++         writel_relaxed(__val >> 32, __addr + 4);        \
+++ +++         writel_relaxed(__val, __addr);                  \
+++ +++ } while (0)
+++ +++#endif
+++ +++
       /* Configuration registers */
       #define ARM_SMMU_GR0_sCR0                0x0
       #define sCR0_CLIENTPD                    (1 << 0)
       #define ARM_SMMU_CB_SCTLR                0x0
       #define ARM_SMMU_CB_RESUME               0x8
       #define ARM_SMMU_CB_TTBCR2               0x10
--- ---#define ARM_SMMU_CB_TTBR0_LO             0x20
--- ---#define ARM_SMMU_CB_TTBR0_HI             0x24
--- ---#define ARM_SMMU_CB_TTBR1_LO             0x28
--- ---#define ARM_SMMU_CB_TTBR1_HI             0x2c
+++ +++#define ARM_SMMU_CB_TTBR0                0x20
+++ +++#define ARM_SMMU_CB_TTBR1                0x28
       #define ARM_SMMU_CB_TTBCR                0x30
       #define ARM_SMMU_CB_S1_MAIR0             0x38
       #define ARM_SMMU_CB_S1_MAIR1             0x3c
       #define TTBCR2_SEP_SHIFT         15
       #define TTBCR2_SEP_UPSTREAM              (0x7 << TTBCR2_SEP_SHIFT)
       
--- ---#define TTBRn_HI_ASID_SHIFT            16
+++ +++#define TTBRn_ASID_SHIFT         48
       
       #define FSR_MULTI                        (1 << 31)
       #define FSR_SS                           (1 << 30)
@@@@@@@@ -695,12 -695,12 -695,12 -705,12 -695,12 -695,12 -695,12 +705,12 @@@@@@@@ static void arm_smmu_init_context_bank(
                                       struct io_pgtable_cfg *pgtbl_cfg)
       {
        u32 reg;
+++ +++ u64 reg64;
        bool stage1;
        struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
--- --- void __iomem *cb_base, *gr0_base, *gr1_base;
+++ +++ void __iomem *cb_base, *gr1_base;
       
--- --- gr0_base = ARM_SMMU_GR0(smmu);
        gr1_base = ARM_SMMU_GR1(smmu);
        stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
        cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
       
        /* TTBRs */
        if (stage1) {
--- ---         reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
--- ---         reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
--- ---         reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
--- ---
--- ---         reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
--- ---         reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
--- ---         reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
+++ +++         reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+++ +++
+++ +++         reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+++ +++         smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+++ +++
+++ +++         reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
+++ +++         reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+++ +++         smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);
        } else {
--- ---         reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
--- ---         reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32;
--- ---         writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+++ +++         reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
+++ +++         smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
        }
       
        /* TTBCR */
@@@@@@@@ -1212,17 -1212,17 -1212,17 -1217,15 -1212,17 -1212,17 -1212,17 +1217,15 @@@@@@@@ static phys_addr_t arm_smmu_iova_to_phy
       
        /* ATS1 registers can only be written atomically */
        va = iova & ~0xfffUL;
--- ---#ifdef CONFIG_64BIT
        if (smmu->version == ARM_SMMU_V2)
--- ---         writeq_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
+++ +++         smmu_writeq(va, cb_base + ARM_SMMU_CB_ATS1PR);
        else
--- ---#endif
                writel_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
       
        if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
                                      !(tmp & ATSR_ACTIVE), 5, 50)) {
                dev_err(dev,
--- ---                 "iova to phys timed out on 0x%pad. Falling back to software table walk.\n",
+++ +++                 "iova to phys timed out on %pad. Falling back to software table walk.\n",
                        &iova);
                return ops->iova_to_phys(ops, iova);
        }
@@@@@@@@ -1292,33 -1292,33 -1292,33 -1295,33 -1292,33 -1292,25 -1292,33 +1295,25 @@@@@@@@ static void __arm_smmu_release_pci_iomm
        kfree(data);
       }
       
----- -static int arm_smmu_add_pci_device(struct pci_dev *pdev)
+++++ +static int arm_smmu_init_pci_device(struct pci_dev *pdev,
+++++ +                             struct iommu_group *group)
       {
----- - int i, ret;
----- - u16 sid;
----- - struct iommu_group *group;
        struct arm_smmu_master_cfg *cfg;
----- -
----- - group = iommu_group_get_for_dev(&pdev->dev);
----- - if (IS_ERR(group))
----- -         return PTR_ERR(group);
+++++ + u16 sid;
+++++ + int i;
       
        cfg = iommu_group_get_iommudata(group);
        if (!cfg) {
                cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
----- -         if (!cfg) {
----- -                 ret = -ENOMEM;
----- -                 goto out_put_group;
----- -         }
+++++ +         if (!cfg)
+++++ +                 return -ENOMEM;
       
                iommu_group_set_iommudata(group, cfg,
                                          __arm_smmu_release_pci_iommudata);
        }
       
----- - if (cfg->num_streamids >= MAX_MASTER_STREAMIDS) {
----- -         ret = -ENOSPC;
----- -         goto out_put_group;
----- - }
+++++ + if (cfg->num_streamids >= MAX_MASTER_STREAMIDS)
+++++ +         return -ENOSPC;
       
        /*
         * Assume Stream ID == Requester ID for now.
                cfg->streamids[cfg->num_streamids++] = sid;
       
        return 0;
----- -out_put_group:
----- - iommu_group_put(group);
----- - return ret;
       }
       
----- -static int arm_smmu_add_platform_device(struct device *dev)
+++++ +static int arm_smmu_init_platform_device(struct device *dev,
+++++ +                                  struct iommu_group *group)
       {
----- - struct iommu_group *group;
----- - struct arm_smmu_master *master;
        struct arm_smmu_device *smmu = find_smmu_for_device(dev);
+++++ + struct arm_smmu_master *master;
       
        if (!smmu)
                return -ENODEV;
        if (!master)
                return -ENODEV;
       
----- - /* No automatic group creation for platform devices */
----- - group = iommu_group_alloc();
----- - if (IS_ERR(group))
----- -         return PTR_ERR(group);
----- -
        iommu_group_set_iommudata(group, &master->cfg, NULL);
----- - return iommu_group_add_device(group, dev);
+++++ +
+++++ + return 0;
       }
       
       static int arm_smmu_add_device(struct device *dev)
       {
----- - if (dev_is_pci(dev))
----- -         return arm_smmu_add_pci_device(to_pci_dev(dev));
+++++ + struct iommu_group *group;
+++ + +
   -    return arm_smmu_add_platform_device(dev);
+++++ + group = iommu_group_get_for_dev(dev);
+++++ + if (IS_ERR(group))
+++++ +         return PTR_ERR(group);
   +   
--- - - return arm_smmu_add_platform_device(dev);
+++++ + return 0;
       }
       
       static void arm_smmu_remove_device(struct device *dev)
        iommu_group_remove_device(dev);
       }
       
+++++ +static struct iommu_group *arm_smmu_device_group(struct device *dev)
+++++ +{
+++++ + struct iommu_group *group;
+++++ + int ret;
+++++ +
+++++ + if (dev_is_pci(dev))
+++++ +         group = pci_device_group(dev);
+++++ + else
+++++ +         group = generic_device_group(dev);
+++++ +
+++++ + if (IS_ERR(group))
+++++ +         return group;
+++++ +
+++++ + if (dev_is_pci(dev))
+++++ +         ret = arm_smmu_init_pci_device(to_pci_dev(dev), group);
+++++ + else
+++++ +         ret = arm_smmu_init_platform_device(dev, group);
+++++ +
+++++ + if (ret) {
+++++ +         iommu_group_put(group);
+++++ +         group = ERR_PTR(ret);
+++++ + }
+++++ +
+++++ + return group;
+++++ +}
+++++ +
       static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
                                    enum iommu_attr attr, void *data)
       {
@@@@@@@@ -1430,6 -1430,6 -1430,6 -1433,6 -1430,6 -1444,7 -1430,6 +1447,7 @@@@@@@@ static struct iommu_ops arm_smmu_ops = 
        .iova_to_phys           = arm_smmu_iova_to_phys,
        .add_device             = arm_smmu_add_device,
        .remove_device          = arm_smmu_remove_device,
+++++ + .device_group           = arm_smmu_device_group,
        .domain_get_attr        = arm_smmu_domain_get_attr,
        .domain_set_attr        = arm_smmu_domain_set_attr,
        .pgsize_bitmap          = -1UL, /* Restricted during device attach */
index d65cf42399e8e5aa0f856a1ab6869c041adc0c48,c5426e847255367bd1076dd4bed0766297fb99ff,041bc1810a86131deb77152dd6b5a7cd43338a5d,041bc1810a86131deb77152dd6b5a7cd43338a5d,041bc1810a86131deb77152dd6b5a7cd43338a5d,884d9133c63697d48baf8b5b3668419b939131f3,2d7349a3ee1496408f051b4da8accebc8dd02ec1..16b243ead874149d53848d1db0eee5a94cc938ed
       #include <linux/mempool.h>
       #include <linux/memory.h>
       #include <linux/timer.h>
+ +++++#include <linux/io.h>
       #include <linux/iova.h>
       #include <linux/iommu.h>
       #include <linux/intel-iommu.h>
@@@@@@@@ -2115,19 -2116,15 -2115,15 -2115,15 -2115,15 -2115,15 -2115,15 +2116,19 @@@@@@@@ static int __domain_mapping(struct dmar
                                return -ENOMEM;
                        /* It is large page*/
                        if (largepage_lvl > 1) {
 ++++++                         unsigned long nr_superpages, end_pfn;
 ++++++
                                pteval |= DMA_PTE_LARGE_PAGE;
                                lvl_pages = lvl_to_nr_pages(largepage_lvl);
 ++++++
 ++++++                         nr_superpages = sg_res / lvl_pages;
 ++++++                         end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
 ++++++
                                /*
                                 * Ensure that old small page tables are
 ------                          * removed to make room for superpage,
 ------                          * if they exist.
 ++++++                          * removed to make room for superpage(s).
                                 */
 ------                         dma_pte_free_pagetable(domain, iov_pfn,
 ------                                                iov_pfn + lvl_pages - 1);
 ++++++                         dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
                        } else {
                                pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
                        }
@@@@@@@@ -2305,7 -2302,6 -2301,6 -2301,6 -2301,6 -2301,6 -2301,6 +2306,7 @@@@@@@@ static struct dmar_domain *dmar_insert_
       
        if (ret) {
                spin_unlock_irqrestore(&device_domain_lock, flags);
 ++++++         free_devinfo_mem(info);
                return NULL;
        }
       
@@@@@@@@ -2434,17 -2430,11 -2429,17 -2429,17 -2429,17 -2429,17 -2429,17 +2435,11 @@@@@@@@ static int iommu_domain_identity_map(st
                                  DMA_PTE_READ|DMA_PTE_WRITE);
       }
       
- -----static int iommu_prepare_identity_map(struct device *dev,
- -----                               unsigned long long start,
- -----                               unsigned long long end)
+ +++++static int domain_prepare_identity_map(struct device *dev,
+ +++++                                struct dmar_domain *domain,
+ +++++                                unsigned long long start,
+ +++++                                unsigned long long end)
       {
- ----- struct dmar_domain *domain;
- ----- int ret;
- -----
- ----- domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
- ----- if (!domain)
- -----         return -ENOMEM;
- -----
        /* For _hardware_ passthrough, don't bother. But for software
           passthrough, we do it anyway -- it may indicate a memory
           range which is reserved in E820, so which didn't get set
                        dmi_get_system_info(DMI_BIOS_VENDOR),
                        dmi_get_system_info(DMI_BIOS_VERSION),
                     dmi_get_system_info(DMI_PRODUCT_VERSION));
- -----         ret = -EIO;
- -----         goto error;
+ +++++         return -EIO;
        }
       
        if (end >> agaw_to_width(domain->agaw)) {
                     dmi_get_system_info(DMI_BIOS_VENDOR),
                     dmi_get_system_info(DMI_BIOS_VERSION),
                     dmi_get_system_info(DMI_PRODUCT_VERSION));
- -----         ret = -EIO;
- -----         goto error;
+ +++++         return -EIO;
        }
       
- ----- ret = iommu_domain_identity_map(domain, start, end);
- ----- if (ret)
- -----         goto error;
+ +++++ return iommu_domain_identity_map(domain, start, end);
+ +++++}
       
- ----- return 0;
+ +++++static int iommu_prepare_identity_map(struct device *dev,
+ +++++                               unsigned long long start,
+ +++++                               unsigned long long end)
+ +++++{
+ +++++ struct dmar_domain *domain;
+ +++++ int ret;
+ +++++
+ +++++ domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ +++++ if (!domain)
+ +++++         return -ENOMEM;
+ +++++
+ +++++ ret = domain_prepare_identity_map(dev, domain, start, end);
+ +++++ if (ret)
+ +++++         domain_exit(domain);
       
- ----- error:
- ----- domain_exit(domain);
        return ret;
       }
       
@@@@@@@@ -2812,18 -2810,18 -2807,18 -2807,18 -2807,18 -2807,18 -2807,18 +2815,18 @@@@@@@@ static void intel_iommu_init_qi(struct 
       }
       
       static int copy_context_table(struct intel_iommu *iommu,
- -----                       struct root_entry __iomem *old_re,
+ +++++                       struct root_entry *old_re,
                              struct context_entry **tbl,
                              int bus, bool ext)
       {
        int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
- ----- struct context_entry __iomem *old_ce = NULL;
        struct context_entry *new_ce = NULL, ce;
+ +++++ struct context_entry *old_ce = NULL;
        struct root_entry re;
        phys_addr_t old_ce_phys;
       
        tbl_idx = ext ? bus * 2 : bus;
- ----- memcpy_fromio(&re, old_re, sizeof(re));
+ +++++ memcpy(&re, old_re, sizeof(re));
       
        for (devfn = 0; devfn < 256; devfn++) {
                /* First calculate the correct index */
                        }
       
                        ret = -ENOMEM;
- -----                 old_ce = ioremap_cache(old_ce_phys, PAGE_SIZE);
+ +++++                 old_ce = memremap(old_ce_phys, PAGE_SIZE,
+ +++++                                 MEMREMAP_WB);
                        if (!old_ce)
                                goto out;
       
                }
       
                /* Now copy the context entry */
- -----         memcpy_fromio(&ce, old_ce + idx, sizeof(ce));
+ +++++         memcpy(&ce, old_ce + idx, sizeof(ce));
       
                if (!__context_present(&ce))
                        continue;
        __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
       
       out_unmap:
- ----- iounmap(old_ce);
+ +++++ memunmap(old_ce);
       
       out:
        return ret;
       
       static int copy_translation_tables(struct intel_iommu *iommu)
       {
- ----- struct root_entry __iomem *old_rt;
        struct context_entry **ctxt_tbls;
+ +++++ struct root_entry *old_rt;
        phys_addr_t old_rt_phys;
        int ctxt_table_entries;
        unsigned long flags;
        if (!old_rt_phys)
                return -EINVAL;
       
- ----- old_rt = ioremap_cache(old_rt_phys, PAGE_SIZE);
+ +++++ old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
        if (!old_rt)
                return -ENOMEM;
       
        ret = 0;
       
       out_unmap:
- ----- iounmap(old_rt);
+ +++++ memunmap(old_rt);
       
        return ret;
       }
@@@@@@@@ -3220,8 -3219,6 -3215,8 -3215,8 -3215,8 -3215,8 -3215,6 +3224,8 @@@@@@@@ static struct iova *intel_alloc_iova(st
       
        /* Restrict dma_mask to the width that the iommu can handle */
        dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
 +    + /* Ensure we reserve the whole size-aligned region */
 +    + nrpages = __roundup_pow_of_two(nrpages);
       
        if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
                /*
       
       static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)
       {
+ +++++ struct dmar_rmrr_unit *rmrr;
        struct dmar_domain *domain;
+ +++++ struct device *i_dev;
+ +++++ int i, ret;
       
        domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
        if (!domain) {
                return NULL;
        }
       
+ +++++ /* We have a new domain - setup possible RMRRs for the device */
+ +++++ rcu_read_lock();
+ +++++ for_each_rmrr_units(rmrr) {
+ +++++         for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
+ +++++                                   i, i_dev) {
+ +++++                 if (i_dev != dev)
+ +++++                         continue;
+ +++++
+ +++++                 ret = domain_prepare_identity_map(dev, domain,
+ +++++                                                   rmrr->base_address,
+ +++++                                                   rmrr->end_address);
+ +++++                 if (ret)
+ +++++                         dev_err(dev, "Mapping reserved region failed\n");
+ +++++         }
+ +++++ }
+ +++++ rcu_read_unlock();
+ +++++
        return domain;
       }
       
@@@@@@@@ -3718,7 -3735,7 -3713,7 -3713,7 -3713,7 -3713,7 -3711,7 +3742,7 @@@@@@@@ static inline int iommu_devinfo_cache_i
       static int __init iommu_init_mempool(void)
       {
        int ret;
 -    - ret = iommu_iova_cache_init();
 +    + ret = iova_cache_get();
        if (ret)
                return ret;
       
       
        kmem_cache_destroy(iommu_domain_cache);
       domain_error:
 -    - iommu_iova_cache_destroy();
 +    + iova_cache_put();
       
        return -ENOMEM;
       }
@@@@@@@@ -3741,7 -3758,7 -3736,7 -3736,7 -3736,7 -3736,7 -3734,7 +3765,7 @@@@@@@@ static void __init iommu_exit_mempool(v
       {
        kmem_cache_destroy(iommu_devinfo_cache);
        kmem_cache_destroy(iommu_domain_cache);
 -    - iommu_iova_cache_destroy();
 +    + iova_cache_put();
       }
       
       static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
@@@@@@@@ -4877,6 -4894,6 -4872,6 -4872,6 -4872,6 -4872,7 -4870,6 +4901,7 @@@@@@@@ static const struct iommu_ops intel_iom
        .iova_to_phys   = intel_iommu_iova_to_phys,
        .add_device     = intel_iommu_add_device,
        .remove_device  = intel_iommu_remove_device,
+++++ + .device_group   = pci_device_group,
        .pgsize_bitmap  = INTEL_IOMMU_PGSIZES,
       };