From 766e0d83004c0bbba28179ad096243b7ee83d843 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 01 2017 03:50:01 +0000 Subject: import kexec-tools-2.0.14-17.el7 --- diff --git a/.gitignore b/.gitignore index 67ccd94..3e4cfae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ SOURCES/eppic_050615.tar.gz -SOURCES/kdump-anaconda-addon-003-21-g69da0f8.tar.gz -SOURCES/kexec-tools-2.0.7.tar.xz -SOURCES/makedumpfile-1.6.0.tar.gz +SOURCES/kdump-anaconda-addon-003-23-g80e78fb.tar.gz +SOURCES/kexec-tools-2.0.14.tar.xz +SOURCES/makedumpfile-1.6.1.tar.gz diff --git a/.kexec-tools.metadata b/.kexec-tools.metadata index 348dc3e..429335b 100644 --- a/.kexec-tools.metadata +++ b/.kexec-tools.metadata @@ -1,4 +1,4 @@ a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz -303af76846ca0768503258738a43c8adf80e05ce SOURCES/kdump-anaconda-addon-003-21-g69da0f8.tar.gz -56f3c4c829d0078bb705f980e1d9ba22eb9a6246 SOURCES/kexec-tools-2.0.7.tar.xz -c856adc0900638310b0d7d3883b5ee7489395595 SOURCES/makedumpfile-1.6.0.tar.gz +dfa17c4a04bc3775ede56c1fd3a8904e938f0fe1 SOURCES/kdump-anaconda-addon-003-23-g80e78fb.tar.gz +cc3d6155ffb2aac5cf943312b41c0f41141dc9c6 SOURCES/kexec-tools-2.0.14.tar.xz +74ec93ff2709542772175ae7761a2852adce8c35 SOURCES/makedumpfile-1.6.1.tar.gz diff --git a/SOURCES/dracut-kdump-emergency.service b/SOURCES/dracut-kdump-emergency.service index fb764f2..e023284 100644 --- a/SOURCES/dracut-kdump-emergency.service +++ b/SOURCES/dracut-kdump-emergency.service @@ -12,6 +12,7 @@ [Unit] Description=Kdump Emergency DefaultDependencies=no +IgnoreOnIsolate=yes [Service] ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service diff --git a/SOURCES/dracut-kdump-emergency.target b/SOURCES/dracut-kdump-emergency.target new file mode 100644 index 0000000..a1bb493 --- /dev/null +++ b/SOURCES/dracut-kdump-emergency.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Emergency Mode +Documentation=man:systemd.special(7) +Requires=emergency.service +After=emergency.service +AllowIsolate=yes +IgnoreOnIsolate=yes diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index fb93981..3dea978 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -161,7 +161,11 @@ kdump_get_perm_addr() { kdump_setup_ifname() { local _ifname - if [[ $1 =~ eth* ]]; then + # If ifname already has 'kdump-' prefix, we must be switching from + # fadump to kdump. Skip prefixing 'kdump-' in this case as adding + # another prefix may truncate the ifname. Since an ifname with + # 'kdump-' is already persistent, this should be fine. + if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then _ifname="kdump-$1" else _ifname="$1" @@ -742,8 +746,9 @@ install() { ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service" inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh" inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service" - # Replace existing emergency service + # Replace existing emergency service and emergency target cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service" + cp "$moddir/kdump-emergency.target" "$initdir/$systemdsystemunitdir/emergency.target" # Also redirect dracut-emergency to kdump error handler ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service" diff --git a/SOURCES/fadump-howto.txt b/SOURCES/fadump-howto.txt new file mode 100644 index 0000000..1613d02 --- /dev/null +++ b/SOURCES/fadump-howto.txt @@ -0,0 +1,251 @@ +Firmware assisted dump (fadump) HOWTO + +Introduction + +Firmware assisted dump is a new feature in the 3.4 mainline kernel supported +only on powerpc architecture. The goal of firmware-assisted dump is to enable +the dump of a crashed system, and to do so from a fully-reset system, and to +minimize the total elapsed time until the system is back in production use. A +complete documentation on implementation can be found at +Documentation/powerpc/firmware-assisted-dump.txt in upstream linux kernel tree +from 3.4 version and above. + +Please note that the firmware-assisted dump feature is only available on Power6 +and above systems with recent firmware versions. + +Overview + +Fadump + +Fadump is a robust kernel crash dumping mechanism to get reliable kernel crash +dump with assistance from firmware. This approach does not use kexec, instead +firmware assists in booting the kdump kernel while preserving memory contents. +Unlike kdump, the system is fully reset, and loaded with a fresh copy of the +kernel. In particular, PCI and I/O devices are reinitialized and are in a +clean, consistent state. This second kernel, often called a capture kernel, +boots with very little memory and captures the dump image. + +The first kernel registers the sections of memory with the Power firmware for +dump preservation during OS initialization. These registered sections of memory +are reserved by the first kernel during early boot. When a system crashes, the +Power firmware fully resets the system, preserves all the system memory +contents, save the low memory (boot memory of size larger of 5% of system +RAM or 256MB) of RAM to the previous registered region. It will also save +system registers, and hardware PTE's. + +Fadump is supported only on ppc64 platform. The standard kernel and capture +kernel are one and the same on ppc64. + +If you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command: + + # yum install kexec-tools + +Fadump Operational Flow: + +Like kdump, fadump also exports the ELF formatted kernel crash dump through +/proc/vmcore. Hence existing kdump infrastructure can be used to capture fadump +vmcore. The idea is to keep the functionality transparent to end user. From +user perspective there is no change in the way kdump init script works. + +However, unlike kdump, fadump does not pre-load kdump kernel and initrd into +reserved memory, instead it always uses default OS initrd during second boot +after crash. Hence, for fadump, we rebuild the new kdump initrd and replace it +with default initrd. Before replacing existing default initrd we take a backup +of original default initrd for user's reference. The dracut package has been +enhanced to rebuild the default initrd with vmcore capture steps. The initrd +image is rebuilt as per the configuration in /etc/kdump.conf file. + +The control flow of fadump works as follows: +01. System panics. +02. At the crash, kernel informs power firmware that kernel has crashed. +03. Firmware takes the control and reboots the entire system preserving + only the memory (resets all other devices). +04. The reboot follows the normal booting process (non-kexec). +05. The boot loader loads the default kernel and initrd from /boot +06. The default initrd loads and runs /init +07. dracut-kdump.sh script present in fadump aware default initrd checks if + '/proc/device-tree/rtas/ibm,kernel-dump' file exists before executing + steps to capture vmcore. + (This check will help to bypass the vmcore capture steps during normal boot + process.) +09. Captures dump according to /etc/kdump.conf +10. Is dump capture successful (yes goto 12, no goto 11) +11. Perfom the default action specified in /etc/kdump.conf (Default action + is reboot, if unspecified) +12. Reboot + + +How to configure fadump: + +Again, we assume if you're reading this document, you should already have +kexec-tools installed. If not, you install it via the following command: + + # yum install kexec-tools + +To be able to do much of anything interesting in the way of debug analysis, +you'll also need to install the kernel-debuginfo package, of the same arch +as your running kernel, and the crash utility: + + # yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash + +Next up, we need to modify some boot parameters to enable firmware assisted +dump. With the help of grubby, it's very easy to append "fadump=on" to the end +of your kernel boot parameters. Optionally, user can also append +'fadump_reserve_mem=X' kernel cmdline to specify size of the memory to reserve +for boot memory dump preservation. + + # grubby --args="fadump=on" --update-kernel=/boot/vmlinuz-`uname -r` + +The term 'boot memory' means size of the low memory chunk that is required for +a kernel to boot successfully when booted with restricted memory. By default, +the boot memory size will be the larger of 5% of system RAM or 256MB. +Alternatively, user can also specify boot memory size through boot parameter +'fadump_reserve_mem=' which will override the default calculated size. Use this +option if default boot memory size is not sufficient for second kernel to boot +successfully. + +After making said changes, reboot your system, so that the specified memory is +reserved and left untouched by the normal system. Take note that the output of +'free -m' will show X MB less memory than without this parameter, which is +expected. If you see OOM (Out Of Memory) error messages while loading capture +kernel, then you should bump up the memory reservation size. + +Now that you've got that reserved memory region set up, you want to turn on +the kdump init script: + + # systemctl enable kdump.service + +Then, start up kdump as well: + + # systemctl start kdump.service + +This should turn on the firmware assisted functionality in kernel by +echo'ing 1 to /sys/kernel/fadump_registered, leaving the system ready +to capture a vmcore upon crashing. To test this out, you can force-crash +your system by echo'ing a c into /proc/sysrq-trigger: + + # echo c > /proc/sysrq-trigger + +You should see some panic output, followed by the system reset and booting into +fresh copy of kernel. When default initrd loads and runs /init, vmcore should +be copied out to disk (by default, in /var/crash//vmcore), +then the system rebooted back into your normal kernel. + +Once back to your normal kernel, you can use the previously installed crash +kernel in conjunction with the previously installed kernel-debuginfo to +perform postmortem analysis: + + # crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux + /var/crash/2006-08-23-15:34/vmcore + + crash> bt + +and so on... + +Saving vmcore-dmesg.txt +---------------------- +Kernel log bufferes are one of the most important information available +in vmcore. Now before saving vmcore, kernel log bufferes are extracted +from /proc/vmcore and saved into a file vmcore-dmesg.txt. After +vmcore-dmesg.txt, vmcore is saved. Destination disk and directory for +vmcore-dmesg.txt is same as vmcore. Note that kernel log buffers will +not be available if dump target is raw device. + +Dump Triggering methods: + +This section talks about the various ways, other than a Kernel Panic, in which +fadump can be triggered. The following methods assume that fadump is configured +on your system, with the scripts enabled as described in the section above. + +1) AltSysRq C + +FAdump can be triggered with the combination of the 'Alt','SysRq' and 'C' +keyboard keys. Please refer to the following link for more details: + +https://access.redhat.com/articles/231663 + +In addition, on PowerPC boxes, fadump can also be triggered via Hardware +Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys. + +2) Kernel OOPs + +If we want to generate a dump everytime the Kernel OOPses, we can achieve this +by setting the 'Panic On OOPs' option as follows: + + # echo 1 > /proc/sys/kernel/panic_on_oops + +3) PowerPC specific methods: + +On IBM PowerPC machines, issuing a soft reset invokes the XMON debugger(if +XMON is configured). To configure XMON one needs to compile the kernel with +the CONFIG_XMON and CONFIG_XMON_DEFAULT options, or by compiling with +CONFIG_XMON and booting the kernel with xmon=on option. + +Following are the ways to remotely issue a soft reset on PowerPC boxes, which +would drop you to XMON. Pressing a 'X' (capital alphabet X) followed by an +'Enter' here will trigger the dump. + +3.1) HMC + +Hardware Management Console(HMC) available on Power4 and Power5 machines allow +partitions to be reset remotely. This is specially useful in hang situations +where the system is not accepting any keyboard inputs. + +Once you have HMC configured, the following steps will enable you to trigger +fadump via a soft reset: + +On Power4 + Using GUI + + * In the right pane, right click on the partition you wish to dump. + * Select "Operating System->Reset". + * Select "Soft Reset". + * Select "Yes". + + Using HMC Commandline + + # reset_partition -m -p -t soft + +On Power5 + Using GUI + + * In the right pane, right click on the partition you wish to dump. + * Select "Restart Partition". + * Select "Dump". + * Select "OK". + + Using HMC Commandline + + # chsysstate -m -n -o dumprestart -r lpar + +3.2) Blade Management Console for Blade Center + +To initiate a dump operation, go to Power/Restart option under "Blade Tasks" in +the Blade Management Console. Select the corresponding blade for which you want +to initate the dump and then click "Restart blade with NMI". This issues a +system reset and invokes xmon debugger. + + +Advanced Setups & Default action: + +Kdump and fadump exhibit similar behavior in terms of setup & default action. +For fadump advanced setup related information see section "Advanced Setups" in +"kexec-kdump-howto.txt" document. Refer to "Default action" section in "kexec- +kdump-howto.txt" document for fadump default action related information. + +Compression and filtering + +Refer "Compression and filtering" section in "kexec-kdump-howto.txt" document. +Compression and filtering are same for kdump & fadump. + + +Notes on rootfs mount: +Dracut is designed to mount rootfs by default. If rootfs mounting fails it +will refuse to go on. So fadump leaves rootfs mounting to dracut currently. +We make the assumtion that proper root= cmdline is being passed to dracut +initramfs for the time being. If you need modify "KDUMP_COMMANDLINE=" in +/etc/sysconfig/kdump, you will need to make sure that appropriate root= +options are copied from /proc/cmdline. In general it is best to append +command line options using "KDUMP_COMMANDLINE_APPEND=" instead of replacing +the original command line completely. diff --git a/SOURCES/kdump-lib-initramfs.sh b/SOURCES/kdump-lib-initramfs.sh index 68a94e8..2c18c87 100755 --- a/SOURCES/kdump-lib-initramfs.sh +++ b/SOURCES/kdump-lib-initramfs.sh @@ -6,14 +6,14 @@ KDUMP_PATH="/var/crash" CORE_COLLECTOR="" DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -d 31" DMESG_COLLECTOR="/sbin/vmcore-dmesg" -DEFAULT_ACTION="reboot" +DEFAULT_ACTION="systemctl reboot -f" DATEDIR=`date +%Y-%m-%d-%T` HOST_IP='127.0.0.1' DUMP_INSTRUCTION="" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" KDUMP_SCRIPT_DIR="/kdumpscripts" DD_BLKSIZE=512 -FINAL_ACTION="reboot" +FINAL_ACTION="systemctl reboot -f" KDUMP_CONF="/etc/kdump.conf" KDUMP_PRE="" KDUMP_POST="" @@ -57,7 +57,7 @@ get_kdump_confs() DEFAULT_ACTION="kdump_emergency_shell" ;; reboot) - DEFAULT_ACTION="reboot" + DEFAULT_ACTION="systemctl reboot -f" ;; halt) DEFAULT_ACTION="halt" @@ -111,6 +111,8 @@ dump_fs() sync echo "kdump: saving vmcore complete" + # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure + return 0 } save_vmcore_dmesg_fs() { diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index 7012dcf..2c5ced2 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -63,7 +63,7 @@ is_pcs_fence_kdump() [ -x $FENCE_KDUMP_SEND ] || return 1 # fence kdump not configured? - (pcs cluster cib | grep -q 'type="fence_kdump"') &> /dev/null || return 1 + (pcs cluster cib | grep 'type="fence_kdump"') &> /dev/null || return 1 } # Check if fence_kdump is configured using kdump options diff --git a/SOURCES/kdump.conf b/SOURCES/kdump.conf index 2865414..57af7b6 100644 --- a/SOURCES/kdump.conf +++ b/SOURCES/kdump.conf @@ -111,10 +111,17 @@ # The default option is "reboot". # # force_rebuild <0 | 1> -# - By default, kdump initrd will only be rebuilt whennecessary. +# - By default, kdump initrd will only be rebuilt when necessary. # Specify 1 to force rebuilding kdump initrd every time when kdump # service starts. # +# force_no_rebuild <0 | 1> +# - By default, kdump initrd will be rebuilt when necessary. +# Specify 1 to bypass rebuilding of kdump initrd. +# +# force_no_rebuild and force_rebuild options are mutually +# exclusive and they should not be set to 1 simultaneously. +# # override_resettable <0 | 1> # - Usually an unresettable block device can't be a dump target. # Specifying 1 when you want to dump even though the block @@ -129,9 +136,9 @@ # all valid arguments except hosts to send notification to). # # fence_kdump_nodes -# - List of cluster node(s), separated by spaces, to send -# fence_kdump notifications to (this option is mandatory to -# enable fence_kdump). +# - List of cluster node(s) except localhost, separated by spaces, +# to send fence_kdump notifications to. +# (this option is mandatory to enable fence_kdump). # #raw /dev/vg/lv_kdump @@ -150,6 +157,7 @@ core_collector makedumpfile -l --message-level 1 -d 31 #extra_modules gfs2 #default shell #force_rebuild 1 +#force_no_rebuild 1 #dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3" #fence_kdump_args -p 7410 -f auto -c 0 -i 10 #fence_kdump_nodes node1 node2 diff --git a/SOURCES/kdump.conf.5 b/SOURCES/kdump.conf.5 index ca42769..11b1fad 100644 --- a/SOURCES/kdump.conf.5 +++ b/SOURCES/kdump.conf.5 @@ -166,6 +166,16 @@ By default, kdump initrd will only be rebuilt when necessary. Specify 1 to force rebuilding kdump initrd every time when kdump service starts. .RE +.B force_no_rebuild <0 | 1> +.RS +By default, kdump initrd will be rebuilt when necessary. +Specify 1 to bypass rebuilding of kdump initrd. + +.PP +force_no_rebuild and force_rebuild options are mutually exclusive and +they should not be set to 1 simultaneously. +.RE + .B override_resettable <0 | 1> .RS Usually an unresettable block device can't be a dump target. Specifying 1 means @@ -190,7 +200,7 @@ arguments except hosts to send notification to). .B fence_kdump_nodes .RS -List of cluster node(s), separated by spaces, to send fence_kdump notification +List of cluster node(s) except localhost, separated by spaces, to send fence_kdump notification to (this option is mandatory to enable fence_kdump). .RE diff --git a/SOURCES/kdump.sysconfig b/SOURCES/kdump.sysconfig index effe466..d44c8ae 100644 --- a/SOURCES/kdump.sysconfig +++ b/SOURCES/kdump.sysconfig @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices" # Any additional kexec arguments required. In most situations, this should diff --git a/SOURCES/kdump.sysconfig.aarch64 b/SOURCES/kdump.sysconfig.aarch64 index 78b00bb..8a8400a 100644 --- a/SOURCES/kdump.sysconfig.aarch64 +++ b/SOURCES/kdump.sysconfig.aarch64 @@ -14,9 +14,14 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline -KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 rootflags=nofail" +# after processed by KDUMP_COMMANDLINE_REMOVE +KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 swiotlb=noforce cma=0 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 rootflags=nofail" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdump.sysconfig.i386 b/SOURCES/kdump.sysconfig.i386 index bb7a6e5..37d1b96 100644 --- a/SOURCES/kdump.sysconfig.i386 +++ b/SOURCES/kdump.sysconfig.i386 @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never" # Any additional kexec arguments required. In most situations, this should diff --git a/SOURCES/kdump.sysconfig.ppc64 b/SOURCES/kdump.sysconfig.ppc64 index dd09598..3d4db57 100644 --- a/SOURCES/kdump.sysconfig.ppc64 +++ b/SOURCES/kdump.sysconfig.ppc64 @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never" # Any additional kexec arguments required. In most situations, this should diff --git a/SOURCES/kdump.sysconfig.ppc64le b/SOURCES/kdump.sysconfig.ppc64le index dd09598..3d4db57 100644 --- a/SOURCES/kdump.sysconfig.ppc64le +++ b/SOURCES/kdump.sysconfig.ppc64le @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never" # Any additional kexec arguments required. In most situations, this should diff --git a/SOURCES/kdump.sysconfig.s390x b/SOURCES/kdump.sysconfig.s390x index b103a88..96b3d1b 100644 --- a/SOURCES/kdump.sysconfig.s390x +++ b/SOURCES/kdump.sysconfig.s390x @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never" # Any additional /sbin/mkdumprd arguments required. diff --git a/SOURCES/kdump.sysconfig.x86_64 b/SOURCES/kdump.sysconfig.x86_64 index 7991d68..77cbd0e 100644 --- a/SOURCES/kdump.sysconfig.x86_64 +++ b/SOURCES/kdump.sysconfig.x86_64 @@ -14,8 +14,13 @@ KDUMP_KERNELVER="" # /proc/cmdline KDUMP_COMMANDLINE="" +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug notsc kaslr" + # This variable lets us append arguments to the current kdump commandline -# As taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# after processed by KDUMP_COMMANDLINE_REMOVE KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never" # Any additional kexec arguments required. In most situations, this should diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index cedf832..d8e6d2e 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/bash KEXEC=/sbin/kexec KDUMP_KERNELVER="" @@ -8,7 +8,10 @@ KDUMP_CONFIG_FILE="/etc/kdump.conf" MKDUMPRD="/sbin/mkdumprd -f" SAVE_PATH=/var/crash SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" +INITRD_CHECKSUM_LOCATION="/boot/.fadump_initrd_checksum" DUMP_TARGET="" +DEFAULT_INITRD="" +DEFAULT_INITRD_BAK="" TARGET_INITRD="" FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled" FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered" @@ -20,6 +23,9 @@ image_time=0 standard_kexec_args="-p" +# Some default values in case /etc/sysconfig/kdump doesn't include +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" + if [ -f /etc/sysconfig/kdump ]; then . /etc/sysconfig/kdump fi @@ -106,8 +112,10 @@ prepare_cmdline() else cmdline=${KDUMP_COMMANDLINE} fi - cmdline=`remove_cmdline_param "$cmdline" crashkernel hugepages hugepagesz panic_on_warn slub_debug` - + # These params should always be removed + cmdline=`remove_cmdline_param "$cmdline" crashkernel panic_on_warn` + # These params can be removed configurably + cmdline=`remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE}` cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}" @@ -149,9 +157,6 @@ rebuild_fadump_initrd() { local target_initrd_tmp - # backup fadump initrd for reference before replacing it - backup_initrd - # this file tells the initrd is fadump enabled touch /tmp/fadump.initramfs target_initrd_tmp="$TARGET_INITRD.tmp" @@ -215,15 +220,43 @@ check_executable() done } -backup_initrd() +backup_default_initrd() { - local target_initrd_bak + if [ ! -f "$DEFAULT_INITRD" ]; then + return + fi - # Check if backup initrd is already present. - target_initrd_bak="$TARGET_INITRD.bak" - if [ ! -e $target_initrd_bak ];then - echo "Backing up $TARGET_INITRD" - cp $TARGET_INITRD $target_initrd_bak + if [ ! -e $DEFAULT_INITRD_BAK ]; then + echo "Backing up $DEFAULT_INITRD before rebuild." + # save checksum to verify before restoring + sha1sum $DEFAULT_INITRD > $INITRD_CHECKSUM_LOCATION + cp $DEFAULT_INITRD $DEFAULT_INITRD_BAK + if [ $? -ne 0 ]; then + echo "WARNING: failed to backup $DEFAULT_INITRD." + rm -f $DEFAULT_INITRD_BAK + fi + fi +} + +restore_default_initrd() +{ + # If a backup initrd exists, we must be switching back from + # fadump to kdump. Restore the original default initrd. + if [ -f $DEFAULT_INITRD_BAK ] && [ -f $INITRD_CHECKSUM_LOCATION ]; then + # verify checksum before restoring + backup_checksum=`sha1sum $DEFAULT_INITRD_BAK | awk '{ print $1 }'` + default_checksum=`cat $INITRD_CHECKSUM_LOCATION | awk '{ print $1 }'` + if [ "$default_checksum" != "$backup_checksum" ]; then + echo "WARNING: checksum mismatch! Can't restore original initrd.." + else + rm -f $INITRD_CHECKSUM_LOCATION + mv $DEFAULT_INITRD_BAK $DEFAULT_INITRD + if [[ $? -eq 0 ]]; then + echo -n "Restoring original initrd as fadump mode " + echo "is disabled." + sync + fi + fi fi } @@ -244,12 +277,12 @@ check_config() } while read config_opt config_val; do - # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) case "$config_opt" in \#* | "") ;; - raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|default|force_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes) + raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|default|force_rebuild|force_no_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes) + # remove inline comments after the end of a directive. + config_val=$(strip_comments $config_val) [ -z "$config_val" ] && { echo "Invalid kdump config value for option $config_opt." return 1; @@ -315,10 +348,12 @@ check_boot_dir() fi } -setup_target_initrd() +setup_initrd() { + DEFAULT_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`.img" + DEFAULT_INITRD_BAK="${KDUMP_BOOTDIR}/.initramfs-`uname -r`.img.default" if [ $DEFAULT_DUMP_MODE == "fadump" ]; then - TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}.img" + TARGET_INITRD="$DEFAULT_INITRD" if [ ! -s "$TARGET_INITRD" ]; then echo "Error: No initrd found to rebuild!" return 1 @@ -340,7 +375,8 @@ check_files_modified() EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-` EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" - files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS /etc/fstab" + files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS" + [[ -e /etc/fstab ]] && files="$files /etc/fstab" check_exist "$files" && check_executable "$EXTRA_BINS" [ $? -ne 0 ] && return 2 @@ -397,19 +433,15 @@ check_dump_fs_modified() _new_dev=$_target else _new_dev=$(kdump_get_persistent_dev $_target $_new_fstype) - if ! findmnt $_target >/dev/null; then - echo "Dump target $_target is probably not mounted." - return 2 - fi fi - if ! findmnt $_target >/dev/null; then + if ! findmnt $_target >/dev/null; then echo "Dump target $_target is probably not mounted." return 2 fi _new_mntpoint="/kdumproot/$(get_mntpoint_from_target $_target)" - _dracut_args=$(lsinitrd $TARGET_INITRD | grep "^Arguments:" | head -1) + _dracut_args=$(lsinitrd $TARGET_INITRD -f usr/lib/dracut/build-parameter.txt) if [[ -z "$_dracut_args" ]];then echo "Warning: No dracut arguments found in initrd" return 0 @@ -435,36 +467,58 @@ check_dump_fs_modified() check_wdt_modified() { + local -A _drivers + local _alldrivers _active _wdtdrv _wdtppath _dir + local wd_old wd_new + is_wdt_mod_omitted [[ $? -eq 0 ]] && return 0 [[ -d /sys/class/watchdog/ ]] || return 0 - for dir in /sys/class/watchdog/*; do - [[ -d "$dir" ]] || continue - [[ -f "$dir/state" ]] || continue - wdtdrv=$(< "$dir/device/modalias") - wdtdrv=$(modinfo $wdtdrv | grep filename | awk -F"kernel/" '{print $2}') - active=$(< "$dir/state") - # rebuild when: - # module for this watchdog is not found and watchdog is active - # module for this watchdog is found and watchdog is inactive - lsinitrd $TARGET_INITRD | grep $wdtdrv &> /dev/null - if [ $? -ne 0 ]; then - [[ "$active" = "active" ]] && return 1 - else - [[ "$active" = "inactive" ]] && return 1 + # Copied logic from dracut 04watchdog/module-setup.sh::installkernel() + for _dir in /sys/class/watchdog/*; do + [[ -d "$_dir" ]] || continue + [[ -f "$_dir/state" ]] || continue + _active=$(< "$_dir/state") + [[ "$_active" = "active" ]] || continue + # device/modalias will return driver of this device + _wdtdrv=$(< "$_dir/device/modalias") + # There can be more than one module represented by same + # modalias. Currently load all of them. + # TODO: Need to find a way to avoid any unwanted module + # represented by modalias + _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null) + if [[ $_wdtdrv ]]; then + for i in $_wdtdrv; do + _drivers[$i]=1 + done fi + # however in some cases, we also need to check that if there is + # a specific driver for the parent bus/device. In such cases + # we also need to enable driver for parent bus/device. + _wdtppath=$(readlink -f "$_dir/device") + while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do + _wdtppath=$(readlink -f "$_wdtppath/..") + [[ -f "$_wdtppath/modalias" ]] || continue + + _wdtdrv=$(< "$_wdtppath/modalias") + _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null) + if [[ $_wdtdrv ]]; then + for i in $_wdtdrv; do + _drivers[$i]=1 + done + fi + done done - # check if watchdog kernel module unloaded. - loaded_mods=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf) - [[ -n $loaded_mods ]] && loaded_mods=$(echo $loaded_mods | awk -F"rd.driver.pre=" '{print $2}' | sed "s/,/ /g") - for mod in $loaded_mods ; do - lsmod | grep $mod &> /dev/null - [[ $? != 0 ]] && return 1 - done + # ensure that watchdog module is loaded as early as possible + _alldrivers="${!_drivers[*]}" + [[ $_alldrivers ]] && wd_new="rd.driver.pre=${_alldrivers// /,}" + wd_old=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf) - return 0 + [[ "$wd_old" = "$wd_new" ]] && return 0 + + return 1 } # returns 0 if system is not modified @@ -501,8 +555,8 @@ check_rebuild() { local extra_modules local _force_rebuild force_rebuild="0" + local _force_no_rebuild force_no_rebuild="0" local ret system_modified="0" - local initramfs_has_fadump check_boot_dir @@ -513,11 +567,20 @@ check_rebuild() fi kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}" - setup_target_initrd + setup_initrd if [ $? -ne 0 ]; then return 1 fi + _force_no_rebuild=`grep ^force_no_rebuild $KDUMP_CONFIG_FILE 2>/dev/null` + if [ $? -eq 0 ]; then + force_no_rebuild=`echo $_force_no_rebuild | cut -d' ' -f2` + if [ "$force_no_rebuild" != "0" ] && [ "$force_no_rebuild" != "1" ];then + echo "Error: force_no_rebuild value is invalid" + return 1 + fi + fi + _force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE 2>/dev/null` if [ $? -eq 0 ]; then force_rebuild=`echo $_force_rebuild | cut -d' ' -f2` @@ -527,6 +590,16 @@ check_rebuild() fi fi + if [[ "$force_no_rebuild" == "1" && "$force_rebuild" == "1" ]]; then + echo "Error: force_rebuild and force_no_rebuild are enabled simultaneously in kdump.conf" + return 1 + fi + + # Will not rebuild kdump initrd + if [ "$force_no_rebuild" == "1" ]; then + return 0 + fi + #will rebuild every time if extra_modules are specified extra_modules=`grep ^extra_modules $KDUMP_CONFIG_FILE` [ -n "$extra_modules" ] && force_rebuild="1" @@ -537,26 +610,6 @@ check_rebuild() image_time=`stat -c "%Y" $TARGET_INITRD 2>/dev/null` fi - #also rebuild when Pacemaker cluster conf is changed and fence kdump is enabled. - modified_files=$(get_pcs_cluster_modified_files $image_time) - - EXTRA_BINS=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2` - CHECK_FILES=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2` - EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" - CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-` - EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" - files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS /etc/fstab" - - check_exist "$files" && check_executable "$EXTRA_BINS" - [ $? -ne 0 ] && return 1 - - for file in $files; do - time_stamp=`stat -c "%Y" $file` - if [ "$time_stamp" -gt "$image_time" ]; then - modified_files="$modified_files $file" - fi - done - check_system_modified ret=$? if [ $ret -eq 2 ]; then @@ -565,15 +618,10 @@ check_rebuild() system_modified="1" fi - #check if target initrd has fadump support - if [ "$DEFAULT_DUMP_MODE" = "fadump" ] && [ -f "$TARGET_INITRD" ]; then - initramfs_has_fadump=`lsinitrd -m $TARGET_INITRD | grep ^kdumpbase$ | wc -l` - fi + handle_mode_switch if [ $image_time -eq 0 ]; then echo -n "No kdump initial ramdisk found."; echo - elif [ $DEFAULT_DUMP_MODE == "fadump" ] && [ "$initramfs_has_fadump" -eq "0" ]; then - echo "$TARGET_INITRD has no fadump support" elif [ "$force_rebuild" != "0" ]; then echo -n "Force rebuild $TARGET_INITRD"; echo elif [ "$system_modified" != "0" ]; then @@ -600,18 +648,11 @@ need_64bit_headers() print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` } -# Load the kdump kerel specified in /etc/sysconfig/kdump +# Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. load_kdump() { - MEM_RESERVED=$(cat /sys/kernel/kexec_crash_size) - if [ $MEM_RESERVED -eq 0 ] - then - echo "No memory reserved for crash kernel." >&2 - return 1 - fi - ARCH=`uname -m` if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ] then @@ -664,10 +705,10 @@ load_kdump() check_ssh_config() { while read config_opt config_val; do - # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) case "$config_opt" in sshkey) + # remove inline comments after the end of a directive. + config_val=$(strip_comments $config_val) if [ -f "$config_val" ]; then # canonicalize the path SSH_KEY_LOCATION=$(/usr/bin/readlink -m $config_val) @@ -676,9 +717,11 @@ check_ssh_config() fi ;; path) + config_val=$(strip_comments $config_val) SAVE_PATH=$config_val ;; ssh) + config_val=$(strip_comments $config_val) DUMP_TARGET=$config_val ;; *) @@ -750,6 +793,20 @@ show_reserved_mem() echo "Reserved "$mem_mb"MB memory for crash kernel" } +handle_mode_switch() +{ + if [ "$DEFAULT_DUMP_MODE" == "fadump" ]; then + # backup initrd for reference before replacing it + # with fadump aware initrd + backup_default_initrd + else + # check if a backup of default initrd exists. If yes, + # it signifies a switch from fadump mode. So, restore + # the backed up default initrd. + restore_default_initrd + fi +} + is_fadump_capable() { # Check if firmware-assisted dump is enabled @@ -934,8 +991,11 @@ is_secure_mode_enforced() { local secure_mode_byte - secure_mode_byte=$(cat /sys/kernel/security/securelevel) + if [ ! -f /sys/kernel/security/securelevel ]; then + return 1 + fi + secure_mode_byte=$(cat /sys/kernel/security/securelevel) if [ "$secure_mode_byte" = "1" ]; then return 0 fi @@ -943,17 +1003,33 @@ is_secure_mode_enforced() return 1 } +check_crash_mem_reserved() +{ + local mem_reserved + + mem_reserved=$(cat /sys/kernel/kexec_crash_size) + if [ $mem_reserved -eq 0 ]; then + echo "No memory reserved for crash kernel" + return 1 + fi + + return 0 +} + check_kdump_feasibility() { if [ ! -e /sys/kernel/kexec_crash_loaded ]; then echo "Kdump is not supported on this kernel" return 1 fi + check_crash_mem_reserved + return $? } check_fence_kdump_config() { local hostname=`hostname` + local ipaddrs=`hostname -I` local nodes=$(get_option_value "fence_kdump_nodes") for node in $nodes; do @@ -961,6 +1037,12 @@ check_fence_kdump_config() echo "Option fence_kdump_nodes cannot contain $hostname" return 1 fi + # node can be ipaddr + echo $ipaddrs | grep $node > /dev/null + if [ $? -eq 0 ]; then + echo "Option fence_kdump_nodes cannot contain $node" + return 1 + fi done return 0 @@ -1020,22 +1102,23 @@ check_default_config() start() { - check_config + check_dump_feasibility if [ $? -ne 0 ]; then echo "Starting kdump: [FAILED]" return 1 fi - if sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; then - selinux_relabel - fi - save_raw + check_config if [ $? -ne 0 ]; then echo "Starting kdump: [FAILED]" return 1 fi - check_dump_feasibility + if sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; then + selinux_relabel + fi + + save_raw if [ $? -ne 0 ]; then echo "Starting kdump: [FAILED]" return 1 diff --git a/SOURCES/kexec-kdump-howto.txt b/SOURCES/kexec-kdump-howto.txt index f46563f..3b29bbf 100644 --- a/SOURCES/kexec-kdump-howto.txt +++ b/SOURCES/kexec-kdump-howto.txt @@ -91,6 +91,27 @@ This line tells kexec to reserve 64M of ram if the system contains between 512M and 2G of physical memory. If the system contains 2G or more of physical memory, 128M should be reserved. +You can also use the default crashkernel=auto to let kernel set the +crashkernel size. + +crashkernel=auto indicates a best effort estimation for usual use cases, +however one still needs do a test to ensure that the kernel reserved +memory size is enough. + +NOTE: +When a debug variant kernel is used as the capture kernel and the +primary kernel was booted with 'crashkernel=auto' set in the bootargs, +the capture kernel boot can fail. + +A debug variant kernel usually is the same stable kernel with some +debug options enabled which uses much more memory in the kdump kernel. +Thus when you use 'crashkernel=auto', kdump kernel will likely run out +of memory. + +So it is not advisable to use a debug variant kernel as the capture +kernel when primary kernel is booted with 'crashkernel=auto' set in +bootargs. + After making said changes, reboot your system, so that the X MB of memory is left untouched by the normal system, reserved for the capture kernel. Take note that the output of 'free -m' will show X MB less memory than without this diff --git a/SOURCES/kexec-tools-2.0.14-Only-print-debug-message-when-failed-to-serach-for-k.patch b/SOURCES/kexec-tools-2.0.14-Only-print-debug-message-when-failed-to-serach-for-k.patch new file mode 100644 index 0000000..0a312f1 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-Only-print-debug-message-when-failed-to-serach-for-k.patch @@ -0,0 +1,40 @@ +From f85183096d31d865c97565614535d84943b12908 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Baoquan He +Date: Fri, 3 Mar 2017 11:52:15 +0800 +Subject: [PATCH 01/10] Only print debug message when failed to serach for + kernel symbol from /proc/kallsyms + +Kernel symbol page_offset_base could be unavailable when mm KASLR code is +not compiled in kernel. It's inappropriate to print out error message +when failed to search for page_offset_base from /proc/kallsyms. Seems now +there is not a way to find out if mm KASLR is compiled in or not. An +alternative approach is only printing out debug message in get_kernel_sym +if failed to search a expected kernel symbol. + +Do it in this patch, a simple fix. + +Signed-off-by: Baoquan He +Reviewed-by: Pratyush Anand +Acked-by: Dave Young +Signed-off-by: Simon Horman +--- + kexec/arch/i386/crashdump-x86.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c +index 88aeee33572b..c4cf2013a001 100644 +--- a/kexec/arch/i386/crashdump-x86.c ++++ b/kexec/arch/i386/crashdump-x86.c +@@ -127,7 +127,7 @@ static unsigned long long get_kernel_sym(const char *symbol) + } + } + +- fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol); ++ dbgprintf("Cannot get kernel %s symbol address\n", symbol); + return 0; + } + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-identify-PHYS_OFFSET-correctly.patch b/SOURCES/kexec-tools-2.0.14-arm64-identify-PHYS_OFFSET-correctly.patch new file mode 100644 index 0000000..6d63dd8 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-identify-PHYS_OFFSET-correctly.patch @@ -0,0 +1,76 @@ +From 7a4381e2042e2be308c96bc927145bc39a0594cc Mon Sep 17 00:00:00 2001 +Message-Id: <7a4381e2042e2be308c96bc927145bc39a0594cc.1489676829.git.panand@redhat.com> +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:18 +0900 +Subject: [PATCH 04/10] arm64: identify PHYS_OFFSET correctly + +Due to the kernel patch, commit e7cd190385d1 ("arm64: mark reserved +memblock regions explicitly in iomem"), the current code will not be able +to identify the correct value of PHYS_OFFSET if some "reserved" memory +region, which is likely to be UEFI runtime services code/data, exists at +an address below the first "System RAM" regions. + +This patch fixes this issue. + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/iomem.h | 7 +++++++ + kexec/arch/arm64/kexec-arm64.c | 12 ++++++++++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + create mode 100644 kexec/arch/arm64/iomem.h + +diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h +new file mode 100644 +index 000000000000..7fd66eb063e1 +--- /dev/null ++++ b/kexec/arch/arm64/iomem.h +@@ -0,0 +1,7 @@ ++#ifndef IOMEM_H ++#define IOMEM_H ++ ++#define SYSTEM_RAM "System RAM\n" ++#define IOMEM_RESERVED "reserved\n" ++ ++#endif +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 04fd3968bb52..d02b9dac3d33 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -21,6 +21,7 @@ + #include "crashdump-arm64.h" + #include "dt-ops.h" + #include "fs2dt.h" ++#include "iomem.h" + #include "kexec-syscall.h" + #include "arch/options.h" + +@@ -476,7 +477,14 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + return -1; + + r = (struct memory_range *)data + nr; +- r->type = RANGE_RAM; ++ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) ++ r->type = RANGE_RAM; ++ else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED))) ++ r->type = RANGE_RESERVED; ++ else ++ return 1; ++ + r->start = base; + r->end = base + length - 1; + +@@ -495,7 +503,7 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + static int get_memory_ranges_iomem(struct memory_range *array, + unsigned int *count) + { +- *count = kexec_iomem_for_each_line("System RAM\n", ++ *count = kexec_iomem_for_each_line(NULL, + get_memory_ranges_iomem_cb, array); + + if (!*count) { +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-Add-support-for-binary-image-files.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-Add-support-for-binary-image-files.patch new file mode 100644 index 0000000..bbdf554 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-Add-support-for-binary-image-files.patch @@ -0,0 +1,52 @@ +From ba77ebdac0d49ac128f4d31a5fd86e8165ce916a Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Pratyush Anand +Date: Wed, 15 Mar 2017 18:38:24 +0900 +Subject: [PATCH 10/10] arm64: kdump: Add support for binary image files + +This patch adds support to use binary image ie arch/arm64/boot/Image with +kdump. + +Signed-off-by: Pratyush Anand +[takahiro.akashi@linaro.org: a bit reworked] +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/kexec-image-arm64.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c +index 960ed9667a4d..982e431e6d22 100644 +--- a/kexec/arch/arm64/kexec-image-arm64.c ++++ b/kexec/arch/arm64/kexec-image-arm64.c +@@ -4,7 +4,9 @@ + + #define _GNU_SOURCE + ++#include "crashdump-arm64.h" + #include "kexec-arm64.h" ++#include "kexec-syscall.h" + #include + + int image_arm64_probe(const char *kernel_buf, off_t kernel_size) +@@ -58,6 +60,16 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf, + dbgprintf("%s: PE format: %s\n", __func__, + (arm64_header_check_pe_sig(header) ? "yes" : "no")); + ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ /* create and initialize elf core header segment */ ++ result = load_crashdump_segments(info); ++ if (result) { ++ dbgprintf("%s: Creating eflcorehdr failed.\n", ++ __func__); ++ goto exit; ++ } ++ } ++ + /* load the kernel */ + add_segment_phys_virt(info, kernel_buf, kernel_size, + kernel_segment + arm64_mem.text_offset, +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch new file mode 100644 index 0000000..5414e17 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch @@ -0,0 +1,282 @@ +From 7c59b94be4abf8b28dd02bae8b79542377a86618 Mon Sep 17 00:00:00 2001 +Message-Id: <7c59b94be4abf8b28dd02bae8b79542377a86618.1489676829.git.panand@redhat.com> +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:23 +0900 +Subject: [PATCH 09/10] arm64: kdump: add DT properties to crash dump kernel's + dtb + +We pass the following properties to crash dump kernel: +linux,elfcorehdr: elf core header segment, + same as "elfcorehdr=" kernel parameter on other archs +linux,usable-memory-range: usable memory reserved for crash dump kernel + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/kexec-arm64.c | 197 ++++++++++++++++++++++++++++++++++++- + kexec/arch/arm64/kexec-elf-arm64.c | 5 - + 2 files changed, 192 insertions(+), 10 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 5e30107b043f..f3f101d1be48 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -25,6 +25,14 @@ + #include "kexec-syscall.h" + #include "arch/options.h" + ++#define ROOT_NODE_ADDR_CELLS_DEFAULT 1 ++#define ROOT_NODE_SIZE_CELLS_DEFAULT 1 ++ ++#define PROP_ADDR_CELLS "#address-cells" ++#define PROP_SIZE_CELLS "#size-cells" ++#define PROP_ELFCOREHDR "linux,elfcorehdr" ++#define PROP_USABLE_MEM_RANGE "linux,usable-memory-range" ++ + /* Global varables the core kexec routines expect. */ + + unsigned char reuse_initrd; +@@ -128,9 +136,6 @@ int arch_process_options(int argc, char **argv) + case OPT_INITRD: + arm64_opts.initrd = optarg; + break; +- case OPT_PANIC: +- die("load-panic (-p) not supported"); +- break; + default: + break; /* Ignore core and unknown options. */ + } +@@ -281,12 +286,115 @@ on_success: + return 0; + } + ++static int get_cells_size(void *fdt, uint32_t *address_cells, ++ uint32_t *size_cells) ++{ ++ int nodeoffset; ++ const uint32_t *prop = NULL; ++ int prop_len; ++ ++ /* default values */ ++ *address_cells = ROOT_NODE_ADDR_CELLS_DEFAULT; ++ *size_cells = ROOT_NODE_SIZE_CELLS_DEFAULT; ++ ++ /* under root node */ ++ nodeoffset = fdt_path_offset(fdt, "/"); ++ if (nodeoffset < 0) ++ goto on_error; ++ ++ prop = fdt_getprop(fdt, nodeoffset, PROP_ADDR_CELLS, &prop_len); ++ if (prop) { ++ if (prop_len == sizeof(*prop)) ++ *address_cells = fdt32_to_cpu(*prop); ++ else ++ goto on_error; ++ } ++ ++ prop = fdt_getprop(fdt, nodeoffset, PROP_SIZE_CELLS, &prop_len); ++ if (prop) { ++ if (prop_len == sizeof(*prop)) ++ *size_cells = fdt32_to_cpu(*prop); ++ else ++ goto on_error; ++ } ++ ++ dbgprintf("%s: #address-cells:%d #size-cells:%d\n", __func__, ++ *address_cells, *size_cells); ++ return 0; ++ ++on_error: ++ return -EFAILED; ++} ++ ++bool cells_size_fitted(uint32_t address_cells, uint32_t size_cells, ++ struct memory_range *range) ++{ ++ dbgprintf("%s: %llx-%llx\n", __func__, range->start, range->end); ++ ++ /* if *_cells >= 2, cells can hold 64-bit values anyway */ ++ if ((address_cells == 1) && (range->start >= (1ULL << 32))) ++ return false; ++ ++ if ((size_cells == 1) && ++ ((range->end - range->start + 1) >= (1ULL << 32))) ++ return false; ++ ++ return true; ++} ++ ++static void fill_property(void *buf, uint64_t val, uint32_t cells) ++{ ++ uint32_t val32; ++ int i; ++ ++ if (cells == 1) { ++ val32 = cpu_to_fdt32((uint32_t)val); ++ memcpy(buf, &val32, sizeof(uint32_t)); ++ } else { ++ for (i = 0; ++ i < (cells * sizeof(uint32_t) - sizeof(uint64_t)); i++) ++ *(char *)buf++ = 0; ++ ++ val = cpu_to_fdt64(val); ++ memcpy(buf, &val, sizeof(uint64_t)); ++ } ++} ++ ++static int setprop_range(void *fdt, int nodeoffset, ++ const char *name, struct memory_range *range, ++ uint32_t address_cells, uint32_t size_cells) ++{ ++ void *buf, *prop; ++ size_t buf_size; ++ int result; ++ ++ buf_size = (address_cells + size_cells) * sizeof(uint32_t); ++ prop = buf = xmalloc(buf_size); ++ ++ fill_property(prop, range->start, address_cells); ++ prop += address_cells * sizeof(uint32_t); ++ ++ fill_property(prop, range->end - range->start + 1, size_cells); ++ prop += size_cells * sizeof(uint32_t); ++ ++ result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size); ++ ++ free(buf); ++ ++ return result; ++} ++ + /** + * setup_2nd_dtb - Setup the 2nd stage kernel's dtb. + */ + +-static int setup_2nd_dtb(struct dtb *dtb, char *command_line) ++static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) + { ++ uint32_t address_cells, size_cells; ++ int range_len; ++ int nodeoffset; ++ char *new_buf = NULL; ++ int new_size; + int result; + + result = fdt_check_header(dtb->buf); +@@ -298,8 +406,86 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line) + + result = set_bootargs(dtb, command_line); + ++ if (on_crash) { ++ /* determine #address-cells and #size-cells */ ++ result = get_cells_size(dtb->buf, &address_cells, &size_cells); ++ if (result) { ++ fprintf(stderr, ++ "kexec: cannot determine cells-size.\n"); ++ result = -EINVAL; ++ goto on_error; ++ } ++ ++ if (!cells_size_fitted(address_cells, size_cells, ++ &elfcorehdr_mem)) { ++ fprintf(stderr, ++ "kexec: elfcorehdr doesn't fit cells-size.\n"); ++ result = -EINVAL; ++ goto on_error; ++ } ++ ++ if (!cells_size_fitted(address_cells, size_cells, ++ &crash_reserved_mem)) { ++ fprintf(stderr, ++ "kexec: usable memory range doesn't fit cells-size.\n"); ++ result = -EINVAL; ++ goto on_error; ++ } ++ ++ /* duplicate dt blob */ ++ range_len = sizeof(uint32_t) * (address_cells + size_cells); ++ new_size = fdt_totalsize(dtb->buf) ++ + fdt_prop_len(PROP_ELFCOREHDR, range_len) ++ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len); ++ ++ new_buf = xmalloc(new_size); ++ result = fdt_open_into(dtb->buf, new_buf, new_size); ++ if (result) { ++ dbgprintf("%s: fdt_open_into failed: %s\n", __func__, ++ fdt_strerror(result)); ++ result = -ENOSPC; ++ goto on_error; ++ } ++ ++ /* add linux,elfcorehdr */ ++ nodeoffset = fdt_path_offset(new_buf, "/chosen"); ++ result = setprop_range(new_buf, nodeoffset, ++ PROP_ELFCOREHDR, &elfcorehdr_mem, ++ address_cells, size_cells); ++ if (result) { ++ dbgprintf("%s: fdt_setprop failed: %s\n", __func__, ++ fdt_strerror(result)); ++ result = -EINVAL; ++ goto on_error; ++ } ++ ++ /* add linux,usable-memory-range */ ++ nodeoffset = fdt_path_offset(new_buf, "/chosen"); ++ result = setprop_range(new_buf, nodeoffset, ++ PROP_USABLE_MEM_RANGE, &crash_reserved_mem, ++ address_cells, size_cells); ++ if (result) { ++ dbgprintf("%s: fdt_setprop failed: %s\n", __func__, ++ fdt_strerror(result)); ++ result = -EINVAL; ++ goto on_error; ++ } ++ ++ fdt_pack(new_buf); ++ dtb->buf = new_buf; ++ dtb->size = fdt_totalsize(new_buf); ++ } ++ + dump_reservemap(dtb); + ++ ++ return result; ++ ++on_error: ++ fprintf(stderr, "kexec: %s failed.\n", __func__); ++ if (new_buf) ++ free(new_buf); ++ + return result; + } + +@@ -367,7 +553,8 @@ int arm64_load_other_segments(struct kexec_info *info, + } + } + +- result = setup_2nd_dtb(&dtb, command_line); ++ result = setup_2nd_dtb(&dtb, command_line, ++ info->kexec_flags & KEXEC_ON_CRASH); + + if (result) + return -EFAILED; +diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c +index 842ce21e2387..b17a31afa24e 100644 +--- a/kexec/arch/arm64/kexec-elf-arm64.c ++++ b/kexec/arch/arm64/kexec-elf-arm64.c +@@ -47,11 +47,6 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, + int result; + int i; + +- if (info->kexec_flags & KEXEC_ON_CRASH) { +- fprintf(stderr, "kexec: kdump not yet supported on arm64\n"); +- return -EFAILED; +- } +- + result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); + + if (result < 0) { +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-elf-core-header-segment.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-elf-core-header-segment.patch new file mode 100644 index 0000000..6c24d59 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-add-elf-core-header-segment.patch @@ -0,0 +1,191 @@ +From dd3886b82ed56c18d9d6d0e7228a2b31eed0ec5a Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:20 +0900 +Subject: [PATCH 06/10] arm64: kdump: add elf core header segment + +Elf core header contains the information necessary for the coredump of +the 1st kernel, including its physcal memory layout as well as cpu register +states at the panic. +The segment is allocated inside the reserved memory of crash dump kernel. + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/crashdump-arm64.c | 96 ++++++++++++++++++++++++++++++++++++++ + kexec/arch/arm64/crashdump-arm64.h | 3 ++ + kexec/arch/arm64/iomem.h | 2 + + kexec/arch/arm64/kexec-elf-arm64.c | 10 ++++ + 4 files changed, 111 insertions(+) + +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index dcaca434af62..83461312d412 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -39,6 +39,39 @@ struct memory_ranges usablemem_rgns = { + .ranges = &crash_reserved_mem, + }; + ++struct memory_range elfcorehdr_mem; ++ ++static struct crash_elf_info elf_info = { ++ .class = ELFCLASS64, ++#if (__BYTE_ORDER == __LITTLE_ENDIAN) ++ .data = ELFDATA2LSB, ++#else ++ .data = ELFDATA2MSB, ++#endif ++ .machine = EM_AARCH64, ++}; ++ ++/* ++ * Note: The returned value is correct only if !CONFIG_RANDOMIZE_BASE. ++ */ ++static uint64_t get_kernel_page_offset(void) ++{ ++ int i; ++ ++ if (elf_info.kern_vaddr_start == UINT64_MAX) ++ return UINT64_MAX; ++ ++ /* Current max virtual memory range is 48-bits. */ ++ for (i = 48; i > 0; i--) ++ if (!(elf_info.kern_vaddr_start & (1UL << i))) ++ break; ++ ++ if (i <= 0) ++ return UINT64_MAX; ++ else ++ return UINT64_MAX << i; ++} ++ + /* + * iomem_range_callback() - callback called for each iomem region + * @data: not used +@@ -62,6 +95,10 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), + else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) + return mem_regions_add(&crash_memory_rgns, + base, length, RANGE_RAM); ++ else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0) ++ elf_info.kern_paddr_start = base; ++ else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0) ++ elf_info.kern_size = base + length - elf_info.kern_paddr_start; + + return 0; + } +@@ -115,5 +152,64 @@ static int crash_get_memory_ranges(void) + dbgprint_mem_range("Coredump memory ranges", + crash_memory_rgns.ranges, crash_memory_rgns.size); + ++ /* ++ * For additional kernel code/data segment. ++ * kern_paddr_start/kern_size are determined in iomem_range_callback ++ */ ++ elf_info.kern_vaddr_start = get_kernel_sym("_text"); ++ if (!elf_info.kern_vaddr_start) ++ elf_info.kern_vaddr_start = UINT64_MAX; ++ ++ return 0; ++} ++ ++/* ++ * load_crashdump_segments() - load the elf core header ++ * @info: kexec info structure ++ * ++ * This function creates and loads an additional segment of elf core header ++ : which is used to construct /proc/vmcore on crash dump kernel. ++ * ++ * Return 0 in case of success and -1 in case of error. ++ */ ++ ++int load_crashdump_segments(struct kexec_info *info) ++{ ++ unsigned long elfcorehdr; ++ unsigned long bufsz; ++ void *buf; ++ int err; ++ ++ /* ++ * First fetch all the memory (RAM) ranges that we are going to ++ * pass to the crash dump kernel during panic. ++ */ ++ ++ err = crash_get_memory_ranges(); ++ ++ if (err) ++ return err; ++ ++ elf_info.page_offset = get_kernel_page_offset(); ++ dbgprintf("%s: page_offset: %016llx\n", __func__, ++ elf_info.page_offset); ++ ++ err = crash_create_elf64_headers(info, &elf_info, ++ crash_memory_rgns.ranges, crash_memory_rgns.size, ++ &buf, &bufsz, ELF_CORE_HEADER_ALIGN); ++ ++ if (err) ++ return err; ++ ++ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0, ++ crash_reserved_mem.start, crash_reserved_mem.end, ++ -1, 0); ++ ++ elfcorehdr_mem.start = elfcorehdr; ++ elfcorehdr_mem.end = elfcorehdr + bufsz - 1; ++ ++ dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__, ++ elfcorehdr_mem.start, elfcorehdr_mem.end); ++ + return 0; + } +diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h +index 07a0ed0bc344..da75a2d0c5f1 100644 +--- a/kexec/arch/arm64/crashdump-arm64.h ++++ b/kexec/arch/arm64/crashdump-arm64.h +@@ -18,5 +18,8 @@ + + extern struct memory_ranges usablemem_rgns; + extern struct memory_range crash_reserved_mem; ++extern struct memory_range elfcorehdr_mem; ++ ++extern int load_crashdump_segments(struct kexec_info *info); + + #endif /* CRASHDUMP_ARM64_H */ +diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h +index 20cda87dbd02..d4864bb44922 100644 +--- a/kexec/arch/arm64/iomem.h ++++ b/kexec/arch/arm64/iomem.h +@@ -2,6 +2,8 @@ + #define IOMEM_H + + #define SYSTEM_RAM "System RAM\n" ++#define KERNEL_CODE "Kernel code\n" ++#define KERNEL_DATA "Kernel data\n" + #define CRASH_KERNEL "Crash kernel\n" + #define IOMEM_RESERVED "reserved\n" + +diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c +index daf8bf0df9c4..c70a37ae7732 100644 +--- a/kexec/arch/arm64/kexec-elf-arm64.c ++++ b/kexec/arch/arm64/kexec-elf-arm64.c +@@ -119,6 +119,16 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, + dbgprintf("%s: PE format: %s\n", __func__, + (arm64_header_check_pe_sig(header) ? "yes" : "no")); + ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ /* create and initialize elf core header segment */ ++ result = load_crashdump_segments(info); ++ if (result) { ++ dbgprintf("%s: Creating eflcorehdr failed.\n", ++ __func__); ++ goto exit; ++ } ++ } ++ + /* load the kernel */ + result = elf_exec_load(&ehdr, info); + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-identify-memory-regions.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-identify-memory-regions.patch new file mode 100644 index 0000000..b914e43 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-identify-memory-regions.patch @@ -0,0 +1,202 @@ +From 2fa1ef9e45b3ce6f7977a2518e58e177934f377c Mon Sep 17 00:00:00 2001 +Message-Id: <2fa1ef9e45b3ce6f7977a2518e58e177934f377c.1489676829.git.panand@redhat.com> +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:19 +0900 +Subject: [PATCH 05/10] arm64: kdump: identify memory regions + +The following regions need to be identified for later use: + a) memory regions which belong to the 1st kernel + b) usable memory reserved for crash dump kernel + +We go through /proc/iomem to find out a) and b) which are marked +as "System RAM" and "Crash kernel", respectively. + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/Makefile | 2 + + kexec/arch/arm64/crashdump-arm64.c | 100 ++++++++++++++++++++++++++++++++++++- + kexec/arch/arm64/crashdump-arm64.h | 14 +++++- + kexec/arch/arm64/iomem.h | 1 + + 4 files changed, 114 insertions(+), 3 deletions(-) + +diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile +index 74b677f7784e..2d4ae0eed9e0 100644 +--- a/kexec/arch/arm64/Makefile ++++ b/kexec/arch/arm64/Makefile +@@ -6,6 +6,8 @@ arm64_FS2DT_INCLUDE += \ + + arm64_DT_OPS += kexec/dt-ops.c + ++arm64_MEM_REGIONS = kexec/mem_regions.c ++ + arm64_CPPFLAGS += -I $(srcdir)/kexec/ + + arm64_KEXEC_SRCS += \ +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index d2272c8124d0..dcaca434af62 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -1,5 +1,13 @@ + /* + * ARM64 crashdump. ++ * partly derived from arm implementation ++ * ++ * Copyright (c) 2014-2016 Linaro Limited ++ * Author: AKASHI Takahiro ++ * ++ * 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. + */ + + #define _GNU_SOURCE +@@ -10,12 +18,102 @@ + #include "kexec.h" + #include "crashdump.h" + #include "crashdump-arm64.h" ++#include "iomem.h" + #include "kexec-arm64.h" + #include "kexec-elf.h" ++#include "mem_regions.h" + +-struct memory_ranges usablemem_rgns = {}; ++/* memory ranges on crashed kernel */ ++static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES]; ++static struct memory_ranges crash_memory_rgns = { ++ .size = 0, ++ .max_size = CRASH_MAX_MEMORY_RANGES, ++ .ranges = crash_memory_ranges, ++}; ++ ++/* memory range reserved for crashkernel */ ++struct memory_range crash_reserved_mem; ++struct memory_ranges usablemem_rgns = { ++ .size = 0, ++ .max_size = 1, ++ .ranges = &crash_reserved_mem, ++}; ++ ++/* ++ * iomem_range_callback() - callback called for each iomem region ++ * @data: not used ++ * @nr: not used ++ * @str: name of the memory region ++ * @base: start address of the memory region ++ * @length: size of the memory region ++ * ++ * This function is called once for each memory region found in /proc/iomem. ++ * It locates system RAM and crashkernel reserved memory and places these to ++ * variables, respectively, crash_memory_ranges and crash_reserved_mem. ++ */ ++ ++static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), ++ char *str, unsigned long long base, ++ unsigned long long length) ++{ ++ if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0) ++ return mem_regions_add(&usablemem_rgns, ++ base, length, RANGE_RAM); ++ else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) ++ return mem_regions_add(&crash_memory_rgns, ++ base, length, RANGE_RAM); ++ ++ return 0; ++} + + int is_crashkernel_mem_reserved(void) + { ++ if (!crash_reserved_mem.end) ++ kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL); ++ ++ return crash_reserved_mem.start != crash_reserved_mem.end; ++} ++ ++/* ++ * crash_get_memory_ranges() - read system physical memory ++ * ++ * Function reads through system physical memory and stores found memory ++ * regions in crash_memory_ranges. ++ * Regions are sorted in ascending order. ++ * ++ * Returns 0 in case of success and -1 otherwise (errno is set). ++ */ ++static int crash_get_memory_ranges(void) ++{ ++ /* ++ * First read all memory regions that can be considered as ++ * system memory including the crash area. ++ */ ++ if (!usablemem_rgns.size) ++ kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL); ++ ++ /* allow only a single region for crash dump kernel */ ++ if (usablemem_rgns.size != 1) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1); ++ ++ if (mem_regions_exclude(&crash_memory_rgns, &crash_reserved_mem)) { ++ fprintf(stderr, ++ "Error: Number of crash memory ranges excedeed the max limit\n"); ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ /* ++ * Make sure that the memory regions are sorted. ++ */ ++ mem_regions_sort(&crash_memory_rgns); ++ ++ dbgprint_mem_range("Coredump memory ranges", ++ crash_memory_rgns.ranges, crash_memory_rgns.size); ++ + return 0; + } +diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h +index f33c7a25b454..07a0ed0bc344 100644 +--- a/kexec/arch/arm64/crashdump-arm64.h ++++ b/kexec/arch/arm64/crashdump-arm64.h +@@ -1,12 +1,22 @@ + /* + * ARM64 crashdump. ++ * ++ * Copyright (c) 2014-2016 Linaro Limited ++ * Author: AKASHI Takahiro ++ * ++ * 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. + */ + +-#if !defined(CRASHDUMP_ARM64_H) ++#ifndef CRASHDUMP_ARM64_H + #define CRASHDUMP_ARM64_H + + #include "kexec.h" + ++#define CRASH_MAX_MEMORY_RANGES 32 ++ + extern struct memory_ranges usablemem_rgns; ++extern struct memory_range crash_reserved_mem; + +-#endif ++#endif /* CRASHDUMP_ARM64_H */ +diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h +index 7fd66eb063e1..20cda87dbd02 100644 +--- a/kexec/arch/arm64/iomem.h ++++ b/kexec/arch/arm64/iomem.h +@@ -2,6 +2,7 @@ + #define IOMEM_H + + #define SYSTEM_RAM "System RAM\n" ++#define CRASH_KERNEL "Crash kernel\n" + #define IOMEM_RESERVED "reserved\n" + + #endif +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-kernel-image-segment.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-kernel-image-segment.patch new file mode 100644 index 0000000..47c71fd --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-kernel-image-segment.patch @@ -0,0 +1,140 @@ +From af338a51df9012f1b1dca87ddd27a5c66db5b80b Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:21 +0900 +Subject: [PATCH 07/10] arm64: kdump: set up kernel image segment + +On arm64, we can use the same kernel image as 1st kernel, but +we have to modify the entry point as well as segments' addresses +in the kernel's elf header in order to load them into correct places. + +Minor conflicts was resolved in kexec/arch/arm64/crashdump-arm64.c because +get_crash_kernel_load_range() is not yet backported. + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/crashdump-arm64.c | 23 +++++++++++++++++++++++ + kexec/arch/arm64/crashdump-arm64.h | 1 + + kexec/arch/arm64/kexec-arm64.c | 25 ++++++++++++++++++++----- + kexec/arch/arm64/kexec-elf-arm64.c | 10 +++++++++- + 4 files changed, 53 insertions(+), 6 deletions(-) + +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index 83461312d412..9517329e1086 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -213,3 +213,26 @@ int load_crashdump_segments(struct kexec_info *info) + + return 0; + } ++ ++/* ++ * e_entry and p_paddr are actually in virtual address space. ++ * Those values will be translated to physcal addresses by ++ * using virt_to_phys(). ++ * So let's get ready for later use so the memory base (phys_offset) ++ * will be correctly replaced with crash_reserved_mem.start. ++ */ ++void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr) ++{ ++ struct mem_phdr *phdr; ++ int i; ++ ++ ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start; ++ ++ for (i = 0; i < ehdr->e_phnum; i++) { ++ phdr = &ehdr->e_phdr[i]; ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ phdr->p_paddr += ++ (-arm64_mem.phys_offset + crash_reserved_mem.start); ++ } ++} +diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h +index da75a2d0c5f1..382f57154f2a 100644 +--- a/kexec/arch/arm64/crashdump-arm64.h ++++ b/kexec/arch/arm64/crashdump-arm64.h +@@ -21,5 +21,6 @@ extern struct memory_range crash_reserved_mem; + extern struct memory_range elfcorehdr_mem; + + extern int load_crashdump_segments(struct kexec_info *info); ++extern void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr); + + #endif /* CRASHDUMP_ARM64_H */ +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index d02b9dac3d33..5a1da2ec1a34 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -307,12 +307,27 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info) + { + unsigned long hole; + +- hole = locate_hole(info, +- arm64_mem.text_offset + arm64_mem.image_size, +- MiB(2), 0, ULONG_MAX, 1); ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ unsigned long hole_end; ++ ++ hole = (crash_reserved_mem.start < mem_min ? ++ mem_min : crash_reserved_mem.start); ++ hole = _ALIGN_UP(hole, MiB(2)); ++ hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size; ++ ++ if ((hole_end > mem_max) || ++ (hole_end > crash_reserved_mem.end)) { ++ dbgprintf("%s: Crash kernel out of range\n", __func__); ++ hole = ULONG_MAX; ++ } ++ } else { ++ hole = locate_hole(info, ++ arm64_mem.text_offset + arm64_mem.image_size, ++ MiB(2), 0, ULONG_MAX, 1); + +- if (hole == ULONG_MAX) +- dbgprintf("%s: locate_hole failed\n", __func__); ++ if (hole == ULONG_MAX) ++ dbgprintf("%s: locate_hole failed\n", __func__); ++ } + + return hole; + } +diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c +index c70a37ae7732..842ce21e2387 100644 +--- a/kexec/arch/arm64/kexec-elf-arm64.c ++++ b/kexec/arch/arm64/kexec-elf-arm64.c +@@ -9,6 +9,7 @@ + #include + #include + ++#include "crashdump-arm64.h" + #include "kexec-arm64.h" + #include "kexec-elf.h" + #include "kexec-syscall.h" +@@ -105,7 +106,8 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, + } + + arm64_mem.vp_offset = _ALIGN_DOWN(ehdr.e_entry, MiB(2)); +- arm64_mem.vp_offset -= kernel_segment - get_phys_offset(); ++ if (!(info->kexec_flags & KEXEC_ON_CRASH)) ++ arm64_mem.vp_offset -= kernel_segment - get_phys_offset(); + + dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); + dbgprintf("%s: text_offset: %016lx\n", __func__, +@@ -127,6 +129,12 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, + __func__); + goto exit; + } ++ ++ /* ++ * offset addresses in order to fit vmlinux ++ * (elf_exec) into crash kernel's memory ++ */ ++ modify_ehdr_for_crashdump(&ehdr); + } + + /* load the kernel */ +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-other-segments.patch b/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-other-segments.patch new file mode 100644 index 0000000..7261936 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-arm64-kdump-set-up-other-segments.patch @@ -0,0 +1,35 @@ +From 6b1b954c9b2faf4969fa9f285d4162bd41b78498 Mon Sep 17 00:00:00 2001 +Message-Id: <6b1b954c9b2faf4969fa9f285d4162bd41b78498.1489676829.git.panand@redhat.com> +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:22 +0900 +Subject: [PATCH 08/10] arm64: kdump: set up other segments + +We make sure that all the other segments, initrd and device-tree blob, +also be loaded into the reserved memory of crash dump kernel. + +Signed-off-by: AKASHI Takahiro +--- + kexec/arch/arm64/kexec-arm64.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 5a1da2ec1a34..5e30107b043f 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -375,7 +375,10 @@ int arm64_load_other_segments(struct kexec_info *info, + /* Put the other segments after the image. */ + + hole_min = image_base + arm64_mem.image_size; +- hole_max = ULONG_MAX; ++ if (info->kexec_flags & KEXEC_ON_CRASH) ++ hole_max = crash_reserved_mem.end; ++ else ++ hole_max = ULONG_MAX; + + if (arm64_opts.initrd) { + initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size); +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-build_mem_phdrs-check-if-p_paddr-is-invalid.patch b/SOURCES/kexec-tools-2.0.14-build_mem_phdrs-check-if-p_paddr-is-invalid.patch new file mode 100644 index 0000000..f479086 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-build_mem_phdrs-check-if-p_paddr-is-invalid.patch @@ -0,0 +1,43 @@ +From 5520739f1e6e31c7731d34d384bbaf4904282931 Mon Sep 17 00:00:00 2001 +Message-Id: <5520739f1e6e31c7731d34d384bbaf4904282931.1489470510.git.panand@redhat.com> +From: Pratyush Anand +Date: Wed, 1 Mar 2017 11:19:42 +0530 +Subject: [PATCH] build_mem_phdrs(): check if p_paddr is invalid + +Currently, all the p_paddr of PT_LOAD headers are assigned to 0, which +is not correct and could be misleading, since 0 is a valid physical +address. + +Upstream kernel commit "464920104bf7 /proc/kcore: update physical +address for kcore ram and text" fixed it and now invalid PT_LOAD is +assigned as -1. + +kexec/arch/i386/crashdump-x86.c:get_kernel_vaddr_and_size() uses kcore +interface and so calls build_mem_phdrs() for kcore PT_LOAD headers. + +This patch fixes build_mem_phdrs() to check if p_paddr is invalid. + +Signed-off-by: Pratyush Anand +Acked-by: Dave Young +Signed-off-by: Simon Horman +--- + kexec/kexec-elf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kexec/kexec-elf.c b/kexec/kexec-elf.c +index 1d6320a2f0e6..be60bbd48486 100644 +--- a/kexec/kexec-elf.c ++++ b/kexec/kexec-elf.c +@@ -432,7 +432,8 @@ static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, + } + return -1; + } +- if ((phdr->p_paddr + phdr->p_memsz) < phdr->p_paddr) { ++ if (phdr->p_paddr != (unsigned long long)-1 && ++ (phdr->p_paddr + phdr->p_memsz) < phdr->p_paddr) { + /* The memory address wraps */ + if (probe_debug) { + fprintf(stderr, "ELF address wrap around\n"); +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-kexec-Increase-the-upper-limit-for-RAM-segments.patch b/SOURCES/kexec-tools-2.0.14-kexec-Increase-the-upper-limit-for-RAM-segments.patch new file mode 100644 index 0000000..7f95e1e --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-kexec-Increase-the-upper-limit-for-RAM-segments.patch @@ -0,0 +1,32 @@ +From 24aa2d93cac316657a2c20f28b8687bbf7e22991 Mon Sep 17 00:00:00 2001 +Message-Id: <24aa2d93cac316657a2c20f28b8687bbf7e22991.1492785094.git.panand@redhat.com> +From: Sameer Goel +Date: Wed, 18 Jan 2017 16:15:12 -0700 +Subject: [PATCH] kexec: Increase the upper limit for RAM segments + +On a newer UEFI based Qualcomm target the number of system ram regions +retrieved from /proc/iomem are ~40. So increasing the current hardcoded +values to 64 from 16. + +Signed-off-by: Sameer Goel +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h +index bac62f8b19e0..bd4c20e76d15 100644 +--- a/kexec/arch/arm64/kexec-arm64.h ++++ b/kexec/arch/arm64/kexec-arm64.h +@@ -11,7 +11,7 @@ + #include "image-header.h" + #include "kexec.h" + +-#define KEXEC_SEGMENT_MAX 16 ++#define KEXEC_SEGMENT_MAX 64 + + #define BOOT_BLOCK_VERSION 17 + #define BOOT_BLOCK_LAST_COMP_VERSION 16 +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch b/SOURCES/kexec-tools-2.0.14-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch new file mode 100644 index 0000000..4842ea2 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch @@ -0,0 +1,79 @@ +From e7bb07ee7b499f71990e9e83596bdb2ddabdd4cd Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: AKASHI Takahiro +Date: Wed, 15 Mar 2017 18:38:16 +0900 +Subject: [PATCH 02/10] kexec: exntend the semantics of + kexec_iomem_for_each_line + +The current kexec_iomem_for_each_line() counts up all the lines for which +a callback function returns zero(0) or positive, and otherwise it stops +further scanning. +This behavior is incovenient in some cases. For instance, on arm64, we want +to count up "System RAM" entries, but need to skip "reserved" entries. + +So this patch extends the semantics so that we will continue to scan +succeeding entries but not count lines for which a callback function +returns positive. + +The current users of kexec_iomem_for_each_line(), arm, sh and x86, will not +be affected by this change because +* arm + The callback function only returns -1 or 0, and the return value of + kexec_iomem_for_each_line() will never be used. +* sh, x86 + The callback function may return (-1 for sh,) 0 or 1, but always returns + 1 once we have reached the maximum number of entries allowed. + Even so the current kexec_iomem_for_each_line() counts them up. + This change actually fixes this bug. + +Signed-off-by: AKASHI Takahiro +--- + kexec/kexec-iomem.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/kexec/kexec-iomem.c b/kexec/kexec-iomem.c +index 485a2e810080..0a0277a422d8 100644 +--- a/kexec/kexec-iomem.c ++++ b/kexec/kexec-iomem.c +@@ -18,6 +18,9 @@ + * Iterate over each line in the file returned by proc_iomem(). If match is + * NULL or if the line matches with our match-pattern then call the + * callback if non-NULL. ++ * If match is NULL, callback should return a negative if error. ++ * Otherwise the interation goes on, incrementing nr but only if callback ++ * returns 0 (matched). + * + * Return the number of lines matched. + */ +@@ -37,7 +40,7 @@ int kexec_iomem_for_each_line(char *match, + char *str; + int consumed; + int count; +- int nr = 0; ++ int nr = 0, ret; + + fp = fopen(iomem, "r"); + if (!fp) +@@ -50,11 +53,13 @@ int kexec_iomem_for_each_line(char *match, + str = line + consumed; + size = end - start + 1; + if (!match || memcmp(str, match, strlen(match)) == 0) { +- if (callback +- && callback(data, nr, str, start, size) < 0) { +- break; ++ if (callback) { ++ ret = callback(data, nr, str, start, size); ++ if (ret < 0) ++ break; ++ else if (ret == 0) ++ nr++; + } +- nr++; + } + } + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-kexec-generalize-and-rename-get_kernel_stext_sym.patch b/SOURCES/kexec-tools-2.0.14-kexec-generalize-and-rename-get_kernel_stext_sym.patch new file mode 100644 index 0000000..070ed5d --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-kexec-generalize-and-rename-get_kernel_stext_sym.patch @@ -0,0 +1,187 @@ +From d8e8090a66891eb114f31ed0d4c006a161efc109 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Pratyush Anand +Date: Wed, 15 Mar 2017 18:38:17 +0900 +Subject: [PATCH 03/10] kexec: generalize and rename get_kernel_stext_sym() + +get_kernel_stext_sym() has been defined for both arm and i386. Other +architecture might need some other kernel symbol address. Therefore rewrite +this function as generic function to get any kernel symbol address. + +More over, kallsyms is not arch specific representation, therefore have +common function for all arches. + +Signed-off-by: Pratyush Anand +[created symbols.c] +Signed-off-by: AKASHI Takahiro +--- + kexec/Makefile | 1 + + kexec/arch/arm/crashdump-arm.c | 40 +--------------------------------------- + kexec/arch/i386/crashdump-x86.c | 29 ----------------------------- + kexec/kexec.h | 2 ++ + kexec/symbols.c | 34 ++++++++++++++++++++++++++++++++++ + 5 files changed, 38 insertions(+), 68 deletions(-) + create mode 100644 kexec/symbols.c + +diff --git a/kexec/Makefile b/kexec/Makefile +index 39f365f543d7..2b4fb3d162ec 100644 +--- a/kexec/Makefile ++++ b/kexec/Makefile +@@ -26,6 +26,7 @@ KEXEC_SRCS_base += kexec/kernel_version.c + KEXEC_SRCS_base += kexec/lzma.c + KEXEC_SRCS_base += kexec/zlib.c + KEXEC_SRCS_base += kexec/kexec-xen.c ++KEXEC_SRCS_base += kexec/symbols.c + + KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) + +diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c +index 4a89b5ea9645..245c21af5e32 100644 +--- a/kexec/arch/arm/crashdump-arm.c ++++ b/kexec/arch/arm/crashdump-arm.c +@@ -73,48 +73,10 @@ static struct crash_elf_info elf_info = { + + extern unsigned long long user_page_offset; + +-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */ +-static unsigned long long get_kernel_stext_sym(void) +-{ +- const char *kallsyms = "/proc/kallsyms"; +- const char *stext = "_stext"; +- char sym[128]; +- char line[128]; +- FILE *fp; +- unsigned long long vaddr = 0; +- char type; +- +- fp = fopen(kallsyms, "r"); +- if (!fp) { +- fprintf(stderr, "Cannot open %s\n", kallsyms); +- return 0; +- } +- +- while(fgets(line, sizeof(line), fp) != NULL) { +- unsigned long long addr; +- +- if (sscanf(line, "%Lx %c %s", &addr, &type, sym) != 3) +- continue; +- +- if (strcmp(sym, stext) == 0) { +- dbgprintf("kernel symbol %s vaddr = %#llx\n", stext, addr); +- vaddr = addr; +- break; +- } +- } +- +- fclose(fp); +- +- if (vaddr == 0) +- fprintf(stderr, "Cannot get kernel %s symbol address\n", stext); +- +- return vaddr; +-} +- + static int get_kernel_page_offset(struct kexec_info *info, + struct crash_elf_info *elf_info) + { +- unsigned long long stext_sym_addr = get_kernel_stext_sym(); ++ unsigned long long stext_sym_addr = get_kernel_sym("_stext"); + if (stext_sym_addr == 0) { + if (user_page_offset != (-1ULL)) { + elf_info->page_offset = user_page_offset; +diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c +index c4cf2013a001..a324c6c9074f 100644 +--- a/kexec/arch/i386/crashdump-x86.c ++++ b/kexec/arch/i386/crashdump-x86.c +@@ -102,35 +102,6 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info), + return -1; + } + +-/* Retrieve kernel symbol virtual address from /proc/kallsyms */ +-static unsigned long long get_kernel_sym(const char *symbol) +-{ +- const char *kallsyms = "/proc/kallsyms"; +- char sym[128]; +- char line[128]; +- FILE *fp; +- unsigned long long vaddr; +- char type; +- +- fp = fopen(kallsyms, "r"); +- if (!fp) { +- fprintf(stderr, "Cannot open %s\n", kallsyms); +- return 0; +- } +- +- while(fgets(line, sizeof(line), fp) != NULL) { +- if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3) +- continue; +- if (strcmp(sym, symbol) == 0) { +- dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr); +- return vaddr; +- } +- } +- +- dbgprintf("Cannot get kernel %s symbol address\n", symbol); +- return 0; +-} +- + /* Retrieve info regarding virtual address kernel has been compiled for and + * size of the kernel from /proc/kcore. Current /proc/kcore parsing from + * from kexec-tools fails because of malformed elf notes. A kernel patch has +diff --git a/kexec/kexec.h b/kexec/kexec.h +index 9194f1c87c91..b4fafad9487b 100644 +--- a/kexec/kexec.h ++++ b/kexec/kexec.h +@@ -312,4 +312,6 @@ int xen_kexec_load(struct kexec_info *info); + int xen_kexec_unload(uint64_t kexec_flags); + void xen_kexec_exec(void); + ++extern unsigned long long get_kernel_sym(const char *text); ++ + #endif /* KEXEC_H */ +diff --git a/kexec/symbols.c b/kexec/symbols.c +new file mode 100644 +index 000000000000..5e42de98de32 +--- /dev/null ++++ b/kexec/symbols.c +@@ -0,0 +1,34 @@ ++#include ++#include ++#include "kexec.h" ++ ++/* Retrieve kernel symbol virtual address from /proc/kallsyms */ ++unsigned long long get_kernel_sym(const char *symbol) ++{ ++ const char *kallsyms = "/proc/kallsyms"; ++ char sym[128]; ++ char line[128]; ++ FILE *fp; ++ unsigned long long vaddr; ++ char type; ++ ++ fp = fopen(kallsyms, "r"); ++ if (!fp) { ++ fprintf(stderr, "Cannot open %s\n", kallsyms); ++ return 0; ++ } ++ ++ while (fgets(line, sizeof(line), fp) != NULL) { ++ if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3) ++ continue; ++ if (strcmp(sym, symbol) == 0) { ++ dbgprintf("kernel symbol %s vaddr = %16llx\n", ++ symbol, vaddr); ++ return vaddr; ++ } ++ } ++ ++ dbgprintf("Cannot get kernel %s symbol address\n", symbol); ++ ++ return 0; ++} +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-elf_info-kcore-check-for-invalid-physic.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-elf_info-kcore-check-for-invalid-physic.patch new file mode 100644 index 0000000..1edff59 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-elf_info-kcore-check-for-invalid-physic.patch @@ -0,0 +1,47 @@ +From f4ab6897a716d3f3959f6cb8cab27744eaecb5a6 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +References: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Pratyush Anand +Date: Thu, 2 Mar 2017 17:37:16 +0900 +Subject: [PATCH 4/7] [PATCH v3 4/7] elf_info: kcore: check for invalid + physical address + +kcore passes correct phys_start for direct mapped region and an invalid +value (-1) for all other regions after the kernel commit +464920104bf7(/proc/kcore: update physical address for kcore ram and +text). arch specific function is_phys_addr() accepts only virt_start. +Therefore, check for valid phys_start in get_kcore_dump_loads(). + +Signed-off-by: Pratyush Anand +--- + elf_info.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/makedumpfile-1.6.1/elf_info.c b/makedumpfile-1.6.1/elf_info.c +index 65ff333cf33a..c5743b3cab28 100644 +--- a/makedumpfile-1.6.1/elf_info.c ++++ b/makedumpfile-1.6.1/elf_info.c +@@ -881,7 +881,8 @@ int get_kcore_dump_loads(void) + + for (i = 0; i < num_pt_loads; ++i) { + struct pt_load_segment *p = &pt_loads[i]; +- if (!is_phys_addr(p->virt_start)) ++ if (p->phys_start == NOT_PADDR ++ || !is_phys_addr(p->virt_start)) + continue; + loads++; + } +@@ -901,7 +902,8 @@ int get_kcore_dump_loads(void) + + for (i = 0, j = 0; i < num_pt_loads; ++i) { + struct pt_load_segment *p = &pt_loads[i]; +- if (!is_phys_addr(p->virt_start)) ++ if (p->phys_start == NOT_PADDR ++ || !is_phys_addr(p->virt_start)) + continue; + if (j >= loads) + return FALSE; +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-initial-call-cache_init-a-bit-early.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-initial-call-cache_init-a-bit-early.patch new file mode 100644 index 0000000..8523767 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-initial-call-cache_init-a-bit-early.patch @@ -0,0 +1,47 @@ +From 8e2834bac4f62da3894da297f083068431be6d80 Mon Sep 17 00:00:00 2001 +Message-Id: <8e2834bac4f62da3894da297f083068431be6d80.1489471500.git.panand@redhat.com> +In-Reply-To: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +References: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Pratyush Anand +Date: Thu, 2 Mar 2017 17:37:11 +0900 +Subject: [PATCH 2/7] [PATCH v3 2/7] initial(): call cache_init() a bit early + +Call cache_init() before get_kcore_dump_loads(), because latter uses +cache_search(). + +Call path is like this : +get_kcore_dump_loads() -> process_dump_load() -> vaddr_to_paddr() -> +vtop4_x86_64() -> readmem() -> cache_search() + +Signed-off-by: Pratyush Anand +--- + makedumpfile.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/makedumpfile-1.6.1/makedumpfile.c b/makedumpfile-1.6.1/makedumpfile.c +index 6942047199de..3b8e9810468d 100644 +--- a/makedumpfile-1.6.1/makedumpfile.c ++++ b/makedumpfile-1.6.1/makedumpfile.c +@@ -3878,6 +3878,9 @@ initial(void) + if (!get_value_for_old_linux()) + return FALSE; + ++ if (!is_xen_memory() && !cache_init()) ++ return FALSE; ++ + if (info->flag_mem_usage && !get_kcore_dump_loads()) + return FALSE; + +@@ -4000,9 +4003,6 @@ out: + } + } + +- if (!is_xen_memory() && !cache_init()) +- return FALSE; +- + if (debug_info && !get_machdep_info()) + return FALSE; + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Correct-the-calculation-of.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Correct-the-calculation-of.patch new file mode 100644 index 0000000..16388c8 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Correct-the-calculation-of.patch @@ -0,0 +1,45 @@ +From 4c53423b995463067fbbd394e724b4d1d6ea3d62 Mon Sep 17 00:00:00 2001 +Message-Id: <4c53423b995463067fbbd394e724b4d1d6ea3d62.1489471500.git.panand@redhat.com> +In-Reply-To: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +References: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Baoquan He +Date: Thu, 2 Mar 2017 17:37:19 +0900 +Subject: [PATCH 5/7] [PATCH v3 5/7] makedumpfile: Correct the calculation of + kvaddr in set_kcore_vmcoreinfo + +In set_kcore_vmcoreinfo, we calculate the virtual address of vmcoreinfo +by OR operation as below: + + kvaddr = (ulong)vmcoreinfo_addr | PAGE_OFFSET; + +When mm sections kaslr is not enabled, this is correct since the +starting address of direct mapping section is 0xffff880000000000 which +is 1T aligned. Usually system with memory below 1T won't cause problem. + +However with mm section kaslr enabled, the starting address of direct +mapping is 1G aligned. The above code makes kvaddr unsure. + +So change it to adding operation: + kvaddr = (ulong)vmcoreinfo_addr + PAGE_OFFSET; + +Signed-off-by: Baoquan He +--- + elf_info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.1/elf_info.c b/makedumpfile-1.6.1/elf_info.c +index c5743b3cab28..100272f83c48 100644 +--- a/makedumpfile-1.6.1/elf_info.c ++++ b/makedumpfile-1.6.1/elf_info.c +@@ -372,7 +372,7 @@ int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len) + off_t offset_desc; + + offset = UNINITIALIZED; +- kvaddr = (ulong)vmcoreinfo_addr | PAGE_OFFSET; ++ kvaddr = (ulong)vmcoreinfo_addr + PAGE_OFFSET; + + for (i = 0; i < num_pt_loads; ++i) { + struct pt_load_segment *p = &pt_loads[i]; +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Discard-process_dump_load.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Discard-process_dump_load.patch new file mode 100644 index 0000000..30b0e0e --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-Discard-process_dump_load.patch @@ -0,0 +1,57 @@ +From f3ff8c6232de43fa2cc60f5ca0f233cf8eb8d2ad Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +References: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Baoquan He +Date: Thu, 2 Mar 2017 17:37:23 +0900 +Subject: [PATCH 6/7] [PATCH v3 6/7] makedumpfile: Discard process_dump_load + +Kernel commit 464920104bf7 (/proc/kcore: update physical address for +kcore ram and text) provides physical address of direct mapping kcore +program segments. So no need to calculate it specifically now. And the +old code is not correct since it calls vaddr_to_paddr() which has not +been ready at that time. + +Signed-off-by: Baoquan He +--- + elf_info.c | 17 ----------------- + 1 file changed, 17 deletions(-) + +diff --git a/makedumpfile-1.6.1/elf_info.c b/makedumpfile-1.6.1/elf_info.c +index 100272f83c48..8e2437622141 100644 +--- a/makedumpfile-1.6.1/elf_info.c ++++ b/makedumpfile-1.6.1/elf_info.c +@@ -857,22 +857,6 @@ static int exclude_segment(struct pt_load_segment **pt_loads, + return 0; + } + +-static int +-process_dump_load(struct pt_load_segment *pls) +-{ +- unsigned long long paddr; +- +- paddr = vaddr_to_paddr(pls->virt_start); +- pls->phys_start = paddr; +- pls->phys_end = paddr + (pls->virt_end - pls->virt_start); +- DEBUG_MSG("process_dump_load\n"); +- DEBUG_MSG(" phys_start : %llx\n", pls->phys_start); +- DEBUG_MSG(" phys_end : %llx\n", pls->phys_end); +- DEBUG_MSG(" virt_start : %llx\n", pls->virt_start); +- DEBUG_MSG(" virt_end : %llx\n", pls->virt_end); +- +- return TRUE; +-} + + int get_kcore_dump_loads(void) + { +@@ -917,7 +901,6 @@ int get_kcore_dump_loads(void) + } + + pls[j] = *p; +- process_dump_load(&pls[j]); + j++; + } + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-add-runtime-kaslr-offset-if-it-exists.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-add-runtime-kaslr-offset-if-it-exists.patch new file mode 100644 index 0000000..2d90a65 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-makedumpfile-add-runtime-kaslr-offset-if-it-exists.patch @@ -0,0 +1,303 @@ +From 302c16ede3723264ca0abb5eef9c9f553ffcfbd7 Mon Sep 17 00:00:00 2001 +Message-Id: <302c16ede3723264ca0abb5eef9c9f553ffcfbd7.1496033260.git.panand@redhat.com> +From: Pratyush Anand +Date: Wed, 26 Apr 2017 14:36:29 +0530 +Subject: [PATCH 1/3] makedumpfile: add runtime kaslr offset if it exists + +If we have to erase a symbol from vmcore whose address is not present in +vmcoreinfo, then we need to pass vmlinux as well to get the symbol +address. +When kaslr is enabled, virtual address of all the kernel symbols are +randomized with an offset. vmlinux always has a static address, but all +the arch specific calculation are based on run time kernel address. So +we need to find a way to translate symbol address from vmlinux to kernel +run time address. + +without this patch: + # cat > scrub.conf << EOF + [vmlinux] + erase jiffies + erase init_task.utime + for tsk in init_task.tasks.next within task_struct:tasks + erase tsk.utime + endfor + EOF + + # makedumpfile --split -d 5 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3} + + readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore. + readmem: type_addr: 1, addr:f97eaff8, size:8 + vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8). + readmem: Can't convert a virtual address(ffffffff819f1284) to physical address. + readmem: type_addr: 0, addr:ffffffff819f1284, size:390 + check_release: Can't get the address of system_utsname. + +After this patch check_release() is ok, and also we are able to erase +symbol from vmcore. + +Signed-off-by: Pratyush Anand +--- + arch/x86_64.c | 36 ++++++++++++++++++++++++++++++++++++ + erase_info.c | 1 + + makedumpfile.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + makedumpfile.h | 16 ++++++++++++++++ + 4 files changed, 99 insertions(+) + +diff --git a/makedumpfile-1.6.1/arch/x86_64.c b/makedumpfile-1.6.1/arch/x86_64.c +index e978a36f8878..fd2e8ac154d6 100644 +--- a/makedumpfile-1.6.1/arch/x86_64.c ++++ b/makedumpfile-1.6.1/arch/x86_64.c +@@ -33,6 +33,42 @@ get_xen_p2m_mfn(void) + return NOT_FOUND_LONG_VALUE; + } + ++unsigned long ++get_kaslr_offset_x86_64(unsigned long vaddr) ++{ ++ unsigned int i; ++ char buf[BUFSIZE_FGETS], *endp; ++ ++ if (!info->kaslr_offset && info->file_vmcoreinfo) { ++ if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) { ++ ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n", ++ info->name_vmcoreinfo, strerror(errno)); ++ return FALSE; ++ } ++ ++ while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) { ++ i = strlen(buf); ++ if (!i) ++ break; ++ if (buf[i - 1] == '\n') ++ buf[i - 1] = '\0'; ++ if (strncmp(buf, STR_KERNELOFFSET, ++ strlen(STR_KERNELOFFSET)) == 0) ++ info->kaslr_offset = ++ strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16); ++ } ++ } ++ if (vaddr >= __START_KERNEL_map && ++ vaddr < __START_KERNEL_map + info->kaslr_offset) ++ return info->kaslr_offset; ++ else ++ /* ++ * TODO: we need to check if it is vmalloc/vmmemmap/module ++ * address, we will have different offset ++ */ ++ return 0; ++} ++ + static int + get_page_offset_x86_64(void) + { +diff --git a/makedumpfile-1.6.1/erase_info.c b/makedumpfile-1.6.1/erase_info.c +index f2ba9149e93e..60abfa1a1adf 100644 +--- a/makedumpfile-1.6.1/erase_info.c ++++ b/makedumpfile-1.6.1/erase_info.c +@@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned long long base_vaddr, + ce->line, ce->name); + return FALSE; + } ++ ce->sym_addr += get_kaslr_offset(ce->sym_addr); + ce->type_name = get_symbol_type_name(ce->name, + DWARF_INFO_GET_SYMBOL_TYPE, + &ce->size, &ce->type_flag); +diff --git a/makedumpfile-1.6.1/makedumpfile.c b/makedumpfile-1.6.1/makedumpfile.c +index 301772a8820c..9babf1a07154 100644 +--- a/makedumpfile-1.6.1/makedumpfile.c ++++ b/makedumpfile-1.6.1/makedumpfile.c +@@ -3782,6 +3782,46 @@ free_for_parallel() + } + + int ++find_kaslr_offsets() ++{ ++ off_t offset; ++ unsigned long size; ++ int ret = FALSE; ++ ++ get_vmcoreinfo(&offset, &size); ++ ++ if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) { ++ MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO); ++ return FALSE; ++ } ++ if (!copy_vmcoreinfo(offset, size)) ++ goto out; ++ ++ if (!open_vmcoreinfo("r")) ++ goto out; ++ ++ unlink(info->name_vmcoreinfo); ++ ++ /* ++ * This arch specific function should update info->kaslr_offset. If ++ * kaslr is not enabled then offset will be set to 0. arch specific ++ * function might need to read from vmcoreinfo, therefore we have ++ * called this function between open_vmcoreinfo() and ++ * close_vmcoreinfo() ++ */ ++ get_kaslr_offset(SYMBOL(_stext)); ++ ++ close_vmcoreinfo(); ++ ++ ret = TRUE; ++out: ++ free(info->name_vmcoreinfo); ++ info->name_vmcoreinfo = NULL; ++ ++ return ret; ++} ++ ++int + initial(void) + { + off_t offset; +@@ -3833,6 +3873,9 @@ initial(void) + set_dwarf_debuginfo("vmlinux", NULL, + info->name_vmlinux, info->fd_vmlinux); + ++ if (has_vmcoreinfo() && !find_kaslr_offsets()) ++ return FALSE; ++ + if (!get_symbol_info()) + return FALSE; + +@@ -8635,6 +8678,7 @@ close_vmcoreinfo(void) + if(fclose(info->file_vmcoreinfo) < 0) + ERRMSG("Can't close the vmcoreinfo file(%s). %s\n", + info->name_vmcoreinfo, strerror(errno)); ++ info->file_vmcoreinfo = NULL; + } + + void +@@ -11026,11 +11070,13 @@ main(int argc, char *argv[]) + strerror(errno)); + goto out; + } ++ info->file_vmcoreinfo = NULL; + info->fd_vmlinux = -1; + info->fd_xen_syms = -1; + info->fd_memory = -1; + info->fd_dumpfile = -1; + info->fd_bitmap = -1; ++ info->kaslr_offset = 0; + initialize_tables(); + + /* +diff --git a/makedumpfile-1.6.1/makedumpfile.h b/makedumpfile-1.6.1/makedumpfile.h +index e32e567018f6..9f16becadd55 100644 +--- a/makedumpfile-1.6.1/makedumpfile.h ++++ b/makedumpfile-1.6.1/makedumpfile.h +@@ -253,10 +253,14 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); } + #define SYMBOL_INIT(symbol, str_symbol) \ + do { \ + SYMBOL(symbol) = get_symbol_addr(str_symbol); \ ++ if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \ ++ SYMBOL(symbol) += info->kaslr_offset; \ + } while (0) + #define SYMBOL_INIT_NEXT(symbol, str_symbol) \ + do { \ + SYMBOL(symbol) = get_next_symbol_addr(str_symbol); \ ++ if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \ ++ SYMBOL(symbol) += info->kaslr_offset; \ + } while (0) + #define WRITE_SYMBOL(str_symbol, symbol) \ + do { \ +@@ -495,6 +499,7 @@ do { \ + #define STR_CONFIG_X86_PAE "CONFIG_X86_PAE=y" + #define STR_CONFIG_PGTABLE_4 "CONFIG_PGTABLE_4=y" + #define STR_CONFIG_PGTABLE_3 "CONFIG_PGTABLE_3=y" ++#define STR_KERNELOFFSET "KERNELOFFSET=" + + /* + * common value +@@ -838,6 +843,7 @@ int get_xen_info_arm64(void); + #define get_phys_base() get_phys_base_arm64() + #define get_machdep_info() get_machdep_info_arm64() + #define get_versiondep_info() get_versiondep_info_arm64() ++#define get_kaslr_offset(X) FALSE + #define get_xen_basic_info_arch(X) get_xen_basic_info_arm64(X) + #define get_xen_info_arch(X) get_xen_info_arm64(X) + #define is_phys_addr(X) stub_true_ul(X) +@@ -851,6 +857,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr); + #define get_phys_base() get_phys_base_arm() + #define get_machdep_info() get_machdep_info_arm() + #define get_versiondep_info() stub_true() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_arm(X) + #define is_phys_addr(X) stub_true_ul(X) + #endif /* arm */ +@@ -863,11 +870,13 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr); + #define get_phys_base() stub_true() + #define get_machdep_info() get_machdep_info_x86() + #define get_versiondep_info() get_versiondep_info_x86() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_x86(X) + #define is_phys_addr(X) stub_true_ul(X) + #endif /* x86 */ + + #ifdef __x86_64__ ++unsigned long get_kaslr_offset_x86_64(unsigned long vaddr); + int get_phys_base_x86_64(void); + int get_machdep_info_x86_64(void); + int get_versiondep_info_x86_64(void); +@@ -876,6 +885,7 @@ unsigned long long vtop4_x86_64(unsigned long vaddr); + #define get_phys_base() get_phys_base_x86_64() + #define get_machdep_info() get_machdep_info_x86_64() + #define get_versiondep_info() get_versiondep_info_x86_64() ++#define get_kaslr_offset(X) get_kaslr_offset_x86_64(X) + #define vaddr_to_paddr(X) vtop4_x86_64(X) + #define is_phys_addr(X) stub_true_ul(X) + #endif /* x86_64 */ +@@ -888,6 +898,7 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr); + #define get_phys_base() stub_true() + #define get_machdep_info() get_machdep_info_ppc64() + #define get_versiondep_info() get_versiondep_info_ppc64() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X) + #define is_phys_addr(X) stub_true_ul(X) + #endif /* powerpc64 */ +@@ -899,6 +910,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr); + #define get_phys_base() stub_true() + #define get_machdep_info() get_machdep_info_ppc() + #define get_versiondep_info() stub_true() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_ppc(X) + #define is_phys_addr(X) stub_true_ul(X) + #endif /* powerpc32 */ +@@ -911,6 +923,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr); + #define get_phys_base() stub_true() + #define get_machdep_info() get_machdep_info_s390x() + #define get_versiondep_info() stub_true() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X) + #define is_phys_addr(X) is_iomem_phys_addr_s390x(X) + #endif /* s390x */ +@@ -923,6 +936,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr); + #define get_machdep_info() get_machdep_info_ia64() + #define get_phys_base() get_phys_base_ia64() + #define get_versiondep_info() stub_true() ++#define get_kaslr_offset(X) FALSE + #define vaddr_to_paddr(X) vaddr_to_paddr_ia64(X) + #define VADDR_REGION(X) (((unsigned long)(X)) >> REGION_SHIFT) + #define is_phys_addr(X) stub_true_ul(X) +@@ -1152,6 +1166,7 @@ struct DumpInfo { + int vmemmap_psize; + int vmemmap_cnt; + struct ppc64_vmemmap *vmemmap_list; ++ unsigned long kaslr_offset; + + /* + * page table info for ppc64 +@@ -1803,6 +1818,7 @@ struct memory_range { + struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; + int crash_reserved_mem_nr; + ++unsigned long read_vmcoreinfo_symbol(char *str_symbol); + int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size); + int get_str_osrelease_from_vmlinux(void); + int read_vmcoreinfo_xen(void); +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-sadump-set-info-page_size-before-cache_init.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-sadump-set-info-page_size-before-cache_init.patch new file mode 100644 index 0000000..04d47fb --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-sadump-set-info-page_size-before-cache_init.patch @@ -0,0 +1,83 @@ +From 90cc28fc9ab0a0076bcd9120b4f791401655280d Mon Sep 17 00:00:00 2001 +Message-Id: <90cc28fc9ab0a0076bcd9120b4f791401655280d.1496033260.git.panand@redhat.com> +In-Reply-To: <302c16ede3723264ca0abb5eef9c9f553ffcfbd7.1496033260.git.panand@redhat.com> +References: <302c16ede3723264ca0abb5eef9c9f553ffcfbd7.1496033260.git.panand@redhat.com> +From: "Hatayama, Daisuke" +Date: Tue, 23 May 2017 02:52:51 +0000 +Subject: [PATCH 3/3] sadump: set info->page_size before cache_init() + +Currently, makedumpfile results in Segmentation fault on sadump dump +files as follows: + + # LANG=C makedumpfile -f --message-level=31 -ld31 -x vmlinux ./sadump_vmcore sadump_vmcore-ld31 + sadump: read dump device as single partition + sadump: single partition configuration + page_size : 4096 + sadump: timezone information is missing + Segmentation fault + +By bisect, I found that this issue is caused by the following commit +that moves invocation of cache_init() in initial() a bit early: + + # git bisect bad + 8e2834bac4f62da3894da297f083068431be6d80 is the first bad commit + commit 8e2834bac4f62da3894da297f083068431be6d80 + Author: Pratyush Anand + Date: Thu Mar 2 17:37:11 2017 +0900 + + [PATCH v3 2/7] initial(): call cache_init() a bit early + + Call cache_init() before get_kcore_dump_loads(), because latter uses + cache_search(). + + Call path is like this : + get_kcore_dump_loads() -> process_dump_load() -> vaddr_to_paddr() -> + vtop4_x86_64() -> readmem() -> cache_search() + + Signed-off-by: Pratyush Anand + + :100644 100644 6942047199deb09dd1fff2121e264584dbb05587 3b8e9810468de26b0d8b73d456f0bd4f3d3aa2fe M makedumpfile.c + +In this timing, on sadump vmcores, info->page_size has not been +initialized yet so has 0. So, malloc() in cache_init() returns a chunk +of 0 size. A bit later, info->page_size is initialized with 4096. +Later processing on cache.c behaves assuming the chunk size is 8 * +4096. This destroys objects allocated after the chunk, resulting in +the above Segmentation fault. + +To fix this issue, this commit moves setting info->page_size before +cache_init(). + +Signed-off-by: HATAYAMA Daisuke +Cc: Pratyush Anand +--- + makedumpfile.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/makedumpfile-1.6.1/makedumpfile.c b/makedumpfile-1.6.1/makedumpfile.c +index 9babf1a07154..2e4286c83b8f 100644 +--- a/makedumpfile-1.6.1/makedumpfile.c ++++ b/makedumpfile-1.6.1/makedumpfile.c +@@ -3921,6 +3921,9 @@ initial(void) + if (!get_value_for_old_linux()) + return FALSE; + ++ if (info->flag_sadump && !set_page_size(sadump_page_size())) ++ return FALSE; ++ + if (!is_xen_memory() && !cache_init()) + return FALSE; + +@@ -3949,9 +3952,6 @@ initial(void) + return FALSE; + } + +- if (!set_page_size(sadump_page_size())) +- return FALSE; +- + if (!sadump_initialize_bitmap_memory()) + return FALSE; + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-show_mem_usage-calculate-page-offset-af.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-show_mem_usage-calculate-page-offset-af.patch new file mode 100644 index 0000000..5f30a2a --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-show_mem_usage-calculate-page-offset-af.patch @@ -0,0 +1,41 @@ +From 4b0bed3523a5f6c2c428d9dab3d27d4572207d52 Mon Sep 17 00:00:00 2001 +Message-Id: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Pratyush Anand +Date: Thu, 2 Mar 2017 17:37:08 +0900 +Subject: [PATCH 1/7] [PATCH v3 1/7] show_mem_usage(): calculate page offset + after elf load + +x86_64 calculated page offset from PT_LOAD headers. Therefore call +get_page_offset() after get_elf_loads() + +Signed-off-by: Pratyush Anand +--- + makedumpfile.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/makedumpfile-1.6.1/makedumpfile.c b/makedumpfile-1.6.1/makedumpfile.c +index e69b6df9a9ee..6942047199de 100644 +--- a/makedumpfile-1.6.1/makedumpfile.c ++++ b/makedumpfile-1.6.1/makedumpfile.c +@@ -10944,15 +10944,15 @@ int show_mem_usage(void) + + info->dump_level = MAX_DUMP_LEVEL; + +- if (!get_page_offset()) +- return FALSE; +- + if (!open_files_for_creating_dumpfile()) + return FALSE; + + if (!get_elf_loads(info->fd_memory, info->name_memory)) + return FALSE; + ++ if (!get_page_offset()) ++ return FALSE; ++ + if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) + return FALSE; + +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-calculate-page_offset-in-case-of-re-filtering.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-calculate-page_offset-in-case-of-re-filtering.patch new file mode 100644 index 0000000..aaf1730 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-calculate-page_offset-in-case-of-re-filtering.patch @@ -0,0 +1,85 @@ +From 586c58752e0e48e8ed48ba951e5b1448831bbf11 Mon Sep 17 00:00:00 2001 +Message-Id: <586c58752e0e48e8ed48ba951e5b1448831bbf11.1496033260.git.panand@redhat.com> +In-Reply-To: <302c16ede3723264ca0abb5eef9c9f553ffcfbd7.1496033260.git.panand@redhat.com> +References: <302c16ede3723264ca0abb5eef9c9f553ffcfbd7.1496033260.git.panand@redhat.com> +From: Pratyush Anand +Date: Wed, 26 Apr 2017 11:04:07 +0530 +Subject: [PATCH 2/3] x86_64: calculate page_offset in case of + re-filtering/sadump/virsh dump + +we do not call get_elf_info() in case of refiltering and sadump. +Therefore, we will not have any pt_load in that case, and so we get: + +get_page_offset_x86_64: Can't get any pt_load to calculate page offset. + +However, we will have vmcoreinfo and vmlinux information in case of +re-filtering. So, we are able to find kaslr offset and we can get +page_offset_base address. Thus we can read the page offset as well. + +If kaslr is not enabled and also we do not have valid PT_LOAD to +calculate page offset then use old method to find fixed page +offset. + +In case of virsh dump virtual addresses in PT_LOAD are 0. Ignore such +addresses for the page_offset calculation. + +Suggested-by: HATAYAMA Daisuke +Signed-off-by: Pratyush Anand +--- + arch/x86_64.c | 36 +++++++++++++++++++++++++++++------- + 1 file changed, 29 insertions(+), 7 deletions(-) + +diff --git a/makedumpfile-1.6.1/arch/x86_64.c b/makedumpfile-1.6.1/arch/x86_64.c +index fd2e8ac154d6..18384a8dd684 100644 +--- a/makedumpfile-1.6.1/arch/x86_64.c ++++ b/makedumpfile-1.6.1/arch/x86_64.c +@@ -75,17 +75,39 @@ get_page_offset_x86_64(void) + int i; + unsigned long long phys_start; + unsigned long long virt_start; ++ unsigned long page_offset_base; ++ ++ if (info->kaslr_offset) { ++ page_offset_base = get_symbol_addr("page_offset_base"); ++ page_offset_base += info->kaslr_offset; ++ if (!readmem(VADDR, page_offset_base, &info->page_offset, ++ sizeof(info->page_offset))) { ++ ERRMSG("Can't read page_offset_base.\n"); ++ return FALSE; ++ } ++ return TRUE; ++ } + +- for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) { +- if (virt_start < __START_KERNEL_map +- && phys_start != NOT_PADDR) { +- info->page_offset = virt_start - phys_start; +- return TRUE; ++ if (get_num_pt_loads()) { ++ for (i = 0; ++ get_pt_load(i, &phys_start, NULL, &virt_start, NULL); ++ i++) { ++ if (virt_start != NOT_KV_ADDR ++ && virt_start < __START_KERNEL_map ++ && phys_start != NOT_PADDR) { ++ info->page_offset = virt_start - phys_start; ++ return TRUE; ++ } + } + } + +- ERRMSG("Can't get any pt_load to calculate page offset.\n"); +- return FALSE; ++ if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) { ++ info->page_offset = __PAGE_OFFSET_ORIG; ++ } else { ++ info->page_offset = __PAGE_OFFSET_2_6_27; ++ } ++ ++ return TRUE; + } + + int +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-check-physical-address-in-PT_LOA.patch b/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-check-physical-address-in-PT_LOA.patch new file mode 100644 index 0000000..02deed8 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-makedumpfile-x86_64-check-physical-address-in-PT_LOA.patch @@ -0,0 +1,47 @@ +From f1363023b909df886eca5efcb64b78be9b8e6086 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +References: <4b0bed3523a5f6c2c428d9dab3d27d4572207d52.1489471500.git.panand@redhat.com> +From: Pratyush Anand +Date: Thu, 2 Mar 2017 17:37:13 +0900 +Subject: [PATCH 3/7] [PATCH v3 3/7] x86_64: check physical address in PT_LOAD + for none direct mapped regions + +A kcore PT_LOAD can have a section from vmalloc region. However, +physical address in that header would be invalid (-1) after kernel +commit 464920104bf7 (/proc/kcore: update physical address for kcore ram +and text). Therefore, check for valid physical address while calculating +page_offset or phys_offset. + +Signed-off-by: Pratyush Anand +--- + arch/x86_64.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/makedumpfile-1.6.1/arch/x86_64.c b/makedumpfile-1.6.1/arch/x86_64.c +index 893cd516fc8b..e978a36f8878 100644 +--- a/makedumpfile-1.6.1/arch/x86_64.c ++++ b/makedumpfile-1.6.1/arch/x86_64.c +@@ -41,7 +41,8 @@ get_page_offset_x86_64(void) + unsigned long long virt_start; + + for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) { +- if (virt_start < __START_KERNEL_map) { ++ if (virt_start < __START_KERNEL_map ++ && phys_start != NOT_PADDR) { + info->page_offset = virt_start - phys_start; + return TRUE; + } +@@ -76,7 +77,8 @@ get_phys_base_x86_64(void) + } + + for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) { +- if (virt_start >= __START_KERNEL_map) { ++ if (virt_start >= __START_KERNEL_map ++ && phys_start != NOT_PADDR) { + + info->phys_base = phys_start - + (virt_start & ~(__START_KERNEL_map)); +-- +2.9.3 + diff --git a/SOURCES/kexec-tools-2.0.14-ppc64-Reduce-number-of-ELF-LOAD-segments.patch b/SOURCES/kexec-tools-2.0.14-ppc64-Reduce-number-of-ELF-LOAD-segments.patch new file mode 100644 index 0000000..c0ee06a --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-ppc64-Reduce-number-of-ELF-LOAD-segments.patch @@ -0,0 +1,67 @@ +From f63d8530b9b6a2d7e79b946e326e5a2197eb8f87 Mon Sep 17 00:00:00 2001 +From: Petr Tesarik +Date: Thu, 19 Jan 2017 18:37:09 +0100 +Subject: [PATCH] ppc64: Reduce number of ELF LOAD segments + +The number of program header table entries (e_phnum) is an Elf64_Half, +which is a 16-bit entity, i.e. the limit is 65534 entries (one entry is +reserved for NOTE). This is a hard limit, defined by the ELF standard. +It is possible that more LMBs (Logical Memory Blocks) are needed to +represent all RAM on some machines, and this field overflows, causing +an incomplete /proc/vmcore file. + +This has actually happened on a machine with 31TB of RAM and an LMB size +of 256MB. + +However, since there is usually no memory hole between adjacent LMBs, the +map can be "compressed", combining multiple adjacent into a single LOAD +segment. + +Signed-off-by: Petr Tesarik +Signed-off-by: Simon Horman +Signed-off-by: Pingfan Liu +--- + kexec/arch/ppc64/crashdump-ppc64.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c +index b3c8928..f62b159 100644 +--- a/kexec/arch/ppc64/crashdump-ppc64.c ++++ b/kexec/arch/ppc64/crashdump-ppc64.c +@@ -123,6 +123,7 @@ static void exclude_crash_region(uint64_t start, uint64_t end) + static int get_dyn_reconf_crash_memory_ranges(void) + { + uint64_t start, end; ++ uint64_t startrange, endrange; + char fname[128], buf[32]; + FILE *file; + unsigned int i; +@@ -137,6 +138,7 @@ static int get_dyn_reconf_crash_memory_ranges(void) + } + + fseek(file, 4, SEEK_SET); ++ startrange = endrange = 0; + for (i = 0; i < num_of_lmbs; i++) { + if ((n = fread(buf, 1, 24, file)) < 0) { + perror(fname); +@@ -162,8 +164,16 @@ static int get_dyn_reconf_crash_memory_ranges(void) + if ((flags & 0x80) || !(flags & 0x8)) + continue; + +- exclude_crash_region(start, end); ++ if (start != endrange) { ++ if (startrange != endrange) ++ exclude_crash_region(startrange, endrange); ++ startrange = start; ++ } ++ endrange = end; + } ++ if (startrange != endrange) ++ exclude_crash_region(startrange, endrange); ++ + fclose(file); + return 0; + } +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.14-x86-Support-large-number-of-memory-ranges.patch b/SOURCES/kexec-tools-2.0.14-x86-Support-large-number-of-memory-ranges.patch new file mode 100644 index 0000000..69c69ef --- /dev/null +++ b/SOURCES/kexec-tools-2.0.14-x86-Support-large-number-of-memory-ranges.patch @@ -0,0 +1,52 @@ +From 4a6d67d9e938a7accf128aff23f8ad4bda67f729 Mon Sep 17 00:00:00 2001 +From: Xunlei Pang +Date: Thu, 23 Mar 2017 19:16:59 +0800 +Subject: [PATCH] x86: Support large number of memory ranges + +We got a problem on one SGI 64TB machine, the current kexec-tools +failed to work due to the insufficient ranges(MAX_MEMORY_RANGES) +allowed which is defined as 1024(less than the ranges on the machine). +The kcore header is insufficient due to the same reason as well. + +To solve this, this patch simply doubles "MAX_MEMORY_RANGES" and +"KCORE_ELF_HEADERS_SIZE". + +Signed-off-by: Xunlei Pang +Tested-by: Frank Ramsay +Signed-off-by: Simon Horman +--- + kexec/arch/i386/kexec-x86.h | 2 +- + kexec/crashdump.h | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h +index 33df352..51855f8 100644 +--- a/kexec/arch/i386/kexec-x86.h ++++ b/kexec/arch/i386/kexec-x86.h +@@ -1,7 +1,7 @@ + #ifndef KEXEC_X86_H + #define KEXEC_X86_H + +-#define MAX_MEMORY_RANGES 1024 ++#define MAX_MEMORY_RANGES 2048 + + enum coretype { + CORE_TYPE_UNDEF = 0, +diff --git a/kexec/crashdump.h b/kexec/crashdump.h +index 86e1ef2..18bd691 100644 +--- a/kexec/crashdump.h ++++ b/kexec/crashdump.h +@@ -7,8 +7,8 @@ extern int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len); + + /* Need to find a better way to determine per cpu notes section size. */ + #define MAX_NOTE_BYTES 1024 +-/* Expecting ELF headers to fit in 32K. Increase it if you need more. */ +-#define KCORE_ELF_HEADERS_SIZE 32768 ++/* Expecting ELF headers to fit in 64K. Increase it if you need more. */ ++#define KCORE_ELF_HEADERS_SIZE 65536 + /* The address of the ELF header is passed to the secondary kernel + * using the kernel command line option memmap=nnn. + * The smallest unit the kernel accepts is in kilobytes, +-- +1.8.3.1 + diff --git a/SOURCES/kexec-tools-2.0.7-Add-persistent-memory-support.patch b/SOURCES/kexec-tools-2.0.7-Add-persistent-memory-support.patch deleted file mode 100644 index a82c004..0000000 --- a/SOURCES/kexec-tools-2.0.7-Add-persistent-memory-support.patch +++ /dev/null @@ -1,159 +0,0 @@ -From cb9a818ff2ac437e76512ec01c0eb22d0d7456b2 Mon Sep 17 00:00:00 2001 -From: Baoquan He -Date: Wed, 19 Aug 2015 17:03:49 +0800 -Subject: [PATCH] Add persistent memory support - -Kernel add E820_PRAM or E820_PMEM type for NVDIMM memory device. -Now support them in kexec too. - -Reported-by: Toshi Kani -Tested-by: Toshi Kani -Signed-off-by: Baoquan He -Signed-off-by: Simon Horman ---- - include/x86/x86-linux.h | 2 ++ - kexec/arch/i386/crashdump-x86.c | 15 ++++++++++++--- - kexec/arch/i386/kexec-x86-common.c | 10 ++++++++++ - kexec/arch/i386/x86-linux-setup.c | 6 ++++++ - kexec/firmware_memmap.c | 4 ++++ - kexec/kexec.h | 2 ++ - 6 files changed, 36 insertions(+), 3 deletions(-) - -diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h -index 50c7324..7834751 100644 ---- a/include/x86/x86-linux.h -+++ b/include/x86/x86-linux.h -@@ -21,6 +21,8 @@ struct e820entry { - #define E820_RESERVED 2 - #define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */ - #define E820_NVS 4 -+#define E820_PMEM 7 -+#define E820_PRAM 12 - } __attribute__((packed)); - #endif - -diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c -index 569c99a..63959b7 100644 ---- a/kexec/arch/i386/crashdump-x86.c -+++ b/kexec/arch/i386/crashdump-x86.c -@@ -301,6 +301,10 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, - type = RANGE_ACPI; - } else if(memcmp(str,"ACPI Non-volatile Storage\n",26) == 0 ) { - type = RANGE_ACPI_NVS; -+ } else if(memcmp(str,"Persistent Memory (legacy)\n",27) == 0 ) { -+ type = RANGE_PRAM; -+ } else if(memcmp(str,"Persistent Memory\n",18) == 0 ) { -+ type = RANGE_PMEM; - } else if(memcmp(str,"reserved\n",9) == 0 ) { - type = RANGE_RESERVED; - } else if (memcmp(str, "GART\n", 5) == 0) { -@@ -640,6 +644,8 @@ static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk, - strcat (str_mmap, "K$"); - else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS) - strcat (str_mmap, "K#"); -+ else if (type == RANGE_PRAM) -+ strcat (str_mmap, "K!"); - - ultoa(startk, str_tmp); - strcat (str_mmap, str_tmp); -@@ -674,10 +680,11 @@ static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p) - endk = (memmap_p[i].end + 1)/1024; - type = memmap_p[i].type; - -- /* Only adding memory regions of RAM and ACPI */ -+ /* Only adding memory regions of RAM and ACPI and Persistent Mem */ - if (type != RANGE_RAM && - type != RANGE_ACPI && -- type != RANGE_ACPI_NVS) -+ type != RANGE_ACPI_NVS && -+ type != RANGE_PRAM) - continue; - - if (type == RANGE_ACPI || type == RANGE_ACPI_NVS) -@@ -997,7 +1004,9 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, - unsigned long start, end, size, type; - if ( !( mem_range[i].type == RANGE_ACPI - || mem_range[i].type == RANGE_ACPI_NVS -- || mem_range[i].type == RANGE_RESERVED)) -+ || mem_range[i].type == RANGE_RESERVED -+ || mem_range[i].type == RANGE_PMEM -+ || mem_range[i].type == RANGE_PRAM)) - continue; - start = mem_range[i].start; - end = mem_range[i].end; -diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c -index 91e4f94..041c8ec 100644 ---- a/kexec/arch/i386/kexec-x86-common.c -+++ b/kexec/arch/i386/kexec-x86-common.c -@@ -94,6 +94,12 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges - else if (memcmp(str, "ACPI Non-volatile Storage\n", 26) == 0) { - type = RANGE_ACPI_NVS; - } -+ else if (memcmp(str, "Persistent Memory (legacy)\n", 27) == 0) { -+ type = RANGE_PRAM; -+ } -+ else if (memcmp(str, "Persistent Memory\n", 18) == 0) { -+ type = RANGE_PMEM; -+ } - else { - continue; - } -@@ -149,6 +155,10 @@ unsigned xen_e820_to_kexec_type(uint32_t type) - return RANGE_ACPI; - case E820_NVS: - return RANGE_ACPI_NVS; -+ case E820_PMEM: -+ return RANGE_PMEM; -+ case E820_PRAM: -+ return RANGE_PRAM; - case E820_RESERVED: - default: - return RANGE_RESERVED; -diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c -index 9271c6c..c75adaa 100644 ---- a/kexec/arch/i386/x86-linux-setup.c -+++ b/kexec/arch/i386/x86-linux-setup.c -@@ -705,6 +705,12 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode, - case RANGE_ACPI_NVS: - e820[i].type = E820_NVS; - break; -+ case RANGE_PMEM: -+ e820[i].type = E820_PMEM; -+ break; -+ case RANGE_PRAM: -+ e820[i].type = E820_PRAM; -+ break; - default: - case RANGE_RESERVED: - e820[i].type = E820_RESERVED; -diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c -index 6be3c7c..4d84f00 100644 ---- a/kexec/firmware_memmap.c -+++ b/kexec/firmware_memmap.c -@@ -168,6 +168,10 @@ static int parse_memmap_entry(const char *entry, struct memory_range *range) - range->type = RANGE_ACPI_NVS; - else if (strcmp(type, "Uncached RAM") == 0) - range->type = RANGE_UNCACHED; -+ else if (strcmp(type, "Persistent Memory (legacy)") == 0) -+ range->type = RANGE_PRAM; -+ else if (strcmp(type, "Persistent Memory") == 0) -+ range->type = RANGE_PMEM; - else { - fprintf(stderr, "Unknown type (%s) while parsing %s. Please " - "report this as bug. Using RANGE_RESERVED now.\n", -diff --git a/kexec/kexec.h b/kexec/kexec.h -index b129c15..0fa977f 100644 ---- a/kexec/kexec.h -+++ b/kexec/kexec.h -@@ -136,6 +136,8 @@ struct memory_range { - #define RANGE_ACPI 2 - #define RANGE_ACPI_NVS 3 - #define RANGE_UNCACHED 4 -+#define RANGE_PMEM 6 -+#define RANGE_PRAM 11 - }; - - struct memory_ranges { --- -2.5.5 - diff --git a/SOURCES/kexec-tools-2.0.7-Provide-an-option-to-use-new-kexec-system-call.patch b/SOURCES/kexec-tools-2.0.7-Provide-an-option-to-use-new-kexec-system-call.patch deleted file mode 100644 index 7a2b61e..0000000 --- a/SOURCES/kexec-tools-2.0.7-Provide-an-option-to-use-new-kexec-system-call.patch +++ /dev/null @@ -1,443 +0,0 @@ -From 046d1755d2bd723a11a180c265e61a884990712e Mon Sep 17 00:00:00 2001 -From: Vivek Goyal -Date: Mon, 18 Aug 2014 11:22:32 -0400 -Subject: [PATCH] kexec: Provide an option to use new kexec system call - -Hi, - -This is v2 of the patch. Since v1, I moved syscall implemented check littler -earlier in the function as per the feedback. - -Now a new kexec syscall (kexec_file_load()) has been merged in upstream -kernel. This system call takes file descriptors of kernel and initramfs -as input (as opposed to list of segments to be loaded). This new system -call allows for signature verification of the kernel being loaded. - -One use of signature verification of kernel is secureboot systems where -we want to allow kexec into a kernel only if it is validly signed by -a key system trusts. - -This patch provides and option --kexec-file-syscall (-s), to force use of -new system call for kexec. Default is to continue to use old syscall. - -Currently only bzImage64 on x86_64 can be loaded using this system call. -As kernel adds support for more arches and for more image types, kexec-tools -can be modified accordingly. - -Signed-off-by: Vivek Goyal -Acked-by: Baoquan He -Signed-off-by: Simon Horman ---- - kexec/arch/x86_64/kexec-bzImage64.c | 86 +++++++++++++++++++++++ - kexec/kexec-syscall.h | 32 +++++++++ - kexec/kexec.c | 132 +++++++++++++++++++++++++++++++++++- - kexec/kexec.h | 11 ++- - 4 files changed, 257 insertions(+), 4 deletions(-) - -diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c -index 1983bcf..8edb3e4 100644 ---- a/kexec/arch/x86_64/kexec-bzImage64.c -+++ b/kexec/arch/x86_64/kexec-bzImage64.c -@@ -235,6 +235,89 @@ static int do_bzImage64_load(struct kexec_info *info, - return 0; - } - -+/* This assumes file is being loaded using file based kexec syscall */ -+int bzImage64_load_file(int argc, char **argv, struct kexec_info *info) -+{ -+ int ret = 0; -+ char *command_line = NULL, *tmp_cmdline = NULL; -+ const char *ramdisk = NULL, *append = NULL; -+ int entry_16bit = 0, entry_32bit = 0; -+ int opt; -+ int command_line_len; -+ -+ /* See options.h -- add any more there, too. */ -+ static const struct option options[] = { -+ KEXEC_ARCH_OPTIONS -+ { "command-line", 1, 0, OPT_APPEND }, -+ { "append", 1, 0, OPT_APPEND }, -+ { "reuse-cmdline", 0, 0, OPT_REUSE_CMDLINE }, -+ { "initrd", 1, 0, OPT_RAMDISK }, -+ { "ramdisk", 1, 0, OPT_RAMDISK }, -+ { "real-mode", 0, 0, OPT_REAL_MODE }, -+ { "entry-32bit", 0, 0, OPT_ENTRY_32BIT }, -+ { 0, 0, 0, 0 }, -+ }; -+ static const char short_options[] = KEXEC_ARCH_OPT_STR "d"; -+ -+ while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { -+ switch (opt) { -+ default: -+ /* Ignore core options */ -+ if (opt < OPT_ARCH_MAX) -+ break; -+ case OPT_APPEND: -+ append = optarg; -+ break; -+ case OPT_REUSE_CMDLINE: -+ tmp_cmdline = get_command_line(); -+ break; -+ case OPT_RAMDISK: -+ ramdisk = optarg; -+ break; -+ case OPT_REAL_MODE: -+ entry_16bit = 1; -+ break; -+ case OPT_ENTRY_32BIT: -+ entry_32bit = 1; -+ break; -+ } -+ } -+ command_line = concat_cmdline(tmp_cmdline, append); -+ if (tmp_cmdline) -+ free(tmp_cmdline); -+ command_line_len = 0; -+ if (command_line) { -+ command_line_len = strlen(command_line) + 1; -+ } else { -+ command_line = strdup("\0"); -+ command_line_len = 1; -+ } -+ -+ if (entry_16bit || entry_32bit) { -+ fprintf(stderr, "Kexec2 syscall does not support 16bit" -+ " or 32bit entry yet\n"); -+ ret = -1; -+ goto out; -+ } -+ -+ if (ramdisk) { -+ info->initrd_fd = open(ramdisk, O_RDONLY); -+ if (info->initrd_fd == -1) { -+ fprintf(stderr, "Could not open initrd file %s:%s\n", -+ ramdisk, strerror(errno)); -+ ret = -1; -+ goto out; -+ } -+ } -+ -+ info->command_line = command_line; -+ info->command_line_len = command_line_len; -+ return ret; -+out: -+ free(command_line); -+ return ret; -+} -+ - int bzImage64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info) - { -@@ -247,6 +330,9 @@ int bzImage64_load(int argc, char **argv, const char *buf, off_t len, - int opt; - int result; - -+ if (info->file_mode) -+ return bzImage64_load_file(argc, argv, info); -+ - /* See options.h -- add any more there, too. */ - static const struct option options[] = { - KEXEC_ARCH_OPTIONS -diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h -index 6238044..ce2e20b 100644 ---- a/kexec/kexec-syscall.h -+++ b/kexec/kexec-syscall.h -@@ -53,6 +53,19 @@ - #endif - #endif /*ifndef __NR_kexec_load*/ - -+#ifndef __NR_kexec_file_load -+ -+#ifdef __x86_64__ -+#define __NR_kexec_file_load 320 -+#endif -+ -+#ifndef __NR_kexec_file_load -+/* system call not available for the arch */ -+#define __NR_kexec_file_load 0xffffffff /* system call not available */ -+#endif -+ -+#endif /*ifndef __NR_kexec_file_load*/ -+ - struct kexec_segment; - - static inline long kexec_load(void *entry, unsigned long nr_segments, -@@ -61,10 +74,29 @@ static inline long kexec_load(void *entry, unsigned long nr_segments, - return (long) syscall(__NR_kexec_load, entry, nr_segments, segments, flags); - } - -+static inline int is_kexec_file_load_implemented(void) { -+ if (__NR_kexec_file_load != 0xffffffff) -+ return 1; -+ return 0; -+} -+ -+static inline long kexec_file_load(int kernel_fd, int initrd_fd, -+ unsigned long cmdline_len, const char *cmdline_ptr, -+ unsigned long flags) -+{ -+ return (long) syscall(__NR_kexec_file_load, kernel_fd, initrd_fd, -+ cmdline_len, cmdline_ptr, flags); -+} -+ - #define KEXEC_ON_CRASH 0x00000001 - #define KEXEC_PRESERVE_CONTEXT 0x00000002 - #define KEXEC_ARCH_MASK 0xffff0000 - -+/* Flags for kexec file based system call */ -+#define KEXEC_FILE_UNLOAD 0x00000001 -+#define KEXEC_FILE_ON_CRASH 0x00000002 -+#define KEXEC_FILE_NO_INITRAMFS 0x00000004 -+ - /* These values match the ELF architecture values. - * Unless there is a good reason that should continue to be the case. - */ -diff --git a/kexec/kexec.c b/kexec/kexec.c -index 133e622..7e7b604 100644 ---- a/kexec/kexec.c -+++ b/kexec/kexec.c -@@ -51,6 +51,8 @@ - unsigned long long mem_min = 0; - unsigned long long mem_max = ULONG_MAX; - static unsigned long kexec_flags = 0; -+/* Flags for kexec file (fd) based syscall */ -+static unsigned long kexec_file_flags = 0; - int kexec_debug = 0; - - void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr) -@@ -787,6 +789,19 @@ static int my_load(const char *type, int fileind, int argc, char **argv, - return result; - } - -+static int kexec_file_unload(unsigned long kexec_file_flags) -+{ -+ int ret = 0; -+ -+ ret = kexec_file_load(-1, -1, 0, NULL, kexec_file_flags); -+ if (ret != 0) { -+ /* The unload failed, print some debugging information */ -+ fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n", -+ strerror(errno)); -+ } -+ return ret; -+} -+ - static int k_unload (unsigned long kexec_flags) - { - int result; -@@ -925,6 +940,7 @@ void usage(void) - " (0 means it's not jump back or\n" - " preserve context)\n" - " to original kernel.\n" -+ " -s, --kexec-file-syscall Use file based syscall for kexec operation\n" - " -d, --debug Enable debugging to help spot a failure.\n" - "\n" - "Supported kernel file types and options: \n"); -@@ -1072,6 +1088,82 @@ char *concat_cmdline(const char *base, const char *append) - return cmdline; - } - -+/* New file based kexec system call related code */ -+static int do_kexec_file_load(int fileind, int argc, char **argv, -+ unsigned long flags) { -+ -+ char *kernel; -+ int kernel_fd, i; -+ struct kexec_info info; -+ int ret = 0; -+ char *kernel_buf; -+ off_t kernel_size; -+ -+ memset(&info, 0, sizeof(info)); -+ info.segment = NULL; -+ info.nr_segments = 0; -+ info.entry = NULL; -+ info.backup_start = 0; -+ info.kexec_flags = flags; -+ -+ info.file_mode = 1; -+ info.initrd_fd = -1; -+ -+ if (!is_kexec_file_load_implemented()) { -+ fprintf(stderr, "syscall kexec_file_load not available.\n"); -+ return -1; -+ } -+ -+ if (argc - fileind <= 0) { -+ fprintf(stderr, "No kernel specified\n"); -+ usage(); -+ return -1; -+ } -+ -+ kernel = argv[fileind]; -+ -+ kernel_fd = open(kernel, O_RDONLY); -+ if (kernel_fd == -1) { -+ fprintf(stderr, "Failed to open file %s:%s\n", kernel, -+ strerror(errno)); -+ return -1; -+ } -+ -+ /* slurp in the input kernel */ -+ kernel_buf = slurp_decompress_file(kernel, &kernel_size); -+ -+ for (i = 0; i < file_types; i++) { -+ if (file_type[i].probe(kernel_buf, kernel_size) >= 0) -+ break; -+ } -+ -+ if (i == file_types) { -+ fprintf(stderr, "Cannot determine the file type " "of %s\n", -+ kernel); -+ return -1; -+ } -+ -+ ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info); -+ if (ret < 0) { -+ fprintf(stderr, "Cannot load %s\n", kernel); -+ return ret; -+ } -+ -+ /* -+ * If there is no initramfs, set KEXEC_FILE_NO_INITRAMFS flag so that -+ * kernel does not return error with negative initrd_fd. -+ */ -+ if (info.initrd_fd == -1) -+ info.kexec_flags |= KEXEC_FILE_NO_INITRAMFS; -+ -+ ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line_len, -+ info.command_line, info.kexec_flags); -+ if (ret != 0) -+ fprintf(stderr, "kexec_file_load failed: %s\n", -+ strerror(errno)); -+ return ret; -+} -+ - - int main(int argc, char *argv[]) - { -@@ -1083,6 +1175,7 @@ int main(int argc, char *argv[]) - int do_ifdown = 0; - int do_unload = 0; - int do_reuse_initrd = 0; -+ int do_kexec_file_syscall = 0; - void *entry = 0; - char *type = 0; - char *endptr; -@@ -1095,6 +1188,23 @@ int main(int argc, char *argv[]) - }; - static const char short_options[] = KEXEC_ALL_OPT_STR; - -+ /* -+ * First check if --use-kexec-file-syscall is set. That changes lot of -+ * things -+ */ -+ while ((opt = getopt_long(argc, argv, short_options, -+ options, 0)) != -1) { -+ switch(opt) { -+ case OPT_KEXEC_FILE_SYSCALL: -+ do_kexec_file_syscall = 1; -+ break; -+ } -+ } -+ -+ /* Reset getopt for the next pass. */ -+ opterr = 1; -+ optind = 1; -+ - while ((opt = getopt_long(argc, argv, short_options, - options, 0)) != -1) { - switch(opt) { -@@ -1127,6 +1237,8 @@ int main(int argc, char *argv[]) - do_shutdown = 0; - do_sync = 0; - do_unload = 1; -+ if (do_kexec_file_syscall) -+ kexec_file_flags |= KEXEC_FILE_UNLOAD; - break; - case OPT_EXEC: - do_load = 0; -@@ -1169,7 +1281,10 @@ int main(int argc, char *argv[]) - do_exec = 0; - do_shutdown = 0; - do_sync = 0; -- kexec_flags = KEXEC_ON_CRASH; -+ if (do_kexec_file_syscall) -+ kexec_file_flags |= KEXEC_FILE_ON_CRASH; -+ else -+ kexec_flags = KEXEC_ON_CRASH; - break; - case OPT_MEM_MIN: - mem_min = strtoul(optarg, &endptr, 0); -@@ -1194,6 +1309,9 @@ int main(int argc, char *argv[]) - case OPT_REUSE_INITRD: - do_reuse_initrd = 1; - break; -+ case OPT_KEXEC_FILE_SYSCALL: -+ /* We already parsed it. Nothing to do. */ -+ break; - default: - break; - } -@@ -1238,10 +1356,18 @@ int main(int argc, char *argv[]) - } - - if (do_unload) { -- result = k_unload(kexec_flags); -+ if (do_kexec_file_syscall) -+ result = kexec_file_unload(kexec_file_flags); -+ else -+ result = k_unload(kexec_flags); - } - if (do_load && (result == 0)) { -- result = my_load(type, fileind, argc, argv, kexec_flags, entry); -+ if (do_kexec_file_syscall) -+ result = do_kexec_file_load(fileind, argc, argv, -+ kexec_file_flags); -+ else -+ result = my_load(type, fileind, argc, argv, -+ kexec_flags, entry); - } - /* Don't shutdown unless there is something to reboot to! */ - if ((result == 0) && (do_shutdown || do_exec) && !kexec_loaded()) { -diff --git a/kexec/kexec.h b/kexec/kexec.h -index 2fad7dc..4be2b2f 100644 ---- a/kexec/kexec.h -+++ b/kexec/kexec.h -@@ -156,6 +156,13 @@ struct kexec_info { - unsigned long kexec_flags; - unsigned long backup_src_start; - unsigned long backup_src_size; -+ /* Set to 1 if we are using kexec file syscall */ -+ unsigned long file_mode :1; -+ -+ /* Filled by kernel image processing code */ -+ int initrd_fd; -+ char *command_line; -+ int command_line_len; - }; - - struct arch_map_entry { -@@ -207,6 +214,7 @@ extern int file_types; - #define OPT_UNLOAD 'u' - #define OPT_TYPE 't' - #define OPT_PANIC 'p' -+#define OPT_KEXEC_FILE_SYSCALL 's' - #define OPT_MEM_MIN 256 - #define OPT_MEM_MAX 257 - #define OPT_REUSE_INITRD 258 -@@ -230,9 +238,10 @@ extern int file_types; - { "mem-min", 1, 0, OPT_MEM_MIN }, \ - { "mem-max", 1, 0, OPT_MEM_MAX }, \ - { "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \ -+ { "kexec-file-syscall", 0, 0, OPT_KEXEC_FILE_SYSCALL }, \ - { "debug", 0, 0, OPT_DEBUG }, \ - --#define KEXEC_OPT_STR "h?vdfxluet:p" -+#define KEXEC_OPT_STR "h?vdfxluet:ps" - - extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr); - extern void die(const char *fmt, ...) --- -1.9.0 - diff --git a/SOURCES/kexec-tools-2.0.7-kexec-ppc64-disabling-exception-handling-when-buildi.patch b/SOURCES/kexec-tools-2.0.7-kexec-ppc64-disabling-exception-handling-when-buildi.patch deleted file mode 100644 index 4c92242..0000000 --- a/SOURCES/kexec-tools-2.0.7-kexec-ppc64-disabling-exception-handling-when-buildi.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 335bad77fb0750f3961aa8df47c83a522d212b08 Mon Sep 17 00:00:00 2001 -From: Laurent Dufour -Date: Tue, 22 Jul 2014 18:22:28 +0200 -Subject: [PATCH] kexec/ppc64: disabling exception handling when building the - purgatory - -Some Linux distributions would like to turn on the GCC exception handling -by default. As this option introduces symbols in the built code that are -defined in a separate shared library, this is not a good idea to have such -an option activated when building the purgatory. - -This patch forces the exception handling to be turned off when building the -purgatory on ppc64 BE and LE. - -Signed-off-by: Laurent Dufour -Signed-off-by: Simon Horman ---- - purgatory/arch/ppc64/Makefile | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/purgatory/arch/ppc64/Makefile b/purgatory/arch/ppc64/Makefile -index 712e2b1..6c58fa2 100644 ---- a/purgatory/arch/ppc64/Makefile -+++ b/purgatory/arch/ppc64/Makefile -@@ -9,7 +9,8 @@ ppc64_PURGATORY_SRCS += purgatory/arch/ppc64/console-ppc64.c - ppc64_PURGATORY_SRCS += purgatory/arch/ppc64/crashdump_backup.c - ppc64_PURGATORY_SRCS += purgatory/arch/ppc64/misc.S - --ppc64_PURGATORY_EXTRA_CFLAGS += -m64 -msoft-float -fno-stack-protector -+ppc64_PURGATORY_EXTRA_CFLAGS += -m64 -msoft-float -fno-stack-protector \ -+ -fno-exceptions - ppc64_PURGATORY_EXTRA_ASFLAGS += -m64 - ifeq ($(SUBARCH),BE) - ppc64_PURGATORY_EXTRA_LDFLAGS += -melf64ppc --- -1.9.3 - diff --git a/SOURCES/kexec-tools-2.0.7-kexec-ppc64-move-to-device-tree-version-17.patch b/SOURCES/kexec-tools-2.0.7-kexec-ppc64-move-to-device-tree-version-17.patch deleted file mode 100644 index c7a4bb4..0000000 --- a/SOURCES/kexec-tools-2.0.7-kexec-ppc64-move-to-device-tree-version-17.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2ca220389d212249cc842d49084c95e524fb299b Mon Sep 17 00:00:00 2001 -From: Laurent Dufour -Date: Mon, 16 Jun 2014 14:42:43 +0200 -Subject: [PATCH] kexec/ppc64: move to device tree version 17 - -Kernel commit e6a6928c3ea1d0195ed75a091e345696b916c09b changed the way the -device tree is processed in the kernel. Now version 2 is no more supported. - -This patch move the version of the device tree generated in ppc64 -environment from 2 to 17, allowing to kexec kernel 3.16. - -In addition, automates the define of NEED_STRUCTURE_BLOCK_EXTRA_PAD which -should not be set for DT version 16 and above. - -Signed-off-by: Laurent Dufour -Signed-off-by: Simon Horman ---- - kexec/arch/ppc64/kexec-ppc64.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/kexec/arch/ppc64/kexec-ppc64.h b/kexec/arch/ppc64/kexec-ppc64.h -index 9a0aecf..89ee942 100644 ---- a/kexec/arch/ppc64/kexec-ppc64.h -+++ b/kexec/arch/ppc64/kexec-ppc64.h -@@ -6,9 +6,11 @@ - #define CORE_TYPE_ELF32 1 - #define CORE_TYPE_ELF64 2 - --#define BOOT_BLOCK_VERSION 2 --#define BOOT_BLOCK_LAST_COMP_VERSION 2 --#define NEED_STRUCTURE_BLOCK_EXTRA_PAD -+#define BOOT_BLOCK_VERSION 17 -+#define BOOT_BLOCK_LAST_COMP_VERSION 17 -+#if (BOOT_BLOCK_VERSION < 16) -+# define NEED_STRUCTURE_BLOCK_EXTRA_PAD -+#endif - #define HAVE_DYNAMIC_MEMORY - #define NEED_RESERVE_DTB - --- -1.9.3 - diff --git a/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-segmentation-fault-on-sadump-re.patch b/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-segmentation-fault-on-sadump-re.patch deleted file mode 100644 index ab22420..0000000 --- a/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-segmentation-fault-on-sadump-re.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 8edf033f0eada8640f821ea8abd5bc2b0fa09083 Mon Sep 17 00:00:00 2001 -From: HATAYAMA Daisuke -Date: Mon, 20 Jun 2016 14:58:05 +0900 -Subject: [PATCH 1/2] [PATCH 1/2] sadump: fix segmentation fault on - sadump-related formats - -Currently, makedumpfile results in segmentation fault on -sadump-related formats: - - # ~/makedumpfile --message-level 31 -l -d 31 -x ./vmlinux vmcore - sadump: read dump device as single partition - sadump: single partition configuration - page_size : 4096 - Segmentation fault - -This is because although commit -5fc24bf754fa6d2c0bd0f1c6f5655de371efb9d5 started dynamically -allocating the buffer of struct dump_bitmap, the sadump source code -doesn't follow the change. - -This commit fixes this by following the change. - -Signed-off-by: HATAYAMA Daisuke -Signed-off-by: Baoquan He ---- - makedumpfile.c | 5 ++++- - sadump_info.c | 28 ++++++++++++++++++++++++++-- - 2 files changed, 30 insertions(+), 3 deletions(-) - -diff --git a/makedumpfile-1.6.0/makedumpfile.c b/makedumpfile-1.6.0/makedumpfile.c -index fd884d3..ee3174f 100644 ---- a/makedumpfile-1.6.0/makedumpfile.c -+++ b/makedumpfile-1.6.0/makedumpfile.c -@@ -11245,8 +11245,11 @@ out: - free(info->kh_memory); - if (info->valid_pages) - free(info->valid_pages); -- if (info->bitmap_memory) -+ if (info->bitmap_memory) { -+ if (info->bitmap_memory->buf) -+ free(info->bitmap_memory->buf); - free(info->bitmap_memory); -+ } - if (info->fd_memory) - close(info->fd_memory); - if (info->fd_dumpfile) -diff --git a/makedumpfile-1.6.0/sadump_info.c b/makedumpfile-1.6.0/sadump_info.c -index 20376f0..8716167 100644 ---- a/makedumpfile-1.6.0/sadump_info.c -+++ b/makedumpfile-1.6.0/sadump_info.c -@@ -832,18 +832,28 @@ sadump_initialize_bitmap_memory(void) - strerror(errno)); - return FALSE; - } -+ - bmp->fd = info->fd_memory; - bmp->file_name = info->name_memory; - bmp->no_block = -1; -- memset(bmp->buf, 0, BUFSIZE_BITMAP); - bmp->offset = dumpable_bitmap_offset; - -+ bmp->buf = malloc(BUFSIZE_BITMAP); -+ if (!bmp->buf) { -+ ERRMSG("Can't allocate memory for the memory-bitmap's buffer. %s\n", -+ strerror(errno)); -+ free(bmp); -+ return FALSE; -+ } -+ memset(bmp->buf, 0, BUFSIZE_BITMAP); -+ - max_section = divideup(si->max_mapnr, SADUMP_PF_SECTION_NUM); - - block_table = calloc(sizeof(unsigned long long), max_section); - if (block_table == NULL) { - ERRMSG("Can't allocate memory for the block_table. %s\n", - strerror(errno)); -+ free(bmp->buf); - free(bmp); - return FALSE; - } -@@ -870,8 +880,17 @@ sadump_initialize_bitmap_memory(void) - bmp->fd = info->fd_memory; - bmp->file_name = info->name_memory; - bmp->no_block = -1; -- memset(bmp->buf, 0, BUFSIZE_BITMAP); - bmp->offset = si->sub_hdr_offset + sh->block_size * sh->sub_hdr_size; -+ -+ bmp->buf = malloc(BUFSIZE_BITMAP); -+ if (!bmp->buf) { -+ ERRMSG("Can't allocate memory for the memory-bitmap's buffer. %s\n", -+ strerror(errno)); -+ free(bmp); -+ return FALSE; -+ } -+ memset(bmp->buf, 0, BUFSIZE_BITMAP); -+ - si->ram_bitmap = bmp; - - /* -@@ -1904,6 +1923,11 @@ free_sadump_info(void) - fclose(si->file_elf_note); - if (si->cpu_online_mask_buf) - free(si->cpu_online_mask_buf); -+ if (si->ram_bitmap) { -+ if (si->ram_bitmap->buf) -+ free(si->ram_bitmap->buf); -+ free(si->ram_bitmap); -+ } - } - - void --- -2.5.5 - diff --git a/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-wrong-progress-report-on-sadump.patch b/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-wrong-progress-report-on-sadump.patch deleted file mode 100644 index 99f69af..0000000 --- a/SOURCES/kexec-tools-2.0.7-makedumpfile-sadump-fix-wrong-progress-report-on-sadump.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 3883607bb61b265e9de259722b247075f7710994 Mon Sep 17 00:00:00 2001 -From: HATAYAMA Daisuke -Date: Mon, 20 Jun 2016 15:00:53 +0900 -Subject: [PATCH 2/2] [PATCH 2/2] sadump: fix wrong progress report on sadump - formats - -Currently, makedumpfile displays wrong progress report on sadump -formats and could result in "Floating point exception" in the worst -case: - - Original pages : 0x0000000000000000 - Excluded pages : 0x0000000001f2b44a - Pages filled with zero : 0x0000000000b160b5 - Non-private cache pages : 0x0000000000007a7e - Private cache pages : 0x0000000000000431 - User process data pages : 0x000000000140d4dc - Free pages : 0x0000000000000000 - Hwpoison pages : 0x000000000000000a - Remaining pages : 0xfffffffffe0d4bb6 - Floating point exception (core dumped) - -This is because on sadump-related formats, the number of memory hole -pages is not counted, the number of original pages becomes 0 and zero -division exception occurs below: - - 9409void - 9410print_report(void) - 9411{ - 9412 mdf_pfn_t pfn_original, pfn_excluded, shrinking; - 9413 - 9414 /* - 9415 * /proc/vmcore doesn't contain the memory hole area. - 9416 */ - 9417 pfn_original = info->max_mapnr - pfn_memhole; - 9418 - 9419 pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private - 9420 + pfn_user + pfn_free + pfn_hwpoison; - 9421 shrinking = (pfn_original - pfn_excluded) * 100; - 9422 shrinking = shrinking / pfn_original; <-- Here. - -This commit fixes this issue by counting the number of memory hole -pages and so the number of original pages. As a result, makedumpfile -displays correct progress report on sadump formats and doesn't exit -abnormally: - - Original pages : 0x0000000001ffaa23 - Excluded pages : 0x0000000001f2b44a - Pages filled with zero : 0x0000000000b160b5 - Non-private cache pages : 0x0000000000007a7e - Private cache pages : 0x0000000000000431 - User process data pages : 0x000000000140d4dc - Free pages : 0x0000000000000000 - Hwpoison pages : 0x000000000000000a - Remaining pages : 0x00000000000cf5d9 - (The number of pages is reduced to 2%.) - Memory Hole : 0x00000000000a55dd - -------------------------------------------------- - Total pages : 0x00000000020a0000 - - Cache hit: 1570176, miss: 12997082, hit rate: 10.8% - -Signed-off-by: HATAYAMA Daisuke -Signed-off-by: Baoquan He ---- - sadump_info.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/makedumpfile-1.6.0/sadump_info.c b/makedumpfile-1.6.0/sadump_info.c -index 8716167..5ff5595 100644 ---- a/makedumpfile-1.6.0/sadump_info.c -+++ b/makedumpfile-1.6.0/sadump_info.c -@@ -213,6 +213,8 @@ sadump_copy_1st_bitmap_from_memory(void) - char buf[si->sh_memory->block_size]; - off_t offset_page; - unsigned long bitmap_offset, bitmap_len; -+ mdf_pfn_t pfn, pfn_bitmap1; -+ extern mdf_pfn_t pfn_memhole; - - bitmap_offset = si->sub_hdr_offset + sh->block_size*sh->sub_hdr_size; - bitmap_len = sh->block_size * sh->bitmap_blocks; -@@ -250,6 +252,13 @@ sadump_copy_1st_bitmap_from_memory(void) - offset_page += sizeof(buf); - } - -+ pfn_bitmap1 = 0; -+ for (pfn = 0; pfn < info->max_mapnr; ++pfn) { -+ if (sadump_is_ram(pfn)) -+ pfn_bitmap1++; -+ } -+ pfn_memhole = info->max_mapnr - pfn_bitmap1; -+ - /* - * kdump uses the first 640kB on the 2nd kernel. But both - * bitmaps should reflect the 1st kernel memory situation. We --- -2.5.5 - diff --git a/SOURCES/kexec-tools-2.0.7-ppc64-kdump-Fix-ELF-header-endianess.patch b/SOURCES/kexec-tools-2.0.7-ppc64-kdump-Fix-ELF-header-endianess.patch deleted file mode 100644 index eb6bbd7..0000000 --- a/SOURCES/kexec-tools-2.0.7-ppc64-kdump-Fix-ELF-header-endianess.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 45b33eb2e70cd44f41abf1058a92659cb4315011 Mon Sep 17 00:00:00 2001 -From: Laurent Dufour -Date: Fri, 25 Jul 2014 17:07:49 +0200 -Subject: [PATCH] ppc64/kdump: Fix ELF header endianess - -The ELF header created among the loading of the kdump kernel should be -flagged using the current endianess and not always as big endian. - -Without this patch the data exposed in /proc/vmcore are not readable when -running in LE mode. - -Signed-off-by: Laurent Dufour -Signed-off-by: Simon Horman ---- - kexec/arch/ppc64/crashdump-ppc64.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c -index 00a0e63..6214b83 100644 ---- a/kexec/arch/ppc64/crashdump-ppc64.c -+++ b/kexec/arch/ppc64/crashdump-ppc64.c -@@ -38,7 +38,11 @@ - static struct crash_elf_info elf_info64 = - { - class: ELFCLASS64, -+#if BYTE_ORDER == LITTLE_ENDIAN -+ data: ELFDATA2LSB, -+#else - data: ELFDATA2MSB, -+#endif - machine: EM_PPC64, - page_offset: PAGE_OFFSET, - lowmem_limit: MAXMEM, --- -1.9.3 - diff --git a/SOURCES/kexec-tools-2.0.8-Don-t-bail-out-if-check_cpu_nodes-fails.patch b/SOURCES/kexec-tools-2.0.8-Don-t-bail-out-if-check_cpu_nodes-fails.patch deleted file mode 100644 index 383e08f..0000000 --- a/SOURCES/kexec-tools-2.0.8-Don-t-bail-out-if-check_cpu_nodes-fails.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 224112c147c398df25c543fcea42b3a75635c417 Mon Sep 17 00:00:00 2001 -Message-Id: <224112c147c398df25c543fcea42b3a75635c417.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Mark Salter -Date: Mon, 27 Apr 2015 11:18:25 -0400 -Subject: [PATCH 17/17] Don't bail out if check_cpu_nodes() fails - -Current check_cpu_nodes() will fail if firmware does not provide a -devicetree with cpu nodes. When booting with ACPI, we cannot count -on a devicetree with cpu nodes. For now, just warn on error rather -than bailing out. This will allow kexec to work with moonshot. - -Signed-off-by: Mark Salter ---- - kexec/arch/arm64/kexec-arm64.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index d884c7c1707d..12c589f8001c 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -639,7 +639,7 @@ int arm64_load_other_segments(struct kexec_info *info, - result = check_cpu_nodes(&dtb_1, &dtb_2); - - if (result) -- return result; -+ fprintf(stderr, "kexec: Warning: No device tree available.\n"); - - /* - * Put the DTB after the kernel with an alignment of 128 KiB, giving --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-add-aarch64-to-configure.patch b/SOURCES/kexec-tools-2.0.8-add-aarch64-to-configure.patch deleted file mode 100644 index 6db6dad..0000000 --- a/SOURCES/kexec-tools-2.0.8-add-aarch64-to-configure.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Nur -x '*autom4te.cache*' kexec-tools-2.0.7.orig/configure kexec-tools-2.0.7/configure ---- kexec-tools-2.0.7.orig/configure 2014-06-08 20:51:35.000000000 -0400 -+++ kexec-tools-2.0.7/configure 2015-04-21 13:58:57.272137413 -0400 -@@ -2195,6 +2195,9 @@ - ARCH="ppc64" - SUBARCH="LE" - ;; -+ aarch64* ) -+ ARCH="arm64" -+ ;; - arm* ) - ARCH="arm" - ;; diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Add-arm64-kexec-support.patch b/SOURCES/kexec-tools-2.0.8-arm64-Add-arm64-kexec-support.patch deleted file mode 100644 index f1d89c9..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Add-arm64-kexec-support.patch +++ /dev/null @@ -1,1772 +0,0 @@ -From 21014aa0868f11223e3b33afa1b6320b79187dbc Mon Sep 17 00:00:00 2001 -Message-Id: <21014aa0868f11223e3b33afa1b6320b79187dbc.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Geoff Levand -Date: Fri, 17 Apr 2015 10:54:55 -0700 -Subject: [PATCH 02/17] arm64: Add arm64 kexec support - -Add kexec reboot support for ARM64 platforms. Uses purgatory. - -Signed-off-by: Geoff Levand ---- - configure.ac | 3 + - kexec/Makefile | 1 + - kexec/arch/arm64/Makefile | 40 ++ - kexec/arch/arm64/crashdump-arm64.c | 21 + - kexec/arch/arm64/crashdump-arm64.h | 12 + - kexec/arch/arm64/image-header.h | 95 +++ - kexec/arch/arm64/include/arch/options.h | 44 ++ - kexec/arch/arm64/kexec-arm64.c | 1041 +++++++++++++++++++++++++++++++ - kexec/arch/arm64/kexec-arm64.h | 51 ++ - kexec/arch/arm64/kexec-elf-arm64.c | 123 ++++ - kexec/arch/arm64/kexec-image-arm64.c | 50 ++ - kexec/kexec-syscall.h | 9 +- - purgatory/Makefile | 1 + - purgatory/arch/arm64/Makefile | 18 + - purgatory/arch/arm64/entry.S | 54 ++ - purgatory/arch/arm64/purgatory-arm64.c | 35 ++ - 16 files changed, 1596 insertions(+), 2 deletions(-) - create mode 100644 kexec/arch/arm64/Makefile - create mode 100644 kexec/arch/arm64/crashdump-arm64.c - create mode 100644 kexec/arch/arm64/crashdump-arm64.h - create mode 100644 kexec/arch/arm64/image-header.h - create mode 100644 kexec/arch/arm64/include/arch/options.h - create mode 100644 kexec/arch/arm64/kexec-arm64.c - create mode 100644 kexec/arch/arm64/kexec-arm64.h - create mode 100644 kexec/arch/arm64/kexec-elf-arm64.c - create mode 100644 kexec/arch/arm64/kexec-image-arm64.c - create mode 100644 purgatory/arch/arm64/Makefile - create mode 100644 purgatory/arch/arm64/entry.S - create mode 100644 purgatory/arch/arm64/purgatory-arm64.c - -diff --git a/configure.ac b/configure.ac -index 6946780d498f..701ed69c5033 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -35,6 +35,9 @@ case $target_cpu in - ARCH="ppc64" - SUBARCH="LE" - ;; -+ aarch64* ) -+ ARCH="arm64" -+ ;; - arm* ) - ARCH="arm" - ;; -diff --git a/kexec/Makefile b/kexec/Makefile -index 6937a4dbb38b..fac668072463 100644 ---- a/kexec/Makefile -+++ b/kexec/Makefile -@@ -75,6 +75,7 @@ KEXEC_SRCS += $($(ARCH)_DT_OPS) - - include $(srcdir)/kexec/arch/alpha/Makefile - include $(srcdir)/kexec/arch/arm/Makefile -+include $(srcdir)/kexec/arch/arm64/Makefile - include $(srcdir)/kexec/arch/i386/Makefile - include $(srcdir)/kexec/arch/ia64/Makefile - include $(srcdir)/kexec/arch/m68k/Makefile -diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile -new file mode 100644 -index 000000000000..37414dc5c900 ---- /dev/null -+++ b/kexec/arch/arm64/Makefile -@@ -0,0 +1,40 @@ -+ -+arm64_FS2DT += kexec/fs2dt.c -+arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h \ -+ -include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h -+ -+arm64_DT_OPS += kexec/dt-ops.c -+ -+arm64_CPPFLAGS += -I $(srcdir)/kexec/ -+ -+arm64_KEXEC_SRCS += \ -+ kexec/arch/arm64/kexec-arm64.c \ -+ kexec/arch/arm64/kexec-image-arm64.c \ -+ kexec/arch/arm64/kexec-elf-arm64.c \ -+ kexec/arch/arm64/crashdump-arm64.c -+ -+arm64_ARCH_REUSE_INITRD = -+arm64_ADD_SEGMENT = -+arm64_VIRT_TO_PHYS = -+arm64_PHYS_TO_VIRT = -+ -+dist += $(arm64_KEXEC_SRCS) \ -+ kexec/arch/arm64/Makefile \ -+ kexec/arch/arm64/kexec-arm64.h \ -+ kexec/arch/arm64/crashdump-arm64.h -+ -+ifdef HAVE_LIBFDT -+ -+LIBS += -lfdt -+ -+else -+ -+include $(srcdir)/kexec/libfdt/Makefile.libfdt -+ -+libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) -+ -+arm64_CPPFLAGS += -I$(srcdir)/kexec/libfdt -+ -+arm64_KEXEC_SRCS += $(libfdt_SRCS) -+ -+endif -diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c -new file mode 100644 -index 000000000000..d2272c8124d0 ---- /dev/null -+++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -0,0 +1,21 @@ -+/* -+ * ARM64 crashdump. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+ -+#include "kexec.h" -+#include "crashdump.h" -+#include "crashdump-arm64.h" -+#include "kexec-arm64.h" -+#include "kexec-elf.h" -+ -+struct memory_ranges usablemem_rgns = {}; -+ -+int is_crashkernel_mem_reserved(void) -+{ -+ return 0; -+} -diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h -new file mode 100644 -index 000000000000..f33c7a25b454 ---- /dev/null -+++ b/kexec/arch/arm64/crashdump-arm64.h -@@ -0,0 +1,12 @@ -+/* -+ * ARM64 crashdump. -+ */ -+ -+#if !defined(CRASHDUMP_ARM64_H) -+#define CRASHDUMP_ARM64_H -+ -+#include "kexec.h" -+ -+extern struct memory_ranges usablemem_rgns; -+ -+#endif -diff --git a/kexec/arch/arm64/image-header.h b/kexec/arch/arm64/image-header.h -new file mode 100644 -index 000000000000..acb839ab889c ---- /dev/null -+++ b/kexec/arch/arm64/image-header.h -@@ -0,0 +1,95 @@ -+/* -+ * ARM64 binary image support. -+ * Copyright (C) 2014 Linaro. -+ */ -+ -+#if !defined(__ARM64_IMAGE_HEADER_H) -+#define __ARM64_IMAGE_HEADER_H -+ -+#if !defined(__KERNEL__) -+#include -+#endif -+ -+#if !defined(__ASSEMBLY__) -+ -+/** -+ * struct arm64_image_header - arm64 kernel image header. -+ * -+ * @pe_sig: Optional PE format 'MZ' signature. -+ * @branch_code: Reserved for instructions to branch to stext. -+ * @text_offset: The image load offset in LSB byte order. -+ * @image_size: An estimated size of the memory image size in LSB byte order. -+ * @flags: Bit flags: -+ * Bit 7.0: Image byte order, 1=MSB. -+ * @reserved_1: Reserved. -+ * @magic: Magic number, "ARM\x64". -+ * @pe_header: Optional offset to a PE format header. -+ **/ -+ -+struct arm64_image_header { -+ uint8_t pe_sig[2]; -+ uint16_t branch_code[3]; -+ uint64_t text_offset; -+ uint64_t image_size; -+ uint8_t flags[8]; -+ uint64_t reserved_1[3]; -+ uint8_t magic[4]; -+ uint32_t pe_header; -+}; -+ -+static const uint8_t arm64_image_magic[4] = {'A', 'R', 'M', 0x64U}; -+static const uint8_t arm64_image_pe_sig[2] = {'M', 'Z'}; -+static const uint64_t arm64_image_flag_7_be = 0x01U; -+ -+/** -+ * arm64_header_check_magic - Helper to check the arm64 image header. -+ * -+ * Returns non-zero if header is OK. -+ */ -+ -+static inline int arm64_header_check_magic(const struct arm64_image_header *h) -+{ -+ if (!h) -+ return 0; -+ -+ if (!h->text_offset) -+ return 0; -+ -+ return (h->magic[0] == arm64_image_magic[0] -+ && h->magic[1] == arm64_image_magic[1] -+ && h->magic[2] == arm64_image_magic[2] -+ && h->magic[3] == arm64_image_magic[3]); -+} -+ -+/** -+ * arm64_header_check_pe_sig - Helper to check the arm64 image header. -+ * -+ * Returns non-zero if 'MZ' signature is found. -+ */ -+ -+static inline int arm64_header_check_pe_sig(const struct arm64_image_header *h) -+{ -+ if (!h) -+ return 0; -+ -+ return (h->pe_sig[0] == arm64_image_pe_sig[0] -+ && h->pe_sig[1] == arm64_image_pe_sig[1]); -+} -+ -+/** -+ * arm64_header_check_msb - Helper to check the arm64 image header. -+ * -+ * Returns non-zero if the image was built as big endian. -+ */ -+ -+static inline int arm64_header_check_msb(const struct arm64_image_header *h) -+{ -+ if (!h) -+ return 0; -+ -+ return !!(h->flags[7] & arm64_image_flag_7_be); -+} -+ -+#endif /* !defined(__ASSEMBLY__) */ -+ -+#endif -diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h -new file mode 100644 -index 000000000000..51afc5f1f6f2 ---- /dev/null -+++ b/kexec/arch/arm64/include/arch/options.h -@@ -0,0 +1,44 @@ -+#if !defined(KEXEC_ARCH_ARM64_OPTIONS_H) -+#define KEXEC_ARCH_ARM64_OPTIONS_H -+ -+#define OPT_APPEND ((OPT_MAX)+0) -+#define OPT_DTB ((OPT_MAX)+1) -+#define OPT_INITRD ((OPT_MAX)+2) -+#define OPT_LITE ((OPT_MAX)+3) -+#define OPT_PORT ((OPT_MAX)+4) -+#define OPT_ARCH_MAX ((OPT_MAX)+5) -+ -+#define KEXEC_ARCH_OPTIONS \ -+ KEXEC_OPTIONS \ -+ { "append", 1, NULL, OPT_APPEND }, \ -+ { "command-line", 1, NULL, OPT_APPEND }, \ -+ { "dtb", 1, NULL, OPT_DTB }, \ -+ { "initrd", 1, NULL, OPT_INITRD }, \ -+ { "lite", 0, NULL, OPT_LITE }, \ -+ { "port", 1, NULL, OPT_PORT }, \ -+ { "ramdisk", 1, NULL, OPT_INITRD }, \ -+ -+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */ -+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS -+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR -+ -+static const char arm64_opts_usage[] __attribute__ ((unused)) = -+" --append=STRING Set the kernel command line to STRING.\n" -+" --command-line=STRING Set the kernel command line to STRING.\n" -+" --dtb=FILE Use FILE as the device tree blob.\n" -+" --initrd=FILE Use FILE as the kernel initial ramdisk.\n" -+" --lite Fast reboot, no memory integrity checks - currently NOT SUPPORTED.\n"); -+" --port=ADDRESS Purgatory output to port ADDRESS.\n" -+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n"; -+ -+struct arm64_opts { -+ const char *command_line; -+ const char *dtb; -+ const char *initrd; -+ uint64_t port; -+ int lite; -+}; -+ -+extern struct arm64_opts arm64_opts; -+ -+#endif -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -new file mode 100644 -index 000000000000..0860810b6e86 ---- /dev/null -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -0,0 +1,1041 @@ -+/* -+ * ARM64 kexec. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include "dt-ops.h" -+#include "kexec.h" -+#include "crashdump.h" -+#include "crashdump-arm64.h" -+#include "kexec-arm64.h" -+#include "fs2dt.h" -+#include "kexec-syscall.h" -+#include "arch/options.h" -+ -+/* Global varables the core kexec routines expect. */ -+ -+unsigned char reuse_initrd; -+ -+off_t initrd_base; -+off_t initrd_size; -+ -+const struct arch_map_entry arches[] = { -+ { "aarch64", KEXEC_ARCH_ARM64 }, -+ { "aarch64_be", KEXEC_ARCH_ARM64 }, -+ { NULL, 0 }, -+}; -+ -+/* arm64 global varables. */ -+ -+struct arm64_opts arm64_opts; -+struct arm64_mem arm64_mem = { -+ .memstart = UINT64_MAX, -+}; -+ -+static void set_memstart(uint64_t v) -+{ -+ if (arm64_mem.memstart == UINT64_MAX || v < arm64_mem.memstart) -+ arm64_mem.memstart = v; -+} -+ -+static int check_memstart(void) -+{ -+ return arm64_mem.memstart != UINT64_MAX; -+} -+ -+void arch_usage(void) -+{ -+ dbgprintf("Build time: %s : %s\n", __DATE__, __TIME__); -+ printf(arm64_opts_usage); -+} -+ -+int arch_process_options(int argc, char **argv) -+{ -+ static const char short_options[] = KEXEC_OPT_STR ""; -+ static const struct option options[] = { -+ KEXEC_ARCH_OPTIONS -+ { 0 } -+ }; -+ int opt; -+ -+ for (opt = 0; opt != -1; ) { -+ opt = getopt_long(argc, argv, short_options, options, 0); -+ -+ switch (opt) { -+ case OPT_APPEND: -+ arm64_opts.command_line = optarg; -+ break; -+ case OPT_DTB: -+ arm64_opts.dtb = optarg; -+ break; -+ case OPT_INITRD: -+ arm64_opts.initrd = optarg; -+ break; -+ case OPT_LITE: -+ arm64_opts.lite = 1; -+ fprintf(stderr, "kexec: --lite option currently NOT SUPPORTED.\n"); -+ break; -+ case OPT_PORT: -+ arm64_opts.port = strtoull(optarg, NULL, 0); -+ break; -+ default: -+ break; /* Ignore core and unknown options. */ -+ } -+ } -+ -+ kexec_debug = 1; // FIXME: for debugging only. -+ -+ dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, -+ arm64_opts.command_line); -+ dbgprintf("%s:%d: initrd: %s\n", __func__, __LINE__, -+ arm64_opts.initrd); -+ dbgprintf("%s:%d: dtb: %s\n", __func__, __LINE__, arm64_opts.dtb); -+ dbgprintf("%s:%d: lite: %d\n", __func__, __LINE__, arm64_opts.lite); -+ dbgprintf("%s:%d: port: 0x%" PRIx64 "\n", __func__, __LINE__, -+ arm64_opts.port); -+ -+ return 0; -+} -+ -+struct dtb { -+ char *buf; -+ off_t size; -+ const char *name; -+ const char *path; -+}; -+ -+static void dump_reservemap(const struct dtb *dtb) -+{ -+ int i; -+ -+ for (i = 0; ; i++) { -+ uint64_t address; -+ uint64_t size; -+ -+ fdt_get_mem_rsv(dtb->buf, i, &address, &size); -+ -+ if (!size) -+ break; -+ -+ dbgprintf("%s: %s {%" PRIx64 ", %" PRIx64 "}\n", __func__, -+ dtb->name, address, size); -+ } -+} -+ -+enum cpu_enable_method { -+ cpu_enable_method_unknown, -+ cpu_enable_method_psci, -+ cpu_enable_method_spin_table, -+}; -+ -+/** -+ * struct cpu_properties - Various properties from a device tree cpu node. -+ * -+ * These properties will be valid over a dtb re-size. -+ */ -+ -+struct cpu_properties { -+ uint64_t hwid; -+ uint64_t cpu_release_addr; -+ char node_path[128]; -+ char enable_method[128]; -+ enum cpu_enable_method type; -+}; -+ -+/** -+ * read_cpu_properties - Helper to read the device tree cpu properties. -+ */ -+ -+static int read_cpu_properties(struct cpu_properties *cp, -+ const struct dtb *dtb, int node_offset, unsigned int address_cells) -+{ -+ int result; -+ const void *data; -+ -+ result = fdt_get_path(dtb->buf, node_offset, cp->node_path, -+ sizeof(cp->node_path)); -+ -+ if (result < 0) { -+ fprintf(stderr, "kexec: %s:%d: %s: fdt_get_path failed: %s\n", -+ __func__, __LINE__, dtb->name, fdt_strerror(result)); -+ return result; -+ } -+ -+ data = fdt_getprop(dtb->buf, node_offset, "device_type", &result); -+ -+ if (!data) { -+ dbgprintf("%s: %s (%s) read device_type failed: %s\n", -+ __func__, dtb->name, cp->node_path, -+ fdt_strerror(result)); -+ return result == -FDT_ERR_NOTFOUND ? 0 : result; -+ } -+ -+ if (strcmp(data, "cpu")) { -+ dbgprintf("%s: %s (%s): '%s'\n", __func__, dtb->name, -+ cp->node_path, (const char *)data); -+ return 0; -+ } -+ -+ data = fdt_getprop(dtb->buf, node_offset, "reg", &result); -+ -+ if (!data) { -+ fprintf(stderr, "kexec: %s:%d: read hwid failed: %s\n", -+ __func__, __LINE__, fdt_strerror(result)); -+ return result; -+ } -+ -+ cp->hwid = (address_cells == 1) ? fdt32_to_cpu(*(uint32_t *)data) : -+ fdt64_to_cpu(*(uint64_t *)data); -+ -+ data = fdt_getprop(dtb->buf, node_offset, "enable-method", &result); -+ -+ if (!data) { -+ fprintf(stderr, -+ "kexec: %s:%d: read enable_method failed: %s\n", -+ __func__, __LINE__, fdt_strerror(result)); -+ return result; -+ } -+ -+ strncpy(cp->enable_method, data, sizeof(cp->enable_method)); -+ cp->enable_method[sizeof(cp->enable_method) - 1] = 0; -+ -+ if (!strcmp(cp->enable_method, "psci")) { -+ cp->type = cpu_enable_method_psci; -+ return 1; -+ } -+ -+ if (strcmp(cp->enable_method, "spin-table")) { -+ cp->type = cpu_enable_method_unknown; -+ return -1; -+ } -+ -+ cp->type = cpu_enable_method_spin_table; -+ -+ data = fdt_getprop(dtb->buf, node_offset, "cpu-release-addr", &result); -+ -+ if (!data) { -+ fprintf(stderr, "kexec: %s:%d: " -+ "read cpu-release-addr failed: %s\n", -+ __func__, __LINE__, fdt_strerror(result)); -+ return result; -+ } -+ -+ cp->cpu_release_addr = fdt64_to_cpu(*(uint64_t *)data); -+ -+ return 1; -+} -+ -+static int check_cpu_properties(const struct cpu_properties *cp_1, -+ const struct cpu_properties *cp_2) -+{ -+ assert(cp_1->hwid == cp_2->hwid); -+ -+ if (cp_1->type != cp_2->type) { -+ fprintf(stderr, -+ "%s:%d: hwid-%" PRIx64 ": " -+ "Error: Different enable methods: %s -> %s\n", -+ __func__, __LINE__, cp_1->hwid, cp_1->enable_method, -+ cp_2->enable_method); -+ return -EINVAL; -+ } -+ -+ if (cp_1->type != cpu_enable_method_psci -+ && cp_1->type != cpu_enable_method_spin_table) { -+ fprintf(stderr, -+ "%s:%d: hwid-%" PRIx64 ": " -+ "Warning: Unknown enable method: %s.\n", -+ __func__, __LINE__, cp_1->hwid, -+ cp_1->enable_method); -+ } -+ -+ if (cp_1->type == cpu_enable_method_spin_table) { -+ if (cp_1->cpu_release_addr != cp_2->cpu_release_addr) { -+ fprintf(stderr, "%s:%d: hwid-%" PRIx64 ": " -+ "Error: Different cpu-release-addr: " -+ "%" PRIx64 " -> %" PRIx64 ".\n", -+ __func__, __LINE__, -+ cp_1->hwid, -+ cp_2->cpu_release_addr, -+ cp_1->cpu_release_addr); -+ return -EINVAL; -+ } -+ } -+ -+ dbgprintf("%s: hwid-%" PRIx64 ": OK\n", __func__, cp_1->hwid); -+ -+ return 0; -+} -+ -+struct cpu_info { -+ unsigned int cpu_count; -+ struct cpu_properties *cp; -+}; -+ -+static int read_cpu_info(struct cpu_info *info, const struct dtb *dtb) -+{ -+ int i; -+ int offset; -+ int result; -+ int depth; -+ const void *data; -+ unsigned int address_cells; -+ -+ offset = fdt_subnode_offset(dtb->buf, 0, "cpus"); -+ -+ if (offset < 0) { -+ fprintf(stderr, "kexec: %s:%d: read cpus node failed: %s\n", -+ __func__, __LINE__, fdt_strerror(offset)); -+ return offset; -+ } -+ -+ data = fdt_getprop(dtb->buf, offset, "#address-cells", &result); -+ -+ if (!data) { -+ fprintf(stderr, -+ "kexec: %s:%d: read cpus address-cells failed: %s\n", -+ __func__, __LINE__, fdt_strerror(result)); -+ return result; -+ } -+ -+ address_cells = fdt32_to_cpu(*(uint32_t *)data); -+ -+ if (address_cells < 1 || address_cells > 2) { -+ fprintf(stderr, -+ "kexec: %s:%d: bad cpus address-cells value: %u\n", -+ __func__, __LINE__, address_cells); -+ return -EINVAL; -+ } -+ -+ for (i = 0, depth = 0; ; i++) { -+ info->cp = realloc(info->cp, (i + 1) * sizeof(*info->cp)); -+ -+ if (!info->cp) { -+ fprintf(stderr, "kexec: %s:%d: malloc failed: %s\n", -+ __func__, __LINE__, fdt_strerror(offset)); -+ result = -ENOMEM; -+ goto on_error; -+ } -+ -+next_node: -+ memset(&info->cp[i], 0, sizeof(*info->cp)); -+ -+ offset = fdt_next_node(dtb->buf, offset, &depth); -+ -+ if (offset < 0) { -+ fprintf(stderr, "kexec: %s:%d: " -+ "read cpu node failed: %s\n", __func__, -+ __LINE__, fdt_strerror(offset)); -+ result = offset; -+ goto on_error; -+ } -+ -+ if (depth != 1) -+ break; -+ -+ result = read_cpu_properties(&info->cp[i], dtb, offset, -+ address_cells); -+ -+ if (result == 0) -+ goto next_node; -+ -+ if (result < 0) -+ goto on_error; -+ -+ if (info->cp[i].type == cpu_enable_method_psci) -+ dbgprintf("%s: %s cpu-%d (%s): hwid-%" PRIx64 ", '%s'\n", -+ __func__, dtb->name, i, info->cp[i].node_path, -+ info->cp[i].hwid, -+ info->cp[i].enable_method); -+ else -+ dbgprintf("%s: %s cpu-%d (%s): hwid-%" PRIx64 ", '%s', " -+ "cpu-release-addr %" PRIx64 "\n", -+ __func__, dtb->name, i, info->cp[i].node_path, -+ info->cp[i].hwid, -+ info->cp[i].enable_method, -+ info->cp[i].cpu_release_addr); -+ } -+ -+ info->cpu_count = i; -+ return 0; -+ -+on_error: -+ free(info->cp); -+ info->cp = NULL; -+ return result; -+} -+ -+static int check_cpu_nodes(const struct dtb *dtb_1, const struct dtb *dtb_2) -+{ -+ int result; -+ unsigned int cpu_1; -+ struct cpu_info info_1; -+ struct cpu_info info_2; -+ unsigned int to_process; -+ -+ memset(&info_1, 0, sizeof(info_1)); -+ memset(&info_2, 0, sizeof(info_2)); -+ -+ result = read_cpu_info(&info_1, dtb_1); -+ -+ if (result) -+ goto on_exit; -+ -+ result = read_cpu_info(&info_2, dtb_2); -+ -+ if (result) -+ goto on_exit; -+ -+ to_process = info_1.cpu_count < info_2.cpu_count -+ ? info_1.cpu_count : info_2.cpu_count; -+ -+ for (cpu_1 = 0; cpu_1 < info_1.cpu_count; cpu_1++) { -+ struct cpu_properties *cp_1 = &info_1.cp[cpu_1]; -+ unsigned int cpu_2; -+ -+ for (cpu_2 = 0; cpu_2 < info_2.cpu_count; cpu_2++) { -+ struct cpu_properties *cp_2 = &info_2.cp[cpu_2]; -+ -+ if (cp_1->hwid != cp_2->hwid) -+ continue; -+ -+ to_process--; -+ -+ result = check_cpu_properties(cp_1, cp_2); -+ -+ if (result) -+ goto on_exit; -+ } -+ } -+ -+ if (to_process) { -+ fprintf(stderr, "kexec: %s:%d: Warning: " -+ "Failed to process %u CPUs.\n", -+ __func__, __LINE__, to_process); -+ result = -EINVAL; -+ goto on_exit; -+ } -+ -+on_exit: -+ free(info_1.cp); -+ free(info_2.cp); -+ return result; -+} -+ -+static int set_bootargs(struct dtb *dtb, const char *command_line) -+{ -+ int result; -+ -+ if (!command_line || !command_line[0]) -+ return 0; -+ -+ result = dtb_set_bootargs((char **)&dtb->buf, &dtb->size, command_line); -+ -+ if (result) -+ fprintf(stderr, -+ "kexec: Set device tree bootargs failed.\n"); -+ -+ return result; -+} -+ -+static int read_proc_dtb(struct dtb *dtb, const char *command_line) -+{ -+ int result; -+ struct stat s; -+ static const char path[] = "/proc/device-tree"; -+ -+ result = stat(path, &s); -+ -+ if (result) { -+ dbgprintf("%s: %s\n", __func__, strerror(errno)); -+ return -1; -+ } -+ -+ dtb->path = path; -+ create_flatten_tree((char **)&dtb->buf, &dtb->size, -+ (command_line && command_line[0]) ? command_line : NULL); -+ -+ return 0; -+} -+ -+static int read_sys_dtb(struct dtb *dtb, const char *command_line) -+{ -+ int result; -+ struct stat s; -+ static const char path[] = "/sys/firmware/fdt"; -+ -+ result = stat(path, &s); -+ -+ if (result) { -+ dbgprintf("%s: %s\n", __func__, strerror(errno)); -+ return -1; -+ } -+ -+ dtb->path = path; -+ dtb->buf = slurp_file("/sys/firmware/fdt", &dtb->size); -+ -+ return set_bootargs(dtb, command_line); -+} -+ -+static int read_1st_dtb(struct dtb *dtb, const char *command_line) -+{ -+ int result; -+ -+ result = read_sys_dtb(dtb, command_line); -+ -+ if (!result) -+ goto on_success; -+ -+ result = read_proc_dtb(dtb, command_line); -+ -+ if (!result) -+ goto on_success; -+ -+ return -1; -+ -+on_success: -+ dbgprintf("%s: found %s\n", __func__, dtb->path); -+ return 0; -+} -+ -+static int setup_2nd_dtb(char *command_line, const struct dtb *dtb_1, -+ struct dtb *dtb_2) -+{ -+ int result; -+ -+ result = fdt_check_header(dtb_2->buf); -+ -+ if (result) { -+ fprintf(stderr, "kexec: Invalid 2nd device tree.\n"); -+ return -EINVAL; -+ } -+ -+ result = set_bootargs(dtb_2, command_line); -+ -+ dump_reservemap(dtb_2); -+ -+ return result; -+} -+ -+static uint64_t read_sink(const char *command_line) -+{ -+ uint64_t v; -+ const char *p; -+ -+ if (arm64_opts.port) -+ return arm64_opts.port; -+ -+#if defined(ARM64_DEBUG_PORT) -+ return (uint64_t)(ARM64_DEBUG_PORT); -+#endif -+ if (!command_line) -+ return 0; -+ -+ p = strstr(command_line, "earlyprintk="); -+ -+ if (!p) -+ return 0; -+ -+ while (*p != ',') -+ p++; -+ -+ p++; -+ -+ while (isspace(*p)) -+ p++; -+ -+ if (*p == 0) -+ return 0; -+ -+ errno = 0; -+ -+ v = strtoull(p, NULL, 0); -+ -+ if (errno) -+ return 0; -+ -+ return v; -+} -+ -+/** -+ * arm64_load_other_segments - Prepare the dtb, initrd and purgatory segments. -+ */ -+ -+int arm64_load_other_segments(struct kexec_info *info, -+ unsigned long kernel_entry) -+{ -+ int result; -+ struct mem_ehdr ehdr; -+ unsigned long dtb_max; -+ unsigned long dtb_base; -+ char *initrd_buf = NULL; -+ uint64_t purgatory_sink; -+ unsigned long purgatory_base; -+ struct dtb dtb_1 = {.name = "dtb_1"}; -+ struct dtb dtb_2 = {.name = "dtb_2"}; -+ char command_line[COMMAND_LINE_SIZE] = ""; -+ -+ if (arm64_opts.command_line) { -+ strncpy(command_line, arm64_opts.command_line, -+ sizeof(command_line)); -+ command_line[sizeof(command_line) - 1] = 0; -+ } -+ -+ purgatory_sink = read_sink(command_line); -+ -+ dbgprintf("%s:%d: purgatory sink: 0x%" PRIx64 "\n", __func__, __LINE__, -+ purgatory_sink); -+ -+ if (arm64_opts.dtb) { -+ dtb_2.buf = slurp_file(arm64_opts.dtb, &dtb_2.size); -+ assert(dtb_2.buf); -+ } -+ -+ result = read_1st_dtb(&dtb_1, command_line); -+ -+ if (result && !arm64_opts.dtb) { -+ fprintf(stderr, "kexec: Error: No device tree available.\n"); -+ return result; -+ } -+ -+ if (result && arm64_opts.dtb) -+ dtb_1 = dtb_2; -+ else if (!result && !arm64_opts.dtb) -+ dtb_2 = dtb_1; -+ -+ result = setup_2nd_dtb(command_line, &dtb_1, &dtb_2); -+ -+ if (result) -+ return result; -+ -+ result = check_cpu_nodes(&dtb_1, &dtb_2); -+ -+ if (result) -+ return result; -+ -+ /* -+ * Put the DTB after the kernel with an alignment of 128 KiB, giving -+ * a max supported DTB size of 128 KiB (worst case). Also add 2 KiB -+ * to the DTB size for any DTB growth. -+ */ -+ -+ dtb_max = dtb_2.size + 2 * 1024; -+ -+ dtb_base = locate_hole(info, dtb_max, 128UL * 1024, -+ arm64_mem.memstart + arm64_mem.text_offset -+ + arm64_mem.image_size, -+ _ALIGN_UP(arm64_mem.memstart + arm64_mem.text_offset, -+ 512UL * 1024 * 1024), -+ 1); -+ -+ dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, -+ dtb_2.size); -+ -+ if (dtb_base == ULONG_MAX) -+ return -ENOMEM; -+ -+ purgatory_base = dtb_base + dtb_2.size; -+ initrd_base = 0; -+ initrd_size = 0; -+ -+ if (arm64_opts.initrd) { -+ initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size); -+ -+ if (!initrd_buf) -+ fprintf(stderr, "kexec: Empty ramdisk file.\n"); -+ else { -+ /* Put the initrd after the DTB with an alignment of -+ * page size. */ -+ -+ initrd_base = locate_hole(info, initrd_size, 0, -+ dtb_base + dtb_max, -1, 1); -+ -+ dbgprintf("initrd: base %lx, size %lxh (%ld)\n", -+ initrd_base, initrd_size, initrd_size); -+ -+ if (initrd_base == ULONG_MAX) -+ return -ENOMEM; -+ -+ result = dtb_set_initrd((char **)&dtb_2.buf, -+ &dtb_2.size, initrd_base, -+ initrd_base + initrd_size); -+ -+ if (result) -+ return result; -+ -+ purgatory_base = initrd_base + initrd_size; -+ } -+ } -+ -+ if (dtb_2.size > dtb_max) { -+ fprintf(stderr, "%s: Error: Too many DTB mods.\n", __func__); -+ return -EINVAL; -+ } -+ -+ add_segment_phys_virt(info, dtb_2.buf, dtb_2.size, dtb_base, -+ dtb_2.size, 0); -+ -+ if (arm64_opts.initrd) -+ add_segment_phys_virt(info, initrd_buf, initrd_size, -+ initrd_base, initrd_size, 0); -+ -+ if (arm64_opts.lite) { -+ fprintf(stderr, "kexec: --lite option currently NOT SUPPORTED.\n"); -+ return -ENOSYS; -+ } else { -+ result = build_elf_rel_info(purgatory, purgatory_size, &ehdr, -+ 0); -+ -+ if (result < 0) { -+ fprintf(stderr, "%s: Error: " -+ "build_elf_rel_info failed.\n", __func__); -+ return -EBADF; -+ } -+ -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -+ purgatory_base, ULONG_MAX, 1, 0); -+ -+ info->entry = (void *)elf_rel_get_addr(&info->rhdr, -+ "purgatory_start"); -+ -+ elf_rel_set_symbol(&info->rhdr, "arm64_sink", &purgatory_sink, -+ sizeof(purgatory_sink)); -+ -+ elf_rel_set_symbol(&info->rhdr, "arm64_kernel_entry", -+ &kernel_entry, sizeof(kernel_entry)); -+ -+ elf_rel_set_symbol(&info->rhdr, "arm64_dtb_addr", &dtb_base, -+ sizeof(dtb_base)); -+ } -+ -+ return 0; -+} -+ -+unsigned long virt_to_phys(unsigned long v) -+{ -+ unsigned long p; -+ -+ assert(arm64_mem.page_offset); -+ assert(check_memstart()); -+ -+ p = v - arm64_mem.page_offset + arm64_mem.memstart; -+ -+ dbgprintf("%s: %016lx -> %016lx\n", __func__, v, p); -+ return p; -+} -+ -+unsigned long phys_to_virt(struct crash_elf_info *UNUSED(elf_info), -+ unsigned long p) -+{ -+ unsigned long v; -+ -+ assert(arm64_mem.page_offset); -+ assert(check_memstart()); -+ -+ v = p - arm64_mem.memstart + arm64_mem.page_offset; -+ -+ dbgprintf("%s: %016lx -> %016lx\n", __func__, p, v); -+ return p; -+} -+ -+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz, -+ unsigned long base, size_t memsz) -+{ -+ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1); -+} -+ -+int arm64_process_image_header(const struct arm64_image_header *h) -+{ -+#if !defined(KERNEL_IMAGE_SIZE) -+# define KERNEL_IMAGE_SIZE (768 * 1024) -+#endif -+ -+ if (!arm64_header_check_magic(h)) -+ return -EINVAL; -+ -+ if (h->image_size) { -+ arm64_mem.text_offset = le64_to_cpu(h->text_offset); -+ arm64_mem.image_size = le64_to_cpu(h->image_size); -+ } else { -+ /* For 3.16 and older kernels. */ -+ arm64_mem.text_offset = 0x80000; -+ arm64_mem.image_size = KERNEL_IMAGE_SIZE; -+ } -+ -+ return 0; -+} -+ -+static int get_memory_ranges_dt(struct memory_range *array, unsigned int *count) -+{ -+ struct region {uint64_t base; uint64_t size;}; -+ struct dtb dtb = {.name = "range_dtb"}; -+ int offset; -+ int result; -+ -+ *count = 0; -+ -+ result = read_1st_dtb(&dtb, NULL); -+ -+ if (result) { -+ goto on_error; -+ } -+ -+ result = fdt_check_header(dtb.buf); -+ -+ if (result) { -+ dbgprintf("%s:%d: %s: fdt_check_header failed:%s\n", __func__, -+ __LINE__, dtb.path, fdt_strerror(result)); -+ goto on_error; -+ } -+ -+ for (offset = 0; ; ) { -+ const struct region *region; -+ const struct region *end; -+ int len; -+ -+ offset = fdt_subnode_offset(dtb.buf, offset, "memory"); -+ -+ if (offset == -FDT_ERR_NOTFOUND) -+ break; -+ -+ if (offset <= 0) { -+ dbgprintf("%s:%d: fdt_subnode_offset failed: %d %s\n", -+ __func__, __LINE__, offset, -+ fdt_strerror(offset)); -+ goto on_error; -+ } -+ -+ dbgprintf("%s:%d: node_%d %s\n", __func__, __LINE__, offset, -+ fdt_get_name(dtb.buf, offset, NULL)); -+ -+ region = fdt_getprop(dtb.buf, offset, "reg", &len); -+ -+ if (region <= 0) { -+ dbgprintf("%s:%d: fdt_getprop failed: %d %s\n", -+ __func__, __LINE__, offset, -+ fdt_strerror(offset)); -+ goto on_error; -+ } -+ -+ for (end = region + len / sizeof(*region); -+ region < end && *count < KEXEC_SEGMENT_MAX; -+ region++) { -+ struct memory_range r; -+ -+ r.type = RANGE_RAM; -+ r.start = fdt64_to_cpu(region->base); -+ r.end = r.start + fdt64_to_cpu(region->size); -+ -+ if (!region->size) { -+ dbgprintf("%s:%d: SKIP: %016llx - %016llx\n", -+ __func__, __LINE__, r.start, r.end); -+ continue; -+ } -+ -+ dbgprintf("%s:%d: RAM: %016llx - %016llx\n", __func__, -+ __LINE__, r.start, r.end); -+ -+ array[(*count)++] = r; -+ -+ set_memstart(r.start); -+ } -+ } -+ -+ if (!*count) { -+ dbgprintf("%s:%d: %s: No RAM found.\n", __func__, __LINE__, -+ dtb.path); -+ goto on_error; -+ } -+ -+ dbgprintf("%s:%d: %s: Success\n", __func__, __LINE__, dtb.path); -+ result = 0; -+ goto on_exit; -+ -+on_error: -+ fprintf(stderr, "%s:%d: %s: Unusable device-tree file\n", __func__, -+ __LINE__, dtb.path); -+ result = -1; -+ -+on_exit: -+ free(dtb.buf); -+ return result; -+} -+ -+static int get_memory_ranges_iomem(struct memory_range *array, -+ unsigned int *count) -+{ -+ const char *iomem; -+ char line[MAX_LINE]; -+ FILE *fp; -+ -+ *count = 0; -+ -+ iomem = proc_iomem(); -+ fp = fopen(iomem, "r"); -+ -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); -+ return -1; -+ } -+ -+ while(fgets(line, sizeof(line), fp) != 0) { -+ struct memory_range r; -+ char *str; -+ int consumed; -+ -+ if (*count >= KEXEC_SEGMENT_MAX) -+ break; -+ -+ if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed) -+ != 2) -+ continue; -+ -+ str = line + consumed; -+ r.end++; -+ -+ if (memcmp(str, "System RAM\n", 11)) { -+ dbgprintf("%s:%d: SKIP: %016Lx - %016Lx : %s", __func__, -+ __LINE__, r.start, r.end, str); -+ continue; -+ } -+ -+ r.type = RANGE_RAM; -+ -+ dbgprintf("%s:%d: RAM: %016llx - %016llx : %s", __func__, -+ __LINE__, r.start, r.end, str); -+ -+ array[(*count)++] = r; -+ -+ set_memstart(r.start); -+ } -+ -+ fclose(fp); -+ -+ if (!*count) { -+ dbgprintf("%s:%d: failed: No RAM found.\n", __func__, __LINE__); -+ return -1; -+ } -+ -+ dbgprintf("%s:%d: Success\n", __func__, __LINE__); -+ return 0; -+} -+ -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) -+{ -+ static struct memory_range array[KEXEC_SEGMENT_MAX]; -+ unsigned int count; -+ int result; -+ -+ result = get_memory_ranges_dt(array, &count); -+ -+ if (result) -+ result = get_memory_ranges_iomem(array, &count); -+ -+ *range = result ? NULL : array; -+ *ranges = result ? 0 : count; -+ -+ return result; -+} -+ -+struct file_type file_type[] = { -+ {"elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage}, -+ {"image-arm64", image_arm64_probe, image_arm64_load, image_arm64_usage}, -+}; -+ -+int file_types = sizeof(file_type) / sizeof(file_type[0]); -+ -+int arch_compat_trampoline(struct kexec_info *info) -+{ -+ return 0; -+} -+ -+int machine_verify_elf_rel(struct mem_ehdr *ehdr) -+{ -+ return (ehdr->e_machine == EM_AARCH64); -+} -+ -+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, -+ void *ptr, unsigned long address, unsigned long value) -+{ -+#if !defined(R_AARCH64_ABS64) -+# define R_AARCH64_ABS64 257 -+#endif -+ -+#if !defined(R_AARCH64_LD_PREL_LO19) -+# define R_AARCH64_LD_PREL_LO19 273 -+#endif -+ -+#if !defined(R_AARCH64_ADR_PREL_LO21) -+# define R_AARCH64_ADR_PREL_LO21 274 -+#endif -+ -+#if !defined(R_AARCH64_JUMP26) -+# define R_AARCH64_JUMP26 282 -+#endif -+ -+#if !defined(R_AARCH64_CALL26) -+# define R_AARCH64_CALL26 283 -+#endif -+ -+ uint64_t *location = (uint64_t *)ptr; -+ uint64_t data = *location; -+ const char *type = NULL; -+ -+ switch(r_type) { -+ case R_AARCH64_ABS64: -+ type = "ABS64"; -+ *location += value; -+ break; -+ case R_AARCH64_LD_PREL_LO19: -+ type = "LD_PREL_LO19"; -+ *location += ((value - address) << 3) & 0xffffe0; -+ break; -+ case R_AARCH64_ADR_PREL_LO21: -+ if (value & 3) -+ die("%s: ERROR Unaligned value: %lx\n", __func__, -+ value); -+ type = "ADR_PREL_LO21"; -+ *location += ((value - address) << 3) & 0xffffe0; -+ break; -+ case R_AARCH64_JUMP26: -+ type = "JUMP26"; -+ *location += ((value - address) >> 2) & 0x3ffffff; -+ break; -+ case R_AARCH64_CALL26: -+ type = "CALL26"; -+ *location += ((value - address) >> 2) & 0x3ffffff; -+ break; -+ default: -+ die("%s: ERROR Unknown type: %lu\n", __func__, r_type); -+ break; -+ } -+ -+ dbgprintf("%s: %s %lx->%lx\n", __func__, type, data, *location); -+} -+ -+void arch_reuse_initrd(void) -+{ -+ reuse_initrd = 1; -+} -+ -+void arch_update_purgatory(struct kexec_info *UNUSED(info)) -+{ -+} -diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h -new file mode 100644 -index 000000000000..057acf313b49 ---- /dev/null -+++ b/kexec/arch/arm64/kexec-arm64.h -@@ -0,0 +1,51 @@ -+/* -+ * ARM64 kexec. -+ */ -+ -+#if !defined(KEXEC_ARM64_H) -+#define KEXEC_ARM64_H -+ -+#include -+#include -+ -+#include "image-header.h" -+#include "kexec.h" -+ -+#define KEXEC_SEGMENT_MAX 16 -+ -+#define BOOT_BLOCK_VERSION 17 -+#define BOOT_BLOCK_LAST_COMP_VERSION 16 -+#define COMMAND_LINE_SIZE 512 -+ -+int elf_arm64_probe(const char *kernel_buf, off_t kernel_size); -+int elf_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info); -+void elf_arm64_usage(void); -+ -+int image_arm64_probe(const char *kernel_buf, off_t kernel_size); -+int image_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info); -+void image_arm64_usage(void); -+ -+struct memory_ranges usablemem_rgns; -+off_t initrd_base; -+off_t initrd_size; -+ -+/** -+ * struct arm64_mem - Memory layout info. -+ */ -+ -+struct arm64_mem { -+ uint64_t text_offset; -+ uint64_t image_size; -+ uint64_t page_offset; -+ uint64_t memstart; -+}; -+ -+extern struct arm64_mem arm64_mem; -+ -+int arm64_process_image_header(const struct arm64_image_header *h); -+int arm64_load_other_segments(struct kexec_info *info, -+ unsigned long kernel_entry); -+ -+#endif -diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c -new file mode 100644 -index 000000000000..13dc5e2724d9 ---- /dev/null -+++ b/kexec/arch/arm64/kexec-elf-arm64.c -@@ -0,0 +1,123 @@ -+/* -+ * ARM64 kexec elf support. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dt-ops.h" -+#include "crashdump-arm64.h" -+#include "kexec-arm64.h" -+#include "fs2dt.h" -+#include "kexec-syscall.h" -+#include "arch/options.h" -+ -+int elf_arm64_probe(const char *kernel_buf, off_t kernel_size) -+{ -+ int result; -+ struct mem_ehdr ehdr; -+ -+ result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); -+ -+ if (result < 0) { -+ dbgprintf("%s: Not an ELF executable.\n", __func__); -+ goto on_exit; -+ } -+ -+ if (ehdr.e_machine != EM_AARCH64) { -+ dbgprintf("%s: Not an AARCH64 ELF executable.\n", __func__); -+ result = -EINVAL; -+ goto on_exit; -+ } -+ -+ result = 0; -+ -+on_exit: -+ free_elf_info(&ehdr); -+ return result; -+} -+ -+int elf_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info) -+{ -+ int result; -+ struct mem_ehdr ehdr; -+ bool found_header; -+ int i; -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ fprintf(stderr, "kexec: kdump not yet supported on arm64\n"); -+ return -EINVAL; -+ } -+ -+ result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); -+ -+ if (result < 0) { -+ dbgprintf("%s: build_elf_exec_info failed\n", __func__); -+ goto exit; -+ } -+ -+ /* Find and process the arm64 image header. */ -+ -+ for (i = 0, found_header = false; i < ehdr.e_phnum; i++) { -+ struct mem_phdr *phdr = &ehdr.e_phdr[i]; -+ const struct arm64_image_header *h; -+ -+ if (phdr->p_type != PT_LOAD) -+ continue; -+ -+ h = (const struct arm64_image_header *)(kernel_buf -+ + phdr->p_offset); -+ -+ if (arm64_process_image_header(h)) -+ continue; -+ -+ found_header = true; -+ -+ arm64_mem.page_offset = phdr->p_vaddr - arm64_mem.text_offset; -+ -+ dbgprintf("%s: PE format: %s\n", __func__, -+ (arm64_header_check_pe_sig(h) ? "yes" : "no")); -+ dbgprintf("p_vaddr: %016llx\n", phdr->p_vaddr); -+ -+ break; -+ } -+ -+ if (!found_header) { -+ fprintf(stderr, "kexec: Bad arm64 image header.\n"); -+ result = -EINVAL; -+ goto exit; -+ } -+ -+ result = elf_exec_load(&ehdr, info); -+ -+ if (result) { -+ fprintf(stderr, "kexec: Elf load failed.\n"); -+ goto exit; -+ } -+ -+ dbgprintf("%s: text_offset: %016lx\n", __func__, arm64_mem.text_offset); -+ dbgprintf("%s: image_size: %016lx\n", __func__, arm64_mem.image_size); -+ dbgprintf("%s: page_offset: %016lx\n", __func__, arm64_mem.page_offset); -+ dbgprintf("%s: memstart: %016lx\n", __func__, arm64_mem.memstart); -+ dbgprintf("%s: e_entry: %016llx -> %016lx\n", __func__, -+ ehdr.e_entry, virt_to_phys(ehdr.e_entry)); -+ -+ result = arm64_load_other_segments(info, virt_to_phys(ehdr.e_entry)); -+exit: -+ free_elf_info(&ehdr); -+ return result; -+} -+ -+void elf_arm64_usage(void) -+{ -+ printf( -+" An arm64 ELF file, big or little endian.\n" -+" Typically vmlinux or a stripped version of vmlinux.\n\n"); -+} -diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c -new file mode 100644 -index 000000000000..b025dc6c0185 ---- /dev/null -+++ b/kexec/arch/arm64/kexec-image-arm64.c -@@ -0,0 +1,50 @@ -+/* -+ * ARM64 kexec binary image support. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+ -+#include "dt-ops.h" -+#include "image-header.h" -+#include "kexec-arm64.h" -+#include "fs2dt.h" -+#include "kexec-syscall.h" -+#include "arch/options.h" -+ -+int image_arm64_probe(const char *kernel_buf, off_t kernel_size) -+{ -+ const struct arm64_image_header *h; -+ -+ if (kernel_size < sizeof(struct arm64_image_header)) -+ return -EINVAL; -+ -+ h = (const struct arm64_image_header *)(kernel_buf); -+ -+ if (!arm64_header_check_magic(h)) -+ return -1; -+ -+ dbgprintf("%s: PE format: %s\n", __func__, -+ (arm64_header_check_pe_sig(h) ? "yes" : "no")); -+ -+ fprintf(stderr, "kexec: arm64 binary Image files are currently NOT SUPPORTED.\n"); -+ -+ return -1; -+} -+ -+int image_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info) -+{ -+ return -ENOSYS; -+} -+ -+void image_arm64_usage(void) -+{ -+ printf( -+" An arm64 binary Image file, big or little endian.\n" -+" This file type is currently NOT SUPPORTED.\n\n"); -+} -diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h -index ce2e20b8b04b..267b75b02272 100644 ---- a/kexec/kexec-syscall.h -+++ b/kexec/kexec-syscall.h -@@ -39,8 +39,8 @@ - #ifdef __s390__ - #define __NR_kexec_load 277 - #endif --#ifdef __arm__ --#define __NR_kexec_load __NR_SYSCALL_BASE + 347 -+#if defined(__arm__) || defined(__arm64__) -+#define __NR_kexec_load __NR_SYSCALL_BASE + 347 - #endif - #if defined(__mips__) - #define __NR_kexec_load 4311 -@@ -108,6 +108,8 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, - #define KEXEC_ARCH_PPC64 (21 << 16) - #define KEXEC_ARCH_IA_64 (50 << 16) - #define KEXEC_ARCH_ARM (40 << 16) -+#define KEXEC_ARCH_ARM64 (183 << 16) -+/* #define KEXEC_ARCH_AARCH64 (183 << 16) */ - #define KEXEC_ARCH_S390 (22 << 16) - #define KEXEC_ARCH_SH (42 << 16) - #define KEXEC_ARCH_MIPS_LE (10 << 16) -@@ -153,5 +155,8 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, - #ifdef __m68k__ - #define KEXEC_ARCH_NATIVE KEXEC_ARCH_68K - #endif -+#if defined(__arm64__) -+#define KEXEC_ARCH_NATIVE KEXEC_ARCH_ARM64 -+#endif - - #endif /* KEXEC_SYSCALL_H */ -diff --git a/purgatory/Makefile b/purgatory/Makefile -index 19457029e79f..0c85da6e29b8 100644 ---- a/purgatory/Makefile -+++ b/purgatory/Makefile -@@ -18,6 +18,7 @@ dist += purgatory/Makefile $(PURGATORY_SRCS) \ - - include $(srcdir)/purgatory/arch/alpha/Makefile - include $(srcdir)/purgatory/arch/arm/Makefile -+include $(srcdir)/purgatory/arch/arm64/Makefile - include $(srcdir)/purgatory/arch/i386/Makefile - include $(srcdir)/purgatory/arch/ia64/Makefile - include $(srcdir)/purgatory/arch/mips/Makefile -diff --git a/purgatory/arch/arm64/Makefile b/purgatory/arch/arm64/Makefile -new file mode 100644 -index 000000000000..636abeab17b2 ---- /dev/null -+++ b/purgatory/arch/arm64/Makefile -@@ -0,0 +1,18 @@ -+ -+arm64_PURGATORY_EXTRA_CFLAGS = \ -+ -mcmodel=large \ -+ -fno-stack-protector \ -+ -fno-asynchronous-unwind-tables \ -+ -Wundef \ -+ -Werror-implicit-function-declaration \ -+ -Wdeclaration-after-statement \ -+ -Werror=implicit-int \ -+ -Werror=strict-prototypes -+ -+arm64_PURGATORY_SRCS += \ -+ purgatory/arch/arm64/entry.S \ -+ purgatory/arch/arm64/purgatory-arm64.c -+ -+dist += \ -+ $(arm64_PURGATORY_SRCS) \ -+ purgatory/arch/arm64/Makefile -diff --git a/purgatory/arch/arm64/entry.S b/purgatory/arch/arm64/entry.S -new file mode 100644 -index 000000000000..140e91d87ab1 ---- /dev/null -+++ b/purgatory/arch/arm64/entry.S -@@ -0,0 +1,54 @@ -+/* -+ * ARM64 purgatory. -+ */ -+ -+.macro debug_brk -+ mov x0, #0x18; /* angel_SWIreason_ReportException */ -+ mov x1, #0x20000; -+ add x1, x1, #0x20; /* ADP_Stopped_BreakPoint */ -+ hlt #0xf000 /* A64 semihosting */ -+.endm -+ -+.macro size, sym:req -+ .size \sym, . - \sym -+.endm -+ -+.text -+ -+.globl purgatory_start -+purgatory_start: -+ -+ adr x19, .Lstack -+ mov sp, x19 -+ -+ bl purgatory -+ -+1: debug_brk -+ b 1b -+ -+size purgatory_start -+ -+.align 4 -+ .rept 256 -+ .quad 0 -+ .endr -+.Lstack: -+ -+.data -+ -+.align 3 -+ -+.globl arm64_sink -+arm64_sink: -+ .quad 0 -+size arm64_sink -+ -+.globl arm64_kernel_entry -+arm64_kernel_entry: -+ .quad 0 -+size arm64_kernel_entry -+ -+.globl arm64_dtb_addr -+arm64_dtb_addr: -+ .quad 0 -+size arm64_dtb_addr -diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c -new file mode 100644 -index 000000000000..25960c30bd05 ---- /dev/null -+++ b/purgatory/arch/arm64/purgatory-arm64.c -@@ -0,0 +1,35 @@ -+/* -+ * ARM64 purgatory. -+ */ -+ -+#include -+#include -+ -+/* Symbols set by kexec. */ -+ -+extern uint32_t *arm64_sink; -+extern void (*arm64_kernel_entry)(uint64_t); -+extern uint64_t arm64_dtb_addr; -+ -+void putchar(int ch) -+{ -+ if (!arm64_sink) -+ return; -+ -+ *arm64_sink = ch; -+ -+ if (ch == '\n') -+ *arm64_sink = '\r'; -+} -+ -+void setup_arch(void) -+{ -+ printf("purgatory: kernel_entry: %lx\n", -+ (unsigned long)arm64_kernel_entry); -+ printf("purgatory: dtb: %lx\n", arm64_dtb_addr); -+} -+ -+void post_verification_setup_arch(void) -+{ -+ arm64_kernel_entry(arm64_dtb_addr); -+} --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Add-enable-disable-d-cache-support-for-purgato.patch b/SOURCES/kexec-tools-2.0.8-arm64-Add-enable-disable-d-cache-support-for-purgato.patch deleted file mode 100644 index 9a65476..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Add-enable-disable-d-cache-support-for-purgato.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 8b40614f4c1925fe94f274dfc69d1a63537fe399 Mon Sep 17 00:00:00 2001 -Message-Id: <8b40614f4c1925fe94f274dfc69d1a63537fe399.1430751022.git.panand@redhat.com> -From: Pratyush Anand -Date: Mon, 4 May 2015 17:43:25 +0530 -Subject: [PATCH 1/3] arm64: Add enable/disable d-cache support for purgatory - -This patch adds support to enable/disable d-cache, which can be used for -faster purgatory sha256 verification. - -Signed-off-by: Pratyush Anand ---- - purgatory/arch/arm64/Makefile | 1 + - purgatory/arch/arm64/cache.S | 222 ++++++++++++++++++++++++++++++++++++++++++ - purgatory/arch/arm64/cache.h | 42 ++++++++ - 3 files changed, 265 insertions(+) - create mode 100644 purgatory/arch/arm64/cache.S - create mode 100644 purgatory/arch/arm64/cache.h - -diff --git a/purgatory/arch/arm64/Makefile b/purgatory/arch/arm64/Makefile -index 5d35161fc5f4..04fef16476fb 100644 ---- a/purgatory/arch/arm64/Makefile -+++ b/purgatory/arch/arm64/Makefile -@@ -12,6 +12,7 @@ arm64_PURGATORY_EXTRA_CFLAGS = \ - - arm64_PURGATORY_SRCS += \ - purgatory/arch/arm64/entry.S \ -+ purgatory/arch/arm64/cache.S \ - purgatory/arch/arm64/purgatory-arm64.c - - dist += \ -diff --git a/purgatory/arch/arm64/cache.S b/purgatory/arch/arm64/cache.S -new file mode 100644 -index 000000000000..6bbdeacdab47 ---- /dev/null -+++ b/purgatory/arch/arm64/cache.S -@@ -0,0 +1,222 @@ -+/* -+ * Cache maintenance -+ * Some of the routine has been copied from Linux Kernel, therefore -+ * copying the license as well. -+ * -+ * Copyright (C) 2001 Deep Blue Solutions Ltd. -+ * Copyright (C) 2012 ARM Ltd. -+ * Copyright (C) 2015 Pratyush Anand -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include "cache.h" -+ -+/* -+ * dcache_line_size - get the minimum D-cache line size from the CTR register. -+ */ -+ .macro dcache_line_size, reg, tmp -+ mrs \tmp, ctr_el0 // read CTR -+ ubfm \tmp, \tmp, #16, #19 // cache line size encoding -+ mov \reg, #4 // bytes per word -+ lsl \reg, \reg, \tmp // actual cache line size -+ .endm -+ -+/* -+ * __inval_cache_range(start, end) -+ * - start - start address of region -+ * - end - end address of region -+ */ -+__inval_cache_range: -+ dcache_line_size x2, x3 -+ sub x3, x2, #1 -+ tst x1, x3 // end cache line aligned? -+ bic x1, x1, x3 -+ b.eq 1f -+ dc civac, x1 // clean & invalidate D / U line -+1: tst x0, x3 // start cache line aligned? -+ bic x0, x0, x3 -+ b.eq 2f -+ dc civac, x0 // clean & invalidate D / U line -+ b 3f -+2: dc ivac, x0 // invalidate D / U line -+3: add x0, x0, x2 -+ cmp x0, x1 -+ b.lo 2b -+ dsb sy -+ ret -+/* -+ * __flush_dcache_range(start, end) -+ * - start - start address of region -+ * - end - end address of region -+ * -+ */ -+__flush_dcache_range: -+ dcache_line_size x2, x3 -+ sub x3, x2, #1 -+ bic x0, x0, x3 -+1: dc civac, x0 // clean & invalidate D line / unified line -+ add x0, x0, x2 -+ cmp x0, x1 -+ b.lo 1b -+ dsb sy -+ ret -+ -+/* -+ * enable_dcache(start, end, page_table) -+ * - start - start address of ram -+ * - end - end address of ram -+ * - page_table - base of page table -+ */ -+.globl enable_dcache -+enable_dcache: -+ stp x6, x7, [sp,#-16]! -+ stp x16, x17, [sp,#-16]! -+ stp x18, x19, [sp,#-16]! -+ -+ /* save args */ -+ mov x16, x0 /* first segment start */ -+ mov x17, x1 /* last segment end */ -+ mov x18, x2 /* page table */ -+ mov x19, x30 /* save ret addr */ -+ -+ /* -+ * Invalidate the page tables to avoid potential -+ * dirty cache lines being evicted. -+ */ -+ mov x0, x18 -+ add x1, x0, #PAGE_TABLE_SIZE -+ bl __inval_cache_range -+ -+ /* -+ * Clear the page tables. -+ */ -+ mov x0, x18 -+ add x1, x0, #PAGE_TABLE_SIZE -+1: stp xzr, xzr, [x0], #16 -+ stp xzr, xzr, [x0], #16 -+ stp xzr, xzr, [x0], #16 -+ stp xzr, xzr, [x0], #16 -+ cmp x0, x1 -+ b.lo 1b -+ -+ /* -+ * Create the identity mapping. -+ */ -+ ldr x6, =SECTION_SHIFT -+ ldr x7, =MM_MMUFLAGS -+ lsr x0, x16, x6 //first index -+ lsr x1, x17, x6 //last index -+ -+next_sect: -+ lsl x2, x0, x6 //section -+ orr x2, x2, x7 -+ str x2, [x18, x0, lsl #3] -+ add x0, x0, #1 -+ cmp x0, x1 -+ b.ls next_sect -+ -+ /* -+ * Since the page tables have been populated with non-cacheable -+ * accesses (MMU disabled), invalidate the idmap page -+ * tables again to remove any speculatively loaded cache lines. -+ */ -+ mov x0, x18 -+ add x1, x0, #PAGE_TABLE_SIZE -+ bl __inval_cache_range -+ -+ mrs x0, CurrentEL -+ cmp x0, #12 //EL3 -+ b.eq set_el3 -+ cmp x0, #8 //EL2 -+ b.eq set_el2 -+ cmp x0, #4 //EL1 -+ b.eq set_el1 -+ b done_enable -+ -+set_el1: -+ msr ttbr0_el1, x18 -+ ldr x0, =TCR_FLAGS -+ orr x0, x0, #TCR_EL1_IPS_BITS -+ msr tcr_el1, x0 -+ ldr x0, =MEMORY_ATTRIBUTES -+ msr mair_el1, x0 -+ mrs x0, sctlr_el1 -+ orr x0, x0, #CR_M -+ orr x0, x0, #CR_C -+ msr sctlr_el1, x0 -+ b done_enable -+set_el2: -+ msr ttbr0_el2, x18 -+ ldr x0, =TCR_FLAGS -+ orr x0, x0, #TCR_EL2_IPS_BITS -+ msr tcr_el2, x0 -+ ldr x0, =MEMORY_ATTRIBUTES -+ msr mair_el2, x0 -+ mrs x0, sctlr_el2 -+ orr x0, x0, #CR_M -+ orr x0, x0, #CR_C -+ msr sctlr_el2, x0 -+ b done_enable -+set_el3: -+ msr ttbr0_el3, x18 -+ ldr x0, =TCR_FLAGS -+ orr x0, x0, #TCR_EL3_IPS_BITS -+ msr tcr_el3, x0 -+ ldr x0, =MEMORY_ATTRIBUTES -+ msr mair_el3, x0 -+ mrs x0, sctlr_el3 -+ orr x0, x0, #CR_M -+ orr x0, x0, #CR_C -+ msr sctlr_el3, x0 -+done_enable: -+ -+ mov x30, x19 -+ ldp x18, x19, [sp],#16 -+ ldp x16, x17, [sp],#16 -+ ldp x6, x7, [sp],#16 -+ -+ ret -+ -+.globl disable_dcache -+disable_dcache: -+ stp x5, x30, [sp,#-16]! -+ mrs x5, CurrentEL -+ cmp x5, #12 //EL3 -+ b.eq disable_el3 -+ cmp x5, #8 //EL2 -+ b.eq disable_el2 -+ cmp x5, #4 //EL1 -+ b.eq disable_el1 -+ b done_disable -+disable_el3: -+ mrs x5, sctlr_el3 -+ bic x5, x2, #CR_M -+ bic x5, x2, #CR_C -+ msr sctlr_el3, x5 -+ b done_disable -+disable_el2: -+ mrs x5, sctlr_el2 -+ bic x5, x2, #CR_M -+ bic x5, x2, #CR_C -+ msr sctlr_el2, x5 -+ b done_disable -+disable_el1: -+ mrs x5, sctlr_el1 -+ bic x5, x2, #CR_M -+ bic x5, x2, #CR_C -+ msr sctlr_el1, x5 -+done_disable: -+ bl __flush_dcache_range -+ ldp x5, x30, [sp],#16 -+ ret -diff --git a/purgatory/arch/arm64/cache.h b/purgatory/arch/arm64/cache.h -new file mode 100644 -index 000000000000..3ca1d7f9a5ca ---- /dev/null -+++ b/purgatory/arch/arm64/cache.h -@@ -0,0 +1,42 @@ -+#ifndef __CACHE_H__ -+#define __CACHE_H__ -+ -+#define VA_BITS 42 -+#define SECTION_SHIFT 29 -+#define PAGE_TABLE_SIZE (1 << (VA_BITS - SECTION_SHIFT + 3)) -+ -+#define TCR_TG0_64K (1 << 14) -+#define TCR_SHARED_NON (0 << 12) -+#define TCR_ORGN_WBWA (1 << 10) -+#define TCR_IRGN_WBWA (1 << 8) -+#define TCR_T0SZ(x) ((64 - (x)) << 0) -+#define TCR_EL1_IPS_BITS (3 << 32) /* 42 bits physical address */ -+#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ -+#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */ -+ -+#define TCR_FLAGS (TCR_TG0_64K | TCR_SHARED_NON | TCR_ORGN_WBWA | \ -+ TCR_IRGN_WBWA | TCR_T0SZ(VA_BITS)) -+ -+#define MT_DEVICE_NGNRNE 0 -+#define MT_DEVICE_NGNRE 1 -+#define MT_DEVICE_GRE 2 -+#define MT_NORMAL_NC 3 -+#define MT_NORMAL 4 -+ -+#define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE*8)) | \ -+ (0x04 << (MT_DEVICE_NGNRE*8)) | \ -+ (0x0c << (MT_DEVICE_GRE*8)) | \ -+ (0x44 << (MT_NORMAL_NC*8)) | \ -+ (0xff << (MT_NORMAL*8))) -+ -+#define CR_M (1 << 0) /* MMU enable */ -+#define CR_C (1 << 2) /* Dcache enable */ -+ -+ -+#define PMD_TYPE_SECT (1 << 0) -+#define PMD_SECT_AF (1 << 10) -+#define PMD_ATTRINDX(t) ((t) << 2) -+#define PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF) -+#define MM_MMUFLAGS PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS -+ -+#endif --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-kexec-lite-option.patch b/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-kexec-lite-option.patch deleted file mode 100644 index 04baeb6..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-kexec-lite-option.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d665fa8c7cb6fa6713bad2633b9cccbad98245bc Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Geoff Levand -Date: Fri, 17 Apr 2015 10:54:55 -0700 -Subject: [PATCH 04/17] arm64: Add support for kexec --lite option - -WARNING: This implementation uses kernel feature not yet merged upstream. In -the future I may convert this to use a minimal purgatory that is just a -trampoline. ---- - kexec/arch/arm64/include/arch/options.h | 2 +- - kexec/arch/arm64/kexec-arm64.c | 8 +++----- - 2 files changed, 4 insertions(+), 6 deletions(-) - -diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h -index 903b4a1fbd7f..afe3e9827ff3 100644 ---- a/kexec/arch/arm64/include/arch/options.h -+++ b/kexec/arch/arm64/include/arch/options.h -@@ -29,7 +29,7 @@ static const char arm64_opts_usage[] __attribute__ ((unused)) = - " --command-line=STRING Set the kernel command line to STRING.\n" - " --dtb=FILE Use FILE as the device tree blob.\n" - " --initrd=FILE Use FILE as the kernel initial ramdisk.\n" --" --lite Fast reboot, no memory integrity checks - currently NOT SUPPORTED.\n"); -+" --lite Fast reboot, no memory integrity checks.\n" - " --port=ADDRESS Purgatory output to port ADDRESS.\n" - " --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n" - " --reuse-cmdline Use command line arg of primary kernel.\n"; -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 22d70244f8db..6398e55fe575 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -96,7 +96,6 @@ int arch_process_options(int argc, char **argv) - break; - case OPT_LITE: - arm64_opts.lite = 1; -- fprintf(stderr, "kexec: --lite option currently NOT SUPPORTED.\n"); - break; - case OPT_PORT: - arm64_opts.port = strtoull(optarg, NULL, 0); -@@ -702,10 +701,9 @@ int arm64_load_other_segments(struct kexec_info *info, - add_segment_phys_virt(info, initrd_buf, initrd_size, - initrd_base, initrd_size, 0); - -- if (arm64_opts.lite) { -- fprintf(stderr, "kexec: --lite option currently NOT SUPPORTED.\n"); -- return -ENOSYS; -- } else { -+ if (arm64_opts.lite) -+ info->entry = (void *)kernel_entry; -+ else { - result = build_elf_rel_info(purgatory, purgatory_size, &ehdr, - 0); - --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-reuse-cmdline-option.patch b/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-reuse-cmdline-option.patch deleted file mode 100644 index 52ba3c3..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Add-support-for-reuse-cmdline-option.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0730d377b6a6f6cdac25f26016a95db8a9333802 Mon Sep 17 00:00:00 2001 -Message-Id: <0730d377b6a6f6cdac25f26016a95db8a9333802.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Pratyush Anand -Date: Fri, 17 Apr 2015 10:54:55 -0700 -Subject: [PATCH 03/17] arm64: Add support for --reuse-cmdline option - -Signed-off-by: Pratyush Anand -Signed-off-by: Geoff Levand ---- - kexec/arch/arm64/include/arch/options.h | 7 +++++-- - kexec/arch/arm64/kexec-arm64.c | 8 +++++++- - 2 files changed, 12 insertions(+), 3 deletions(-) - -diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h -index 51afc5f1f6f2..903b4a1fbd7f 100644 ---- a/kexec/arch/arm64/include/arch/options.h -+++ b/kexec/arch/arm64/include/arch/options.h -@@ -6,7 +6,8 @@ - #define OPT_INITRD ((OPT_MAX)+2) - #define OPT_LITE ((OPT_MAX)+3) - #define OPT_PORT ((OPT_MAX)+4) --#define OPT_ARCH_MAX ((OPT_MAX)+5) -+#define OPT_REUSE_CMDLINE ((OPT_MAX+5)) -+#define OPT_ARCH_MAX ((OPT_MAX)+6) - - #define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ -@@ -17,6 +18,7 @@ - { "lite", 0, NULL, OPT_LITE }, \ - { "port", 1, NULL, OPT_PORT }, \ - { "ramdisk", 1, NULL, OPT_INITRD }, \ -+ { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ - - #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */ - #define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS -@@ -29,7 +31,8 @@ static const char arm64_opts_usage[] __attribute__ ((unused)) = - " --initrd=FILE Use FILE as the kernel initial ramdisk.\n" - " --lite Fast reboot, no memory integrity checks - currently NOT SUPPORTED.\n"); - " --port=ADDRESS Purgatory output to port ADDRESS.\n" --" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n"; -+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n" -+" --reuse-cmdline Use command line arg of primary kernel.\n"; - - struct arm64_opts { - const char *command_line; -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 0860810b6e86..22d70244f8db 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -75,13 +75,18 @@ int arch_process_options(int argc, char **argv) - { 0 } - }; - int opt; -+ const char *append = NULL; -+ char *tmp_cmdline = NULL; - - for (opt = 0; opt != -1; ) { - opt = getopt_long(argc, argv, short_options, options, 0); - - switch (opt) { - case OPT_APPEND: -- arm64_opts.command_line = optarg; -+ append = optarg; -+ break; -+ case OPT_REUSE_CMDLINE: -+ tmp_cmdline = get_command_line(); - break; - case OPT_DTB: - arm64_opts.dtb = optarg; -@@ -101,6 +106,7 @@ int arch_process_options(int argc, char **argv) - } - } - -+ arm64_opts.command_line = concat_cmdline(tmp_cmdline, append); - kexec_debug = 1; // FIXME: for debugging only. - - dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Enable-disable-D-cache-before-after-sha-verifi.patch b/SOURCES/kexec-tools-2.0.8-arm64-Enable-disable-D-cache-before-after-sha-verifi.patch deleted file mode 100644 index e21d5ae..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Enable-disable-D-cache-before-after-sha-verifi.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2939844d0211a820cf22a8d666df90af889ec6f1 Mon Sep 17 00:00:00 2001 -Message-Id: <2939844d0211a820cf22a8d666df90af889ec6f1.1430751022.git.panand@redhat.com> -In-Reply-To: <8b40614f4c1925fe94f274dfc69d1a63537fe399.1430751022.git.panand@redhat.com> -References: <8b40614f4c1925fe94f274dfc69d1a63537fe399.1430751022.git.panand@redhat.com> -From: Pratyush Anand -Date: Mon, 4 May 2015 17:50:21 +0530 -Subject: [PATCH 3/3] arm64: Enable/disable D-cache before/after sha - verification - -Enable D cache before SHA verification and disable it before switching -to kernel. - -Since we only map RAM area, therefore currently no printf is allowed -between d-cache enable and disable events. Identity mapping for port -area with device type memory attributes need to be created for printf to -work. - -Signed-off-by: Pratyush Anand ---- - purgatory/arch/arm64/purgatory-arm64.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c -index 3a1c9243bfa2..e045039039b6 100644 ---- a/purgatory/arch/arm64/purgatory-arm64.c -+++ b/purgatory/arch/arm64/purgatory-arm64.c -@@ -2,6 +2,7 @@ - * ARM64 purgatory. - */ - -+#include "cache.h" - #include - #include - -@@ -10,6 +11,8 @@ - extern uint32_t *arm64_sink; - extern void (*arm64_kernel_entry)(uint64_t); - extern uint64_t arm64_dtb_addr; -+extern uint64_t arm64_ram_start; -+extern uint64_t arm64_ram_end; - - static void wait_for_xmit_complete(void) - { -@@ -44,14 +47,23 @@ void putchar(int ch) - } - } - -+uint64_t page_table[PAGE_TABLE_SIZE / sizeof(uint64_t)] __attribute__ ((aligned (PAGE_TABLE_SIZE))) = { }; -+extern void enable_dcache(uint64_t , uint64_t , uint64_t *); -+extern void disable_dcache(uint64_t , uint64_t); -+ - void setup_arch(void) - { - printf("purgatory: kernel_entry: %lx\n", - (unsigned long)arm64_kernel_entry); - printf("purgatory: dtb: %lx\n", arm64_dtb_addr); -+ printf("purgatory: RAM start: %lx\n", arm64_ram_start); -+ printf("purgatory: RAM end: %lx\n", arm64_ram_end); -+ -+ enable_dcache(arm64_ram_start, arm64_ram_end, page_table); - } - - void post_verification_setup_arch(void) - { -+ disable_dcache(arm64_ram_start, arm64_ram_end); - arm64_kernel_entry(arm64_dtb_addr); - } --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Kexec-Add-support-for-binary-image.patch b/SOURCES/kexec-tools-2.0.8-arm64-Kexec-Add-support-for-binary-image.patch deleted file mode 100644 index 1461967..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Kexec-Add-support-for-binary-image.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 6dd781cca908aea5f282b5c980d806c2f35ea171 Mon Sep 17 00:00:00 2001 -Message-Id: <6dd781cca908aea5f282b5c980d806c2f35ea171.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Pratyush Anand -Date: Mon, 13 Apr 2015 17:19:49 +0530 -Subject: [PATCH 05/17] arm64: Kexec: Add support for binary image - -This patch adds support to use binary image ie arch/arm64/boot/Image. - -Binary image does not have sufficient knowledge to extract page offset -information, which is needed by kexec tool. Use a new command parameter ---page-offset, so that user can provide page offset information for -linear mapping. - -Signed-off-by: Pratyush Anand ---- - kexec/arch/arm64/include/arch/options.h | 9 ++-- - kexec/arch/arm64/kexec-arm64.c | 3 ++ - kexec/arch/arm64/kexec-arm64.h | 2 + - kexec/arch/arm64/kexec-image-arm64.c | 86 +++++++++++++++++++++++++++++++-- - 4 files changed, 93 insertions(+), 7 deletions(-) - -diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h -index afe3e9827ff3..fa4ad2c68642 100644 ---- a/kexec/arch/arm64/include/arch/options.h -+++ b/kexec/arch/arm64/include/arch/options.h -@@ -5,9 +5,10 @@ - #define OPT_DTB ((OPT_MAX)+1) - #define OPT_INITRD ((OPT_MAX)+2) - #define OPT_LITE ((OPT_MAX)+3) --#define OPT_PORT ((OPT_MAX)+4) --#define OPT_REUSE_CMDLINE ((OPT_MAX+5)) --#define OPT_ARCH_MAX ((OPT_MAX)+6) -+#define OPT_PAGE_OFFSET ((OPT_MAX)+4) -+#define OPT_PORT ((OPT_MAX)+5) -+#define OPT_REUSE_CMDLINE ((OPT_MAX+6)) -+#define OPT_ARCH_MAX ((OPT_MAX)+7) - - #define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ -@@ -16,6 +17,7 @@ - { "dtb", 1, NULL, OPT_DTB }, \ - { "initrd", 1, NULL, OPT_INITRD }, \ - { "lite", 0, NULL, OPT_LITE }, \ -+ { "page-offset", 1, NULL, OPT_PAGE_OFFSET }, \ - { "port", 1, NULL, OPT_PORT }, \ - { "ramdisk", 1, NULL, OPT_INITRD }, \ - { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ -@@ -38,6 +40,7 @@ struct arm64_opts { - const char *command_line; - const char *dtb; - const char *initrd; -+ uint64_t page_offset; - uint64_t port; - int lite; - }; -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 6398e55fe575..86408598a465 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -100,6 +100,9 @@ int arch_process_options(int argc, char **argv) - case OPT_PORT: - arm64_opts.port = strtoull(optarg, NULL, 0); - break; -+ case OPT_PAGE_OFFSET: -+ arm64_opts.page_offset = strtoull(optarg, NULL, 0); -+ break; - default: - break; /* Ignore core and unknown options. */ - } -diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h -index 057acf313b49..7f0ca13fec11 100644 ---- a/kexec/arch/arm64/kexec-arm64.h -+++ b/kexec/arch/arm64/kexec-arm64.h -@@ -17,6 +17,8 @@ - #define BOOT_BLOCK_LAST_COMP_VERSION 16 - #define COMMAND_LINE_SIZE 512 - -+#define ARM64_DEFAULT_PAGE_OFFSET 0xfffffe0000000000 -+ - int elf_arm64_probe(const char *kernel_buf, off_t kernel_size); - int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - off_t kernel_size, struct kexec_info *info); -diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c -index b025dc6c0185..c577b96d5e31 100644 ---- a/kexec/arch/arm64/kexec-image-arm64.c -+++ b/kexec/arch/arm64/kexec-image-arm64.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include "dt-ops.h" - #include "image-header.h" -@@ -31,20 +32,97 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size) - dbgprintf("%s: PE format: %s\n", __func__, - (arm64_header_check_pe_sig(h) ? "yes" : "no")); - -- fprintf(stderr, "kexec: arm64 binary Image files are currently NOT SUPPORTED.\n"); -+ return 0; -+} -+ -+static unsigned long long get_kernel_text_sym(void) -+{ -+ const char *kallsyms = "/proc/kallsyms"; -+ const char *text = "_text"; -+ char sym[128]; -+ char line[128]; -+ FILE *fp; -+ unsigned long long vaddr; -+ char type; - -- return -1; -+ fp = fopen(kallsyms, "r"); if (!fp) { -+ fprintf(stderr, "Cannot open %s\n", kallsyms); -+ return 0; -+ } -+ -+ while(fgets(line, sizeof(line), fp) != NULL) { -+ if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3) -+ continue; -+ if (strcmp(sym, text) == 0) { -+ dbgprintf("kernel symbol %s vaddr = %16llx\n", text, vaddr); -+ return vaddr; -+ } -+ } -+ -+ fprintf(stderr, "Cannot get kernel %s symbol address\n", text); -+ return 0; -+} -+ -+static unsigned long long get_kernel_page_offset(void) -+{ -+ unsigned long long text_sym_addr = get_kernel_text_sym(); -+ unsigned long long text_page_offset = -+ text_sym_addr & 0xFFFFFFFFFFE00000; -+ -+ if(arm64_opts.page_offset) { -+ if (text_page_offset != arm64_opts.page_offset) -+ dbgprintf("User page offset %lx did not match with text page offset %llx\n", -+ arm64_opts.page_offset, text_page_offset); -+ return arm64_opts.page_offset; -+ } else if(text_page_offset) { -+ dbgprintf("text page offset is %llx\n", text_page_offset); -+ return text_page_offset; -+ } else { -+ return ARM64_DEFAULT_PAGE_OFFSET; -+ } - } - - int image_arm64_load(int argc, char **argv, const char *kernel_buf, - off_t kernel_size, struct kexec_info *info) - { -- return -ENOSYS; -+ int result; -+ uint64_t start; -+ const struct arm64_image_header *h; -+ char *header_option = NULL; -+ -+ h = (const struct arm64_image_header *)(kernel_buf); -+ -+ arm64_mem.text_offset = le64_to_cpu(h->text_offset); -+ arm64_mem.image_size = le64_to_cpu(h->image_size); -+ -+ arm64_mem.page_offset = get_kernel_page_offset(); -+ -+ result = parse_iomem_single("Kernel code\n", &start, NULL); -+ -+ if (result) { -+ fprintf(stderr, "kexec: Could not get kernel code address.\n"); -+ return -1; -+ } -+ start -= arm64_mem.text_offset; -+ -+ /* Add kernel */ -+ add_segment_phys_virt(info, kernel_buf, kernel_size, -+ start + arm64_mem.text_offset, -+ kernel_size, 0); -+ -+ info->entry = (void *)start + arm64_mem.text_offset; -+ -+ result = arm64_load_other_segments(info, (unsigned long)info->entry); -+ -+ if (header_option) -+ free(header_option); -+ -+ return result; - } - - void image_arm64_usage(void) - { - printf( - " An arm64 binary Image file, big or little endian.\n" --" This file type is currently NOT SUPPORTED.\n\n"); -+" --page-offset Kernel page-offset for binary image load.\n"); - } --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-Pass-RAM-boundary-to-purgatory.patch b/SOURCES/kexec-tools-2.0.8-arm64-Pass-RAM-boundary-to-purgatory.patch deleted file mode 100644 index 424beaa..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-Pass-RAM-boundary-to-purgatory.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 04a2b7bb55bfee0495cc39796846adf8d6a313bc Mon Sep 17 00:00:00 2001 -Message-Id: <04a2b7bb55bfee0495cc39796846adf8d6a313bc.1430751022.git.panand@redhat.com> -In-Reply-To: <8b40614f4c1925fe94f274dfc69d1a63537fe399.1430751022.git.panand@redhat.com> -References: <8b40614f4c1925fe94f274dfc69d1a63537fe399.1430751022.git.panand@redhat.com> -From: Pratyush Anand -Date: Mon, 4 May 2015 17:47:14 +0530 -Subject: [PATCH 2/3] arm64: Pass RAM boundary to purgatory - -RAM boundary which includes all the sections is needed for creating -identity page mapping and to enable d-cache for those areas. - -Signed-off-by: Pratyush Anand ---- - kexec/arch/arm64/include/types.h | 16 ++++++++++++++++ - kexec/arch/arm64/kexec-arm64.c | 16 +++++++++++++++- - purgatory/arch/arm64/entry.S | 10 ++++++++++ - 3 files changed, 41 insertions(+), 1 deletion(-) - create mode 100644 kexec/arch/arm64/include/types.h - -diff --git a/kexec/arch/arm64/include/types.h b/kexec/arch/arm64/include/types.h -new file mode 100644 -index 000000000000..08f833a6d585 ---- /dev/null -+++ b/kexec/arch/arm64/include/types.h -@@ -0,0 +1,16 @@ -+#ifndef _TYPES_H_ -+#define _TYPES_H_ -+ -+#define min(x,y) ({ \ -+ typeof(x) _x = (x); \ -+ typeof(y) _y = (y); \ -+ (void) (&_x == &_y); \ -+ _x < _y ? _x : _y; }) -+ -+#define max(x,y) ({ \ -+ typeof(x) _x = (x); \ -+ typeof(y) _y = (y); \ -+ (void) (&_x == &_y); \ -+ _x > _y ? _x : _y; }) -+ -+#endif /* _TYPES_H_ */ -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 12c589f8001c..8ce4a61fc9c2 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -28,6 +28,7 @@ - #include "fs2dt.h" - #include "kexec-syscall.h" - #include "arch/options.h" -+#include "types.h" - - /* Global varables the core kexec routines expect. */ - -@@ -588,9 +589,11 @@ static uint64_t read_sink(const char *command_line) - int arm64_load_other_segments(struct kexec_info *info, - unsigned long kernel_entry, char *option) - { -- int result; -+ int result, i; - struct mem_ehdr ehdr; - unsigned long dtb_base; -+ unsigned long arm64_ram_start = -1; -+ unsigned long arm64_ram_end = 0; - unsigned long hole_min, hole_max; - char *initrd_buf = NULL; - uint64_t purgatory_sink; -@@ -720,6 +723,17 @@ int arm64_load_other_segments(struct kexec_info *info, - - elf_rel_set_symbol(&info->rhdr, "arm64_dtb_addr", &dtb_base, - sizeof(dtb_base)); -+ for (i = 0; i < info->nr_segments; i++) { -+ arm64_ram_start = min(arm64_ram_start, -+ (unsigned long)info->segment[i].mem); -+ arm64_ram_end = max(arm64_ram_end, -+ ((unsigned long)info->segment[i].mem + -+ info->segment[i].memsz)); -+ } -+ elf_rel_set_symbol(&info->rhdr, "arm64_ram_start", -+ &arm64_ram_start, sizeof(arm64_ram_start)); -+ elf_rel_set_symbol(&info->rhdr, "arm64_ram_end", -+ &arm64_ram_end, sizeof(arm64_ram_end)); - } - - return 0; -diff --git a/purgatory/arch/arm64/entry.S b/purgatory/arch/arm64/entry.S -index 140e91d87ab1..0713ccdec4ad 100644 ---- a/purgatory/arch/arm64/entry.S -+++ b/purgatory/arch/arm64/entry.S -@@ -52,3 +52,13 @@ size arm64_kernel_entry - arm64_dtb_addr: - .quad 0 - size arm64_dtb_addr -+ -+.globl arm64_ram_start -+arm64_ram_start: -+ .quad 0 -+size arm64_ram_start -+ -+.globl arm64_ram_end -+arm64_ram_end: -+ .quad 0 -+size arm64_ram_end --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-clean-up-on-crash-dump.patch b/SOURCES/kexec-tools-2.0.8-arm64-clean-up-on-crash-dump.patch deleted file mode 100644 index c2af525..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-clean-up-on-crash-dump.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 359dec003b758e4d950de965f76ecaf6d81c007d Mon Sep 17 00:00:00 2001 -Message-Id: <359dec003b758e4d950de965f76ecaf6d81c007d.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Wed, 22 Apr 2015 11:20:27 +0900 -Subject: [PATCH 12/17] arm64: clean up on crash dump - ---- - kexec/arch/arm64/crashdump-arm64.c | 12 +++--------- - kexec/arch/arm64/crashdump-arm64.h | 6 +++--- - kexec/arch/arm64/kexec-elf-arm64.c | 9 +++++---- - 3 files changed, 11 insertions(+), 16 deletions(-) - -diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c -index 04958418ae82..a929b9e3ecb1 100644 ---- a/kexec/arch/arm64/crashdump-arm64.c -+++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -288,7 +288,7 @@ int load_crashdump_segments(struct kexec_info *info, char **option) - return 0; - } - --void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr) -+void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr) - { - struct mem_phdr *phdr; - int i; -@@ -304,13 +304,7 @@ void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr) - } - } - --void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info) -+void *get_crash_entry(void) - { -- info->entry = (void *)crash_reserved_mem.start + arm64_mem.text_offset; --} -- --off_t locate_dtb_in_crashmem(struct kexec_info *info, off_t dtb_size) --{ -- return locate_hole(info, dtb_size, 128UL * 1024, -- crash_reserved_mem.start, crash_reserved_mem.end, -1); -+ return (void *)crash_reserved_mem.start + arm64_mem.text_offset; - } -diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h -index d4fd3f2288c9..6457ea7cabec 100644 ---- a/kexec/arch/arm64/crashdump-arm64.h -+++ b/kexec/arch/arm64/crashdump-arm64.h -@@ -17,10 +17,10 @@ - #define CRASH_MAX_MEMORY_RANGES 32 - - extern struct memory_ranges usablemem_rgns; -+extern struct memory_range crash_reserved_mem; - - int load_crashdump_segments(struct kexec_info *info, char **option); --void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr); --void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info); --off_t locate_dtb_in_crashmem(struct kexec_info *info, off_t dtb_size); -+void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr); -+void *get_crash_entry(void); - - #endif -diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c -index f5ecda825278..9fda5e539471 100644 ---- a/kexec/arch/arm64/kexec-elf-arm64.c -+++ b/kexec/arch/arm64/kexec-elf-arm64.c -@@ -93,16 +93,17 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - } - - if (info->kexec_flags & KEXEC_ON_CRASH) { -+ /* allocate and initialize elf core header */ - result = load_crashdump_segments(info, &header_option); - - if (result) { - fprintf(stderr, "kexec: creating eflcorehdr failed.\n"); - goto exit; - } -- } - -- if (info->kexec_flags & KEXEC_ON_CRASH) -- modify_ehdr_for_crashmem(&ehdr); -+ /* offset addresses to load vmlinux(elf_exec) in crash memory */ -+ modify_ehdr_for_crashdump(&ehdr); -+ } - - result = elf_exec_load(&ehdr, info); - -@@ -112,7 +113,7 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - } - - if (info->kexec_flags & KEXEC_ON_CRASH) -- set_crash_entry(&ehdr, info); -+ info->entry = get_crash_entry(); - else - info->entry = (void *)virt_to_phys(ehdr.e_entry); - --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-fix-elf-related-header-issues.patch b/SOURCES/kexec-tools-2.0.8-arm64-fix-elf-related-header-issues.patch deleted file mode 100644 index 0fadd22..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-fix-elf-related-header-issues.patch +++ /dev/null @@ -1,71 +0,0 @@ -From edac28173d05a547ad20442991ffd7708eba10bb Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Tue, 17 Feb 2015 15:53:07 +0900 -Subject: [PATCH 07/17] arm64: fix elf-related header issues - -- add a missing EM_AARCH64 macro -- linux/elf.h was also replaced with elf.h because they are conflicting - each other. ---- - include/elf.h | 1 + - kexec/arch/arm64/kexec-arm64.c | 3 +-- - kexec/arch/arm64/kexec-elf-arm64.c | 3 +-- - 3 files changed, 3 insertions(+), 4 deletions(-) - -diff --git a/include/elf.h b/include/elf.h -index 5db637ba2f60..cd2802ae1091 100644 ---- a/include/elf.h -+++ b/include/elf.h -@@ -259,6 +259,7 @@ typedef struct - #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ - #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ - #define EM_NUM 95 -+#define EM_AARCH64 183 /* ARMv8-A */ - - /* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 86408598a465..eb68b6b3d9e3 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -19,8 +20,6 @@ - - #include - --#include -- - #include "dt-ops.h" - #include "kexec.h" - #include "crashdump.h" -diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c -index 13dc5e2724d9..8b336054a6ab 100644 ---- a/kexec/arch/arm64/kexec-elf-arm64.c -+++ b/kexec/arch/arm64/kexec-elf-arm64.c -@@ -5,12 +5,11 @@ - #define _GNU_SOURCE - - #include -+#include - #include - #include - #include - --#include -- - #include "dt-ops.h" - #include "crashdump-arm64.h" - #include "kexec-arm64.h" --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-kdump-Add-support-for-binary-image.patch b/SOURCES/kexec-tools-2.0.8-arm64-kdump-Add-support-for-binary-image.patch deleted file mode 100644 index 8eb064b..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-kdump-Add-support-for-binary-image.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 249821e20306fbafff9094a4e02c82b189ea0676 Mon Sep 17 00:00:00 2001 -Message-Id: <249821e20306fbafff9094a4e02c82b189ea0676.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Pratyush Anand -Date: Tue, 21 Apr 2015 18:23:38 +0530 -Subject: [PATCH 14/17] arm64: kdump: Add support for binary image - -This patch adds support to use binary image ie arch/arm64/boot/Image -with kdump. - -Signed-off-by: Pratyush Anand ---- - kexec/arch/arm64/kexec-image-arm64.c | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - -diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c -index c577b96d5e31..6f8a6590639a 100644 ---- a/kexec/arch/arm64/kexec-image-arm64.c -+++ b/kexec/arch/arm64/kexec-image-arm64.c -@@ -10,6 +10,7 @@ - #include - #include - -+#include "crashdump-arm64.h" - #include "dt-ops.h" - #include "image-header.h" - #include "kexec-arm64.h" -@@ -97,13 +98,23 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf, - - arm64_mem.page_offset = get_kernel_page_offset(); - -- result = parse_iomem_single("Kernel code\n", &start, NULL); -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ result = load_crashdump_segments(info, &header_option); - -- if (result) { -- fprintf(stderr, "kexec: Could not get kernel code address.\n"); -- return -1; -+ if (result) { -+ fprintf(stderr, "kexec: load crashdump segments failed.\n"); -+ return -1; -+ } -+ start = crash_reserved_mem.start; -+ } else { -+ result = parse_iomem_single("Kernel code\n", &start, NULL); -+ -+ if (result) { -+ fprintf(stderr, "kexec: Could not get kernel code address.\n"); -+ return -1; -+ } -+ start -= arm64_mem.text_offset; - } -- start -= arm64_mem.text_offset; - - /* Add kernel */ - add_segment_phys_virt(info, kernel_buf, kernel_size, -@@ -112,7 +123,8 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf, - - info->entry = (void *)start + arm64_mem.text_offset; - -- result = arm64_load_other_segments(info, (unsigned long)info->entry); -+ result = arm64_load_other_segments(info, (unsigned long)info->entry, -+ header_option); - - if (header_option) - free(header_option); --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-kdump-append-kdump-specific-parameter-to-comma.patch b/SOURCES/kexec-tools-2.0.8-arm64-kdump-append-kdump-specific-parameter-to-comma.patch deleted file mode 100644 index a1b5609..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-kdump-append-kdump-specific-parameter-to-comma.patch +++ /dev/null @@ -1,78 +0,0 @@ -From dd86e7cedfc0509df5dd7f824611d59cf7e9f007 Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Tue, 24 Feb 2015 16:46:35 +0900 -Subject: [PATCH 09/17] arm64: kdump: append kdump-specific parameter to - command line - ---- - kexec/arch/arm64/kexec-arm64.c | 9 +++++++-- - kexec/arch/arm64/kexec-arm64.h | 2 +- - kexec/arch/arm64/kexec-elf-arm64.c | 3 ++- - 3 files changed, 10 insertions(+), 4 deletions(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index e83e83bdd6db..173631c66951 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -586,7 +586,7 @@ static uint64_t read_sink(const char *command_line) - */ - - int arm64_load_other_segments(struct kexec_info *info, -- unsigned long kernel_entry) -+ unsigned long kernel_entry, char *option) - { - int result; - struct mem_ehdr ehdr; -@@ -599,14 +599,19 @@ int arm64_load_other_segments(struct kexec_info *info, - struct dtb dtb_2 = {.name = "dtb_2"}; - char command_line[COMMAND_LINE_SIZE] = ""; - -+ dbgprintf("%s:%d: add '%s' to command line\n", __func__, __LINE__, -+ option); -+ - if (arm64_opts.command_line) { - strncpy(command_line, arm64_opts.command_line, - sizeof(command_line)); - command_line[sizeof(command_line) - 1] = 0; - } - -- purgatory_sink = read_sink(command_line); -+ if (option && option[0]) -+ strcat(command_line, option); - -+ purgatory_sink = read_sink(command_line); - dbgprintf("%s:%d: purgatory sink: 0x%" PRIx64 "\n", __func__, __LINE__, - purgatory_sink); - -diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h -index 7f0ca13fec11..7e4d0568bd01 100644 ---- a/kexec/arch/arm64/kexec-arm64.h -+++ b/kexec/arch/arm64/kexec-arm64.h -@@ -48,6 +48,6 @@ extern struct arm64_mem arm64_mem; - - int arm64_process_image_header(const struct arm64_image_header *h); - int arm64_load_other_segments(struct kexec_info *info, -- unsigned long kernel_entry); -+ unsigned long kernel_entry, char *option); - - #endif -diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c -index 903602985eb4..f5ecda825278 100644 ---- a/kexec/arch/arm64/kexec-elf-arm64.c -+++ b/kexec/arch/arm64/kexec-elf-arm64.c -@@ -123,7 +123,8 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - dbgprintf("%s: e_entry: %016llx -> %016lx\n", __func__, - ehdr.e_entry, virt_to_phys(ehdr.e_entry)); - -- result = arm64_load_other_segments(info, (unsigned long)info->entry); -+ result = arm64_load_other_segments(info, (unsigned long)info->entry, -+ header_option); - exit: - free_elf_info(&ehdr); - if (header_option) --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-kdump-copy-dtb-file-into-crash-kernel-memory.patch b/SOURCES/kexec-tools-2.0.8-arm64-kdump-copy-dtb-file-into-crash-kernel-memory.patch deleted file mode 100644 index 516aa71..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-kdump-copy-dtb-file-into-crash-kernel-memory.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 55cd3491542a0d696451611a4cae38db78f964dd Mon Sep 17 00:00:00 2001 -Message-Id: <55cd3491542a0d696451611a4cae38db78f964dd.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Tue, 24 Feb 2015 15:48:29 +0900 -Subject: [PATCH 10/17] arm64: kdump: copy dtb file into crash kernel memory - ---- - kexec/arch/arm64/crashdump-arm64.c | 6 ++++++ - kexec/arch/arm64/crashdump-arm64.h | 1 + - kexec/arch/arm64/kexec-arm64.c | 15 +++++++++------ - 3 files changed, 16 insertions(+), 6 deletions(-) - -diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c -index ec83cf0c0f38..80f5985c5d85 100644 ---- a/kexec/arch/arm64/crashdump-arm64.c -+++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -306,3 +306,9 @@ void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info) - { - info->entry = (void *)crash_reserved_mem.start + arm64_mem.text_offset; - } -+ -+off_t locate_dtb_in_crashmem(struct kexec_info *info, off_t dtb_size) -+{ -+ return locate_hole(info, dtb_size, 128UL * 1024, -+ crash_reserved_mem.start, crash_reserved_mem.end, -1); -+} -diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h -index 3f8b38350841..d4fd3f2288c9 100644 ---- a/kexec/arch/arm64/crashdump-arm64.h -+++ b/kexec/arch/arm64/crashdump-arm64.h -@@ -21,5 +21,6 @@ extern struct memory_ranges usablemem_rgns; - int load_crashdump_segments(struct kexec_info *info, char **option); - void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr); - void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info); -+off_t locate_dtb_in_crashmem(struct kexec_info *info, off_t dtb_size); - - #endif -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 173631c66951..190037c75186 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -650,12 +650,15 @@ int arm64_load_other_segments(struct kexec_info *info, - - dtb_max = dtb_2.size + 2 * 1024; - -- dtb_base = locate_hole(info, dtb_max, 128UL * 1024, -- arm64_mem.memstart + arm64_mem.text_offset -- + arm64_mem.image_size, -- _ALIGN_UP(arm64_mem.memstart + arm64_mem.text_offset, -- 512UL * 1024 * 1024), -- 1); -+ if (info->kexec_flags & KEXEC_ON_CRASH) -+ dtb_base = locate_dtb_in_crashmem(info, dtb_max); -+ else -+ dtb_base = locate_hole(info, dtb_max, 128UL * 1024, -+ arm64_mem.memstart + arm64_mem.text_offset -+ + arm64_mem.image_size, -+ _ALIGN_UP(arm64_mem.memstart + arm64_mem.text_offset, -+ 512UL * 1024 * 1024), -+ 1); - - dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, - dtb_2.size); --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-kdump-create-elf-core-header.patch b/SOURCES/kexec-tools-2.0.8-arm64-kdump-create-elf-core-header.patch deleted file mode 100644 index 31d3dbe..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-kdump-create-elf-core-header.patch +++ /dev/null @@ -1,468 +0,0 @@ -From 9cd9f0ab98ce6ddbdbb9a045ed2887e0dd857afe Mon Sep 17 00:00:00 2001 -Message-Id: <9cd9f0ab98ce6ddbdbb9a045ed2887e0dd857afe.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Tue, 17 Feb 2015 16:06:55 +0900 -Subject: [PATCH 08/17] arm64: kdump: create elf core header - ---- - kexec/arch/arm64/crashdump-arm64.c | 295 ++++++++++++++++++++++++++++++++++++- - kexec/arch/arm64/crashdump-arm64.h | 17 ++- - kexec/arch/arm64/kexec-arm64.c | 4 +- - kexec/arch/arm64/kexec-elf-arm64.c | 31 +++- - 4 files changed, 332 insertions(+), 15 deletions(-) - -diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c -index d2272c8124d0..ec83cf0c0f38 100644 ---- a/kexec/arch/arm64/crashdump-arm64.c -+++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -1,11 +1,28 @@ - /* -- * ARM64 crashdump. -+ * crashdump for arm64 -+ * -+ * Copyright (C) Nokia Corporation, 2010. -+ * Author: Mika Westerberg -+ * -+ * Based on x86 implementation -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * Copyright (c) 2014 Linaro Limited -+ * Author: AKASHI Takahiro -+ * -+ * 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. - */ - --#define _GNU_SOURCE -+#define _GNU_SOURCE /* for asprintf */ - -+#include -+#include - #include --#include -+#include -+#include -+#include - - #include "kexec.h" - #include "crashdump.h" -@@ -13,9 +30,279 @@ - #include "kexec-arm64.h" - #include "kexec-elf.h" - --struct memory_ranges usablemem_rgns = {}; -+ -+/* -+ * Used to save various memory ranges/regions needed for the captured -+ * kernel to boot. (like memmap= option in other archs) -+ */ -+static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES]; -+struct memory_ranges crashmem_rgns = { -+ .size = 0, -+ .ranges = crash_memory_ranges, -+}; -+ -+/* memory range reserved for crashkernel */ -+struct memory_range crash_reserved_mem; -+struct memory_ranges usablemem_rgns = { -+ .size = 0, -+ .ranges = &crash_reserved_mem, -+}; -+ -+static struct crash_elf_info elf_info = { -+ .class = ELFCLASS64, -+#if (__BYTE_ORDER == __LITTLE_ENDIAN) -+ .data = ELFDATA2LSB, -+#else -+ .data = ELFDATA2MSB, -+#endif -+ .machine = EM_AARCH64, -+}; - - int is_crashkernel_mem_reserved(void) - { -+ uint64_t start, end; -+ -+ if (parse_iomem_single("Crash kernel\n", &start, &end) == 0) -+ return start != end; -+ -+ return 0; -+} -+ -+/* -+ * crash_range_callback() - callback called for each iomem region -+ * @data: not used -+ * @nr: not used -+ * @str: name of the memory region -+ * @base: start address of the memory region -+ * @length: size of the memory region -+ * -+ * This function is called once for each memory region found in /proc/iomem. -+ * It locates system RAM and crashkernel reserved memory and places these to -+ * variables: @crash_memory_ranges and @crash_reserved_mem. Number of memory -+ * regions is placed in @crash_memory_nr_ranges. -+ */ -+ -+static int crash_range_callback(void *UNUSED(data), int UNUSED(nr), -+ char *str, unsigned long long base, -+ unsigned long long length) -+{ -+ struct memory_range *range; -+ -+ assert(arm64_mem.memstart); -+ -+ if (crashmem_rgns.size >= CRASH_MAX_MEMORY_RANGES) -+ return 1; -+ -+ range = crashmem_rgns.ranges + crashmem_rgns.size; -+ -+ if (strncmp(str, "System RAM\n", 11) == 0) { -+ range->start = base; -+ range->end = base + length - 1; -+ range->type = RANGE_RAM; -+ crashmem_rgns.size++; -+ } else if (strncmp(str, "Crash kernel\n", 13) == 0) { -+ if (base < arm64_mem.memstart) -+ base += arm64_mem.memstart; -+ crash_reserved_mem.start = base; -+ crash_reserved_mem.end = base + length - 1; -+ crash_reserved_mem.type = RANGE_RAM; -+ usablemem_rgns.size++; -+ } -+ -+ return 0; -+} -+ -+/* -+ * crash_exclude_range() - excludes memory region reserved for crashkernel -+ * -+ * Function locates where crashkernel reserved memory is and removes that -+ * region from the available memory regions. -+ */ -+static void crash_exclude_range(void) -+{ -+ const struct memory_range *range = &crash_reserved_mem; -+ int i; -+ -+ for (i = 0; i < crashmem_rgns.size; i++) { -+ struct memory_range *r = crashmem_rgns.ranges + i; -+ -+ /* -+ * We assume that crash area is fully contained in -+ * some larger memory area. -+ */ -+ if (r->start <= range->start && r->end >= range->end) { -+ struct memory_range *new; -+ -+ if (r->start == range->start) { -+ if (r->end == range->end) { -+ memcpy(r, r + 1, -+ sizeof(r) -+ * (crashmem_rgns.size - i - 1)); -+ crashmem_rgns.size--; -+ } else { -+ r->start = range->end + 1; -+ } -+ break; -+ } -+ if (r->end == range->end) { -+ r->end = range->start - 1; -+ break; -+ } -+ -+ /* -+ * Let's split this area into 2 smaller ones and -+ * remove excluded range from between. First create -+ * new entry for the remaining area. -+ */ -+ new = crashmem_rgns.ranges + crashmem_rgns.size; -+ new->start = range->end + 1; -+ new->end = r->end; -+ crashmem_rgns.size++; -+ /* -+ * Next update this area to end before excluded range. -+ */ -+ r->end = range->start - 1; -+ break; -+ } -+ } -+} -+ -+/* -+ * crash_get_memory_ranges() - read system physical memory -+ * -+ * Function reads through system physical memory and stores found memory -+ * regions in @crash_memory_ranges. Number of memory regions found is placed -+ * in @crash_memory_nr_ranges. Regions are sorted in ascending order. -+ * -+ * Returns %0 in case of success and %-1 otherwise (errno is set). -+ */ -+static int crash_get_memory_ranges(void) -+{ -+ /* -+ * First read all memory regions that can be considered as -+ * system memory including the crash area. -+ */ -+ kexec_iomem_for_each_line(NULL, crash_range_callback, NULL); -+ -+ if (usablemem_rgns.size != 1) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ /* -+ * Exclude memory reserved for crashkernel (this may result int -+ * split memory regions). -+ */ -+ /* -+ * FIXME: -+ * Do we have to check crashkernel is within main memory? -+ */ -+ crash_exclude_range(); -+ -+ return 0; -+} -+ -+/* -+ * range_size - Return range size in MiB. -+ */ -+ -+static unsigned long range_size(const struct memory_range *r) -+{ -+ return (r->end - r->start + 1) >> 20; -+} -+ -+static void dump_crash_ranges(void) -+{ -+ int i; -+ -+ if (!kexec_debug) -+ return; -+ -+ dbgprintf("%s: kernel: %016llx - %016llx (%ld MiB)\n", __func__, -+ crash_reserved_mem.start, crash_reserved_mem.end, -+ range_size(&crash_reserved_mem)); -+ -+ for (i = 0; i < crashmem_rgns.size; i++) { -+ struct memory_range *r = crashmem_rgns.ranges + i; -+ dbgprintf("%s: RAM: %016llx - %016llx (%ld MiB)\n", __func__, -+ r->start, r->end, range_size(r)); -+ } -+} -+ -+/* -+ * load_crashdump_segments() - create elf core header for /proc/vmcore -+ * @info: kexec info structure -+ * @option: To be appended to kernel command line -+ * -+ * This function loads additional segments which are needed for the dump -+ * capture kernel. It also updates kernel command line passed in -+ * @command_line_extra to have the correct parameters for the dump capture -+ * kernel. -+ * -+ * Return %0 in case of success and %-1 in case of error. -+ */ -+ -+int load_crashdump_segments(struct kexec_info *info, char **option) -+{ -+ unsigned long elfcorehdr; -+ unsigned long bufsz; -+ void *buf; -+ int err; -+ -+ /* -+ * First fetch all the memory (RAM) ranges that we are going to -+ * pass to the crashdump kernel during panic. -+ */ -+ -+ err = crash_get_memory_ranges(); -+ -+ if (err) -+ return err; -+ -+ dump_crash_ranges(); -+ -+ elf_info.page_offset = arm64_mem.page_offset; -+ -+ err = crash_create_elf64_headers(info, &elf_info, crashmem_rgns.ranges, -+ crashmem_rgns.size, &buf, &bufsz, ELF_CORE_HEADER_ALIGN); -+ -+ if (err) -+ return err; -+ -+ /* -+ * FIXME: check if we need 128KB alignment here as stated in arm. -+ */ -+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0, -+ crash_reserved_mem.start, crash_reserved_mem.end, -+ -1, 0); -+ -+ err = asprintf(option, " elfcorehdr=%#lx@%#lx", bufsz, elfcorehdr); -+ -+ if (err == -1) -+ return err; -+ -+ dbgprintf("%s:%s\n", __func__, *option); -+ - return 0; - } -+ -+void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr) -+{ -+ struct mem_phdr *phdr; -+ int i; -+ -+ ehdr->e_entry += crash_reserved_mem.start; -+ -+ for (i = 0; i < ehdr->e_phnum; i++) { -+ phdr = &ehdr->e_phdr[i]; -+ if (phdr->p_type != PT_LOAD) -+ continue; -+ phdr->p_paddr += -+ (-arm64_mem.memstart + crash_reserved_mem.start); -+ } -+} -+ -+void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info) -+{ -+ info->entry = (void *)crash_reserved_mem.start + arm64_mem.text_offset; -+} -diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h -index f33c7a25b454..3f8b38350841 100644 ---- a/kexec/arch/arm64/crashdump-arm64.h -+++ b/kexec/arch/arm64/crashdump-arm64.h -@@ -1,12 +1,25 @@ - /* -- * ARM64 crashdump. -+ * crashdump for arm64 -+ * -+ * Copyright (c) 2014 Linaro Limited -+ * Author: AKASHI Takahiro -+ * -+ * 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. - */ - --#if !defined(CRASHDUMP_ARM64_H) -+#ifndef CRASHDUMP_ARM64_H - #define CRASHDUMP_ARM64_H - - #include "kexec.h" - -+#define CRASH_MAX_MEMORY_RANGES 32 -+ - extern struct memory_ranges usablemem_rgns; - -+int load_crashdump_segments(struct kexec_info *info, char **option); -+void modify_ehdr_for_crashmem(struct mem_ehdr *ehdr); -+void set_crash_entry(struct mem_ehdr *ehdr, struct kexec_info *info); -+ - #endif -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index eb68b6b3d9e3..e83e83bdd6db 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -758,7 +758,7 @@ unsigned long phys_to_virt(struct crash_elf_info *UNUSED(elf_info), - v = p - arm64_mem.memstart + arm64_mem.page_offset; - - dbgprintf("%s: %016lx -> %016lx\n", __func__, p, v); -- return p; -+ return v; - } - - void add_segment(struct kexec_info *info, const void *buf, size_t bufsz, -@@ -924,7 +924,7 @@ static int get_memory_ranges_iomem(struct memory_range *array, - - r.type = RANGE_RAM; - -- dbgprintf("%s:%d: RAM: %016llx - %016llx : %s", __func__, -+ dbgprintf("%s:%d: RAM: %016llx - %016llx : %s", __func__, - __LINE__, r.start, r.end, str); - - array[(*count)++] = r; -diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c -index 8b336054a6ab..903602985eb4 100644 ---- a/kexec/arch/arm64/kexec-elf-arm64.c -+++ b/kexec/arch/arm64/kexec-elf-arm64.c -@@ -9,9 +9,10 @@ - #include - #include - #include -+#include - --#include "dt-ops.h" - #include "crashdump-arm64.h" -+#include "dt-ops.h" - #include "kexec-arm64.h" - #include "fs2dt.h" - #include "kexec-syscall.h" -@@ -45,16 +46,13 @@ on_exit: - int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - off_t kernel_size, struct kexec_info *info) - { -+ char *header_option = NULL; - int result; - struct mem_ehdr ehdr; - bool found_header; - int i; - -- if (info->kexec_flags & KEXEC_ON_CRASH) { -- fprintf(stderr, "kexec: kdump not yet supported on arm64\n"); -- return -EINVAL; -- } -- -+ /* Parse the Elf file */ - result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); - - if (result < 0) { -@@ -94,6 +92,18 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - goto exit; - } - -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ result = load_crashdump_segments(info, &header_option); -+ -+ if (result) { -+ fprintf(stderr, "kexec: creating eflcorehdr failed.\n"); -+ goto exit; -+ } -+ } -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) -+ modify_ehdr_for_crashmem(&ehdr); -+ - result = elf_exec_load(&ehdr, info); - - if (result) { -@@ -101,6 +111,11 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - goto exit; - } - -+ if (info->kexec_flags & KEXEC_ON_CRASH) -+ set_crash_entry(&ehdr, info); -+ else -+ info->entry = (void *)virt_to_phys(ehdr.e_entry); -+ - dbgprintf("%s: text_offset: %016lx\n", __func__, arm64_mem.text_offset); - dbgprintf("%s: image_size: %016lx\n", __func__, arm64_mem.image_size); - dbgprintf("%s: page_offset: %016lx\n", __func__, arm64_mem.page_offset); -@@ -108,9 +123,11 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf, - dbgprintf("%s: e_entry: %016llx -> %016lx\n", __func__, - ehdr.e_entry, virt_to_phys(ehdr.e_entry)); - -- result = arm64_load_other_segments(info, virt_to_phys(ehdr.e_entry)); -+ result = arm64_load_other_segments(info, (unsigned long)info->entry); - exit: - free_elf_info(&ehdr); -+ if (header_option) -+ free(header_option); - return result; - } - --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-pass-mem-parameter-to-a-crash-dump-kernel.patch b/SOURCES/kexec-tools-2.0.8-arm64-pass-mem-parameter-to-a-crash-dump-kernel.patch deleted file mode 100644 index b21731c..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-pass-mem-parameter-to-a-crash-dump-kernel.patch +++ /dev/null @@ -1,30 +0,0 @@ -From dbb9a351c5bd0c51b959a9ffc19859bee1b82008 Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Thu, 26 Mar 2015 19:13:44 +0900 -Subject: [PATCH 11/17] arm64: pass "mem=" parameter to a crash dump kernel - ---- - kexec/arch/arm64/crashdump-arm64.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c -index 80f5985c5d85..04958418ae82 100644 ---- a/kexec/arch/arm64/crashdump-arm64.c -+++ b/kexec/arch/arm64/crashdump-arm64.c -@@ -276,7 +276,9 @@ int load_crashdump_segments(struct kexec_info *info, char **option) - crash_reserved_mem.start, crash_reserved_mem.end, - -1, 0); - -- err = asprintf(option, " elfcorehdr=%#lx@%#lx", bufsz, elfcorehdr); -+ err = asprintf(option, " elfcorehdr=%#lx@%#lx mem=%#llx", -+ bufsz, elfcorehdr, -+ crash_reserved_mem.end - crash_reserved_mem.start + 1); - - if (err == -1) - return err; --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-prefer-reading-memory-ranges-from-iomem-over-f.patch b/SOURCES/kexec-tools-2.0.8-arm64-prefer-reading-memory-ranges-from-iomem-over-f.patch deleted file mode 100644 index 5aedb3c..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-prefer-reading-memory-ranges-from-iomem-over-f.patch +++ /dev/null @@ -1,42 +0,0 @@ -From edc4648e608533e05f323b5682ab98ebd37eacca Mon Sep 17 00:00:00 2001 -Message-Id: -From: Pratyush Anand -Date: Thu, 30 Jun 2016 23:16:18 +0530 -Subject: [PATCH] arm64: prefer reading memory ranges from iomem over fdt - -Some of the fdt might not have correct memory ranges defined in "memory" -nodes. For example: apm-mustang.dts expects boot loader to update "memory" -node with appropriate value. - -Now, what if boot loader /firmware does not update it. Offcourse, its an -issue in firmware. But, since we will always have more updated memory -ranges in /proc/iomem, so prefer to read it from there. - -Specifically, after kernel commit 500899c2cc3e3f06140373b587a69d30650f2d9d, -it becomes important to work kexec with such buggy firmware. - -Signed-off-by: Pratyush Anand ---- - kexec/arch/arm64/kexec-arm64.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index f936dd2de458..d1fdd64a60c2 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -1016,10 +1016,10 @@ int get_memory_ranges(struct memory_range **range, int *ranges, - unsigned int count; - int result; - -- result = get_memory_ranges_dt(array, &count); -+ result = get_memory_ranges_iomem(array, &count); - - if (result) -- result = get_memory_ranges_iomem(array, &count); -+ result = get_memory_ranges_dt(array, &count); - - *range = result ? NULL : array; - *ranges = result ? 0 : count; --- -2.5.5 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-remove-restriction-on-the-segments-order.patch b/SOURCES/kexec-tools-2.0.8-arm64-remove-restriction-on-the-segments-order.patch deleted file mode 100644 index 0d850fe..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-remove-restriction-on-the-segments-order.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 97905e5e71d417e8bbbfa3c42d559a464a1570da Mon Sep 17 00:00:00 2001 -Message-Id: <97905e5e71d417e8bbbfa3c42d559a464a1570da.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Wed, 22 Apr 2015 11:21:05 +0900 -Subject: [PATCH 13/17] arm64: remove restriction on the segments order - -Done by changing locate_hole() to add_buffer_phys_virt() in -load_other_segments() since locate_hole() assumes that the segments in -struct info be sorted properly. -This also simplifies the difference between kexec case and kdump case. ---- - kexec/arch/arm64/kexec-arm64.c | 57 +++++++++++++++--------------------------- - 1 file changed, 20 insertions(+), 37 deletions(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 190037c75186..d884c7c1707d 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -590,11 +590,10 @@ int arm64_load_other_segments(struct kexec_info *info, - { - int result; - struct mem_ehdr ehdr; -- unsigned long dtb_max; - unsigned long dtb_base; -+ unsigned long hole_min, hole_max; - char *initrd_buf = NULL; - uint64_t purgatory_sink; -- unsigned long purgatory_base; - struct dtb dtb_1 = {.name = "dtb_1"}; - struct dtb dtb_2 = {.name = "dtb_2"}; - char command_line[COMMAND_LINE_SIZE] = ""; -@@ -648,27 +647,15 @@ int arm64_load_other_segments(struct kexec_info *info, - * to the DTB size for any DTB growth. - */ - -- dtb_max = dtb_2.size + 2 * 1024; -- -- if (info->kexec_flags & KEXEC_ON_CRASH) -- dtb_base = locate_dtb_in_crashmem(info, dtb_max); -- else -- dtb_base = locate_hole(info, dtb_max, 128UL * 1024, -- arm64_mem.memstart + arm64_mem.text_offset -- + arm64_mem.image_size, -- _ALIGN_UP(arm64_mem.memstart + arm64_mem.text_offset, -- 512UL * 1024 * 1024), -- 1); -- -- dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, -- dtb_2.size); -- -- if (dtb_base == ULONG_MAX) -- return -ENOMEM; -- -- purgatory_base = dtb_base + dtb_2.size; -- initrd_base = 0; -- initrd_size = 0; -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ hole_min = crash_reserved_mem.start + arm64_mem.text_offset -+ + arm64_mem.image_size; -+ hole_max = crash_reserved_mem.end; -+ } else { -+ hole_min = arm64_mem.memstart + arm64_mem.text_offset -+ + arm64_mem.image_size; -+ hole_max = ULONG_MAX; -+ } - - if (arm64_opts.initrd) { - initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size); -@@ -679,8 +666,9 @@ int arm64_load_other_segments(struct kexec_info *info, - /* Put the initrd after the DTB with an alignment of - * page size. */ - -- initrd_base = locate_hole(info, initrd_size, 0, -- dtb_base + dtb_max, -1, 1); -+ initrd_base = add_buffer_phys_virt(info, initrd_buf, -+ initrd_size, initrd_size, 0, -+ hole_min, hole_max, 1, 0); - - dbgprintf("initrd: base %lx, size %lxh (%ld)\n", - initrd_base, initrd_size, initrd_size); -@@ -694,22 +682,17 @@ int arm64_load_other_segments(struct kexec_info *info, - - if (result) - return result; -- -- purgatory_base = initrd_base + initrd_size; - } - } - -- if (dtb_2.size > dtb_max) { -- fprintf(stderr, "%s: Error: Too many DTB mods.\n", __func__); -- return -EINVAL; -- } -+ dtb_base = add_buffer_phys_virt(info, dtb_2.buf, dtb_2.size, dtb_2.size, -+ 128UL * 1024, hole_min, hole_max, 1, 0); - -- add_segment_phys_virt(info, dtb_2.buf, dtb_2.size, dtb_base, -- dtb_2.size, 0); -+ dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, -+ dtb_2.size); - -- if (arm64_opts.initrd) -- add_segment_phys_virt(info, initrd_buf, initrd_size, -- initrd_base, initrd_size, 0); -+ if (dtb_base == ULONG_MAX) -+ return -ENOMEM; - - if (arm64_opts.lite) - info->entry = (void *)kernel_entry; -@@ -724,7 +707,7 @@ int arm64_load_other_segments(struct kexec_info *info, - } - - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- purgatory_base, ULONG_MAX, 1, 0); -+ hole_min, hole_max, 1, 0); - - info->entry = (void *)elf_rel_get_addr(&info->rhdr, - "purgatory_start"); --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch b/SOURCES/kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch deleted file mode 100644 index 400a868..0000000 --- a/SOURCES/kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fc60d1ebadfba9a4344969507d8bd9de43c5c7e8 Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Pratyush Anand -Date: Thu, 16 Apr 2015 14:00:03 +0530 -Subject: [PATCH 15/17] arm64: wait for transmit completion before next - character transmission - -Previous transmission must be completed before next character to be -transmitted, otherwise TX buffer may saturate and we will not see all -the characters on screen. - -Signed-off-by: Pratyush Anand ---- - purgatory/arch/arm64/purgatory-arm64.c | 24 +++++++++++++++++++++++- - 1 file changed, 23 insertions(+), 1 deletion(-) - -diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c -index 25960c30bd05..3a1c9243bfa2 100644 ---- a/purgatory/arch/arm64/purgatory-arm64.c -+++ b/purgatory/arch/arm64/purgatory-arm64.c -@@ -11,15 +11,37 @@ extern uint32_t *arm64_sink; - extern void (*arm64_kernel_entry)(uint64_t); - extern uint64_t arm64_dtb_addr; - -+static void wait_for_xmit_complete(void) -+{ -+ volatile uint32_t status; -+ volatile uint32_t *status_reg; -+ -+ /* -+ * Since most of the UART with ARM platform has LSR register at -+ * offset 0x14 and should have value as 0x60 for TX empty, so we -+ * have hardcoded these values. Can modify in future if need -+ * arises. -+ */ -+ status_reg = (volatile uint32_t *)((uint64_t)arm64_sink + 0x14); -+ while (1) { -+ status = *status_reg; -+ if ((status & 0x60) == 0x60) -+ break; -+ } -+} -+ - void putchar(int ch) - { - if (!arm64_sink) - return; - -+ wait_for_xmit_complete(); - *arm64_sink = ch; - -- if (ch == '\n') -+ if (ch == '\n') { -+ wait_for_xmit_complete(); - *arm64_sink = '\r'; -+ } - } - - void setup_arch(void) --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-bugfix-calc-correct-end-address-of-memory-ranges-in-.patch b/SOURCES/kexec-tools-2.0.8-bugfix-calc-correct-end-address-of-memory-ranges-in-.patch deleted file mode 100644 index b3d5ef6..0000000 --- a/SOURCES/kexec-tools-2.0.8-bugfix-calc-correct-end-address-of-memory-ranges-in-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0ed5f4fb8dfd33bc52c8dbe15c61285d50c769b2 Mon Sep 17 00:00:00 2001 -Message-Id: <0ed5f4fb8dfd33bc52c8dbe15c61285d50c769b2.1431592766.git.panand@redhat.com> -In-Reply-To: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -References: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: AKASHI Takahiro -Date: Fri, 22 Aug 2014 13:48:52 +0900 -Subject: [PATCH 06/17] (bugfix) calc correct end address of memory ranges in - device tree - -The end address of "reg" attribute in device tree's memory should be -inclusive. ---- - kexec/fs2dt.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c -index 1e5f074da8b2..3ba217873f4f 100644 ---- a/kexec/fs2dt.c -+++ b/kexec/fs2dt.c -@@ -234,7 +234,8 @@ static void add_dyn_reconf_usable_mem_property__(int fd) - ranges_size*8); - } - ranges[rlen++] = cpu_to_be64(loc_base); -- ranges[rlen++] = cpu_to_be64(loc_end - loc_base); -+ ranges[rlen++] = cpu_to_be64(loc_end -+ - loc_base + 1); - rngs_cnt++; - } - } -@@ -348,7 +349,7 @@ static void add_usable_mem_property(int fd, size_t len) - ranges_size*sizeof(*ranges)); - } - ranges[rlen++] = cpu_to_be64(loc_base); -- ranges[rlen++] = cpu_to_be64(loc_end - loc_base); -+ ranges[rlen++] = cpu_to_be64(loc_end - loc_base + 1); - } - } - --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-fs2dt.c-move-copy-old-root-param-as-a-new-function.patch b/SOURCES/kexec-tools-2.0.8-fs2dt.c-move-copy-old-root-param-as-a-new-function.patch deleted file mode 100644 index 0f38093..0000000 --- a/SOURCES/kexec-tools-2.0.8-fs2dt.c-move-copy-old-root-param-as-a-new-function.patch +++ /dev/null @@ -1,129 +0,0 @@ -From a1ae68d19b6e3534ead0aab04ca84de24962def7 Mon Sep 17 00:00:00 2001 -From: "dyoung@redhat.com" -Date: Wed, 28 Oct 2015 13:41:35 +0800 -Subject: [PATCH 1/3] fs2dt.c: move copy old root param as a new function - -Split the copy old root param code to a new function dt_copy_old_root_param -Also add a global variable dt_no_old_root, do not copy root param when -dt_no_old_root == 1. It will be used in later patches. - -Signed-off-by: Dave Young -Signed-off-by: Simon Horman ---- - kexec/fs2dt.c | 66 ++++++++++++++++++++++++++++++++++++----------------------- - kexec/fs2dt.h | 1 + - 2 files changed, 41 insertions(+), 26 deletions(-) - -diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c -index d73e144..0ea785f 100644 ---- a/kexec/fs2dt.c -+++ b/kexec/fs2dt.c -@@ -53,6 +53,7 @@ extern unsigned char reuse_initrd; - /* Used for enabling printing message from purgatory code - * Only has implemented for PPC64 */ - int my_debug; -+int dt_no_old_root; - - /* This provides the behaviour of hte existing ppc64 implementation */ - static void pad_structure_block(size_t len) { -@@ -511,6 +512,37 @@ static int comparefunc(const struct dirent **dentry1, - return strcmp(str1, str2); - } - -+/* grab root= from the old command line */ -+static void dt_copy_old_root_param(void) -+{ -+ FILE *fp; -+ char filename[MAXPATH]; -+ char *last_cmdline = NULL; -+ char *p, *old_param; -+ size_t len = 0; -+ -+ strcpy(filename, pathname); -+ strcat(filename, "bootargs"); -+ fp = fopen(filename, "r"); -+ if (fp) { -+ if (getline(&last_cmdline, &len, fp) == -1) -+ die("unable to read %s\n", filename); -+ -+ p = strstr(last_cmdline, "root="); -+ if (p) { -+ old_param = strtok(p, " "); -+ len = strlen(local_cmdline); -+ if (len != 0) -+ strcat(local_cmdline, " "); -+ strcat(local_cmdline, old_param); -+ } -+ } -+ if (last_cmdline) -+ free(last_cmdline); -+ -+ fclose(fp); -+} -+ - /* - * put a node (directory) in the property structure. first properties - * then children. -@@ -579,8 +611,11 @@ static void putnode(void) - reserve(initrd_base, initrd_size); - } - -- /* Add cmdline to the second kernel. Check to see if the new -- * cmdline has a root=. If not, use the old root= cmdline. */ -+ /* -+ * Add cmdline to the second kernel. Use the old root= cmdline if there -+ * is no root= in the new command line and there's no --dt-no-old-root -+ * option being used. -+ */ - if (!strcmp(basename,"chosen/")) { - size_t result; - size_t cmd_len = 0; -@@ -598,30 +633,9 @@ static void putnode(void) - param = strstr(local_cmdline, "root="); - } - -- /* ... if not, grab root= from the old command line */ -- if (!param) { -- FILE *fp; -- char *last_cmdline = NULL; -- char *old_param; -- -- strcpy(filename, pathname); -- strcat(filename, "bootargs"); -- fp = fopen(filename, "r"); -- if (fp) { -- if (getline(&last_cmdline, &cmd_len, fp) == -1) -- die("unable to read %s\n", filename); -- -- param = strstr(last_cmdline, "root="); -- if (param) { -- old_param = strtok(param, " "); -- if (cmd_len != 0) -- strcat(local_cmdline, " "); -- strcat(local_cmdline, old_param); -- } -- } -- if (last_cmdline) -- free(last_cmdline); -- } -+ if (!param && !dt_no_old_root) -+ dt_copy_old_root_param(); -+ - strcat(local_cmdline, " "); - cmd_len = strlen(local_cmdline); - cmd_len = cmd_len + 1; -diff --git a/kexec/fs2dt.h b/kexec/fs2dt.h -index 6c5c3b2..7633273 100644 ---- a/kexec/fs2dt.h -+++ b/kexec/fs2dt.h -@@ -31,6 +31,7 @@ extern struct bootblock bb[1]; - /* Used for enabling printing message from purgatory code - * Only has implemented for PPC64 */ - int my_debug; -+extern int dt_no_old_root; - - void reserve(unsigned long long where, unsigned long long length); - void create_flatten_tree(char **, off_t *, const char *); --- -2.5.0 - diff --git a/SOURCES/kexec-tools-2.0.8-kexec-Add-common-device-tree-routines.patch b/SOURCES/kexec-tools-2.0.8-kexec-Add-common-device-tree-routines.patch deleted file mode 100644 index b2630fc..0000000 --- a/SOURCES/kexec-tools-2.0.8-kexec-Add-common-device-tree-routines.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 1fb6841aa15407dbf371589d7abca7bc2d35815c Mon Sep 17 00:00:00 2001 -Message-Id: <1fb6841aa15407dbf371589d7abca7bc2d35815c.1431592766.git.panand@redhat.com> -From: Geoff Levand -Date: Fri, 17 Apr 2015 10:54:55 -0700 -Subject: [PATCH 01/17] kexec: Add common device tree routines - -Signed-off-by: Geoff Levand ---- - kexec/Makefile | 4 ++ - kexec/dt-ops.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - kexec/dt-ops.h | 13 ++++++ - 3 files changed, 153 insertions(+) - create mode 100644 kexec/dt-ops.c - create mode 100644 kexec/dt-ops.h - -diff --git a/kexec/Makefile b/kexec/Makefile -index a758b4aae13a..6937a4dbb38b 100644 ---- a/kexec/Makefile -+++ b/kexec/Makefile -@@ -69,6 +69,10 @@ dist += kexec/fs2dt.c kexec/fs2dt.h - $(ARCH)_FS2DT = - KEXEC_SRCS += $($(ARCH)_FS2DT) - -+dist += kexec/dt-ops.c kexec/dt-ops.h -+$(ARCH)_DT_OPS = -+KEXEC_SRCS += $($(ARCH)_DT_OPS) -+ - include $(srcdir)/kexec/arch/alpha/Makefile - include $(srcdir)/kexec/arch/arm/Makefile - include $(srcdir)/kexec/arch/i386/Makefile -diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c -new file mode 100644 -index 000000000000..bbba986cfbb4 ---- /dev/null -+++ b/kexec/dt-ops.c -@@ -0,0 +1,136 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "kexec.h" -+#include "dt-ops.h" -+ -+static const char n_chosen[] = "/chosen"; -+ -+static const char p_bootargs[] = "bootargs"; -+static const char p_initrd_start[] = "linux,initrd-start"; -+static const char p_initrd_end[] = "linux,initrd-end"; -+ -+int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end) -+{ -+ int result; -+ uint64_t value; -+ -+ dbgprintf("%s: start %jd, end %jd, size %jd (%jd KiB)\n", -+ __func__, (intmax_t)start, (intmax_t)end, -+ (intmax_t)(end - start), -+ (intmax_t)(end - start) / 1024); -+ -+ value = cpu_to_fdt64(start); -+ -+ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_start, -+ &value, sizeof(value)); -+ -+ if (result) -+ return result; -+ -+ value = cpu_to_fdt64(end); -+ -+ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_end, -+ &value, sizeof(value)); -+ -+ if (result) { -+ dtb_delete_property(*dtb, n_chosen, p_initrd_start); -+ return result; -+ } -+ -+ return 0; -+} -+ -+int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line) -+{ -+ return dtb_set_property(dtb, dtb_size, n_chosen, p_bootargs, -+ command_line, strlen(command_line) + 1); -+} -+ -+int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, -+ const char *prop, const void *value, int value_len) -+{ -+ int result; -+ int nodeoffset; -+ void *new_dtb; -+ int new_size; -+ -+ value_len = FDT_TAGALIGN(value_len); -+ -+ new_size = FDT_TAGALIGN(*dtb_size + fdt_node_len(node) -+ + fdt_prop_len(prop, value_len)); -+ -+ new_dtb = malloc(new_size); -+ -+ if (!new_dtb) { -+ dbgprintf("%s: malloc failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ result = fdt_open_into(*dtb, new_dtb, new_size); -+ -+ if (result) { -+ dbgprintf("%s: fdt_open_into failed: %s\n", __func__, -+ fdt_strerror(result)); -+ goto on_error; -+ } -+ -+ nodeoffset = fdt_path_offset(new_dtb, node); -+ -+ if (nodeoffset == -FDT_ERR_NOTFOUND) { -+ result = fdt_add_subnode(new_dtb, nodeoffset, node); -+ -+ if (result) { -+ dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__, -+ fdt_strerror(result)); -+ goto on_error; -+ } -+ } else if (nodeoffset < 0) { -+ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, -+ fdt_strerror(nodeoffset)); -+ goto on_error; -+ } -+ -+ result = fdt_setprop(new_dtb, nodeoffset, prop, value, value_len); -+ -+ if (result) { -+ dbgprintf("%s: fdt_setprop failed: %s\n", __func__, -+ fdt_strerror(result)); -+ goto on_error; -+ } -+ -+ free(*dtb); -+ -+ *dtb = new_dtb; -+ *dtb_size = new_size; -+ -+ return 0; -+ -+on_error: -+ free(new_dtb); -+ return result; -+} -+ -+int dtb_delete_property(char *dtb, const char *node, const char *prop) -+{ -+ int result; -+ int nodeoffset = fdt_path_offset(dtb, node); -+ -+ if (nodeoffset < 0) { -+ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, -+ fdt_strerror(nodeoffset)); -+ return nodeoffset; -+ } -+ -+ result = fdt_delprop(dtb, nodeoffset, prop); -+ -+ if (result) -+ dbgprintf("%s: fdt_delprop failed: %s\n", __func__, -+ fdt_strerror(nodeoffset)); -+ -+ return result; -+} -diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h -new file mode 100644 -index 000000000000..e70d15d8ffbf ---- /dev/null -+++ b/kexec/dt-ops.h -@@ -0,0 +1,13 @@ -+#if !defined(KEXEC_DT_OPS_H) -+#define KEXEC_DT_OPS_H -+ -+#include -+ -+int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end); -+int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line); -+int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, -+ const char *prop, const void *value, int value_len); -+ -+int dtb_delete_property(char *dtb, const char *node, const char *prop); -+ -+#endif --- -2.1.0 - diff --git a/SOURCES/kexec-tools-2.0.8-ppc64-add-arch-option-dt-no-old-root.patch b/SOURCES/kexec-tools-2.0.8-ppc64-add-arch-option-dt-no-old-root.patch deleted file mode 100644 index 0a8e532..0000000 --- a/SOURCES/kexec-tools-2.0.8-ppc64-add-arch-option-dt-no-old-root.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 83a65e2e13af2041b2816712475e3fec6fdc9e68 Mon Sep 17 00:00:00 2001 -From: "dyoung@redhat.com" -Date: Wed, 28 Oct 2015 13:41:37 +0800 -Subject: [PATCH 3/3] ppc64: add arch option --dt-no-old-root - -When createing fdt from /proc/device-tree, if there's local --command-line -option provided but there's no root= specified, kexec-tools will copy the root= -param from 1st kernel cmdline by default. In case one want kexec boot without -root= it will be impossible. - -Thus add the new option so that one can provide --dt-no-old-root for above -mentioned case. - -Reported-by: Jan Stodola -Signed-off-by: Dave Young -Signed-off-by: Simon Horman ---- - kexec/arch/ppc64/include/arch/options.h | 4 +++- - kexec/arch/ppc64/kexec-ppc64.c | 5 +++++ - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/ppc64/include/arch/options.h b/kexec/arch/ppc64/include/arch/options.h -index 4ad9b75..71632ec 100644 ---- a/kexec/arch/ppc64/include/arch/options.h -+++ b/kexec/arch/ppc64/include/arch/options.h -@@ -2,7 +2,8 @@ - #define KEXEC_ARCH_PPC64_OPTIONS_H - - #define OPT_ELF64_CORE (OPT_MAX+0) --#define OPT_ARCH_MAX (OPT_MAX+1) -+#define OPT_DT_NO_OLD_ROOT (OPT_MAX+1) -+#define OPT_ARCH_MAX (OPT_MAX+2) - - /* All 'local' loader options: */ - #define OPT_APPEND (OPT_ARCH_MAX+0) -@@ -14,6 +15,7 @@ - #define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ - { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \ -+ { "dt-no-old-root", 0, 0, OPT_DT_NO_OLD_ROOT }, \ - - #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" - -diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c -index 6e79f52..09ee025 100644 ---- a/kexec/arch/ppc64/kexec-ppc64.c -+++ b/kexec/arch/ppc64/kexec-ppc64.c -@@ -869,6 +869,8 @@ int file_types = sizeof(file_type) / sizeof(file_type[0]); - void arch_usage(void) - { - fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n"); -+ fprintf(stderr, " --dt-no-old-root Do not reuse old kernel root= param.\n" \ -+ " while creating flatten device tree.\n"); - } - - struct arch_options_t arch_options = { -@@ -895,6 +897,9 @@ int arch_process_options(int argc, char **argv) - case OPT_ELF64_CORE: - arch_options.core_header_type = CORE_TYPE_ELF64; - break; -+ case OPT_DT_NO_OLD_ROOT: -+ dt_no_old_root = 1; -+ break; - } - } - /* Reset getopt for the next pass; called in other source modules */ --- -2.5.0 - diff --git a/SOURCES/kexec-tools-2.0.8-ppc64-erase-unnecessary-segment-info-printing.patch b/SOURCES/kexec-tools-2.0.8-ppc64-erase-unnecessary-segment-info-printing.patch deleted file mode 100644 index 8f6a286..0000000 --- a/SOURCES/kexec-tools-2.0.8-ppc64-erase-unnecessary-segment-info-printing.patch +++ /dev/null @@ -1,30 +0,0 @@ -In ppc64 loading, it will print the segment information. This is not -wanted since other Archs don't have this. People even think there's -something wrong. So erase it to make it be consistent with other Archs. - -And if people really want to check these info, they can specify "-d" -option. They are printed in print_segments() too. - -Signed-off-by: Baoquan He ---- - kexec/arch/ppc64/kexec-elf-ppc64.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c -index ce10367..4a1540e 100644 ---- a/kexec/arch/ppc64/kexec-elf-ppc64.c -+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c -@@ -377,10 +377,6 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, - dbgprintf("opal_base is %llx\n", (unsigned long long) my_opal_base); - dbgprintf("opal_entry is %llx\n", (unsigned long long) my_opal_entry); - -- for (i = 0; i < info->nr_segments; i++) -- fprintf(stderr, "segment[%d].mem:%p memsz:%zu\n", i, -- info->segment[i].mem, info->segment[i].memsz); -- - return 0; - } - --- -1.9.0 - diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index 1865079..f1150bc 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -104,7 +104,7 @@ to_mount() { fi _fstype=$(findmnt -k -f -n -r -o FSTYPE $_dev) - _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev) + [[ -e /etc/fstab ]] && _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev) [ -z "$_options" ] && _options=$(findmnt -k -f -n -r -o OPTIONS $_dev) # with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd # kernel, filter it out here. diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 4288482..da23392 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools -Version: 2.0.7 -Release: 50%{?dist} +Version: 2.0.14 +Release: 17%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component. @@ -13,8 +13,9 @@ Source5: kdump.sysconfig.ppc64 Source6: kdump.sysconfig.ia64 Source7: mkdumprd Source8: kdump.conf -Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.0/makedumpfile-1.6.0.tar.gz +Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.1/makedumpfile-1.6.1.tar.gz Source10: kexec-kdump-howto.txt +Source11: fadump-howto.txt Source12: mkdumprd.8 Source14: 98-kexec.rules Source15: kdump.conf.5 @@ -26,7 +27,7 @@ Source21: kdump-in-cluster-environment.txt Source22: supported-kdump-targets.txt Source23: kdump-dep-generator.sh Source24: kdump-lib-initramfs.sh -Source25: kdump-anaconda-addon-003-21-g69da0f8.tar.gz +Source25: kdump-anaconda-addon-003-23-g80e78fb.tar.gz Source26: kdump.sysconfig.ppc64le Source27: kdump.sysconfig.aarch64 Source28: kdumpctl.8 @@ -42,6 +43,7 @@ Source103: dracut-kdump-error-handler.sh Source104: dracut-kdump-emergency.service Source105: dracut-kdump-error-handler.service Source106: dracut-kdump-capture.service +Source107: dracut-kdump-emergency.target Requires(post): systemd-units Requires(preun): systemd-units @@ -63,14 +65,11 @@ Obsoletes: diskdumputils netdump # # Patches 0 through 100 are meant for x86 kexec-tools enablement # -Patch0: kexec-tools-2.0.7-Add-persistent-memory-support.patch # # Patches 101 through 200 are meant for x86_64 kexec-tools enablement # -Patch101: kexec-tools-2.0.7-Provide-an-option-to-use-new-kexec-system-call.patch -Patch102: kexec-tools-2.0.7-makedumpfile-sadump-fix-segmentation-fault-on-sadump-re.patch -Patch103: kexec-tools-2.0.7-makedumpfile-sadump-fix-wrong-progress-report-on-sadump.patch +Patch101: kexec-tools-2.0.14-x86-Support-large-number-of-memory-ranges.patch # # Patches 201 through 300 are meant for ia64 kexec-tools enablement @@ -79,13 +78,7 @@ Patch103: kexec-tools-2.0.7-makedumpfile-sadump-fix-wrong-progress-report-on-sad # # Patches 301 through 400 are meant for ppc64 kexec-tools enablement # -Patch301: kexec-tools-2.0.7-kexec-ppc64-disabling-exception-handling-when-buildi.patch -Patch302: kexec-tools-2.0.7-kexec-ppc64-move-to-device-tree-version-17.patch -Patch303: kexec-tools-2.0.7-ppc64-kdump-Fix-ELF-header-endianess.patch -Patch304: kexec-tools-2.0.8-ppc64-erase-unnecessary-segment-info-printing.patch -# patch305 depends on generic patch patch680 thus patch 680 should be applied -# before patch305 -Patch305: kexec-tools-2.0.8-ppc64-add-arch-option-dt-no-old-root.patch +Patch301: kexec-tools-2.0.14-ppc64-Reduce-number-of-ELF-LOAD-segments.patch # # Patches 401 through 500 are meant for s390 kexec-tools enablement @@ -95,34 +88,35 @@ Patch305: kexec-tools-2.0.8-ppc64-add-arch-option-dt-no-old-root.patch # # -# Patches 601 onward are generic patches +# Patches 601 through 700 are meant for arm64 kexec-tools enablement # -Patch601: kexec-tools-2.0.3-disable-kexec-test.patch - -Patch650: kexec-tools-2.0.8-add-aarch64-to-configure.patch -Patch651: kexec-tools-2.0.8-kexec-Add-common-device-tree-routines.patch -Patch652: kexec-tools-2.0.8-arm64-Add-arm64-kexec-support.patch -Patch653: kexec-tools-2.0.8-arm64-Add-support-for-reuse-cmdline-option.patch -Patch654: kexec-tools-2.0.8-arm64-Add-support-for-kexec-lite-option.patch -Patch655: kexec-tools-2.0.8-arm64-Kexec-Add-support-for-binary-image.patch -Patch656: kexec-tools-2.0.8-bugfix-calc-correct-end-address-of-memory-ranges-in-.patch -Patch657: kexec-tools-2.0.8-arm64-fix-elf-related-header-issues.patch -Patch658: kexec-tools-2.0.8-arm64-kdump-create-elf-core-header.patch -Patch659: kexec-tools-2.0.8-arm64-kdump-append-kdump-specific-parameter-to-comma.patch -Patch660: kexec-tools-2.0.8-arm64-kdump-copy-dtb-file-into-crash-kernel-memory.patch -Patch661: kexec-tools-2.0.8-arm64-pass-mem-parameter-to-a-crash-dump-kernel.patch -Patch662: kexec-tools-2.0.8-arm64-clean-up-on-crash-dump.patch -Patch663: kexec-tools-2.0.8-arm64-remove-restriction-on-the-segments-order.patch -Patch664: kexec-tools-2.0.8-arm64-kdump-Add-support-for-binary-image.patch -Patch665: kexec-tools-2.0.8-arm64-wait-for-transmit-completion-before-next-chara.patch -Patch667: kexec-tools-2.0.8-Don-t-bail-out-if-check_cpu_nodes-fails.patch -Patch668: kexec-tools-2.0.8-arm64-Add-enable-disable-d-cache-support-for-purgato.patch -Patch669: kexec-tools-2.0.8-arm64-Pass-RAM-boundary-to-purgatory.patch -Patch670: kexec-tools-2.0.8-arm64-Enable-disable-D-cache-before-after-sha-verifi.patch -Patch671: kexec-tools-2.0.8-arm64-prefer-reading-memory-ranges-from-iomem-over-f.patch - - -Patch680: kexec-tools-2.0.8-fs2dt.c-move-copy-old-root-param-as-a-new-function.patch +Patch601: kexec-tools-2.0.14-Only-print-debug-message-when-failed-to-serach-for-k.patch +Patch602: kexec-tools-2.0.14-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch +Patch603: kexec-tools-2.0.14-kexec-generalize-and-rename-get_kernel_stext_sym.patch +Patch604: kexec-tools-2.0.14-arm64-identify-PHYS_OFFSET-correctly.patch +Patch605: kexec-tools-2.0.14-arm64-kdump-identify-memory-regions.patch +Patch606: kexec-tools-2.0.14-arm64-kdump-add-elf-core-header-segment.patch +Patch607: kexec-tools-2.0.14-arm64-kdump-set-up-kernel-image-segment.patch +Patch608: kexec-tools-2.0.14-arm64-kdump-set-up-other-segments.patch +Patch609: kexec-tools-2.0.14-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch +Patch610: kexec-tools-2.0.14-arm64-kdump-Add-support-for-binary-image-files.patch +Patch611: kexec-tools-2.0.14-kexec-Increase-the-upper-limit-for-RAM-segments.patch + +# +# Patches 701 onward are generic patches +# +Patch701: kexec-tools-2.0.3-disable-kexec-test.patch +Patch702: kexec-tools-2.0.14-build_mem_phdrs-check-if-p_paddr-is-invalid.patch +Patch703: kexec-tools-2.0.14-makedumpfile-show_mem_usage-calculate-page-offset-af.patch +Patch704: kexec-tools-2.0.14-makedumpfile-initial-call-cache_init-a-bit-early.patch +Patch705: kexec-tools-2.0.14-makedumpfile-x86_64-check-physical-address-in-PT_LOA.patch +Patch706: kexec-tools-2.0.14-makedumpfile-elf_info-kcore-check-for-invalid-physic.patch +Patch707: kexec-tools-2.0.14-makedumpfile-makedumpfile-Correct-the-calculation-of.patch +Patch708: kexec-tools-2.0.14-makedumpfile-makedumpfile-Discard-process_dump_load.patch +Patch709: kexec-tools-2.0.14-makedumpfile-makedumpfile-add-runtime-kaslr-offset-if-it-exists.patch +Patch710: kexec-tools-2.0.14-makedumpfile-sadump-set-info-page_size-before-cache_init.patch +Patch711: kexec-tools-2.0.14-makedumpfile-x86_64-calculate-page_offset-in-case-of-re-filtering.patch + # # Patch 701 through 800 are meant for kdump anaconda addon # @@ -161,38 +155,30 @@ tar -z -x -v -f %{SOURCE19} tar -z -x -v -f %{SOURCE25} -%patch0 -p1 %patch101 -p1 -%patch102 -p1 -%patch103 -p1 %patch301 -p1 -%patch302 -p1 -%patch303 -p1 -%patch304 -p1 %patch601 -p1 -%patch650 -p1 -%patch651 -p1 -%patch652 -p1 -%patch653 -p1 -%patch654 -p1 -%patch655 -p1 -%patch656 -p1 -%patch657 -p1 -%patch658 -p1 -%patch659 -p1 -%patch660 -p1 -%patch661 -p1 -%patch662 -p1 -%patch663 -p1 -%patch664 -p1 -%patch665 -p1 -%patch667 -p1 -%patch668 -p1 -%patch669 -p1 -%patch670 -p1 -%patch671 -p1 -%patch680 -p1 -%patch305 -p1 +%patch602 -p1 +%patch603 -p1 +%patch604 -p1 +%patch605 -p1 +%patch606 -p1 +%patch607 -p1 +%patch608 -p1 +%patch609 -p1 +%patch610 -p1 +%patch611 -p1 +%patch701 -p1 +%patch702 -p1 +%patch703 -p1 +%patch704 -p1 +%patch705 -p1 +%patch706 -p1 +%patch707 -p1 +%patch708 -p1 +%patch709 -p1 +%patch710 -p1 +%patch711 -p1 %ifarch ppc @@ -223,14 +209,15 @@ export CFLAGS="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2" rm -f kexec-tools.spec.in # setup the docs cp %{SOURCE10} . +cp %{SOURCE11} . cp %{SOURCE21} . cp %{SOURCE22} . make %ifarch %{ix86} x86_64 ia64 ppc64 s390x ppc64le aarch64 make -C eppic/libeppic -make -C makedumpfile-1.6.0 LINKTYPE=dynamic USELZO=on USESNAPPY=on -make -C makedumpfile-1.6.0 LDFLAGS="-I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so +make -C makedumpfile-1.6.1 LINKTYPE=dynamic USELZO=on USESNAPPY=on +make -C makedumpfile-1.6.1 LDFLAGS="-I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so %endif make -C kdump-anaconda-addon/po @@ -271,13 +258,13 @@ install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_unitdir}/kdump.service install -m 755 -D %{SOURCE23} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh %ifarch %{ix86} x86_64 ia64 ppc64 s390x ppc64le aarch64 -install -m 755 makedumpfile-1.6.0/makedumpfile $RPM_BUILD_ROOT/sbin/makedumpfile -install -m 644 makedumpfile-1.6.0/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz -install -m 644 makedumpfile-1.6.0/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz -install -m 644 makedumpfile-1.6.0/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample -install -m 755 makedumpfile-1.6.0/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so +install -m 755 makedumpfile-1.6.1/makedumpfile $RPM_BUILD_ROOT/sbin/makedumpfile +install -m 644 makedumpfile-1.6.1/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz +install -m 644 makedumpfile-1.6.1/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz +install -m 644 makedumpfile-1.6.1/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample +install -m 755 makedumpfile-1.6.1/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ -install -m 644 makedumpfile-1.6.0/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ +install -m 644 makedumpfile-1.6.1/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ %endif make -C kdump-anaconda-addon install DESTDIR=$RPM_BUILD_ROOT %find_lang kdump-anaconda-addon @@ -293,6 +280,7 @@ cp %{SOURCE103} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpb cp %{SOURCE104} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE104}} cp %{SOURCE105} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE105}} cp %{SOURCE106} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE106}} +cp %{SOURCE107} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE107}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}} @@ -400,6 +388,7 @@ done %doc COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc fadump-howto.txt %doc kdump-in-cluster-environment.txt %doc supported-kdump-targets.txt @@ -415,6 +404,96 @@ done %doc %changelog +* Tue Jun 27 2017 Pingfan Liu - 2.0.14-17 +- revert udev rule changes + +* Fri Jun 23 2017 Pingfan Liu - 2.0.14-16 +- udev rules: fix the hotplug rule file removing path + +* Thu Jun 22 2017 Pingfan Liu - 2.0.14-15 +- Revert "pc64/ppc64le: drop cpu online rule in 40-redhat.rules in kdump initramfs" +- udev rules: mask cpu hotplug rules + +* Mon Jun 12 2017 Pingfan Liu - 2.0.14-14 +- kdump.conf.5: clarify the fence_kdump_nodes option +- kdumpctl: for fence_kdump, the ipaddr of this node should be excluded from list + +* Wed Jun 7 2017 Pingfan Liu - 2.0.14-13 +- kdumpctl: change the shebang header to use /bin/bash + +* Thu Jun 1 2017 Pingfan Liu - 2.0.14-12 +- kdump.sysconfig.x86_64: remove kaslr in kdump kernel cmdline +- Revert commit b590153 kdump.sysconfig/x86_64: Add nokaslr to kdump kernel cmdline + +* Wed May 31 2017 Pingfan Liu - 2.0.14-11 +- makedumpfile: Fix refiltering, sadump and virsh dump + +* Mon May 15 2017 Pingfan Liu - 2.0.14-10 +- kdumpctl: call strip_comments only when necessary to speedup +- Revert "kdumpctl: improve "while read" time for /etc/kdump.conf" + +* Tue May 9 2017 Pingfan Liu - 2.0.14-9 +- kdumpctl: bail out earlier in case of no reserved memory +- kdumpctrl: kdump feasibility should fail if no crash memory +- kdumpctl: improve "while read" time for /etc/kdump.conf +- kdumpctl: update check_dump_fs_modified() to use "lsinitrd -f" +- kdumpctl: improve check_wdt_modified() +- kdumpctl: remove is_mode_switched() +- arm64: cmdline: modify to optimize size for memory reservation + +* Mon May 8 2017 Pingfan Liu - 2.0.14-8 +- kdump.sysconfig/x86_64: Add nokaslr to kdump kernel cmdline + +* Fri Apr 28 2017 Pingfan Liu - 2.0.14-7 +- arm64: Increase the upper limit for RAM segments +- kdump: Introduce 'force_no_rebuild' option +- kdump-lib-initramfs.sh: ignore the failure of echo +- use "systemctl reboot -f" for reboot action + +* Thu Apr 13 2017 Pingfan Liu - 2.0.14-6 +- Update kdump anaconda addon + +* Mon Apr 10 2017 Pingfan Liu - 2.0.14-5 +- ppc64: Reduce number of ELF LOAD segments +- kexec-kdump-howto: Include notes about using debug kernel as crash kernel +- Correct two typos in kdumpctl and kdump.conf + +* Sat Apr 1 2017 Pingfan Liu - 2.0.14-4 +- kdump-emergency: fix "Transaction is destructive" emergency failure +- x86: Support large number of memory ranges + +* Mon Mar 20 2017 Pingfan Liu - 2.0.14-3 +- arm64: backport latest kdump patches +- Fix `makedumpfile --mem-usage /proc/kcore` +- kdump-lib.sh: fix incorrect usage with pipe as input for grep -q in is_pcs_fence_kdump() + +* Mon Mar 6 2017 Pingfan Liu - 2.0.14-2 +- kdumpctl: check the existence of /sys/kernel/security/securelevel +- kdump.sysconfig.x86_64: Remove 'notsc' from kdump kernel cmdline +- kdump.sysconfig: add KDUMP_COMMANDLINE_REMOVE for aarch64 and ia64 +- kdump.sysconfig: add KDUMP_COMMANDLINE_REMOVE +- Document: fix incorrect link in fadump-how.txt +- kexec-tools.spec: add %doc for fadump-howto.txt + +* Fri Feb 24 2017 Pingfan Liu - 2.0.14-1 +- rebase kexec-tools from 2.0.7 to 2.0.14 + +* Thu Feb 23 2017 Pingfan Liu - 2.0.7-54 +- fix the build error of Release 2.0.7-53 + +* Thu Feb 23 2017 Pingfan Liu - 2.0.7-53 +- makedumpfile: rebase makedumpfile from 1.6.0 to 1.6.1 + +* Thu Feb 23 2017 Pingfan Liu - 2.0.7-52 +- kdumpctl: check /etc/fstab modification only when it exists +- kdumpctl: remove duplicate statement +- kdumpctl: Kill duplicate code related to file modication check +- fadump: restore default initrd when fadump mode is disabled +- kdump/fadump: fix network interface name when switching from fadump to kdump + +* Thu Feb 23 2017 Pingfan Liu - 2.0.7-51 +- Update kdump anaconda addon + * Mon Sep 05 2016 Baoquan He - 2.0.7-50 - spec: Update to add dependency on dracut-network version >= 033-449 - mkdumprd: Do not add "nfs" dracut module explicitly