/* * Copyright 2002 Andi Kleen, SuSE Labs. * Thanks to Ben LaHaise for precious feedback. */#include<linux/highmem.h>#include<linux/bootmem.h>#include<linux/module.h>#include<linux/sched.h>#include<linux/mm.h>#include<linux/interrupt.h>#include<linux/seq_file.h>#include<linux/debugfs.h>#include<linux/pfn.h>#include<linux/percpu.h>#include<linux/gfp.h>#include<linux/pci.h>#include<asm/e820.h>#include<asm/processor.h>#include<asm/tlbflush.h>#include<asm/sections.h>#include<asm/setup.h>#include<asm/uaccess.h>#include<asm/pgalloc.h>#include<asm/proto.h>#include<asm/pat.h>/* * The current flushing context - we pass it instead of 5 arguments: */structcpa_data{unsignedlong*vaddr;pgprot_tmask_set;pgprot_tmask_clr;intnumpages;intflags;unsignedlongpfn;unsignedforce_split:1;intcurpage;structpage**pages;};/* * Serialize cpa() (for !DEBUG_PAGEALLOC which uses large identity mappings) * using cpa_lock. So that we don't allow any other cpu, with stale large tlb * entries change the page attribute in parallel to some other cpu * splitting a large page entry along with changing the attribute. */staticDEFINE_SPINLOCK(cpa_lock);#define CPA_FLUSHTLB 1#define CPA_ARRAY 2#define CPA_PAGES_ARRAY 4#ifdef CONFIG_PROC_FSstaticunsignedlongdirect_pages_count[PG_LEVEL_NUM];voidupdate_page_count(intlevel,unsignedlongpages){/* Protect against CPA */spin_lock(&pgd_lock);direct_pages_count[level]+=pages;spin_unlock(&pgd_lock);}staticvoidsplit_page_count(intlevel){direct_pages_count[level]--;direct_pages_count[level-1]+=PTRS_PER_PTE;}voidarch_report_meminfo(struct