diff --git a/include/linux/kexec.h b/include/linux/kexec.h index a1f12e959bba..3c1deba496c9 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -380,8 +380,8 @@ extern note_buf_t __percpu *crash_notes; extern bool kexec_in_progress; int crash_shrink_memory(unsigned long new_size); -size_t crash_get_memory_size(void); void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); +ssize_t crash_get_memory_size(void); void arch_kexec_protect_crashkres(void); void arch_kexec_unprotect_crashkres(void); diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index c589c7a9562c..e47870f30728 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -989,13 +989,16 @@ void crash_kexec(struct pt_regs *regs) } } -size_t crash_get_memory_size(void) +ssize_t crash_get_memory_size(void) { - size_t size = 0; + ssize_t size = 0; + + if (!mutex_trylock(&kexec_mutex)) + return -EBUSY; - mutex_lock(&kexec_mutex); if (crashk_res.end != crashk_res.start) size = resource_size(&crashk_res); + mutex_unlock(&kexec_mutex); return size; } @@ -1016,7 +1019,8 @@ int crash_shrink_memory(unsigned long new_size) unsigned long old_size; struct resource *ram_res; - mutex_lock(&kexec_mutex); + if (!mutex_trylock(&kexec_mutex)) + return -EBUSY; if (kexec_crash_image) { ret = -ENOENT; diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 35859da8bd4f..e20c19e3ba49 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -106,7 +106,12 @@ KERNEL_ATTR_RO(kexec_crash_loaded); static ssize_t kexec_crash_size_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%zu\n", crash_get_memory_size()); + ssize_t size = crash_get_memory_size(); + + if (size < 0) + return size; + + return sprintf(buf, "%zd\n", size); } static ssize_t kexec_crash_size_store(struct kobject *kobj, struct kobj_attribute *attr,