diff --git a/SOURCES/98-kexec.rules.ppc64 b/SOURCES/98-kexec.rules.ppc64 new file mode 100644 index 0000000..9d783a0 --- /dev/null +++ b/SOURCES/98-kexec.rules.ppc64 @@ -0,0 +1,15 @@ +SUBSYSTEM=="cpu", ACTION=="online", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload" + +GOTO="kdump_reload_end" + +LABEL="kdump_reload" + +# If kdump is not loaded, calling "kdumpctl reload" will end up +# doing nothing, but it and systemd-run will always generate +# extra logs for each call, so trigger the "kdumpctl reload" +# only if kdump service is active to avoid unnecessary logs +RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet /usr/bin/kdumpctl reload'" + +LABEL="kdump_reload_end" diff --git a/SOURCES/dracut-kdump.sh b/SOURCES/dracut-kdump.sh index 42ba37f..816760f 100755 --- a/SOURCES/dracut-kdump.sh +++ b/SOURCES/dracut-kdump.sh @@ -144,7 +144,6 @@ read_kdump_conf() 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 dracut_args) config_val=$(get_dracut_args_target "$config_val") @@ -160,7 +159,7 @@ read_kdump_conf() add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val" ;; esac - done < $KDUMP_CONF + done <<< "$(read_strip_comments $KDUMP_CONF)" } fence_kdump_notify() diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index c833bfe..f106259 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -445,7 +445,6 @@ kdump_install_conf() { 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 ext[234]|xfs|btrfs|minix|raw) sed -i -e "s#^$config_opt[[:space:]]\+$config_val#$config_opt $(kdump_to_udev_name $config_val)#" ${initdir}/tmp/$$-kdump.conf @@ -468,7 +467,7 @@ kdump_install_conf() { dracut_install "${config_val%%[[:blank:]]*}" ;; esac - done < /etc/kdump.conf + done <<< "$(read_strip_comments /etc/kdump.conf)" default_dump_target_install_conf diff --git a/SOURCES/kdump-lib-initramfs.sh b/SOURCES/kdump-lib-initramfs.sh index 2c18c87..a11ba10 100755 --- a/SOURCES/kdump-lib-initramfs.sh +++ b/SOURCES/kdump-lib-initramfs.sh @@ -26,7 +26,6 @@ get_kdump_confs() 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 path) KDUMP_PATH="$config_val" @@ -71,7 +70,7 @@ get_kdump_confs() esac ;; esac - done < $KDUMP_CONF + done <<< "$(read_strip_comments $KDUMP_CONF)" if [ -z "$CORE_COLLECTOR" ]; then CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR" diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index 043800a..fd94fb8 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -61,6 +61,14 @@ strip_comments() echo $@ | sed -e 's/\(.*\)#.*/\1/' } +# Read from kdump config file stripping all comments +read_strip_comments() +{ + # strip heading spaces, and print any content starting with + # neither space or #, and strip everything after # + sed -n -e "s/^\s*\([^# \t][^#]\+\).*/\1/gp" $1 +} + # Check if fence kdump is configured in Pacemaker cluster is_pcs_fence_kdump() { @@ -337,6 +345,11 @@ is_ipv6_address() echo $1 | grep -q ":" } +has_hpwdt() +{ + cat /proc/modules | grep -q hpwdt +} + # get ip address or hostname from nfs/ssh config value get_remote_host() { @@ -508,13 +521,62 @@ get_dracut_args_target() echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1 } -# Get currently loaded modules -# sorted, and delimited by newline -get_loaded_kernel_modules() -{ - local modules=( ) - while read _module _size _used _used_by; do - modules+=( "$_module" ) - done <<< "$(lsmod | sed -n '1!p')" - printf '%s\n' "${modules[@]}" | sort +# get_maj_min +# Prints the major and minor of a device node. +# Example: +# $ get_maj_min /dev/sda2 +# 8:2 +get_maj_min() { + local _maj _min _majmin + _majmin="$(stat -L -c '%t:%T' "$1" 2>/dev/null)" + printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))" +} + +# Not every device in /dev/mapper should be examined. +# If it is an LVM device, touch only devices which have /dev/VG/LV symlink. +lvm_internal_dev() { + local dev_dm_dir=/sys/dev/block/$1/dm + [[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device + local DM_VG_NAME DM_LV_NAME DM_LV_LAYER + eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null) + [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this! + [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]] +} + +check_vol_slaves_all() { + local _lv _vg _pv _majmin + _majmin="$2" + _lv="/dev/block/$_majmin" + _dm="/sys/dev/block/$_majmin/dm" + [[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || return 1 + _vg=$(dmsetup splitname --noheadings -o vg_name $(<"$_dm/name") ) + # strip space + _vg="${_vg//[[:space:]]/}" + if [[ $_vg ]]; then + for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null) + do + check_block_and_slaves_all $1 $(get_maj_min $_pv) + done + return 0 + fi + return 1 +} + +check_block_and_slaves_all() { + local _x _ret=1 + [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry. + if ! lvm_internal_dev $2 && "$1" $2; then + _ret=0 + fi + check_vol_slaves_all "$@" && return 0 + if [[ -f /sys/dev/block/$2/../dev ]] && [[ /sys/dev/block/$2/../subsystem -ef /sys/class/block ]]; then + check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0 + fi + [[ -d /sys/dev/block/$2/slaves ]] || return 1 + for _x in /sys/dev/block/$2/slaves/*; do + [[ -f $_x/dev ]] || continue + [[ $_x/subsystem -ef /sys/class/block ]] || continue + check_block_and_slaves_all $1 $(<"$_x/dev") && _ret=0 + done + return $_ret } diff --git a/SOURCES/kdump.conf b/SOURCES/kdump.conf index 57af7b6..286ad27 100644 --- a/SOURCES/kdump.conf +++ b/SOURCES/kdump.conf @@ -32,7 +32,7 @@ # # # - Will mount -t , and copy -# /proc/vmcore to //%DATE/. +# /proc/vmcore to //%HOST_IP-%DATE/. # NOTE: can be a device node, label or uuid. # It's recommended to use persistent device names # such as /dev/vg/. diff --git a/SOURCES/kdump.conf.5 b/SOURCES/kdump.conf.5 index 11b1fad..990076e 100644 --- a/SOURCES/kdump.conf.5 +++ b/SOURCES/kdump.conf.5 @@ -55,7 +55,7 @@ The default value is /root/.ssh/kdump_id_rsa. .B .RS Will mount -t , and copy /proc/vmcore to -//%DATE/. NOTE: can be a device node, label +//%HOST_IP-%DATE/. NOTE: can be a device node, label or uuid. It's recommended to use persistent device names such as /dev/vg/. Otherwise it's suggested to use label or uuid. .RE diff --git a/SOURCES/kdump.sysconfig b/SOURCES/kdump.sysconfig index d44c8ae..30ef461 100644 --- a/SOURCES/kdump.sysconfig +++ b/SOURCES/kdump.sysconfig @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE -KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices" +KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdump.sysconfig.aarch64 b/SOURCES/kdump.sysconfig.aarch64 index 8a8400a..63bb46e 100644 --- a/SOURCES/kdump.sysconfig.aarch64 +++ b/SOURCES/kdump.sysconfig.aarch64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" # This variable lets us append arguments to the current kdump commandline # 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" +KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 swiotlb=noforce cma=0 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 rootflags=nofail novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdump.sysconfig.ppc64 b/SOURCES/kdump.sysconfig.ppc64 index 38caf75..6727f94 100644 --- a/SOURCES/kdump.sysconfig.ppc64 +++ b/SOURCES/kdump.sysconfig.ppc64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" # This variable lets us append arguments to the current kdump commandline # 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" +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 novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdump.sysconfig.ppc64le b/SOURCES/kdump.sysconfig.ppc64le index 38caf75..6727f94 100644 --- a/SOURCES/kdump.sysconfig.ppc64le +++ b/SOURCES/kdump.sysconfig.ppc64le @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" # This variable lets us append arguments to the current kdump commandline # 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" +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 novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdump.sysconfig.s390x b/SOURCES/kdump.sysconfig.s390x index 96b3d1b..6299651 100644 --- a/SOURCES/kdump.sysconfig.s390x +++ b/SOURCES/kdump.sysconfig.s390x @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" # This variable lets us append arguments to the current kdump commandline # 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" +KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never novmcoredd" # Any additional /sbin/mkdumprd arguments required. MKDUMPRD_ARGS="" diff --git a/SOURCES/kdump.sysconfig.x86_64 b/SOURCES/kdump.sysconfig.x86_64 index 9595271..61ad9c9 100644 --- a/SOURCES/kdump.sysconfig.x86_64 +++ b/SOURCES/kdump.sysconfig.x86_64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug kaslr" # This variable lets us append arguments to the current kdump commandline # 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 nokaslr" +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 nokaslr novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index d80bec8..89fd73b 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -148,6 +148,9 @@ prepare_cmdline() if [ ! -z ${id} ] ; then cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id}) fi + if has_hpwdt; then + cmdline="${cmdline} rd.driver.pre=hpwdt" + fi KDUMP_COMMANDLINE=$cmdline } @@ -314,7 +317,6 @@ check_config() ;; 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; @@ -329,7 +331,7 @@ check_config() return 1; ;; esac - done < $KDUMP_CONFIG_FILE + done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)" check_default_config || return 1 @@ -445,6 +447,9 @@ check_dump_fs_modified() local _old_dev _old_mntpoint _old_fstype local _new_dev _new_mntpoint _new_fstype local _target _path _dracut_args + local _target_drivers _module_name + + local _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | tr '\n' ' ')" # No need to check in case of mount target specified via "dracut_args". if is_mount_in_dracut_args; then @@ -473,6 +478,38 @@ check_dump_fs_modified() fi fi + _record_block_drivers() { + local _drivers + if [[ -b /dev/block/$1 ]]; then + _drivers=$(udevadm info -a "/dev/block/$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') + fi + if [[ -b $1 ]]; then + _drivers=$(udevadm info -a "$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') + fi + for _driver in $_drivers; do + if ! [[ " $_target_drivers " == *" $_driver "* ]]; then + _target_drivers="$_target_drivers $_driver" + fi + done + return 1 + } + + check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")" + for _driver in $_target_drivers; do + # Older version of kmod util doesn't give module name, so follow Kbuild's + # name-fix rule and deduce the name. + _module_name=$(echo "$_driver" | sed "s/\(,\|-\)/_/g") + # Target is mounted already, if module is not included by current kernel, + # could be a deprecated/invalid driver name or builtin module + if ! (grep -q "\b$_module_name\b" /proc/modules); then + continue + fi + if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then + echo "Detected change in block device driver, $_module_name is not included" + return 1 + fi + done + if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then _new_dev=$_target else @@ -570,31 +607,6 @@ check_wdt_modified() return 1 } -check_kmodules_modified() -{ - # always sort again to avoid LANG/LC inconsistent problem - local _old_modules="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | sort)" - local _new_modules="$(get_loaded_kernel_modules | sort)" - - [[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list is absent or empty" - - local _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules")) - local _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules")) - - if [ "$_old_modules" != "$_new_modules" ]; then - echo "Detected change(s) of loaded kernel modules list:" - [[ -n $_added_modules ]] && for _module in $_added_modules; do - echo " +$_module" - done - [[ -n $_dropped_modules ]] && for _module in $_dropped_modules; do - echo " -$_module" - done - return 1 - fi - - return 0 -} - # returns 0 if system is not modified # returns 1 if system is modified # returns 2 if system modification is invalid @@ -622,11 +634,6 @@ check_system_modified() return 1 fi - check_kmodules_modified - if [ $? -ne 0 ]; then - return 1 - fi - return 0 } @@ -787,7 +794,6 @@ check_ssh_config() 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) @@ -796,17 +802,15 @@ 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 ;; *) ;; esac - done < $KDUMP_CONFIG_FILE + done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)" #make sure they've configured kdump.conf for ssh dumps local SSH_TARGET=`echo -n $DUMP_TARGET | sed -n '/.*@/p'` @@ -1222,7 +1226,8 @@ reload() fi if [ $DEFAULT_DUMP_MODE == "fadump" ]; then - stop_fadump + reload_fadump + return $? else stop_kdump fi @@ -1278,6 +1283,26 @@ stop_kdump() return 0 } +reload_fadump() +{ + echo 1 > $FADUMP_REGISTER_SYS_NODE + if [ $? == 0 ]; then + echo "fadump: re-registered successfully" + return 0 + else + # FADump could fail on older kernel where re-register + # support is not enabled. Try stop/start from userspace + # to handle such scenario. + stop_fadump + if [ $? == 0 ]; then + start_fadump + return $? + fi + fi + + return 1 +} + stop() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then diff --git a/SOURCES/kexec-kdump-howto.txt b/SOURCES/kexec-kdump-howto.txt index 3b29bbf..2c51c6d 100644 --- a/SOURCES/kexec-kdump-howto.txt +++ b/SOURCES/kexec-kdump-howto.txt @@ -112,6 +112,12 @@ 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. +Besides, since kdump needs to access /proc/kallsyms during a kernel +loading if KASLR is enabled, check /proc/sys/kernel/kptr_restrict to +make sure that the content of /proc/kallsyms is exposed correctly. +We recommend to set the value of kptr_restrict to '1'. Otherwise +capture kernel loading could fail. + 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 @@ -669,6 +675,24 @@ not been written in watchdog-core framework then this option will not have any effect and module will not be added. Please note that only systemd watchdog daemon is supported as watchdog kick application. +Notes on device dump: + +Device dump allows drivers to append dump data to vmcore, so you can +collect driver specified debug info. Since the drivers could append the +data without any limit and the data is stored in memory, this may +bring a significant memory stress. So device dump is presently +disabled by default by passing "novmcoredd" command line option to the +kdump capture kernel. If you want to collect debug data with +device dump, you need to modify "KDUMP_COMMANDLINE_APPEND=" value in +'/etc/sysconfig/kdump' and remove the "novmcoredd" option. +You also need to increase the "crashkernel=" value accordingly in case +of OOM issues with kdump kernel. Also the kdump initramfs won't +automatically include the device drivers which support device dump, +(it includes only device drivers that are required for dump target +setup). So, to ensure the device dump data is included in the vmcore, +you need to explicitly add related device drivers by using +"extra_modules" option in /etc/kdump.conf + Parallel Dumping Operation ========================== Kexec allows kdump using multiple cpus. So parallel feature can accelerate diff --git a/SOURCES/kexec-tools-2.0.15-i386-kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch b/SOURCES/kexec-tools-2.0.15-i386-kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch new file mode 100644 index 0000000..c6a43c6 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-i386-kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch @@ -0,0 +1,34 @@ +From 1ac3e4a570005707260ea3e74ac011bd926b168b Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Thu, 6 Sep 2018 13:56:18 +0800 +Subject: [PATCH] kdump: fix an error that can not parse the e820 reserved + region + +When kexec-tools load the kernel and initramfs for kdump, kexec-tools will +read /proc/iomem and recreate the e820 ranges for kdump kernel. But it fails +to parse the e820 reserved region, because the memcmp() is case sensitive +when comparing the string. In fact, it may be "Reserved" or "reserved" in +the /proc/iomem, so we have to fix these cases. + +Signed-off-by: Lianbo Jiang +Reviewed-by: Dave Young +Signed-off-by: Simon Horman +--- + kexec/arch/i386/crashdump-x86.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c +index 437e8a8..140f45b 100644 +--- a/kexec/arch/i386/crashdump-x86.c ++++ b/kexec/arch/i386/crashdump-x86.c +@@ -289,6 +289,8 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, + type = RANGE_PMEM; + } else if(memcmp(str,"reserved\n",9) == 0 ) { + type = RANGE_RESERVED; ++ } else if (memcmp(str, "Reserved\n", 9) == 0) { ++ type = RANGE_RESERVED; + } else if (memcmp(str, "GART\n", 5) == 0) { + gart_start = start; + gart_end = end; +-- +2.17.1 diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Prepare-paddr_to_vaddr-for-arch-specific-p2v-c.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Prepare-paddr_to_vaddr-for-arch-specific-p2v-c.patch deleted file mode 100644 index 86f6a40..0000000 --- a/SOURCES/kexec-tools-2.0.15-makedumpfile-Prepare-paddr_to_vaddr-for-arch-specific-p2v-c.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 9eb5a31bc2d7f6af88459b89c414fe144e7491f8 Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Thu, 8 Nov 2018 14:26:43 -0500 -Subject: [PATCH] [PATCH] Prepare paddr_to_vaddr() for arch-specific p2v conversion - -Currently, conversion from physical address to virtual address in ---mem-usage option is "paddr + PAGE_OFFSET", which was written for -x86_64, but it's not suitable especially for arm64. - -This patch introduces paddr_to_vaddr() macro to get prepared for -arch-specific physical to virtual conversion. - -Tested-by: Bhupesh Sharma -Signed-off-by: Kazuhito Hagio ---- - elf_info.c | 7 ++++--- - makedumpfile.h | 11 +++++++++++ - 2 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/makedumpfile-1.6.2/elf_info.c b/makedumpfile-1.6.2/elf_info.c -index 711601a170c7..1d33e96684b6 100644 ---- a/makedumpfile-1.6.2/elf_info.c -+++ b/makedumpfile-1.6.2/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 = paddr_to_vaddr(vmcoreinfo_addr); - - for (i = 0; i < num_pt_loads; ++i) { - struct pt_load_segment *p = &pt_loads[i]; -@@ -810,10 +810,11 @@ static int exclude_segment(struct pt_load_segment **pt_loads, - int i, j, tidx = -1; - unsigned long long vstart, vend, kvstart, kvend; - struct pt_load_segment temp_seg = {0}; -- kvstart = (ulong)start + PAGE_OFFSET; -- kvend = (ulong)end + PAGE_OFFSET; - unsigned long size; - -+ kvstart = paddr_to_vaddr(start); -+ kvend = paddr_to_vaddr(end); -+ - for (i = 0; i < (*num_pt_loads); i++) { - vstart = (*pt_loads)[i].virt_start; - vend = (*pt_loads)[i].virt_end; -diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h -index 5f7a1dcf3b2f..010a9ce302bd 100644 ---- a/makedumpfile-1.6.2/makedumpfile.h -+++ b/makedumpfile-1.6.2/makedumpfile.h -@@ -929,6 +929,8 @@ typedef unsigned long pgd_t; - static inline int stub_true() { return TRUE; } - static inline int stub_true_ul(unsigned long x) { return TRUE; } - static inline int stub_false() { return FALSE; } -+#define paddr_to_vaddr_general(X) ((X) + PAGE_OFFSET) -+ - #ifdef __aarch64__ - int get_phys_base_arm64(void); - int get_machdep_info_arm64(void); -@@ -938,6 +940,7 @@ int get_xen_basic_info_arm64(void); - int get_xen_info_arm64(void); - #define find_vmemmap() stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_arm64(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define get_phys_base() get_phys_base_arm64() - #define get_machdep_info() get_machdep_info_arm64() - #define get_versiondep_info() get_versiondep_info_arm64() -@@ -958,6 +961,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr); - #define get_versiondep_info() stub_true() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_arm(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* arm */ -@@ -972,6 +976,7 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr); - #define get_versiondep_info() get_versiondep_info_x86() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_x86(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* x86 */ -@@ -989,6 +994,7 @@ unsigned long long vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pag - #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 paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* x86_64 */ -@@ -1004,6 +1010,7 @@ int arch_crashkernel_mem_size_ppc64(void); - #define get_versiondep_info() get_versiondep_info_ppc64() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() arch_crashkernel_mem_size_ppc64() - #endif /* powerpc64 */ -@@ -1017,6 +1024,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr); - #define get_versiondep_info() stub_true() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_ppc(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* powerpc32 */ -@@ -1031,6 +1039,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr); - #define get_versiondep_info() stub_true() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) is_iomem_phys_addr_s390x(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* s390x */ -@@ -1045,6 +1054,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr); - #define get_versiondep_info() stub_true() - #define get_kaslr_offset(X) stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_ia64(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define VADDR_REGION(X) (((unsigned long)(X)) >> REGION_SHIFT) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() -@@ -1059,6 +1069,7 @@ unsigned long long vaddr_to_paddr_sparc64(unsigned long vaddr); - #define get_phys_base() get_phys_base_sparc64() - #define get_versiondep_info() get_versiondep_info_sparc64() - #define vaddr_to_paddr(X) vaddr_to_paddr_sparc64(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) - #define is_phys_addr(X) stub_true_ul(X) - #define arch_crashkernel_mem_size() stub_false() - #endif /* sparc64 */ --- -2.7.4 diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-Update-help-text-to-indicate-mem-usage-is-supp.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-Update-help-text-to-indicate-mem-usage-is-supp.patch new file mode 100644 index 0000000..8d83fbe --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-Update-help-text-to-indicate-mem-usage-is-supp.patch @@ -0,0 +1,39 @@ +From 29dbb597089981a5e3c97ae4f768ff8a22094294 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Thu, 25 Oct 2018 11:48:27 +0530 +Subject: [PATCH] [PATCH] Update help text to indicate --mem-usage is supported + on archs other than x86_64 + +Commit 8449bda73ab14516d4bf81d29503c1ea203bb865 ("Documentation: +Update documentation regarding --mem-usage' option"), updated the +makedumpfile man page to indicate that this option is now +supported on x86_64, arm64, ppc64 and s390x. + +However, the help text for makedumpfile (which one can see +by running 'makedumpfile --help'), still reflects the old +support status, i.e. this option is only supported on x86_64. + +This patch changes the help text to be in sync with the man +page text. + +Signed-off-by: Bhupesh Sharma +--- + print_info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.2/print_info.c b/makedumpfile-1.6.2/print_info.c +index 732d5b806c24..0be12ea8803c 100644 +--- a/makedumpfile-1.6.2/print_info.c ++++ b/makedumpfile-1.6.2/print_info.c +@@ -300,7 +300,7 @@ print_usage(void) + MSG(" necessary to specify [-x VMLINUX] or [-i VMCOREINFO].\n"); + MSG("\n"); + MSG(" [--mem-usage]:\n"); +- MSG(" This option is only for x86_64.\n"); ++ MSG(" This option is currently supported on x86_64, arm64, ppc64 and s390x.\n"); + MSG(" This option is used to show the page numbers of current system in different\n"); + MSG(" use. It should be executed in 1st kernel. By the help of this, user can know\n"); + MSG(" how many pages is dumpable when different dump_level is specified. It analyzes\n"); +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-restore-info-page_offset-and-implement-paddr_t.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-restore-info-page_offset-and-implement-paddr_t.patch deleted file mode 100644 index 10a3ca0..0000000 --- a/SOURCES/kexec-tools-2.0.15-makedumpfile-arm64-restore-info-page_offset-and-implement-paddr_t.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 91dc4cab62568605a274dd2260e863df2ade0230 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Thu, 27 Dec 2018 15:26:16 +0530 -Subject: makedumpfile/arm64: Fix 'info->page_offset' calculation - -This patch is a partial backport of the makedumpfile commit -bc8b3bbf41580723435d5d4c6da17db3c9e5ad6d. - -Since the upstream makedumpfile implementation had intermediate patches -applied which eased 'page_offset' calculation for arm64 arch, but these -were reverted via bc8b3bbf41580723435d5d4c6da17db3c9e5ad6d. - -So, its not very useful to backport all those intermediate patches. - -Signed-off-by: Bhupesh Sharma ---- - arch/arm64.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- - makedumpfile.c | 6 +++++ - makedumpfile.h | 7 +++++- - 3 files changed, 82 insertions(+), 6 deletions(-) - -diff --git a/makedumpfile-1.6.2/arch/arm64.c b/makedumpfile-1.6.2/arch/arm64.c -index fe49d408186e..491010846f8e 100644 ---- a/makedumpfile-1.6.2/arch/arm64.c -+++ b/makedumpfile-1.6.2/arch/arm64.c -@@ -168,11 +168,76 @@ get_kvbase_arm64(void) - int - get_phys_base_arm64(void) - { -- info->phys_base = NUMBER(PHYS_OFFSET); -+ int i; -+ unsigned long long phys_start; -+ unsigned long long virt_start; -+ -+ if (NUMBER(PHYS_OFFSET) != NOT_FOUND_NUMBER) { -+ info->phys_base = NUMBER(PHYS_OFFSET); -+ DEBUG_MSG("phys_base : %lx (vmcoreinfo)\n", -+ info->phys_base); -+ return TRUE; -+ } - -- DEBUG_MSG("phys_base : %lx\n", info->phys_base); -+ if (get_num_pt_loads() && PAGE_OFFSET) { -+ for (i = 0; -+ get_pt_load(i, &phys_start, NULL, &virt_start, NULL); -+ i++) { -+ if (virt_start != NOT_KV_ADDR -+ && virt_start >= PAGE_OFFSET -+ && phys_start != NOT_PADDR) { -+ info->phys_base = phys_start - -+ (virt_start & ~PAGE_OFFSET); -+ DEBUG_MSG("phys_base : %lx (pt_load)\n", -+ info->phys_base); -+ return TRUE; -+ } -+ } -+ } - -- return TRUE; -+ ERRMSG("Cannot determine phys_base\n"); -+ return FALSE; -+} -+ -+unsigned long -+get_kaslr_offset_arm64(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); -+ DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset); -+ } -+ } -+ } -+ -+ if (vaddr >= __START_KERNEL_map && -+ vaddr < __START_KERNEL_map + info->kaslr_offset) { -+ DEBUG_MSG("info->kaslr_offset: %lx\n", 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; -+ } - } - - ulong -@@ -285,8 +350,8 @@ get_versiondep_info_arm64(void) - - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); - -- DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset, -- va_bits); -+ DEBUG_MSG("va_bits : %d\n", va_bits); -+ DEBUG_MSG("page_offset : %lx\n", info->page_offset); - - return TRUE; - } -diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c -index c9634cd42858..78ebced33e6a 100644 ---- a/makedumpfile-1.6.2/makedumpfile.c -+++ b/makedumpfile-1.6.2/makedumpfile.c -@@ -2339,6 +2339,7 @@ read_vmcoreinfo_basic_info(void) - break; - if (buf[i - 1] == '\n') - buf[i - 1] = '\0'; -+ - if (strncmp(buf, STR_OSRELEASE, strlen(STR_OSRELEASE)) == 0) { - get_release = TRUE; - /* if the release have been stored, skip this time. */ -@@ -2382,6 +2383,7 @@ read_vmcoreinfo_basic_info(void) - strlen(STR_CONFIG_PGTABLE_4)) == 0) - vt.mem_flags |= MEMORY_PAGETABLE_4L; - } -+ - if (!get_release || !info->page_size) { - ERRMSG("Invalid format in %s", info->name_vmcoreinfo); - return FALSE; -@@ -11084,6 +11086,10 @@ int show_mem_usage(void) - if (!get_page_offset()) - return FALSE; - -+ /* paddr_to_vaddr() on arm64 needs phys_base. */ -+ if (!get_phys_base()) -+ return FALSE; -+ - if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) - return FALSE; - -diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h -index 010a9ce302bd..177805935b71 100644 ---- a/makedumpfile-1.6.2/makedumpfile.h -+++ b/makedumpfile-1.6.2/makedumpfile.h -@@ -529,6 +529,8 @@ do { \ - #ifdef __aarch64__ - unsigned long get_kvbase_arm64(void); - #define KVBASE get_kvbase_arm64() -+#define __START_KERNEL_map (0xffffffff80000000UL) -+ - #endif /* aarch64 */ - - #ifdef __arm__ -@@ -938,9 +940,12 @@ unsigned long long vaddr_to_paddr_arm64(unsigned long vaddr); - int get_versiondep_info_arm64(void); - int get_xen_basic_info_arm64(void); - int get_xen_info_arm64(void); -+unsigned long get_kaslr_offset_arm64(unsigned long vaddr); -+#define paddr_to_vaddr_arm64(X) (((X) - info->phys_base) | PAGE_OFFSET) -+ - #define find_vmemmap() stub_false() - #define vaddr_to_paddr(X) vaddr_to_paddr_arm64(X) --#define paddr_to_vaddr(X) paddr_to_vaddr_general(X) -+#define paddr_to_vaddr(X) paddr_to_vaddr_arm64(X) - #define get_phys_base() get_phys_base_arm64() - #define get_machdep_info() get_machdep_info_arm64() - #define get_versiondep_info() get_versiondep_info_arm64() --- -2.7.4 diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-exclude-pages-that-are-logically-offline.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-exclude-pages-that-are-logically-offline.patch new file mode 100644 index 0000000..241c7f3 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-exclude-pages-that-are-logically-offline.patch @@ -0,0 +1,147 @@ +From adc459398196322830e3b4bfacfab941c5f75f3a Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Thu, 22 Nov 2018 11:09:38 +0100 +Subject: [PATCH] [PATCH] exclude pages that are logically offline + +Linux marks pages that are logically offline via a page flag (map count). +Such pages e.g. include pages infated as part of a balloon driver or +pages that were not actually onlined when onlining the whole section. + +While the hypervisor usually allows to read such inflated memory, we +basically read and dump data that is completely irrelevant. Also, this +might result in quite some overhead in the hypervisor. In addition, +we saw some problems under Hyper-V, whereby we can crash the kernel by +dumping, when reading memory of a partially onlined memory segment +(for memory added by the Hyper-V balloon driver). + +Therefore, don't read and dump pages that are marked as being logically +offline. + +Signed-off-by: David Hildenbrand +--- + makedumpfile.c | 34 ++++++++++++++++++++++++++++++---- + makedumpfile.h | 1 + + 2 files changed, 31 insertions(+), 4 deletions(-) + +diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c +index c9634cd..44c3aad 100644 +--- a/makedumpfile-1.6.2/makedumpfile.c ++++ b/makedumpfile-1.6.2/makedumpfile.c +@@ -88,6 +88,7 @@ mdf_pfn_t pfn_cache_private; + mdf_pfn_t pfn_user; + mdf_pfn_t pfn_free; + mdf_pfn_t pfn_hwpoison; ++mdf_pfn_t pfn_offline; + + mdf_pfn_t num_dumped; + +@@ -249,6 +250,21 @@ isHugetlb(unsigned long dtor) + && (SYMBOL(free_huge_page) == dtor)); + } + ++static int ++isOffline(unsigned long flags, unsigned int _mapcount) ++{ ++ if (NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE) == NOT_FOUND_NUMBER) ++ return FALSE; ++ ++ if (flags & (1UL << NUMBER(PG_slab))) ++ return FALSE; ++ ++ if (_mapcount == (int)NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE)) ++ return TRUE; ++ ++ return FALSE; ++} ++ + static inline unsigned long + calculate_len_buf_out(long page_size) + { +@@ -2258,6 +2274,8 @@ write_vmcoreinfo_data(void) + WRITE_NUMBER("PG_hwpoison", PG_hwpoison); + + WRITE_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE); ++ WRITE_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE", ++ PAGE_OFFLINE_MAPCOUNT_VALUE); + WRITE_NUMBER("phys_base", phys_base); + + WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); +@@ -2656,6 +2674,7 @@ read_vmcoreinfo(void) + READ_SRCFILE("pud_t", pud_t); + + READ_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE); ++ READ_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE", PAGE_OFFLINE_MAPCOUNT_VALUE); + READ_NUMBER("phys_base", phys_base); + #ifdef __aarch64__ + READ_NUMBER("VA_BITS", VA_BITS); +@@ -5918,6 +5937,12 @@ __exclude_unnecessary_pages(unsigned long mem_map, + else if (isHWPOISON(flags)) { + pfn_counter = &pfn_hwpoison; + } ++ /* ++ * Exclude pages that are logically offline. ++ */ ++ else if (isOffline(flags, _mapcount)) { ++ pfn_counter = &pfn_offline; ++ } + /* + * Unexcludable page + */ +@@ -7399,7 +7424,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) + */ + if (info->flag_cyclic) { + pfn_zero = pfn_cache = pfn_cache_private = 0; +- pfn_user = pfn_free = pfn_hwpoison = 0; ++ pfn_user = pfn_free = pfn_hwpoison = pfn_offline = 0; + pfn_memhole = info->max_mapnr; + } + +@@ -8674,7 +8699,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d + * Reset counter for debug message. + */ + pfn_zero = pfn_cache = pfn_cache_private = 0; +- pfn_user = pfn_free = pfn_hwpoison = 0; ++ pfn_user = pfn_free = pfn_hwpoison = pfn_offline = 0; + pfn_memhole = info->max_mapnr; + + /* +@@ -9619,7 +9644,7 @@ print_report(void) + pfn_original = info->max_mapnr - pfn_memhole; + + pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private +- + pfn_user + pfn_free + pfn_hwpoison; ++ + pfn_user + pfn_free + pfn_hwpoison + pfn_offline; + shrinking = (pfn_original - pfn_excluded) * 100; + shrinking = shrinking / pfn_original; + +@@ -9633,6 +9658,7 @@ print_report(void) + REPORT_MSG(" User process data pages : 0x%016llx\n", pfn_user); + REPORT_MSG(" Free pages : 0x%016llx\n", pfn_free); + REPORT_MSG(" Hwpoison pages : 0x%016llx\n", pfn_hwpoison); ++ REPORT_MSG(" Offline pages : 0x%016llx\n", pfn_offline); + REPORT_MSG(" Remaining pages : 0x%016llx\n", + pfn_original - pfn_excluded); + REPORT_MSG(" (The number of pages is reduced to %lld%%.)\n", +@@ -9660,7 +9686,7 @@ print_mem_usage(void) + pfn_original = info->max_mapnr - pfn_memhole; + + pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private +- + pfn_user + pfn_free + pfn_hwpoison; ++ + pfn_user + pfn_free + pfn_hwpoison + pfn_offline; + shrinking = (pfn_original - pfn_excluded) * 100; + shrinking = shrinking / pfn_original; + total_size = info->page_size * pfn_original; +diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h +index 5f7a1dc..a390582 100644 +--- a/makedumpfile-1.6.2/makedumpfile.h ++++ b/makedumpfile-1.6.2/makedumpfile.h +@@ -1874,6 +1874,7 @@ struct number_table { + long PG_hwpoison; + + long PAGE_BUDDY_MAPCOUNT_VALUE; ++ long PAGE_OFFLINE_MAPCOUNT_VALUE; + long SECTION_SIZE_BITS; + long MAX_PHYSMEM_BITS; + long HUGETLB_PAGE_DTOR; +-- +2.21.0 diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch new file mode 100644 index 0000000..b590bcc --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch @@ -0,0 +1,231 @@ +Delivered-To: bhsharma@gapps.redhat.com +Received: by 2002:a2e:e0a:0:0:0:0:0 with SMTP id 10csp381404ljo; + Fri, 21 Jun 2019 02:43:25 -0700 (PDT) +X-Google-Smtp-Source: APXvYqzT5Jnctz0U7KDu97glThU9nNU8uoBaTPDtgGoLDaTrBerwj871GlRx1br1kO3Xi9egk5Ga +X-Received: by 2002:a0c:d0fc:: with SMTP id b57mr43991751qvh.78.1561110205383; + Fri, 21 Jun 2019 02:43:25 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1561110205; cv=none; + d=google.com; s=arc-20160816; + b=UGnWY4xATAi/VC/zo6DWbisWbInCXQEb7saZdCpdFg6DjOXNGTGy8OoGOrKaF2an1F + /30UqiXL5Yd3KF5eCKmMCuvQ+CUwUKDAUtewF1t4iGMe6Z3aIi4z6mZaDZELpIIeYSOh + WO0qQC+gnyBlQuAbDBSo5NUprcZ8xMsCs0d5kZr3BVgGOXJtZgmIBVLV4yKHRjDW29Nn + P/pelr5UUYaNW1C0ILMv60vk0Py4VM5oRTQ4otxgkw9soGxUjTsMEA0X49vOdVrfXa9P + QZbvmXrMB22TNGHkWgPjAkHFxXakJEDq18fwX0dTuxTbx9vlFyaaBdv+CQ+yqfixS70j + +93w== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=message-id:date:subject:cc:to:from:delivered-to; + bh=0Hr1bq++ZN4c9flsD+ZIcevaW3VxsiFEPs30XoiYUL4=; + b=paFXhKPPrG7vRaUqzedY45uKY678PbjOiGQSyfzC6DSZFuZ4NepnUyEGwVmd+b0Scc + O6bzSXYRuXGALKasZkfkEeJLyJUldvlZcmcnGO64gmKGyEq8wmrGGG3J66y2M9UC22NI + PQ6u0bmWizODueS2cKkHJ+MsmkJ91523n359wDPTb5hyt25mZ/Ax9s7SfHzshVHjdvLx + Ugmod/BpgtWaxDUKoIdM4a6hM9UOLcyla/XE5HlJlijZHVa0rmQLvKqHBpdWD6FgacTJ + BF6xPn0fDSZqWz4LwElIuzRiF405Hp8cq4LxGvTZNVm4F9WK+QurgUq/Um/LeJWZ0fgF + kfTA== +ARC-Authentication-Results: i=1; mx.google.com; + spf=pass (google.com: domain gapps.redhat.com configured 209.132.183.28 as internal address) smtp.mailfrom=lijiang@redhat.com +Return-Path: +Received: from mx1.redhat.com (mx1.redhat.com. [209.132.183.28]) + by mx.google.com with ESMTPS id u34si1484288qtj.352.2019.06.21.02.43.25 + for + (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); + Fri, 21 Jun 2019 02:43:25 -0700 (PDT) +Received-SPF: pass (google.com: domain gapps.redhat.com configured 209.132.183.28 as internal address) +Authentication-Results: mx.google.com; + spf=pass (google.com: domain gapps.redhat.com configured 209.132.183.28 as internal address) smtp.mailfrom=lijiang@redhat.com +Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) + (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) + (No client certificate requested) + by mx1.redhat.com (Postfix) with ESMTPS id 8C7DB3004425 + for ; Fri, 21 Jun 2019 09:43:24 +0000 (UTC) +Received: by smtp.corp.redhat.com (Postfix) + id 8712D5D9E5; Fri, 21 Jun 2019 09:43:24 +0000 (UTC) +Delivered-To: bhsharma@redhat.com +Received: from localhost.localdomain.com (ovpn-12-71.pek2.redhat.com [10.72.12.71]) + by smtp.corp.redhat.com (Postfix) with ESMTP id BF70C5D9D2; + Fri, 21 Jun 2019 09:43:17 +0000 (UTC) +From: Lianbo Jiang +To: bhsharma@redhat.com +Cc: lijiang@redhat.com +Subject: [PATCH] x86_64: Add support for AMD Secure Memory Encryption +Date: Fri, 21 Jun 2019 17:43:12 +0800 +Message-Id: <20190621094312.3180-1-lijiang@redhat.com> +X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 +X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Fri, 21 Jun 2019 09:43:24 +0000 (UTC) + +On AMD machine with Secure Memory Encryption (SME) feature, if SME is +enabled, page tables contain a specific attribute bit (C-bit) in their +entries to indicate whether a page is encrypted or unencrypted. + +So get NUMBER(sme_mask) from vmcoreinfo, which stores the value of +the C-bit position, and drop it to obtain the true physical address. + +Signed-off-by: Lianbo Jiang +--- + arch/x86_64.c | 28 +++++++++++++++++++--------- + makedumpfile.c | 4 ++++ + makedumpfile.h | 1 + + 3 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/makedumpfile-1.6.2/arch/x86_64.c b/makedumpfile-1.6.2/arch/x86_64.c +index 33621f1f259c..d897e35f062e 100644 +--- a/makedumpfile-1.6.2/arch/x86_64.c ++++ b/makedumpfile-1.6.2/arch/x86_64.c +@@ -259,6 +259,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + { + unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte; + unsigned long pte_paddr, pte; ++ unsigned long entry_mask = ENTRY_MASK; + + /* + * Get PGD. +@@ -269,6 +270,10 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + if (page_dir == NOT_PADDR) + return NOT_PADDR; + } ++ ++ if (NUMBER(sme_mask) != NOT_FOUND_NUMBER) ++ entry_mask &= ~(NUMBER(sme_mask)); ++ + page_dir += pml4_index(vaddr) * sizeof(unsigned long); + if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) { + ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir); +@@ -285,7 +290,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + /* + * Get PUD. + */ +- pgd_paddr = pml4 & ENTRY_MASK; ++ pgd_paddr = pml4 & entry_mask; + pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long); + if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) { + ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr); +@@ -299,13 +304,13 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + return NOT_PADDR; + } + if (pgd_pte & _PAGE_PSE) /* 1GB pages */ +- return (pgd_pte & ENTRY_MASK & PGDIR_MASK) + ++ return (pgd_pte & entry_mask & PGDIR_MASK) + + (vaddr & ~PGDIR_MASK); + + /* + * Get PMD. + */ +- pmd_paddr = pgd_pte & ENTRY_MASK; ++ pmd_paddr = pgd_pte & entry_mask; + pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long); + if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) { + ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr); +@@ -319,13 +324,13 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + return NOT_PADDR; + } + if (pmd_pte & _PAGE_PSE) /* 2MB pages */ +- return (pmd_pte & ENTRY_MASK & PMD_MASK) + ++ return (pmd_pte & entry_mask & PMD_MASK) + + (vaddr & ~PMD_MASK); + + /* + * Get PTE. + */ +- pte_paddr = pmd_pte & ENTRY_MASK; ++ pte_paddr = pmd_pte & entry_mask; + pte_paddr += pte_index(vaddr) * sizeof(unsigned long); + if (!readmem(PADDR, pte_paddr, &pte, sizeof pte)) { + ERRMSG("Can't get pte (pte_paddr:%lx).\n", pte_paddr); +@@ -338,7 +343,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable) + ERRMSG("Can't get a valid pte.\n"); + return NOT_PADDR; + } +- return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr); ++ return (pte & entry_mask) + PAGEOFFSET(vaddr); + } + + unsigned long long +@@ -553,6 +558,7 @@ find_vmemmap_x86_64() + unsigned long pmd, tpfn; + unsigned long pvaddr = 0; + unsigned long data_addr = 0, last_data_addr = 0, start_data_addr = 0; ++ unsigned long pmask = PMASK; + /* + * data_addr is the paddr of the page holding the page structs. + * We keep lists of contiguous pages and the pfn's that their +@@ -569,6 +575,10 @@ find_vmemmap_x86_64() + ERRMSG("init_level4_pgt not found\n"); + return FAILED; + } ++ ++ if (NUMBER(sme_mask) != NOT_FOUND_NUMBER) ++ pmask &= ~(NUMBER(sme_mask)); ++ + pagestructsize = size_table.page; + hugepagesize = PTRS_PER_PMD * info->page_size; + vaddr_base = info->vmemmap_start; +@@ -597,7 +607,7 @@ find_vmemmap_x86_64() + return FAILED; + } + /* mask the pgd entry for the address of the pud page */ +- pud_addr &= PMASK; ++ pud_addr &= pmask; + if (pud_addr == 0) + continue; + /* read the entire pud page */ +@@ -610,7 +620,7 @@ find_vmemmap_x86_64() + /* pudp points to an entry in the pud page */ + for (pudp = (unsigned long *)pud_page, pudindex = 0; + pudindex < PTRS_PER_PUD; pudindex++, pudp++) { +- pmd_addr = *pudp & PMASK; ++ pmd_addr = *pudp & pmask; + /* read the entire pmd page */ + if (pmd_addr == 0) + continue; +@@ -652,7 +662,7 @@ find_vmemmap_x86_64() + * - we discontiguous page is a string of valids + */ + if (pmd) { +- data_addr = (pmd & PMASK); ++ data_addr = (pmd & pmask); + if (start_range) { + /* first-time kludge */ + start_data_addr = data_addr; +diff --git a/makedumpfile-1.6.2/makedumpfile.c b/makedumpfile-1.6.2/makedumpfile.c +index c9634cd42858..ed097c7e597a 100644 +--- a/makedumpfile-1.6.2/makedumpfile.c ++++ b/makedumpfile-1.6.2/makedumpfile.c +@@ -960,6 +960,8 @@ next_page: + read_size = MIN(info->page_size - PAGEOFFSET(paddr), size); + + pgaddr = PAGEBASE(paddr); ++ if (NUMBER(sme_mask) != NOT_FOUND_NUMBER) ++ pgaddr = pgaddr & ~(NUMBER(sme_mask)); + pgbuf = cache_search(pgaddr, read_size); + if (!pgbuf) { + ++cache_miss; +@@ -2248,6 +2250,7 @@ write_vmcoreinfo_data(void) + + WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES); + WRITE_NUMBER("N_ONLINE", N_ONLINE); ++ WRITE_NUMBER("sme_mask", sme_mask); + + WRITE_NUMBER("PG_lru", PG_lru); + WRITE_NUMBER("PG_private", PG_private); +@@ -2642,6 +2645,7 @@ read_vmcoreinfo(void) + + READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES); + READ_NUMBER("N_ONLINE", N_ONLINE); ++ READ_NUMBER("sme_mask", sme_mask); + + READ_NUMBER("PG_lru", PG_lru); + READ_NUMBER("PG_private", PG_private); +diff --git a/makedumpfile-1.6.2/makedumpfile.h b/makedumpfile-1.6.2/makedumpfile.h +index 5f7a1dcf3b2f..bc3a4555132a 100644 +--- a/makedumpfile-1.6.2/makedumpfile.h ++++ b/makedumpfile-1.6.2/makedumpfile.h +@@ -1860,6 +1860,7 @@ struct array_table { + struct number_table { + long NR_FREE_PAGES; + long N_ONLINE; ++ long sme_mask; + + /* + * Page flags +-- +2.17.1 + diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index 8da5c87..6e347ac 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -35,7 +35,10 @@ is_wdt_addition_needed [[ $? -eq 0 ]] && WDTCFG="-a watchdog" extra_modules="" -dracut_args=("--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg" $WDTCFG) +if has_hpwdt; then + extra_modules=hpwdt +fi +dracut_args=("--quiet" "--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg" $WDTCFG) OVERRIDE_RESETTABLE=0 add_dracut_arg() { @@ -440,7 +443,6 @@ fi 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 extra_modules) extra_modules="$extra_modules $config_val" @@ -492,13 +494,9 @@ do add_dracut_arg $config_val ;; *) - if [ -n $(echo $config_opt | grep "^#.*$") ] - then - continue - fi ;; esac -done < $conf_file +done <<< "$(read_strip_comments $conf_file)" handle_default_dump_target diff --git a/SOURCES/supported-kdump-targets.txt b/SOURCES/supported-kdump-targets.txt index c761489..ea56fb6 100644 --- a/SOURCES/supported-kdump-targets.txt +++ b/SOURCES/supported-kdump-targets.txt @@ -49,7 +49,7 @@ storage: network: Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna, cnic, netxen_nic, qlge, bnx2x, bnx, qlcnic, be2net, enic, - virtio-net, ixgbevf, igbvf) + virtio-net, ixgbevf, igbvf, atlantic) protocol: ipv4 bonding vlan diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index e83756f..87d8c46 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.15 -Release: 21%{?dist}.4 +Release: 33%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component. @@ -15,7 +15,8 @@ Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6. Source10: kexec-kdump-howto.txt Source11: fadump-howto.txt Source12: mkdumprd.8 -Source14: 98-kexec.rules +Source13: 98-kexec.rules +Source14: 98-kexec.rules.ppc64 Source15: kdump.conf.5 Source16: kdump.service Source18: kdump.sysconfig.s390x @@ -63,6 +64,7 @@ Obsoletes: diskdumputils netdump # # Patches 0 through 100 are meant for x86 kexec-tools enablement # +Patch0: kexec-tools-2.0.15-i386-kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch # # Patches 101 through 200 are meant for x86_64 kexec-tools enablement @@ -116,8 +118,9 @@ Patch719: kexec-tools-2.0.15-makedumpfile-Use-integer-arithmetics-for-th.patch Patch720: kexec-tools-2.0.15-makedumpfile-Use-monotonic-clock-to-calculate-ETA-and-s.patch Patch721: kexec-tools-2.0.15-makedumpfile-Check-if-clock_gettime-requires-lrt.patch Patch722: kexec-tools-2.0.15-makedumpfile-when-refiltering-initialize-refiltered-bitm.patch -Patch723: kexec-tools-2.0.15-makedumpfile-Prepare-paddr_to_vaddr-for-arch-specific-p2v-c.patch -Patch724: kexec-tools-2.0.15-makedumpfile-arm64-restore-info-page_offset-and-implement-paddr_t.patch +Patch723: kexec-tools-2.0.15-makedumpfile-Update-help-text-to-indicate-mem-usage-is-supp.patch +Patch724: kexec-tools-2.0.15-makedumpfile-exclude-pages-that-are-logically-offline.patch +Patch725: kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch # @@ -158,6 +161,7 @@ tar -z -x -v -f %{SOURCE19} tar -z -x -v -f %{SOURCE25} +%patch0 -p1 %patch101 -p1 %patch301 -p1 %patch302 -p1 @@ -188,6 +192,7 @@ tar -z -x -v -f %{SOURCE25} %patch722 -p1 %patch723 -p1 %patch724 -p1 +%patch725 -p1 %ifarch ppc @@ -262,9 +267,12 @@ install -m 644 %{SOURCE12} $RPM_BUILD_ROOT%{_mandir}/man8/mkdumprd.8 install -m 644 %{SOURCE28} $RPM_BUILD_ROOT%{_mandir}/man8/kdumpctl.8 install -m 755 %{SOURCE20} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib.sh install -m 755 %{SOURCE24} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib-initramfs.sh -%ifnarch s390x +%ifnarch s390x ppc64 ppc64le # For s390x the ELF header is created in the kdump kernel and therefore kexec # udev rules are not required +install -m 644 %{SOURCE13} $RPM_BUILD_ROOT%{_udevrulesdir}/98-kexec.rules +%endif +%ifarch ppc64 ppc64le install -m 644 %{SOURCE14} $RPM_BUILD_ROOT%{_udevrulesdir}/98-kexec.rules %endif install -m 644 %{SOURCE15} $RPM_BUILD_ROOT%{_mandir}/man5/kdump.conf.5 @@ -429,19 +437,50 @@ done %doc %changelog -* Mon Jun 10 2019 Bhupesh Sharma 2.0.15-21.4 -- [Hyper-V] Error applying Memory changes to larger size +* Sat Jun 22 2019 Bhupesh Sharma 2.0.15-33 +- makedumpfile: x86_64: Add support for AMD Secure Memory Encryption + [Fix the Fix the patch to make sure makedumpfile-1.6.2/ path is used] + +* Fri Jun 21 2019 Bhupesh Sharma 2.0.15-32 +- makedumpfile: exclude pages that are logically offline +- makedumpfile: x86_64: Add support for AMD Secure Memory Encryption + +* Mon Jun 10 2019 Bhupesh Sharma 2.0.15-31 +- Disable vmcore device dump by default + +* Wed May 22 2019 Bhupesh Sharma 2.0.15-30 +- Optimize kdumpctl restart and initramfs rebuild speed -* Fri Mar 22 2019 Bhupesh Sharma 2.0.15-21.3 -- makedumpfile/arm64: Fix 'info->page_offset' calculation (use correct - bug number) +* Thu May 9 2019 Bhupesh Sharma 2.0.15-29 +- Fix previous faulty initramfs rebuild triggering -* Fri Mar 22 2019 Bhupesh Sharma 2.0.15-21.2 -- makedumpfile/arm64: Fix 'info->page_offset' calculation +* Thu May 9 2019 Bhupesh Sharma 2.0.15-28 +- kexec.rules: create dedicated udev rules for ppc64 -* Tue Mar 12 2019 Bhupesh Sharma 2.0.15-21.1 +* Wed Mar 27 2019 Bhupesh Sharma 2.0.15-27 +- kexec-kdump-howto: Add note on setting correct value of kptr_restrict + +* Mon Mar 18 2019 Bhupesh Sharma 2.0.15-26 +- fadump: leverage kernel support to re-regisgter FADump + +* Mon Mar 18 2019 Bhupesh Sharma 2.0.15-25 +- Make udev reload rules quiet during bootup + +* Thu Mar 7 2019 Bhupesh Sharma 2.0.15-24 +- mkdumprd: use --quiet dracut argument to speedup initramfs build - mkdumprd: refine regex on dropping mount options +* Fri Feb 8 2019 Bhupesh Sharma 2.0.15-23 +- kdump: fix an error that can not parse the e820 reserved region +- Doc: add document to declare atlantic support + +* Fri Jan 18 2019 Pingfan Liu 2.0.15-22 +- doc/kdump.conf: Local dump path should be //%HOST_IP-%DATE +- Update help text to indicate --mem-usage is supported on archs other than x86_64 +- Add missing usage info +- Rewrite kdump's udev rules, use reload instead of restart +- kdumpctl: Add reload support + * Thu Aug 30 2018 Pingfan Liu 2.0.15-21 - kexec/ppc64: add support to parse ibm, dynamic-memory-v2