Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'iommu-fixes-v6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

Pull iommu fixes from Joerg Roedel:

- iommupt: Fix an oops found by syzcaller in the new generic
IO-page-table code.

- AMD-Vi: Fix IO_PAGE_FAULTs in kdump kernels triggered by re-using
domain-ids from previous kernel.

* tag 'iommu-fixes-v6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
amd/iommu: Make protection domain ID functions non-static
amd/iommu: Preserve domain ids inside the kdump kernel
iommupt: Return ERR_PTR from _table_alloc()

+47 -12
+5
drivers/iommu/amd/amd_iommu.h
··· 173 173 bool translation_pre_enabled(struct amd_iommu *iommu); 174 174 int __init add_special_device(u8 type, u8 id, u32 *devid, bool cmd_line); 175 175 176 + int amd_iommu_pdom_id_alloc(void); 177 + int amd_iommu_pdom_id_reserve(u16 id, gfp_t gfp); 178 + void amd_iommu_pdom_id_free(int id); 179 + void amd_iommu_pdom_id_destroy(void); 180 + 176 181 #ifdef CONFIG_DMI 177 182 void amd_iommu_apply_ivrs_quirks(void); 178 183 #else
+21 -3
drivers/iommu/amd/init.c
··· 1136 1136 static bool __reuse_device_table(struct amd_iommu *iommu) 1137 1137 { 1138 1138 struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg; 1139 - u32 lo, hi, old_devtb_size; 1139 + struct dev_table_entry *old_dev_tbl_entry; 1140 + u32 lo, hi, old_devtb_size, devid; 1140 1141 phys_addr_t old_devtb_phys; 1142 + u16 dom_id; 1143 + bool dte_v; 1141 1144 u64 entry; 1142 1145 1143 1146 /* Each IOMMU use separate device table with the same size */ ··· 1174 1171 if (pci_seg->old_dev_tbl_cpy == NULL) { 1175 1172 pr_err("Failed to remap memory for reusing old device table!\n"); 1176 1173 return false; 1174 + } 1175 + 1176 + for (devid = 0; devid <= pci_seg->last_bdf; devid++) { 1177 + old_dev_tbl_entry = &pci_seg->old_dev_tbl_cpy[devid]; 1178 + dte_v = FIELD_GET(DTE_FLAG_V, old_dev_tbl_entry->data[0]); 1179 + dom_id = FIELD_GET(DEV_DOMID_MASK, old_dev_tbl_entry->data[1]); 1180 + 1181 + if (!dte_v || !dom_id) 1182 + continue; 1183 + /* 1184 + * ID reservation can fail with -ENOSPC when there 1185 + * are multiple devices present in the same domain, 1186 + * hence check only for -ENOMEM. 1187 + */ 1188 + if (amd_iommu_pdom_id_reserve(dom_id, GFP_KERNEL) == -ENOMEM) 1189 + return false; 1177 1190 } 1178 1191 1179 1192 return true; ··· 3146 3127 3147 3128 static void __init free_dma_resources(void) 3148 3129 { 3149 - ida_destroy(&pdom_ids); 3150 - 3130 + amd_iommu_pdom_id_destroy(); 3151 3131 free_unity_maps(); 3152 3132 } 3153 3133
+18 -9
drivers/iommu/amd/iommu.c
··· 1811 1811 * contain. 1812 1812 * 1813 1813 ****************************************************************************/ 1814 - 1815 - static int pdom_id_alloc(void) 1814 + int amd_iommu_pdom_id_alloc(void) 1816 1815 { 1817 1816 return ida_alloc_range(&pdom_ids, 1, MAX_DOMAIN_ID - 1, GFP_ATOMIC); 1818 1817 } 1819 1818 1820 - static void pdom_id_free(int id) 1819 + int amd_iommu_pdom_id_reserve(u16 id, gfp_t gfp) 1820 + { 1821 + return ida_alloc_range(&pdom_ids, id, id, gfp); 1822 + } 1823 + 1824 + void amd_iommu_pdom_id_free(int id) 1821 1825 { 1822 1826 ida_free(&pdom_ids, id); 1827 + } 1828 + 1829 + void amd_iommu_pdom_id_destroy(void) 1830 + { 1831 + ida_destroy(&pdom_ids); 1823 1832 } 1824 1833 1825 1834 static void free_gcr3_tbl_level1(u64 *tbl) ··· 1873 1864 gcr3_info->glx = 0; 1874 1865 1875 1866 /* Free per device domain ID */ 1876 - pdom_id_free(gcr3_info->domid); 1867 + amd_iommu_pdom_id_free(gcr3_info->domid); 1877 1868 1878 1869 iommu_free_pages(gcr3_info->gcr3_tbl); 1879 1870 gcr3_info->gcr3_tbl = NULL; ··· 1909 1900 return -EBUSY; 1910 1901 1911 1902 /* Allocate per device domain ID */ 1912 - domid = pdom_id_alloc(); 1903 + domid = amd_iommu_pdom_id_alloc(); 1913 1904 if (domid <= 0) 1914 1905 return -ENOSPC; 1915 1906 gcr3_info->domid = domid; 1916 1907 1917 1908 gcr3_info->gcr3_tbl = iommu_alloc_pages_node_sz(nid, GFP_ATOMIC, SZ_4K); 1918 1909 if (gcr3_info->gcr3_tbl == NULL) { 1919 - pdom_id_free(domid); 1910 + amd_iommu_pdom_id_free(domid); 1920 1911 return -ENOMEM; 1921 1912 } 1922 1913 ··· 2512 2503 if (!domain) 2513 2504 return NULL; 2514 2505 2515 - domid = pdom_id_alloc(); 2506 + domid = amd_iommu_pdom_id_alloc(); 2516 2507 if (domid <= 0) { 2517 2508 kfree(domain); 2518 2509 return NULL; ··· 2811 2802 2812 2803 WARN_ON(!list_empty(&domain->dev_list)); 2813 2804 pt_iommu_deinit(&domain->iommu); 2814 - pdom_id_free(domain->id); 2805 + amd_iommu_pdom_id_free(domain->id); 2815 2806 kfree(domain); 2816 2807 } 2817 2808 ··· 2862 2853 domain->ops = &identity_domain_ops; 2863 2854 domain->owner = &amd_iommu_ops; 2864 2855 2865 - identity_domain.id = pdom_id_alloc(); 2856 + identity_domain.id = amd_iommu_pdom_id_alloc(); 2866 2857 2867 2858 protection_domain_init(&identity_domain); 2868 2859 }
+3
drivers/iommu/generic_pt/iommu_pt.h
··· 372 372 373 373 table_mem = iommu_alloc_pages_node_sz(iommu_table->nid, gfp, 374 374 log2_to_int(lg2sz)); 375 + if (!table_mem) 376 + return ERR_PTR(-ENOMEM); 377 + 375 378 if (pt_feature(common, PT_FEAT_DMA_INCOHERENT) && 376 379 mode == ALLOC_NORMAL) { 377 380 int ret = iommu_pages_start_incoherent(