x86/Hyper-V: Report crash data in die() when panic_on_oops is set

When oops happens with panic_on_oops unset, the oops
thread is killed by die() and system continues to run.
In such case, guest should not report crash register
data to host since system still runs. Check panic_on_oops
and return directly in hyperv_report_panic() when the function
is called in the die() and panic_on_oops is unset. Fix it.

Fixes: 7ed4325a44 ("Drivers: hv: vmbus: Make panic reporting to be more useful")
Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/20200406155331.2105-7-Tianyu.Lan@microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
This commit is contained in:
Tianyu Lan 2020-04-06 08:53:31 -07:00 committed by Wei Liu
parent 040026df70
commit f3a99e761e
3 changed files with 9 additions and 4 deletions

View File

@ -20,6 +20,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hyperv.h> #include <linux/hyperv.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/cpuhotplug.h> #include <linux/cpuhotplug.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <clocksource/hyperv_timer.h> #include <clocksource/hyperv_timer.h>
@ -419,11 +420,14 @@ void hyperv_cleanup(void)
} }
EXPORT_SYMBOL_GPL(hyperv_cleanup); EXPORT_SYMBOL_GPL(hyperv_cleanup);
void hyperv_report_panic(struct pt_regs *regs, long err) void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
{ {
static bool panic_reported; static bool panic_reported;
u64 guest_id; u64 guest_id;
if (in_die && !panic_on_oops)
return;
/* /*
* We prefer to report panic on 'die' chain as we have proper * We prefer to report panic on 'die' chain as we have proper
* registers to report, but if we miss it (e.g. on BUG()) we need * registers to report, but if we miss it (e.g. on BUG()) we need

View File

@ -31,6 +31,7 @@
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/kernel.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <clocksource/hyperv_timer.h> #include <clocksource/hyperv_timer.h>
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
@ -75,7 +76,7 @@ static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
&& hyperv_report_reg()) { && hyperv_report_reg()) {
regs = current_pt_regs(); regs = current_pt_regs();
hyperv_report_panic(regs, val); hyperv_report_panic(regs, val, false);
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
@ -92,7 +93,7 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
* the notification here. * the notification here.
*/ */
if (hyperv_report_reg()) if (hyperv_report_reg())
hyperv_report_panic(regs, val); hyperv_report_panic(regs, val, true);
return NOTIFY_DONE; return NOTIFY_DONE;
} }

View File

@ -163,7 +163,7 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
return nr_bank; return nr_bank;
} }
void hyperv_report_panic(struct pt_regs *regs, long err); void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
void hyperv_report_panic_msg(phys_addr_t pa, size_t size); void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
bool hv_is_hyperv_initialized(void); bool hv_is_hyperv_initialized(void);
bool hv_is_hibernation_supported(void); bool hv_is_hibernation_supported(void);