Loading arch/x86/mm/init_32.c +4 −2 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ struct add_highpages_data { unsigned long end_pfn; }; static void __init add_highpages_work_fn(unsigned long start_pfn, static int __init add_highpages_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax) { int node_pfn; Loading @@ -311,7 +311,7 @@ static void __init add_highpages_work_fn(unsigned long start_pfn, final_start_pfn = max(start_pfn, data->start_pfn); final_end_pfn = min(end_pfn, data->end_pfn); if (final_start_pfn >= final_end_pfn) return; return 0; for (node_pfn = final_start_pfn; node_pfn < final_end_pfn; node_pfn++) { Loading @@ -321,6 +321,8 @@ static void __init add_highpages_work_fn(unsigned long start_pfn, add_one_highpage_init(page, node_pfn); } return 0; } void __init add_highpages_with_active_regions(int nid, unsigned long start_pfn, Loading drivers/pci/intel-iommu.c +37 −14 Original line number Diff line number Diff line Loading @@ -1637,12 +1637,43 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, } #ifdef CONFIG_DMAR_GFX_WA extern int arch_get_ram_range(int slot, u64 *addr, u64 *size); struct iommu_prepare_data { struct pci_dev *pdev; int ret; }; static int __init iommu_prepare_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax) { struct iommu_prepare_data *data; data = (struct iommu_prepare_data *)datax; data->ret = iommu_prepare_identity_map(data->pdev, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); return data->ret; } static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) { int nid; struct iommu_prepare_data data; data.pdev = pdev; data.ret = 0; for_each_online_node(nid) { work_with_active_regions(nid, iommu_prepare_work_fn, &data); if (data.ret) return data.ret; } return data.ret; } static void __init iommu_prepare_gfx_mapping(void) { struct pci_dev *pdev = NULL; u64 base, size; int slot; int ret; for_each_pci_dev(pdev) { Loading @@ -1651,16 +1682,8 @@ static void __init iommu_prepare_gfx_mapping(void) continue; printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", pci_name(pdev)); slot = arch_get_ram_range(0, &base, &size); while (slot >= 0) { ret = iommu_prepare_identity_map(pdev, base, base + size); ret = iommu_prepare_with_active_regions(pdev); if (ret) goto error; slot = arch_get_ram_range(slot, &base, &size); } continue; error: printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); } } Loading include/linux/mm.h +1 −1 Original line number Diff line number Diff line Loading @@ -1011,7 +1011,7 @@ extern unsigned long find_min_pfn_with_active_regions(void); extern unsigned long find_max_pfn_with_active_regions(void); extern void free_bootmem_with_active_regions(int nid, unsigned long max_low_pfn); typedef void (*work_fn_t)(unsigned long, unsigned long, void *); typedef int (*work_fn_t)(unsigned long, unsigned long, void *); extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); extern void sparse_memory_present_with_active_regions(int nid); #ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID Loading mm/page_alloc.c +7 −3 Original line number Diff line number Diff line Loading @@ -2932,10 +2932,14 @@ void __init free_bootmem_with_active_regions(int nid, void __init work_with_active_regions(int nid, work_fn_t work_fn, void *data) { int i; int ret; for_each_active_range_index_in_nid(i, nid) work_fn(early_node_map[i].start_pfn, early_node_map[i].end_pfn, data); for_each_active_range_index_in_nid(i, nid) { ret = work_fn(early_node_map[i].start_pfn, early_node_map[i].end_pfn, data); if (ret) break; } } /** * sparse_memory_present_with_active_regions - Call memory_present for each active range Loading Loading
arch/x86/mm/init_32.c +4 −2 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ struct add_highpages_data { unsigned long end_pfn; }; static void __init add_highpages_work_fn(unsigned long start_pfn, static int __init add_highpages_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax) { int node_pfn; Loading @@ -311,7 +311,7 @@ static void __init add_highpages_work_fn(unsigned long start_pfn, final_start_pfn = max(start_pfn, data->start_pfn); final_end_pfn = min(end_pfn, data->end_pfn); if (final_start_pfn >= final_end_pfn) return; return 0; for (node_pfn = final_start_pfn; node_pfn < final_end_pfn; node_pfn++) { Loading @@ -321,6 +321,8 @@ static void __init add_highpages_work_fn(unsigned long start_pfn, add_one_highpage_init(page, node_pfn); } return 0; } void __init add_highpages_with_active_regions(int nid, unsigned long start_pfn, Loading
drivers/pci/intel-iommu.c +37 −14 Original line number Diff line number Diff line Loading @@ -1637,12 +1637,43 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, } #ifdef CONFIG_DMAR_GFX_WA extern int arch_get_ram_range(int slot, u64 *addr, u64 *size); struct iommu_prepare_data { struct pci_dev *pdev; int ret; }; static int __init iommu_prepare_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax) { struct iommu_prepare_data *data; data = (struct iommu_prepare_data *)datax; data->ret = iommu_prepare_identity_map(data->pdev, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); return data->ret; } static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) { int nid; struct iommu_prepare_data data; data.pdev = pdev; data.ret = 0; for_each_online_node(nid) { work_with_active_regions(nid, iommu_prepare_work_fn, &data); if (data.ret) return data.ret; } return data.ret; } static void __init iommu_prepare_gfx_mapping(void) { struct pci_dev *pdev = NULL; u64 base, size; int slot; int ret; for_each_pci_dev(pdev) { Loading @@ -1651,16 +1682,8 @@ static void __init iommu_prepare_gfx_mapping(void) continue; printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", pci_name(pdev)); slot = arch_get_ram_range(0, &base, &size); while (slot >= 0) { ret = iommu_prepare_identity_map(pdev, base, base + size); ret = iommu_prepare_with_active_regions(pdev); if (ret) goto error; slot = arch_get_ram_range(slot, &base, &size); } continue; error: printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); } } Loading
include/linux/mm.h +1 −1 Original line number Diff line number Diff line Loading @@ -1011,7 +1011,7 @@ extern unsigned long find_min_pfn_with_active_regions(void); extern unsigned long find_max_pfn_with_active_regions(void); extern void free_bootmem_with_active_regions(int nid, unsigned long max_low_pfn); typedef void (*work_fn_t)(unsigned long, unsigned long, void *); typedef int (*work_fn_t)(unsigned long, unsigned long, void *); extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); extern void sparse_memory_present_with_active_regions(int nid); #ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID Loading
mm/page_alloc.c +7 −3 Original line number Diff line number Diff line Loading @@ -2932,10 +2932,14 @@ void __init free_bootmem_with_active_regions(int nid, void __init work_with_active_regions(int nid, work_fn_t work_fn, void *data) { int i; int ret; for_each_active_range_index_in_nid(i, nid) work_fn(early_node_map[i].start_pfn, early_node_map[i].end_pfn, data); for_each_active_range_index_in_nid(i, nid) { ret = work_fn(early_node_map[i].start_pfn, early_node_map[i].end_pfn, data); if (ret) break; } } /** * sparse_memory_present_with_active_regions - Call memory_present for each active range Loading