| @@ -3019,7 +3019,13 @@ static int __init init_dmars(void) · 3018 unmodified lines |
| 3019 | 3019 | |
| 3020 | 3020 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 3021 | 3021 | if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) { |
| 3022 | + /* |
| 3023 | + * Call dmar_alloc_hwirq() with dmar_global_lock held, |
| 3024 | + * could cause possible lock race condition. |
| 3025 | + */ |
| 3026 | + up_write(&dmar_global_lock); |
| 3022 | 3027 | ret = intel_svm_enable_prq(iommu); |
| 3028 | + down_write(&dmar_global_lock); |
| 3023 | 3029 | if (ret) |
| 3024 | 3030 | goto free_iommu; |
| 3025 | 3031 | } |
| @@ -3932,6 +3938,7 @@ int __init intel_iommu_init(void) · 906 unmodified lines |
| 3932 | 3938 | force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) || |
| 3933 | 3939 | platform_optin_force_iommu(); |
| 3934 | 3940 | |
| 3941 | + down_write(&dmar_global_lock); |
| 3935 | 3942 | if (dmar_table_init()) { |
| 3936 | 3943 | if (force_on) |
| 3937 | 3944 | panic("tboot: Failed to initialize DMAR table\n"); |
| @@ -3944,6 +3951,16 @@ int __init intel_iommu_init(void) · 6 unmodified lines |
| 3944 | 3951 | goto out_free_dmar; |
| 3945 | 3952 | } |
| 3946 | 3953 | |
| 3954 | + up_write(&dmar_global_lock); |
| 3955 | + |
| 3956 | + /* |
| 3957 | + * The bus notifier takes the dmar_global_lock, so lockdep will |
| 3958 | + * complain later when we register it under the lock. |
| 3959 | + */ |
| 3960 | + dmar_register_bus_notifier(); |
| 3961 | + |
| 3962 | + down_write(&dmar_global_lock); |
| 3963 | + |
| 3947 | 3964 | if (!no_iommu) |
| 3948 | 3965 | intel_iommu_debugfs_init(); |
| 3949 | 3966 | |
| @@ -3988,9 +4005,11 @@ int __init intel_iommu_init(void) · 38 unmodified lines |
| 3988 | 4005 | pr_err("Initialization failed\n"); |
| 3989 | 4006 | goto out_free_dmar; |
| 3990 | 4007 | } |
| 4008 | + up_write(&dmar_global_lock); |
| 3991 | 4009 | |
| 3992 | 4010 | init_iommu_pm_ops(); |
| 3993 | 4011 | |
| 4012 | + down_read(&dmar_global_lock); |
| 3994 | 4013 | for_each_active_iommu(iommu, drhd) { |
| 3995 | 4014 | /* |
| 3996 | 4015 | * The flush queue implementation does not perform |
| @@ -4008,11 +4027,13 @@ int __init intel_iommu_init(void) · 11 unmodified lines |
| 4008 | 4027 | "%s", iommu->name); |
| 4009 | 4028 | iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL); |
| 4010 | 4029 | } |
| 4030 | + up_read(&dmar_global_lock); |
| 4011 | 4031 | |
| 4012 | 4032 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
| 4013 | 4033 | if (si_domain && !hw_pass_through) |
| 4014 | 4034 | register_memory_notifier(&intel_iommu_memory_nb); |
| 4015 | 4035 | |
| 4036 | + down_read(&dmar_global_lock); |
| 4016 | 4037 | if (probe_acpi_namespace_devices()) |
| 4017 | 4038 | pr_warn("ACPI name space devices didn't probe correctly\n"); |
| 4018 | 4039 | |
| @@ -4023,15 +4044,17 @@ int __init intel_iommu_init(void) · 4 unmodified lines |
| 4023 | 4044 | |
| 4024 | 4045 | iommu_disable_protect_mem_regions(iommu); |
| 4025 | 4046 | } |
| 4047 | + up_read(&dmar_global_lock); |
| 4026 | 4048 | |
| 4027 | | − intel_iommu_enabled = 1; |
| 4028 | | − dmar_register_bus_notifier(); |
| 4029 | 4049 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); |
| 4030 | 4050 | |
| 4051 | + intel_iommu_enabled = 1; |
| 4052 | + |
| 4031 | 4053 | return 0; |
| 4032 | 4054 | |
| 4033 | 4055 | out_free_dmar: |
| 4034 | 4056 | intel_iommu_free_dmars(); |
| 4057 | + up_write(&dmar_global_lock); |
| 4035 | 4058 | return ret; |
| 4036 | 4059 | } |
| 4037 | 4060 | |