diff mbox

[13/16] arm64: kdump: add kdump support

Message ID ef50b13d545f37a9fa95c5e6856e35f324798d00.1445297709.git.geoff@infradead.org (mailing list archive)
State New, archived
Headers show

Commit Message

Geoff Levand Oct. 19, 2015, 11:38 p.m. UTC
From: AKASHI Takahiro <takahiro.akashi@linaro.org>

On crash dump kernel, all the information about primary kernel's core
image is available in elf core header specified by "elfcorehdr=" boot
parameter. reserve_elfcorehdr() will set aside the region to avoid any
corruption by crash dump kernel.

Crash dump kernel will access the system memory of primary kernel via
copy_oldmem_page(), which reads one page by ioremap'ing it since it does
not reside in linear mapping on crash dump kernel.
Please note that we should add "mem=X[MG]" boot parameter to limit the
memory size and avoid the following assertion at ioremap():
	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
		return NULL;
when accessing any pages beyond the usable memories of crash dump kernel.

We also need our own elfcorehdr_read() here since the weak definition of
elfcorehdr_read() utilizes copy_oldmem_page() and will hit the assertion
above on arm64.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 arch/arm64/Kconfig             | 12 +++++++
 arch/arm64/kernel/Makefile     |  1 +
 arch/arm64/kernel/crash_dump.c | 71 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/mm/init.c           | 29 +++++++++++++++++
 4 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/kernel/crash_dump.c

Comments

Dave Young Oct. 22, 2015, 3:25 a.m. UTC | #1
Hi, AKASHI,

On 10/19/15 at 11:38pm, Geoff Levand wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> 
> On crash dump kernel, all the information about primary kernel's core
> image is available in elf core header specified by "elfcorehdr=" boot
> parameter. reserve_elfcorehdr() will set aside the region to avoid any
> corruption by crash dump kernel.
> 
> Crash dump kernel will access the system memory of primary kernel via
> copy_oldmem_page(), which reads one page by ioremap'ing it since it does
> not reside in linear mapping on crash dump kernel.
> Please note that we should add "mem=X[MG]" boot parameter to limit the
> memory size and avoid the following assertion at ioremap():
> 	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> 		return NULL;
> when accessing any pages beyond the usable memories of crash dump kernel.

How does kexec-tools pass usable memory ranges to kernel? using dtb?
Passing an extra mem=X sounds odd in the design. Kdump kernel should get
usable ranges and hanle the limit better than depending on an extern kernel
param. 

Thanks
Dave
AKASHI Takahiro Oct. 22, 2015, 4:29 a.m. UTC | #2
Hi Dave,

Thank you for your comment.

On 10/22/2015 12:25 PM, Dave Young wrote:
> Hi, AKASHI,
>
> On 10/19/15 at 11:38pm, Geoff Levand wrote:
>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>
>> On crash dump kernel, all the information about primary kernel's core
>> image is available in elf core header specified by "elfcorehdr=" boot
>> parameter. reserve_elfcorehdr() will set aside the region to avoid any
>> corruption by crash dump kernel.
>>
>> Crash dump kernel will access the system memory of primary kernel via
>> copy_oldmem_page(), which reads one page by ioremap'ing it since it does
>> not reside in linear mapping on crash dump kernel.
>> Please note that we should add "mem=X[MG]" boot parameter to limit the
>> memory size and avoid the following assertion at ioremap():
>> 	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
>> 		return NULL;
>> when accessing any pages beyond the usable memories of crash dump kernel.
>
> How does kexec-tools pass usable memory ranges to kernel? using dtb?
> Passing an extra mem=X sounds odd in the design. Kdump kernel should get
> usable ranges and hanle the limit better than depending on an extern kernel
> param.

Well, regarding "depending on an external kernel param,"
- this limitation ("mem=") is compatible with arm(32) implementation although
   it is not clearly described in kernel's Documentation/kdump/kdump.txt.
- "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
   The parameter is explicitly generated and added by kexec-tools.

Do I miss your point?

Thanks,
-Takahiro AKASHI

> Thanks
> Dave
>
Dave Young Oct. 22, 2015, 5:15 a.m. UTC | #3
On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
> Hi Dave,
> 
> Thank you for your comment.
> 
> On 10/22/2015 12:25 PM, Dave Young wrote:
> >Hi, AKASHI,
> >
> >On 10/19/15 at 11:38pm, Geoff Levand wrote:
> >>From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>
> >>On crash dump kernel, all the information about primary kernel's core
> >>image is available in elf core header specified by "elfcorehdr=" boot
> >>parameter. reserve_elfcorehdr() will set aside the region to avoid any
> >>corruption by crash dump kernel.
> >>
> >>Crash dump kernel will access the system memory of primary kernel via
> >>copy_oldmem_page(), which reads one page by ioremap'ing it since it does
> >>not reside in linear mapping on crash dump kernel.
> >>Please note that we should add "mem=X[MG]" boot parameter to limit the
> >>memory size and avoid the following assertion at ioremap():
> >>	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> >>		return NULL;
> >>when accessing any pages beyond the usable memories of crash dump kernel.
> >
> >How does kexec-tools pass usable memory ranges to kernel? using dtb?
> >Passing an extra mem=X sounds odd in the design. Kdump kernel should get
> >usable ranges and hanle the limit better than depending on an extern kernel
> >param.
> 
> Well, regarding "depending on an external kernel param,"
> - this limitation ("mem=") is compatible with arm(32) implementation although
>   it is not clearly described in kernel's Documentation/kdump/kdump.txt.
> - "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
>   The parameter is explicitly generated and added by kexec-tools.
> 
> Do I miss your point?

Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
says: The boot loader must pass at a minimum the size and location of the
system memory

In arm64 booting.txt, it does mentions about dtb but without above sentence.

So if you are using dtb to pass memory I think the extra mem= should be not
necessary unless there's other limitations dtb can not been used.

One thing I'm confused is mem= only pass the memory size, where does you pass
the start addresses? What if there's multiple sections such as some reserved
ranges 2nd kernel also need?

Thanks
Dave
AKASHI Takahiro Oct. 22, 2015, 9:57 a.m. UTC | #4
(added Ard to Cc.)

On 10/22/2015 02:15 PM, Dave Young wrote:
> On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
>> Hi Dave,
>>
>> Thank you for your comment.
>>
>> On 10/22/2015 12:25 PM, Dave Young wrote:
>>> Hi, AKASHI,
>>>
>>> On 10/19/15 at 11:38pm, Geoff Levand wrote:
>>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>>
>>>> On crash dump kernel, all the information about primary kernel's core
>>>> image is available in elf core header specified by "elfcorehdr=" boot
>>>> parameter. reserve_elfcorehdr() will set aside the region to avoid any
>>>> corruption by crash dump kernel.
>>>>
>>>> Crash dump kernel will access the system memory of primary kernel via
>>>> copy_oldmem_page(), which reads one page by ioremap'ing it since it does
>>>> not reside in linear mapping on crash dump kernel.
>>>> Please note that we should add "mem=X[MG]" boot parameter to limit the
>>>> memory size and avoid the following assertion at ioremap():
>>>> 	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
>>>> 		return NULL;
>>>> when accessing any pages beyond the usable memories of crash dump kernel.
>>>
>>> How does kexec-tools pass usable memory ranges to kernel? using dtb?
>>> Passing an extra mem=X sounds odd in the design. Kdump kernel should get
>>> usable ranges and hanle the limit better than depending on an extern kernel
>>> param.
>>
>> Well, regarding "depending on an external kernel param,"
>> - this limitation ("mem=") is compatible with arm(32) implementation although
>>    it is not clearly described in kernel's Documentation/kdump/kdump.txt.
>> - "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
>>    The parameter is explicitly generated and added by kexec-tools.
>>
>> Do I miss your point?
>
> Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
> says: The boot loader must pass at a minimum the size and location of the
> system memory
>
> In arm64 booting.txt, it does mentions about dtb but without above sentence.
>
> So if you are using dtb to pass memory I think the extra mem= should be not
> necessary unless there's other limitations dtb can not been used.

I would expect comments from arm64 maintainers here.

In my old implementation, I added "usablemem" attributes, along with "reg," to
"memory" nodes in dtb to specify the usable memory region on crash dump kernel.

But I removed this feature partly because, on uefi system, uefi might pass
no memory information in dtb.

> One thing I'm confused is mem= only pass the memory size, where does you pass
> the start addresses?

In the current arm64 implementation, any regions below the start address will
be ignored as system ram.

> What if there's multiple sections such as some reserved
> ranges 2nd kernel also need?

My patch utilizes only a single contiguous region of memory as system ram.
One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.

Please let me know if there is any other case that should be supported.

Thanks,
-Takahiro AKASHI

> Thanks
> Dave
>
Dave Young Oct. 23, 2015, 9:50 a.m. UTC | #5
On 10/22/15 at 06:57pm, AKASHI Takahiro wrote:
> (added Ard to Cc.)
> 
> On 10/22/2015 02:15 PM, Dave Young wrote:
> >On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
> >>Hi Dave,
> >>
> >>Thank you for your comment.
> >>
> >>On 10/22/2015 12:25 PM, Dave Young wrote:
> >>>Hi, AKASHI,
> >>>
> >>>On 10/19/15 at 11:38pm, Geoff Levand wrote:
> >>>>From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>>>
> >>>>On crash dump kernel, all the information about primary kernel's core
> >>>>image is available in elf core header specified by "elfcorehdr=" boot
> >>>>parameter. reserve_elfcorehdr() will set aside the region to avoid any
> >>>>corruption by crash dump kernel.
> >>>>
> >>>>Crash dump kernel will access the system memory of primary kernel via
> >>>>copy_oldmem_page(), which reads one page by ioremap'ing it since it does
> >>>>not reside in linear mapping on crash dump kernel.
> >>>>Please note that we should add "mem=X[MG]" boot parameter to limit the
> >>>>memory size and avoid the following assertion at ioremap():
> >>>>	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> >>>>		return NULL;
> >>>>when accessing any pages beyond the usable memories of crash dump kernel.
> >>>
> >>>How does kexec-tools pass usable memory ranges to kernel? using dtb?
> >>>Passing an extra mem=X sounds odd in the design. Kdump kernel should get
> >>>usable ranges and hanle the limit better than depending on an extern kernel
> >>>param.
> >>
> >>Well, regarding "depending on an external kernel param,"
> >>- this limitation ("mem=") is compatible with arm(32) implementation although
> >>   it is not clearly described in kernel's Documentation/kdump/kdump.txt.
> >>- "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
> >>   The parameter is explicitly generated and added by kexec-tools.
> >>
> >>Do I miss your point?
> >
> >Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
> >says: The boot loader must pass at a minimum the size and location of the
> >system memory
> >
> >In arm64 booting.txt, it does mentions about dtb but without above sentence.
> >
> >So if you are using dtb to pass memory I think the extra mem= should be not
> >necessary unless there's other limitations dtb can not been used.
> 
> I would expect comments from arm64 maintainers here.
> 
> In my old implementation, I added "usablemem" attributes, along with "reg," to
> "memory" nodes in dtb to specify the usable memory region on crash dump kernel.
> 
> But I removed this feature partly because, on uefi system, uefi might pass
> no memory information in dtb.

If this is the case there must be somewhere else one can pass memory infomation
to kernel, the booting.txt should be updated?

kexec as a boot loader need use same method as the 1st kernel boot loader.

> 
> >One thing I'm confused is mem= only pass the memory size, where does you pass
> >the start addresses?
> 
> In the current arm64 implementation, any regions below the start address will
> be ignored as system ram.
> 
> >What if there's multiple sections such as some reserved
> >ranges 2nd kernel also need?
> 
> My patch utilizes only a single contiguous region of memory as system ram.
> One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.
> 
> Please let me know if there is any other case that should be supported.

For example the elf headers range, you reserved them in kdump kernel code,
but kexec-tools can do that early if it can provides all memory info to 2nd
kernel. Ditto for mark all the memory ranges 1st kernel used as reserved.

Thanks
Dave
AKASHI Takahiro Oct. 29, 2015, 5:55 a.m. UTC | #6
Dave,

On 10/23/2015 06:50 PM, Dave Young wrote:
> On 10/22/15 at 06:57pm, AKASHI Takahiro wrote:
>> (added Ard to Cc.)
>>
>> On 10/22/2015 02:15 PM, Dave Young wrote:
>>> On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
>>>> Hi Dave,
>>>>
>>>> Thank you for your comment.
>>>>
>>>> On 10/22/2015 12:25 PM, Dave Young wrote:
>>>>> Hi, AKASHI,
>>>>>
>>>>> On 10/19/15 at 11:38pm, Geoff Levand wrote:
>>>>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>>>>
>>>>>> On crash dump kernel, all the information about primary kernel's core
>>>>>> image is available in elf core header specified by "elfcorehdr=" boot
>>>>>> parameter. reserve_elfcorehdr() will set aside the region to avoid any
>>>>>> corruption by crash dump kernel.
>>>>>>
>>>>>> Crash dump kernel will access the system memory of primary kernel via
>>>>>> copy_oldmem_page(), which reads one page by ioremap'ing it since it does
>>>>>> not reside in linear mapping on crash dump kernel.
>>>>>> Please note that we should add "mem=X[MG]" boot parameter to limit the
>>>>>> memory size and avoid the following assertion at ioremap():
>>>>>> 	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
>>>>>> 		return NULL;
>>>>>> when accessing any pages beyond the usable memories of crash dump kernel.
>>>>>
>>>>> How does kexec-tools pass usable memory ranges to kernel? using dtb?
>>>>> Passing an extra mem=X sounds odd in the design. Kdump kernel should get
>>>>> usable ranges and hanle the limit better than depending on an extern kernel
>>>>> param.
>>>>
>>>> Well, regarding "depending on an external kernel param,"
>>>> - this limitation ("mem=") is compatible with arm(32) implementation although
>>>>    it is not clearly described in kernel's Documentation/kdump/kdump.txt.
>>>> - "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
>>>>    The parameter is explicitly generated and added by kexec-tools.
>>>>
>>>> Do I miss your point?
>>>
>>> Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
>>> says: The boot loader must pass at a minimum the size and location of the
>>> system memory
>>>
>>> In arm64 booting.txt, it does mentions about dtb but without above sentence.
>>>
>>> So if you are using dtb to pass memory I think the extra mem= should be not
>>> necessary unless there's other limitations dtb can not been used.
>>
>> I would expect comments from arm64 maintainers here.
>>
>> In my old implementation, I added "usablemem" attributes, along with "reg," to
>> "memory" nodes in dtb to specify the usable memory region on crash dump kernel.
>>
>> But I removed this feature partly because, on uefi system, uefi might pass
>> no memory information in dtb.
>
> If this is the case there must be somewhere else one can pass memory infomation
> to kernel, the booting.txt should be updated?
>
> kexec as a boot loader need use same method as the 1st kernel boot loader.
>
>>
>>> One thing I'm confused is mem= only pass the memory size, where does you pass
>>> the start addresses?
>>
>> In the current arm64 implementation, any regions below the start address will
>> be ignored as system ram.
>>
>>> What if there's multiple sections such as some reserved
>>> ranges 2nd kernel also need?
>>
>> My patch utilizes only a single contiguous region of memory as system ram.
>> One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.
>>
>> Please let me know if there is any other case that should be supported.
>
> For example the elf headers range, you reserved them in kdump kernel code,
> but kexec-tools can do that early if it can provides all memory info to 2nd
> kernel. Ditto for mark all the memory ranges 1st kernel used as reserved.

It seems to me that the issue you mentioned here is totally independent
from "mem=" issue, isn't it?
(and "elfcorehdr=" is a common way for crash dump kernel to know the region.)

-Takahiro AKASHI

> Thanks
> Dave
>
Dave Young Oct. 29, 2015, 6:40 a.m. UTC | #7
Hi, AKASHI

On 10/29/15 at 02:55pm, AKASHI Takahiro wrote:
> Dave,
> 
> On 10/23/2015 06:50 PM, Dave Young wrote:
> >On 10/22/15 at 06:57pm, AKASHI Takahiro wrote:
> >>(added Ard to Cc.)
> >>
> >>On 10/22/2015 02:15 PM, Dave Young wrote:
> >>>On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
> >>>>Hi Dave,
> >>>>
> >>>>Thank you for your comment.
> >>>>
> >>>>On 10/22/2015 12:25 PM, Dave Young wrote:
> >>>>>Hi, AKASHI,
> >>>>>
> >>>>>On 10/19/15 at 11:38pm, Geoff Levand wrote:
> >>>>>>From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>>>>>
> >>>>>>On crash dump kernel, all the information about primary kernel's core
> >>>>>>image is available in elf core header specified by "elfcorehdr=" boot
> >>>>>>parameter. reserve_elfcorehdr() will set aside the region to avoid any
> >>>>>>corruption by crash dump kernel.
> >>>>>>
> >>>>>>Crash dump kernel will access the system memory of primary kernel via
> >>>>>>copy_oldmem_page(), which reads one page by ioremap'ing it since it does
> >>>>>>not reside in linear mapping on crash dump kernel.
> >>>>>>Please note that we should add "mem=X[MG]" boot parameter to limit the
> >>>>>>memory size and avoid the following assertion at ioremap():
> >>>>>>	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> >>>>>>		return NULL;
> >>>>>>when accessing any pages beyond the usable memories of crash dump kernel.
> >>>>>
> >>>>>How does kexec-tools pass usable memory ranges to kernel? using dtb?
> >>>>>Passing an extra mem=X sounds odd in the design. Kdump kernel should get
> >>>>>usable ranges and hanle the limit better than depending on an extern kernel
> >>>>>param.
> >>>>
> >>>>Well, regarding "depending on an external kernel param,"
> >>>>- this limitation ("mem=") is compatible with arm(32) implementation although
> >>>>   it is not clearly described in kernel's Documentation/kdump/kdump.txt.
> >>>>- "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
> >>>>   The parameter is explicitly generated and added by kexec-tools.
> >>>>
> >>>>Do I miss your point?
> >>>
> >>>Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
> >>>says: The boot loader must pass at a minimum the size and location of the
> >>>system memory
> >>>
> >>>In arm64 booting.txt, it does mentions about dtb but without above sentence.
> >>>
> >>>So if you are using dtb to pass memory I think the extra mem= should be not
> >>>necessary unless there's other limitations dtb can not been used.
> >>
> >>I would expect comments from arm64 maintainers here.
> >>
> >>In my old implementation, I added "usablemem" attributes, along with "reg," to
> >>"memory" nodes in dtb to specify the usable memory region on crash dump kernel.
> >>
> >>But I removed this feature partly because, on uefi system, uefi might pass
> >>no memory information in dtb.
> >
> >If this is the case there must be somewhere else one can pass memory infomation
> >to kernel, the booting.txt should be updated?
> >
> >kexec as a boot loader need use same method as the 1st kernel boot loader.
> >
> >>
> >>>One thing I'm confused is mem= only pass the memory size, where does you pass
> >>>the start addresses?
> >>
> >>In the current arm64 implementation, any regions below the start address will
> >>be ignored as system ram.
> >>
> >>>What if there's multiple sections such as some reserved
> >>>ranges 2nd kernel also need?
> >>
> >>My patch utilizes only a single contiguous region of memory as system ram.
> >>One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.
> >>
> >>Please let me know if there is any other case that should be supported.
> >
> >For example the elf headers range, you reserved them in kdump kernel code,
> >but kexec-tools can do that early if it can provides all memory info to 2nd
> >kernel. Ditto for mark all the memory ranges 1st kernel used as reserved.
> 
> It seems to me that the issue you mentioned here is totally independent
> from "mem=" issue, isn't it?
> (and "elfcorehdr=" is a common way for crash dump kernel to know the region.)

Hmm, I did not talked about the eflcorehdr=, I means the code to reserve the
memory ranges elfcorehdr is using.

Thanks
Dave

> 
> -Takahiro AKASHI
> 
> >Thanks
> >Dave
> >
AKASHI Takahiro Oct. 29, 2015, 6:53 a.m. UTC | #8
On 10/29/2015 03:40 PM, Dave Young wrote:
> Hi, AKASHI
>
> On 10/29/15 at 02:55pm, AKASHI Takahiro wrote:
>> Dave,
>>
>> On 10/23/2015 06:50 PM, Dave Young wrote:
>>> On 10/22/15 at 06:57pm, AKASHI Takahiro wrote:
>>>> (added Ard to Cc.)
>>>>
>>>> On 10/22/2015 02:15 PM, Dave Young wrote:
>>>>> On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
>>>>>> Hi Dave,
>>>>>>
>>>>>> Thank you for your comment.
>>>>>>
>>>>>> On 10/22/2015 12:25 PM, Dave Young wrote:
>>>>>>> Hi, AKASHI,
>>>>>>>
>>>>>>> On 10/19/15 at 11:38pm, Geoff Levand wrote:
>>>>>>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>>>>>>
>>>>>>>> On crash dump kernel, all the information about primary kernel's core
>>>>>>>> image is available in elf core header specified by "elfcorehdr=" boot
>>>>>>>> parameter. reserve_elfcorehdr() will set aside the region to avoid any
>>>>>>>> corruption by crash dump kernel.
>>>>>>>>
>>>>>>>> Crash dump kernel will access the system memory of primary kernel via
>>>>>>>> copy_oldmem_page(), which reads one page by ioremap'ing it since it does
>>>>>>>> not reside in linear mapping on crash dump kernel.
>>>>>>>> Please note that we should add "mem=X[MG]" boot parameter to limit the
>>>>>>>> memory size and avoid the following assertion at ioremap():
>>>>>>>> 	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
>>>>>>>> 		return NULL;
>>>>>>>> when accessing any pages beyond the usable memories of crash dump kernel.
>>>>>>>
>>>>>>> How does kexec-tools pass usable memory ranges to kernel? using dtb?
>>>>>>> Passing an extra mem=X sounds odd in the design. Kdump kernel should get
>>>>>>> usable ranges and hanle the limit better than depending on an extern kernel
>>>>>>> param.
>>>>>>
>>>>>> Well, regarding "depending on an external kernel param,"
>>>>>> - this limitation ("mem=") is compatible with arm(32) implementation although
>>>>>>    it is not clearly described in kernel's Documentation/kdump/kdump.txt.
>>>>>> - "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
>>>>>>    The parameter is explicitly generated and added by kexec-tools.
>>>>>>
>>>>>> Do I miss your point?
>>>>>
>>>>> Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
>>>>> says: The boot loader must pass at a minimum the size and location of the
>>>>> system memory
>>>>>
>>>>> In arm64 booting.txt, it does mentions about dtb but without above sentence.
>>>>>
>>>>> So if you are using dtb to pass memory I think the extra mem= should be not
>>>>> necessary unless there's other limitations dtb can not been used.
>>>>
>>>> I would expect comments from arm64 maintainers here.
>>>>
>>>> In my old implementation, I added "usablemem" attributes, along with "reg," to
>>>> "memory" nodes in dtb to specify the usable memory region on crash dump kernel.
>>>>
>>>> But I removed this feature partly because, on uefi system, uefi might pass
>>>> no memory information in dtb.
>>>
>>> If this is the case there must be somewhere else one can pass memory infomation
>>> to kernel, the booting.txt should be updated?
>>>
>>> kexec as a boot loader need use same method as the 1st kernel boot loader.
>>>
>>>>
>>>>> One thing I'm confused is mem= only pass the memory size, where does you pass
>>>>> the start addresses?
>>>>
>>>> In the current arm64 implementation, any regions below the start address will
>>>> be ignored as system ram.
>>>>
>>>>> What if there's multiple sections such as some reserved
>>>>> ranges 2nd kernel also need?
>>>>
>>>> My patch utilizes only a single contiguous region of memory as system ram.
>>>> One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.
>>>>
>>>> Please let me know if there is any other case that should be supported.
>>>
>>> For example the elf headers range, you reserved them in kdump kernel code,
>>> but kexec-tools can do that early if it can provides all memory info to 2nd
>>> kernel. Ditto for mark all the memory ranges 1st kernel used as reserved.
>>
>> It seems to me that the issue you mentioned here is totally independent
>> from "mem=" issue, isn't it?
>> (and "elfcorehdr=" is a common way for crash dump kernel to know the region.)
>
> Hmm, I did not talked about the eflcorehdr=, I means the code to reserve the
> memory ranges elfcorehdr is using.

So how does it relate to "mem=" issue?

-Takahiro AKASHI

> Thanks
> Dave
>
>>
>> -Takahiro AKASHI
>>
>>> Thanks
>>> Dave
>>>
Dave Young Oct. 29, 2015, 7:01 a.m. UTC | #9
On 10/29/15 at 03:53pm, AKASHI Takahiro wrote:
> On 10/29/2015 03:40 PM, Dave Young wrote:
> >Hi, AKASHI
> >
> >On 10/29/15 at 02:55pm, AKASHI Takahiro wrote:
> >>Dave,
> >>
> >>On 10/23/2015 06:50 PM, Dave Young wrote:
> >>>On 10/22/15 at 06:57pm, AKASHI Takahiro wrote:
> >>>>(added Ard to Cc.)
> >>>>
> >>>>On 10/22/2015 02:15 PM, Dave Young wrote:
> >>>>>On 10/22/15 at 01:29pm, AKASHI Takahiro wrote:
> >>>>>>Hi Dave,
> >>>>>>
> >>>>>>Thank you for your comment.
> >>>>>>
> >>>>>>On 10/22/2015 12:25 PM, Dave Young wrote:
> >>>>>>>Hi, AKASHI,
> >>>>>>>
> >>>>>>>On 10/19/15 at 11:38pm, Geoff Levand wrote:
> >>>>>>>>From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>>>>>>>
> >>>>>>>>On crash dump kernel, all the information about primary kernel's core
> >>>>>>>>image is available in elf core header specified by "elfcorehdr=" boot
> >>>>>>>>parameter. reserve_elfcorehdr() will set aside the region to avoid any
> >>>>>>>>corruption by crash dump kernel.
> >>>>>>>>
> >>>>>>>>Crash dump kernel will access the system memory of primary kernel via
> >>>>>>>>copy_oldmem_page(), which reads one page by ioremap'ing it since it does
> >>>>>>>>not reside in linear mapping on crash dump kernel.
> >>>>>>>>Please note that we should add "mem=X[MG]" boot parameter to limit the
> >>>>>>>>memory size and avoid the following assertion at ioremap():
> >>>>>>>>	if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> >>>>>>>>		return NULL;
> >>>>>>>>when accessing any pages beyond the usable memories of crash dump kernel.
> >>>>>>>
> >>>>>>>How does kexec-tools pass usable memory ranges to kernel? using dtb?
> >>>>>>>Passing an extra mem=X sounds odd in the design. Kdump kernel should get
> >>>>>>>usable ranges and hanle the limit better than depending on an extern kernel
> >>>>>>>param.
> >>>>>>
> >>>>>>Well, regarding "depending on an external kernel param,"
> >>>>>>- this limitation ("mem=") is compatible with arm(32) implementation although
> >>>>>>   it is not clearly described in kernel's Documentation/kdump/kdump.txt.
> >>>>>>- "elfcorehdr" kernel parameter is mandatory on x86 as well as on arm/arm64.
> >>>>>>   The parameter is explicitly generated and added by kexec-tools.
> >>>>>>
> >>>>>>Do I miss your point?
> >>>>>
> >>>>>Arm previously use atag_mem tag for memory kernel uses, with dtb, Booting.txt
> >>>>>says: The boot loader must pass at a minimum the size and location of the
> >>>>>system memory
> >>>>>
> >>>>>In arm64 booting.txt, it does mentions about dtb but without above sentence.
> >>>>>
> >>>>>So if you are using dtb to pass memory I think the extra mem= should be not
> >>>>>necessary unless there's other limitations dtb can not been used.
> >>>>
> >>>>I would expect comments from arm64 maintainers here.
> >>>>
> >>>>In my old implementation, I added "usablemem" attributes, along with "reg," to
> >>>>"memory" nodes in dtb to specify the usable memory region on crash dump kernel.
> >>>>
> >>>>But I removed this feature partly because, on uefi system, uefi might pass
> >>>>no memory information in dtb.
> >>>
> >>>If this is the case there must be somewhere else one can pass memory infomation
> >>>to kernel, the booting.txt should be updated?
> >>>
> >>>kexec as a boot loader need use same method as the 1st kernel boot loader.
> >>>
> >>>>
> >>>>>One thing I'm confused is mem= only pass the memory size, where does you pass
> >>>>>the start addresses?
> >>>>
> >>>>In the current arm64 implementation, any regions below the start address will
> >>>>be ignored as system ram.
> >>>>
> >>>>>What if there's multiple sections such as some reserved
> >>>>>ranges 2nd kernel also need?
> >>>>
> >>>>My patch utilizes only a single contiguous region of memory as system ram.
> >>>>One exception that I notice is uefi's runtime data. They will be ioremap'ed separately.
> >>>>
> >>>>Please let me know if there is any other case that should be supported.
> >>>
> >>>For example the elf headers range, you reserved them in kdump kernel code,
> >>>but kexec-tools can do that early if it can provides all memory info to 2nd
> >>>kernel. Ditto for mark all the memory ranges 1st kernel used as reserved.
> >>
> >>It seems to me that the issue you mentioned here is totally independent
> >>from "mem=" issue, isn't it?
> >>(and "elfcorehdr=" is a common way for crash dump kernel to know the region.)
> >
> >Hmm, I did not talked about the eflcorehdr=, I means the code to reserve the
> >memory ranges elfcorehdr is using.
> 
> So how does it relate to "mem=" issue?

It is just an example that kexec can pass it along with the usable mem range to
kernel via some interface like dtb blob or some other interfaces. 

> 
> -Takahiro AKASHI
> 
> >Thanks
> >Dave
> >
> >>
> >>-Takahiro AKASHI
> >>
> >>>Thanks
> >>>Dave
> >>>
diff mbox

Patch

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 73e8e31..262bd49 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -501,6 +501,18 @@  config KEXEC
 	  but it is independent of the system firmware.   And like a reboot
 	  you can start any kernel with it, not just Linux.
 
+config CRASH_DUMP
+	bool "Build kdump crash kernel"
+	help
+	  Generate crash dump after being started by kexec. This should
+	  be normally only set in special crash dump kernels which are
+	  loaded in the main kernel with kexec-tools into a specially
+	  reserved region and then later executed after a crash by
+	  kdump/kexec. The crash dump kernel must be compiled to a
+	  memory address not used by the main kernel.
+
+	  For more details see Documentation/kdump/kdump.txt
+
 config XEN_DOM0
 	def_bool y
 	depends on XEN
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 989ccd7..7ef9fa4 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -38,6 +38,7 @@  arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 arm64-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o	\
 					   cpu-reset.o
+arm64-obj-$(CONFIG_CRASH_DUMP)		+= crash_dump.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c
new file mode 100644
index 0000000..3d86c0a
--- /dev/null
+++ b/arch/arm64/kernel/crash_dump.c
@@ -0,0 +1,71 @@ 
+/*
+ * Routines for doing kexec-based kdump
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/crash_dump.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+#include <linux/uaccess.h>
+#include <asm/memory.h>
+
+/**
+ * copy_oldmem_page() - copy one page from old kernel memory
+ * @pfn: page frame number to be copied
+ * @buf: buffer where the copied page is placed
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page
+ * @userbuf: if set, @buf is in a user address space
+ *
+ * This function copies one page from old kernel memory into buffer pointed by
+ * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
+ * copied or negative error in case of failure.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+			 size_t csize, unsigned long offset,
+			 int userbuf)
+{
+	void *vaddr;
+
+	if (!csize)
+		return 0;
+
+	vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		if (copy_to_user(buf, vaddr + offset, csize)) {
+			iounmap(vaddr);
+			return -EFAULT;
+		}
+	} else {
+		memcpy(buf, vaddr + offset, csize);
+	}
+
+	iounmap(vaddr);
+
+	return csize;
+}
+
+/**
+ * elfcorehdr_read - read from ELF core header
+ * @buf: buffer where the data is placed
+ * @csize: number of bytes to read
+ * @ppos: address in the memory
+ *
+ * This function reads @count bytes from elf core header which exists
+ * on crash dump kernel's memory.
+ */
+ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
+{
+	memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count);
+	return count;
+}
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f33f201..ff8eeb4 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@ 
 #include <linux/efi.h>
 #include <linux/swiotlb.h>
 #include <linux/kexec.h>
+#include <linux/crash_dump.h>
 
 #include <asm/fixmap.h>
 #include <asm/memory.h>
@@ -116,6 +117,31 @@  static void __init reserve_crashkernel(void)
 }
 #endif /* CONFIG_KEXEC */
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * reserve_elfcorehdr() - reserves memory for elf core header
+ *
+ * This function reserves elf core header given in "elfcorehdr=" kernel
+ * command line parameter. This region contains all the information about
+ * primary kernel's core image and is used by a dump capture kernel to
+ * access the system memory on primary kernel.
+ */
+static void __init reserve_elfcorehdr(void)
+{
+	if (!elfcorehdr_size)
+		return;
+
+	if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
+		pr_warn("elfcorehdr is overlapped\n");
+		return;
+	}
+
+	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
+
+	pr_info("Reserving %lldKB of memory at %lldMB for elfcorehdr\n",
+		elfcorehdr_size >> 10, elfcorehdr_addr >> 20);
+}
+#endif /* CONFIG_CRASH_DUMP */
 /*
  * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
@@ -223,6 +249,9 @@  void __init arm64_memblock_init(void)
 #ifdef CONFIG_KEXEC
 	reserve_crashkernel();
 #endif
+#ifdef CONFIG_CRASH_DUMP
+	reserve_elfcorehdr();
+#endif
 
 	early_init_fdt_scan_reserved_mem();