@@ -804,6 +804,10 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
if (IS_ALIGNED(addr, PAGE_SIZE) &&
IS_ALIGNED(next, PAGE_SIZE)) {
+ /*
+ * Do not free direct mapping pages since they were
+ * freed when offlining.
+ */
if (!direct)
free_pagetable(pte_page(*pte), 0);
@@ -819,10 +823,11 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
* remove the page when it is wholly filled with 0xFD.
*/
memset((void *)addr, PAGE_INUSE, next - addr);
- page_addr = page_address(pte_page(*pte));
+ page_addr = page_address(pte_page(*pte));
if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
- free_pagetable(pte_page(*pte), 0);
+ if (!direct)
+ free_pagetable(pte_page(*pte), 0);
spin_lock(&init_mm.page_table_lock);
pte_clear(&init_mm, addr, pte);
Direct mapped pages were freed when they were offlined, or they were not allocated. So we only need to free vmemmap pages, no need to free direct mapped pages. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> --- arch/x86/mm/init_64.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)