diff --git a/drivers/soc/qcom/mem-offline.c b/drivers/soc/qcom/mem-offline.c index 928184e96c7a..d50667e2e6e8 100644 --- a/drivers/soc/qcom/mem-offline.c +++ b/drivers/soc/qcom/mem-offline.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include #include #include +#include #include #include #include @@ -93,6 +94,22 @@ static void clear_pgtable_mapping(phys_addr_t start, phys_addr_t end) flush_tlb_kernel_range(virt, addr_end); } +static void init_pgtable_mapping(phys_addr_t start, phys_addr_t end) +{ + unsigned long size = end - start; + + /* + * When rodata_full is enabled, memory is mapped at a page size + * granule, as opposed to a block mapping, so restore the attribute + * of each PTE when rodata_full is enabled. + */ + if (rodata_full) + set_memory_valid((unsigned long)phys_to_virt(start), + size >> PAGE_SHIFT, (int)true); + else + create_pgtable_mapping(start, end); +} + static void record_stat(unsigned long sec, ktime_t delay, int mode) { unsigned int total_sec = end_section_nr - start_section_nr + 1; @@ -324,7 +341,7 @@ static int mem_event_callback(struct notifier_block *self, if (!debug_pagealloc_enabled()) { /* Create kernel page-tables */ - create_pgtable_mapping(start_addr, end_addr); + init_pgtable_mapping(start_addr, end_addr); } break;