x86/mm changes for v4.5
Subsystems (5)
Linus,
Please pull the latest x86-mm-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-mm-for-linus
# HEAD: 1f1a89ac05f6e88aa341e86e57435fdbb1177c0c x86/mm: Micro-optimise clflush_cache_range()
The main changes in this cycle were:
- make the debugfs 'kernel_page_tables' file read-only, as it only has read ops. (Borislav Petkov)
- micro-optimize clflush_cache_range() (Chris Wilson)
- swiotlb enhancements, which fixes certain KVM emulated devices (Igor Mammedov)
- fix an LDT related debug message (Jan Beulich)
- modularize CONFIG_X86_PTDUMP (Kees Cook)
- tone down an overly alarming warning (Laura Abbott)
- Mark variable __initdata (Rasmus Villemoes)
- PAT additions (Toshi Kani)
out-of-topic modifications in x86-mm-for-linus:
-------------------------------------------------
include/asm-generic/pgtable.h # d9fe4fab1197: x86/mm/pat: Add untrack_pfn_ include/linux/bootmem.h # 8dd330300197: x86/mm: Introduce max_possib mm/bootmem.c # 8dd330300197: x86/mm: Introduce max_possib mm/mremap.c # d9fe4fab1197: x86/mm/pat: Add untrack_pfn_ mm/nobootmem.c # 8dd330300197: x86/mm: Introduce max_possib
Thanks,
Ingo
------------------>
Borislav Petkov (1):
x86/mm/ptdump: Make (debugfs)/kernel_page_tables read-only
Chris Wilson (1):
x86/mm: Micro-optimise clflush_cache_range()
Igor Mammedov (2):
x86/mm: Introduce max_possible_pfn
x86/mm/64: Enable SWIOTLB if system has SRAT memory regions above MAX_DMA32_PFN
Jan Beulich (1):
x86/LDT: Print the real LDT base address
Kees Cook (1):
x86/mm: Turn CONFIG_X86_PTDUMP into a module
Laura Abbott (1):
x86/mm: Drop WARN from multi-BAR check
Rasmus Villemoes (1):
x86/mm/mtrr: Mark the 'range_new' static variable in mtrr_calc_range_state() as __initdata
Toshi Kani (2):
x86/mm/pat: Add untrack_pfn_moved for mremap x86/mm/pat: Change free_memtype() to support shrinking case
arch/x86/Kconfig.debug | 2 +- arch/x86/kernel/cpu/mtrr/cleanup.c | 11 ++++++-- arch/x86/kernel/pci-swiotlb.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/setup.c | 2 ++ arch/x86/mm/Makefile | 1 + arch/x86/mm/debug_pagetables.c | 46 +++++++++++++++++++++++++++++++++ arch/x86/mm/dump_pagetables.c | 34 ++----------------------- arch/x86/mm/ioremap.c | 4 +-- arch/x86/mm/pageattr.c | 10 +++++--- arch/x86/mm/pat.c | 12 ++++++++- arch/x86/mm/pat_rbtree.c | 52 +++++++++++++++++++++++++++++++------- arch/x86/mm/srat.c | 2 ++ include/asm-generic/pgtable.h | 10 +++++++- include/linux/bootmem.h | 4 +++ mm/bootmem.c | 1 + mm/mremap.c | 4 +++ mm/nobootmem.c | 1 + 18 files changed, 146 insertions(+), 54 deletions(-) create mode 100644 arch/x86/mm/debug_pagetables.c
arch/x86/Kconfig.debug +1 -1
@@ -69,7 +69,7 @@ config X86_PTDUMP_CORE def_bool n config X86_PTDUMP - bool "Export kernel pagetable layout to userspace via debugfs" + tristate "Export kernel pagetable layout to userspace via debugfs" depends on DEBUG_KERNEL select DEBUG_FS select X86_PTDUMP_CORE
arch/x86/kernel/cpu/mtrr/cleanup.c +9 -2
@@ -593,9 +593,16 @@ mtrr_calc_range_state(u64 chunk_size, u64 gran_size, unsigned long x_remove_base, unsigned long x_remove_size, int i) { - static struct range range_new[RANGE_NUM]; +/* +* range_new should really be an automatic variable, but +* putting 4096 bytes on the stack is frowned upon, to put it +* mildly. It is safe to make it a static __initdata variable, +* since mtrr_calc_range_state is only called during init and +* there's no way it will call itself recursively. +*/ +static struct range range_new[RANGE_NUM ]__initdata ;unsigned long range_sums_new; -static int nr_range_new; +int nr_range_new;int num_reg;/* Convert ranges to var ranges state: */
arch/x86/kernel/pci-swiotlb.c +1 -1
@@ -88,7 +88,7 @@ int __init pci_swiotlb_detect_4gb(void) {/* don't initialize swiotlb if iommu=off (no_iommu=1) */ #ifdef CONFIG_X86_64 -if (!no_iommu && max_pfn >MAX_DMA32_PFN ) +if (!no_iommu && max_possible_pfn >MAX_DMA32_PFN ) swiotlb =1 ;#endif return swiotlb;
arch/x86/kernel/process_64.c +1 -1
@@ -125,7 +125,7 @@ void release_thread(struct task_struct *dead_task)if (dead_task->mm->context.ldt) {pr_warn ("WARNING: dead process %s still has LDT? <%p/%d>\n" , dead_task->comm, - dead_task->mm->context.ldt, + dead_task->mm->context.ldt->entries, dead_task->mm->context.ldt->size);BUG (); }
arch/x86/kernel/setup.c +2 -0
@@ -1048,6 +1048,8 @@ void __init setup_arch(char **cmdline_p)if (mtrr_trim_uncached_memory (max_pfn)) max_pfn =e820_end_of_ram_pfn (); + max_possible_pfn = max_pfn; +#ifdef CONFIG_X86_32 /* max_low_pfn get updated here */ find_low_pfn_range ();
arch/x86/mm/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_X86_PTDUMP_CORE) += dump_pagetables.o +obj-$(CONFIG_X86_PTDUMP) += debug_pagetables.o obj-$(CONFIG_HIGHMEM) += highmem_32.o
arch/x86/mm/debug_pagetables.c new file +46 -0
46 lines not on this page · raw message
arch/x86/mm/dump_pagetables.c +2 -32
@@ -426,38 +426,15 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd) {ptdump_walk_pgd_level_core (m, pgd, false); } +EXPORT_SYMBOL_GPL (ptdump_walk_pgd_level);void ptdump_walk_pgd_level_checkwx (void ) {ptdump_walk_pgd_level_core (NULL ,NULL , true); } -#ifdef CONFIG_X86_PTDUMP -static int ptdump_show (struct seq_file *m,void *v) +static int __init pt_dump_init (void ) { -ptdump_walk_pgd_level (m,NULL ); -return 0 ; -} - -static int ptdump_open (struct inode *inode,struct file *filp) -{ -return single_open (filp, ptdump_show,NULL ); -} - -static const struct file_operations ptdump_fops = { - .open = ptdump_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -static int pt_dump_init (void ) -{ -#ifdef CONFIG_X86_PTDUMP -struct dentry *pe; -#endif -#ifdef CONFIG_X86_32 /* Not a compile-time constant on x86-32 */ address_markers[VMALLOC_START_NR ].start_address =VMALLOC_START ;
@@ -468,13 +445,6 @@ static int pt_dump_init(void) address_markers[FIXADDR_START_NR ].start_address =FIXADDR_START ;#endif -#ifdef CONFIG_X86_PTDUMP - pe =debugfs_create_file ("kernel_page_tables" ,0600 ,NULL ,NULL , - &ptdump_fops); -if (!pe) -return -ENOMEM ; -#endif -return 0 ; }
arch/x86/mm/ioremap.c +2 -2
@@ -194,8 +194,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,* Check if the request spans more than any BAR in the iomem resource * tree. */ -WARN_ONCE (iomem_map_sanity_check (unaligned_phys_addr, unaligned_size), -KERN_INFO "Info: mapping multiple BARs. Your kernel is fine." ); +if (iomem_map_sanity_check (unaligned_phys_addr, unaligned_size)) +pr_warn ("caller %pS mapping multiple BARs\n" , caller);return ret_addr; err_free_area:
arch/x86/mm/pageattr.c +6 -4
@@ -129,14 +129,16 @@ within(unsigned long addr, unsigned long start, unsigned long end)*/ void clflush_cache_range (void *vaddr,unsigned int size) { -unsigned long clflush_mask = boot_cpu_data.x86_clflush_size -1 ; +const unsigned long clflush_size = boot_cpu_data.x86_clflush_size; +void *p = (void *)((unsigned long )vaddr & ~(clflush_size -1 ));void *vend = vaddr + size; -void *p; + +if (p >= vend) +return ;mb (); -for (p = (void *)((unsigned long )vaddr & ~clflush_mask); - p < vend; p += boot_cpu_data.x86_clflush_size) +for (; p < vend; p += clflush_size)clflushopt (p);mb ();
arch/x86/mm/pat.c +11 -1
@@ -586,7 +586,7 @@ int free_memtype(u64 start, u64 end) entry =rbt_memtype_erase (start, end);spin_unlock (&memtype_lock); -if (!entry) { +if (IS_ERR (entry)) {pr_info ("x86/PAT: %s:%d freeing invalid memtype [mem %#010Lx-%#010Lx]\n" , current->comm, current->pid, start, end -1 );return -EINVAL ;
@@ -992,6 +992,16 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn, vma->vm_flags &= ~VM_PAT ; } +/* +* untrack_pfn_moved is called, while mremapping a pfnmap for a new region, +* with the old vma after its pfnmap page table has been removed. The new +* vma has a new pfnmap to the same pfn & cache type with VM_PAT set. +*/ +void untrack_pfn_moved (struct vm_area_struct *vma) +{ + vma->vm_flags &= ~VM_PAT ; +} +pgprot_t pgprot_writecombine (pgprot_t prot) { return __pgprot(pgprot_val(prot) |
arch/x86/mm/pat_rbtree.c +43 -9
77 lines not on this page · raw message
arch/x86/mm/srat.c +2 -0
@@ -203,6 +203,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)pr_warn ("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n" , (unsigned long long )start, (unsigned long long )end -1 ); + max_possible_pfn =max (max_possible_pfn,PFN_UP (end -1 )); +return 0 ; out_err_bad_srat:bad_srat ();
include/asm-generic/pgtable.h +9 -1
@@ -569,7 +569,7 @@ static inline int track_pfn_copy(struct vm_area_struct *vma) }/* -* untrack_pfn_vma is called while unmapping a pfnmap for a region. +* untrack_pfn is called while unmapping a pfnmap for a region. * untrack can be called for a specific region indicated by pfn and size or * can be for the entire vma (in which case pfn, size are zero). */
@@ -577,6 +577,13 @@ static inline void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn, unsigned long size) { } + +/* +* untrack_pfn_moved is called while mremapping a pfnmap for a new region. +*/ +static inline void untrack_pfn_moved (struct vm_area_struct *vma) +{ +}#else extern int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, unsigned long pfn, unsigned long addr,
@@ -586,6 +593,7 @@ extern int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,extern int track_pfn_copy (struct vm_area_struct *vma);extern void untrack_pfn (struct vm_area_struct *vma,unsigned long pfn,unsigned long size); +extern void untrack_pfn_moved (struct vm_area_struct *vma);#endif #ifdef __HAVE_COLOR_ZERO_PAGE
include/linux/bootmem.h +4 -0
@@ -19,6 +19,10 @@ extern unsigned long min_low_pfn;* highest page */ extern unsigned long max_pfn; +/* +* highest possible page +*/ +extern unsigned long long max_possible_pfn;#ifndef CONFIG_NO_BOOTMEM /*
mm/bootmem.c +1 -0
@@ -33,6 +33,7 @@ EXPORT_SYMBOL(contig_page_data);unsigned long max_low_pfn;unsigned long min_low_pfn;unsigned long max_pfn; +unsigned long long max_possible_pfn;bootmem_data_t bootmem_node_data[MAX_NUMNODES ]__initdata ;
mm/mremap.c +4 -0
@@ -319,6 +319,10 @@ static unsigned long move_vma(struct vm_area_struct *vma, hiwater_vm = mm->hiwater_vm;vm_stat_account (mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT ); +/* Tell pfnmap has moved from this vma */ +if (unlikely (vma->vm_flags &VM_PFNMAP )) +untrack_pfn_moved (vma); +if (do_munmap (mm, old_addr, old_len) <0 ) {/* OOM: unable to split vma, just get accounts right */ vm_unacct_memory (excess >>PAGE_SHIFT );
mm/nobootmem.c +1 -0
@@ -31,6 +31,7 @@ EXPORT_SYMBOL(contig_page_data);unsigned long max_low_pfn;unsigned long min_low_pfn;unsigned long max_pfn; +unsigned long long max_possible_pfn;static void *__init __alloc_memory_core_early (int nid,u64 size,u64 align,u64 goal,u64 limit)