Re: [PATCH v34 06/14] arm64: kdump: protect crash dump kernel memory
On 30 March 2017 at 10:56, AKASHI Takahirowrote: > Date: Tue, 28 Mar 2017 15:51:24 +0900 > Subject: [PATCH] arm64: kdump: protect crash dump kernel memory > > arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres() > are meant to be called by kexec_load() in order to protect the memory > allocated for crash dump kernel once the image is loaded. > > The protection is implemented by unmapping the relevant segments in crash > dump kernel memory, rather than making it read-only as other archs do, > to prevent coherency issues due to potential cache aliasing (with > mismatched attributes). > > Page-level mappings are consistently used here so that we can change > the attributes of segments in page granularity as well as shrink the region > also in page granularity through /sys/kernel/kexec_crash_size, putting > the freed memory back to buddy system. > > Signed-off-by: AKASHI Takahiro This looks mostly correct. One comment below. > --- > arch/arm64/kernel/machine_kexec.c | 32 +--- > arch/arm64/mm/mmu.c | 103 > -- > 2 files changed, 80 insertions(+), 55 deletions(-) > > diff --git a/arch/arm64/kernel/machine_kexec.c > b/arch/arm64/kernel/machine_kexec.c > index bc96c8a7fc79..b63baa749609 100644 > --- a/arch/arm64/kernel/machine_kexec.c > +++ b/arch/arm64/kernel/machine_kexec.c > @@ -14,7 +14,9 @@ > > #include > #include > +#include > #include > +#include > > #include "cpu-reset.h" > > @@ -22,8 +24,6 @@ > extern const unsigned char arm64_relocate_new_kernel[]; > extern const unsigned long arm64_relocate_new_kernel_size; > > -static unsigned long kimage_start; > - > /** > * kexec_image_info - For debugging output. > */ > @@ -64,8 +64,6 @@ void machine_kexec_cleanup(struct kimage *kimage) > */ > int machine_kexec_prepare(struct kimage *kimage) > { > - kimage_start = kimage->start; > - > kexec_image_info(kimage); > > if (kimage->type != KEXEC_TYPE_CRASH && cpus_are_stuck_in_kernel()) { > @@ -183,7 +181,7 @@ void machine_kexec(struct kimage *kimage) > kexec_list_flush(kimage); > > /* Flush the new image if already in place. */ > - if (kimage->head & IND_DONE) > + if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE)) > kexec_segment_flush(kimage); > > pr_info("Bye!\n"); > @@ -201,7 +199,7 @@ void machine_kexec(struct kimage *kimage) > */ > > cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head, > - kimage_start, 0); > + kimage->start, 0); > > BUG(); /* Should never get here. */ > } > @@ -210,3 +208,25 @@ void machine_crash_shutdown(struct pt_regs *regs) > { > /* Empty routine needed to avoid build errors. */ > } > + > +void arch_kexec_protect_crashkres(void) > +{ > + int i; > + > + kexec_segment_flush(kexec_crash_image); > + > + for (i = 0; i < kexec_crash_image->nr_segments; i++) > + set_memory_valid( > + __phys_to_virt(kexec_crash_image->segment[i].mem), > + kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 0); > +} > + > +void arch_kexec_unprotect_crashkres(void) > +{ > + int i; > + > + for (i = 0; i < kexec_crash_image->nr_segments; i++) > + set_memory_valid( > + __phys_to_virt(kexec_crash_image->segment[i].mem), > + kexec_crash_image->segment[i].memsz >> PAGE_SHIFT, 1); > +} > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index 91502e36e6d9..3cde5f2d30ec 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -22,6 +22,8 @@ > #include > #include > #include > +#include > +#include > #include > #include > #include > @@ -393,10 +395,28 @@ static void update_mapping_prot(phys_addr_t phys, > unsigned long virt, > flush_tlb_kernel_range(virt, virt + size); > } > > -static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t > end) > +static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, > + phys_addr_t end, pgprot_t prot, int flags) > +{ > + __create_pgd_mapping(pgd, start, __phys_to_virt(start), end - start, > +prot, early_pgtable_alloc, flags); > +} > + > +void __init mark_linear_text_alias_ro(void) > +{ > + /* > +* Remove the write permissions from the linear alias of .text/.rodata > +*/ > + update_mapping_prot(__pa_symbol(_text), (unsigned > long)lm_alias(_text), > + (unsigned long)__init_begin - (unsigned > long)_text, > + PAGE_KERNEL_RO); > +} > + > +static void __init map_mem(pgd_t *pgd) > { > phys_addr_t kernel_start = __pa_symbol(_text); > phys_addr_t kernel_end = __pa_symbol(__init_begin); > + struct memblock_region
Re: [RFC PATCH] x86_64/mm/boot: Fix kernel_ident_mapping_init() failure for kexec
On 03/30/2017 at 07:21 PM, Xunlei Pang wrote: > On 03/24/2017 at 08:04 PM, Kirill A. Shutemov wrote: >> On Mon, Mar 20, 2017 at 02:11:31PM +0800, Xunlei Pang wrote: >>> I found that the kdump is broken on linux-4.11.0-rc2+ >> That's actually tip tree or linux-next. The problematic change is not in >> Linus' tree. >> >>> , probably >>> due to the 5level-paging feature that "#define p4d_present(p4d) 1", >>> as a result in ident_p4d_init(), it will go into ident_pud_init() >>> directly without allocating the new pud. >>> >>> Looks like this patch can make it work again. >> Okay, that's bisectability issue. Uncovered by splitting my patchset into >> parts. >> >> Could you check if applying "Part 2" of 5-level paging changes[1] would >> help you? > I confirmed that it works after applying your following patches: > x86: Convert the rest of the code to support p4d_t To be exact, this one("x86: Convert the rest of the code to support p4d_t") fixes the issue. > x86/xen: Change __xen_pgd_walk() and xen_cleanmfnmap() to support p4d > x86/kasan: Prepare clear_pgds() to switch to > x86/mm/pat: Add 5-level paging support > x86/efi: Add 5-level paging support > x86/kexec: Add 5-level paging support > > Regards, > Xunlei > >> Making the code work with both and >> would make it even uglier. Not sure if it >> makes sense to address it on its own if second part fixes the situation. >> >> [1] >> http://lkml.kernel.org/r/20170317185515.8636-1-kirill.shute...@linux.intel.com >> > > ___ > kexec mailing list > kexec@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kexec ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [RFC PATCH] x86_64/mm/boot: Fix kernel_ident_mapping_init() failure for kexec
On 03/24/2017 at 08:04 PM, Kirill A. Shutemov wrote: > On Mon, Mar 20, 2017 at 02:11:31PM +0800, Xunlei Pang wrote: >> I found that the kdump is broken on linux-4.11.0-rc2+ > That's actually tip tree or linux-next. The problematic change is not in > Linus' tree. > >> , probably >> due to the 5level-paging feature that "#define p4d_present(p4d) 1", >> as a result in ident_p4d_init(), it will go into ident_pud_init() >> directly without allocating the new pud. >> >> Looks like this patch can make it work again. > Okay, that's bisectability issue. Uncovered by splitting my patchset into > parts. > > Could you check if applying "Part 2" of 5-level paging changes[1] would > help you? I confirmed that it works after applying your following patches: x86: Convert the rest of the code to support p4d_t x86/xen: Change __xen_pgd_walk() and xen_cleanmfnmap() to support p4d x86/kasan: Prepare clear_pgds() to switch to x86/mm/pat: Add 5-level paging support x86/efi: Add 5-level paging support x86/kexec: Add 5-level paging support Regards, Xunlei > > Making the code work with both and > would make it even uglier. Not sure if it > makes sense to address it on its own if second part fixes the situation. > > [1] > http://lkml.kernel.org/r/20170317185515.8636-1-kirill.shute...@linux.intel.com > ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v34 06/14] arm64: kdump: protect crash dump kernel memory
Ard, On Tue, Mar 28, 2017 at 03:05:58PM +0100, Ard Biesheuvel wrote: > On 28 March 2017 at 12:07, AKASHI Takahirowrote: > > Ard, > > > > On Tue, Mar 28, 2017 at 11:07:05AM +0100, Ard Biesheuvel wrote: > >> On 28 March 2017 at 07:51, AKASHI Takahiro > >> wrote: > >> > arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres() > >> > are meant to be called by kexec_load() in order to protect the memory > >> > allocated for crash dump kernel once the image is loaded. > >> > > >> > The protection is implemented by unmapping the relevant segments in crash > >> > dump kernel memory, rather than making it read-only as other archs do, > >> > to prevent any corruption due to potential cache alias (with different > >> > attributes) problem. > >> > > >> > >> I think it would be more accurate to replace 'corruption' with > >> 'coherency issues', given that this patch does not solve the issue of > >> writable aliases that may be used to modify the contents of the > >> region, but it does prevent issues related to mismatched attributes > >> (which are arguably a bigger concern) > > > > OK > > > >> > Page-level mappings are consistently used here so that we can change > >> > the attributes of segments in page granularity as well as shrink the > >> > region > >> > also in page granularity through /sys/kernel/kexec_crash_size, putting > >> > the freed memory back to buddy system. > >> > > >> > Signed-off-by: AKASHI Takahiro > >> > >> As a head's up, this patch is going to conflict heavily with patches > >> that are queued up in arm64/for-next/core atm. > > > > I'll look into it later, but > > > >> Some questions below. > >> > >> > --- > >> > arch/arm64/kernel/machine_kexec.c | 32 +++--- > >> > arch/arm64/mm/mmu.c | 90 > >> > --- > >> > 2 files changed, 72 insertions(+), 50 deletions(-) > >> > > >> > diff --git a/arch/arm64/kernel/machine_kexec.c > >> > b/arch/arm64/kernel/machine_kexec.c > >> > index bc96c8a7fc79..b63baa749609 100644 > >> > --- a/arch/arm64/kernel/machine_kexec.c > >> > +++ b/arch/arm64/kernel/machine_kexec.c > >> > @@ -14,7 +14,9 @@ > >> > > >> > #include > >> > #include > >> > +#include > >> > #include > >> > +#include > >> > > >> > #include "cpu-reset.h" > >> > > >> > @@ -22,8 +24,6 @@ > >> > extern const unsigned char arm64_relocate_new_kernel[]; > >> > extern const unsigned long arm64_relocate_new_kernel_size; > >> > > >> > -static unsigned long kimage_start; > >> > - > >> > /** > >> > * kexec_image_info - For debugging output. > >> > */ > >> > @@ -64,8 +64,6 @@ void machine_kexec_cleanup(struct kimage *kimage) > >> > */ > >> > int machine_kexec_prepare(struct kimage *kimage) > >> > { > >> > - kimage_start = kimage->start; > >> > - > >> > kexec_image_info(kimage); > >> > > >> > if (kimage->type != KEXEC_TYPE_CRASH && > >> > cpus_are_stuck_in_kernel()) { > >> > @@ -183,7 +181,7 @@ void machine_kexec(struct kimage *kimage) > >> > kexec_list_flush(kimage); > >> > > >> > /* Flush the new image if already in place. */ > >> > - if (kimage->head & IND_DONE) > >> > + if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE)) > >> > kexec_segment_flush(kimage); > >> > > >> > pr_info("Bye!\n"); > >> > @@ -201,7 +199,7 @@ void machine_kexec(struct kimage *kimage) > >> > */ > >> > > >> > cpu_soft_restart(1, reboot_code_buffer_phys, kimage->head, > >> > - kimage_start, 0); > >> > + kimage->start, 0); > >> > > >> > BUG(); /* Should never get here. */ > >> > } > >> > @@ -210,3 +208,25 @@ void machine_crash_shutdown(struct pt_regs *regs) > >> > { > >> > /* Empty routine needed to avoid build errors. */ > >> > } > >> > + > >> > +void arch_kexec_protect_crashkres(void) > >> > +{ > >> > + int i; > >> > + > >> > + kexec_segment_flush(kexec_crash_image); > >> > + > >> > + for (i = 0; i < kexec_crash_image->nr_segments; i++) > >> > + set_memory_valid( > >> > + > >> > __phys_to_virt(kexec_crash_image->segment[i].mem), > >> > + kexec_crash_image->segment[i].memsz >> > >> > PAGE_SHIFT, 0); > >> > +} > >> > + > >> > +void arch_kexec_unprotect_crashkres(void) > >> > +{ > >> > + int i; > >> > + > >> > + for (i = 0; i < kexec_crash_image->nr_segments; i++) > >> > + set_memory_valid( > >> > + > >> > __phys_to_virt(kexec_crash_image->segment[i].mem), > >> > + kexec_crash_image->segment[i].memsz >> > >> > PAGE_SHIFT, 1); > >> > +} > >> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > >> > index d28dbcf596b6..f6a3c0e9d37f 100644 > >> > --- a/arch/arm64/mm/mmu.c > >> > +++ b/arch/arm64/mm/mmu.c > >> > @@ -22,6 +22,8 @@ > >> > #include > >> > #include >