devm_memremap_pages() is currently used by the PCI P2PDMA code to create struct page mappings for IO memory. At present, these mappings are created with PAGE_KERNEL which implies setting the PAT bits to be WB. However, on x86, an mtrr register will typically override this and force the cache type to be UC-. In the case firmware doesn't set this register it is effectively WB and will typically result in a machine check exception when it's accessed. Other arches are not currently likely to function correctly seeing they don't have any MTRR registers to fall back on. To solve this, provide a way to specify the pgprot value explicitly to arch_add_memory(). Of the arches that support MEMORY_HOTPLUG: x86_64, and arm64 need a simple change to pass the pgprot_t down to their respective functions which set up the page tables. For x86_32, set the page tables explicitly using _set_memory_prot() (seeing they are already mapped). For ia64, s390 and sh, reject anything but PAGE_KERNEL settings -- this should be fine, for now, seeing these architectures don't support ZONE_DEVICE. A check in __add_pages() is also added to ensure the pgprot parameter was set for all arches.
Showing the changes to include/linux (1 of 10 files). Show all
Unified · Split
| @@ -60,9 +60,12 @@ enum { · 59 unmodified lines | |||
| 60 | /* | 60 | /* |
| 61 | * Extended parameters for memory hotplug: | 61 | * Extended parameters for memory hotplug: |
| 62 | * altmap: alternative allocator for memmap array (optional) | 62 | * altmap: alternative allocator for memmap array (optional) |
| 63 | * pgprot: page protection flags to apply to newly created page tables | ||
| 64 | * (required) | ||
| 63 | */ | 65 | */ |
| 64 | struct mhp_params { | 66 | struct mhp_params { |
| 65 | struct vmem_altmap *altmap; | 67 | struct vmem_altmap *altmap; |
| 68 | pgprot_t pgprot; | ||
| 66 | }; | 69 | }; |
| 67 | 70 | ||
| 68 | /* | 71 | /* |