mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
hyperv-fixes for 5.7-rc1
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEIbPD0id6easf0xsudhRwX5BBoF4FAl6ViNsTHHdlaS5saXVA a2VybmVsLm9yZwAKCRB2FHBfkEGgXuXIB/4nuYRCt4d/XaeHF6dCWU45ThG+tNs7 p/OnBPZmknI0SnZ4uR/XW5caHEFj7g9ndYh+M1afZ/zKdsc+syMSDT5XhuhC/GKV fQRW0qO8N+IAqXbLzJxyBg6fH2anwfe3w2uy2cKDEZk6d4FD5atTWhRY6R4ISq0l g7pUyvQN1q+G6KH2snmOaZL8mybFkbHrmwtAZzcjzdzqasdLFiQB8EEFkONG66t9 HeNTyUF0mnbGBIePQLSZSHLj5p4yHG/9pa3jgqO5dsmIdsBvoaVNqEi3pCm1s/5n BH9FWn6fTwpcKvtF385yzBiFFlzBVgXbetxuSmxxOkWW4P+db5B/GL2Y =fjSF -----END PGP SIGNATURE----- Merge tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux Pull hyperv fixes from Wei Liu: - a series from Tianyu Lan to fix crash reporting on Hyper-V - three miscellaneous cleanup patches * tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: x86/Hyper-V: Report crash data in die() when panic_on_oops is set x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not set x86/Hyper-V: Report crash register data or kmsg before running crash kernel x86/Hyper-V: Trigger crash enlightenment only once during system crash. x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump x86/Hyper-V: Unload vmbus channel in hv panic callback x86: hyperv: report value of misc_features hv_debugfs: Make hv_debug_root static hv: hyperv_vmbus.h: Replace zero-length array with flexible-array member
This commit is contained in:
commit
8632e9b564
@ -20,6 +20,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/hyperv.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <clocksource/hyperv_timer.h>
|
||||
@ -419,11 +420,14 @@ void hyperv_cleanup(void)
|
||||
}
|
||||
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;
|
||||
u64 guest_id;
|
||||
|
||||
if (in_die && !panic_on_oops)
|
||||
return;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -227,8 +227,8 @@ static void __init ms_hyperv_init_platform(void)
|
||||
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
|
||||
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
|
||||
|
||||
pr_info("Hyper-V: features 0x%x, hints 0x%x\n",
|
||||
ms_hyperv.features, ms_hyperv.hints);
|
||||
pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n",
|
||||
ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
|
||||
|
||||
ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
||||
ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
||||
@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platform(void)
|
||||
cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hyper-V expects to get crash register data or kmsg when
|
||||
* crash enlightment is available and system crashes. Set
|
||||
* crash_kexec_post_notifiers to be true to make sure that
|
||||
* calling crash enlightment interface before running kdump
|
||||
* kernel.
|
||||
*/
|
||||
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
|
||||
crash_kexec_post_notifiers = true;
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
|
||||
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
||||
|
@ -839,6 +839,9 @@ void vmbus_initiate_unload(bool crash)
|
||||
{
|
||||
struct vmbus_channel_message_header hdr;
|
||||
|
||||
if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED)
|
||||
return;
|
||||
|
||||
/* Pre-Win2012R2 hosts don't support reconnect */
|
||||
if (vmbus_proto_version < VERSION_WIN8_1)
|
||||
return;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
struct dentry *hv_debug_root;
|
||||
static struct dentry *hv_debug_root;
|
||||
|
||||
static int hv_debugfs_delay_get(void *data, u64 *val)
|
||||
{
|
||||
|
@ -292,7 +292,7 @@ struct vmbus_msginfo {
|
||||
struct list_head msglist_entry;
|
||||
|
||||
/* The message itself */
|
||||
unsigned char msg[0];
|
||||
unsigned char msg[];
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <clocksource/hyperv_timer.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
@ -48,14 +49,35 @@ static int hyperv_cpuhp_online;
|
||||
|
||||
static void *hv_panic_page;
|
||||
|
||||
/*
|
||||
* Boolean to control whether to report panic messages over Hyper-V.
|
||||
*
|
||||
* It can be set via /proc/sys/kernel/hyperv/record_panic_msg
|
||||
*/
|
||||
static int sysctl_record_panic_msg = 1;
|
||||
|
||||
static int hyperv_report_reg(void)
|
||||
{
|
||||
return !sysctl_record_panic_msg || !hv_panic_page;
|
||||
}
|
||||
|
||||
static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
|
||||
void *args)
|
||||
{
|
||||
struct pt_regs *regs;
|
||||
|
||||
regs = current_pt_regs();
|
||||
vmbus_initiate_unload(true);
|
||||
|
||||
hyperv_report_panic(regs, val);
|
||||
/*
|
||||
* Hyper-V should be notified only once about a panic. If we will be
|
||||
* doing hyperv_report_panic_msg() later with kmsg data, don't do
|
||||
* the notification here.
|
||||
*/
|
||||
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
|
||||
&& hyperv_report_reg()) {
|
||||
regs = current_pt_regs();
|
||||
hyperv_report_panic(regs, val, false);
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@ -65,7 +87,13 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
|
||||
struct die_args *die = (struct die_args *)args;
|
||||
struct pt_regs *regs = die->regs;
|
||||
|
||||
hyperv_report_panic(regs, val);
|
||||
/*
|
||||
* Hyper-V should be notified only once about a panic. If we will be
|
||||
* doing hyperv_report_panic_msg() later with kmsg data, don't do
|
||||
* the notification here.
|
||||
*/
|
||||
if (hyperv_report_reg())
|
||||
hyperv_report_panic(regs, val, true);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@ -1252,13 +1280,6 @@ static void vmbus_isr(void)
|
||||
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Boolean to control whether to report panic messages over Hyper-V.
|
||||
*
|
||||
* It can be set via /proc/sys/kernel/hyperv/record_panic_msg
|
||||
*/
|
||||
static int sysctl_record_panic_msg = 1;
|
||||
|
||||
/*
|
||||
* Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
|
||||
* buffer and call into Hyper-V to transfer the data.
|
||||
@ -1382,19 +1403,29 @@ static int vmbus_bus_init(void)
|
||||
hv_panic_page = (void *)hv_alloc_hyperv_zeroed_page();
|
||||
if (hv_panic_page) {
|
||||
ret = kmsg_dump_register(&hv_kmsg_dumper);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_err("Hyper-V: kmsg dump register "
|
||||
"error 0x%x\n", ret);
|
||||
hv_free_hyperv_page(
|
||||
(unsigned long)hv_panic_page);
|
||||
hv_panic_page = NULL;
|
||||
}
|
||||
} else
|
||||
pr_err("Hyper-V: panic message page memory "
|
||||
"allocation failed");
|
||||
}
|
||||
|
||||
register_die_notifier(&hyperv_die_block);
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&hyperv_panic_block);
|
||||
}
|
||||
|
||||
/*
|
||||
* Always register the panic notifier because we need to unload
|
||||
* the VMbus channel connection to prevent any VMbus
|
||||
* activity after the VM panics.
|
||||
*/
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&hyperv_panic_block);
|
||||
|
||||
vmbus_request_offers();
|
||||
|
||||
return 0;
|
||||
@ -1407,7 +1438,6 @@ err_alloc:
|
||||
hv_remove_vmbus_irq();
|
||||
|
||||
bus_unregister(&hv_bus);
|
||||
hv_free_hyperv_page((unsigned long)hv_panic_page);
|
||||
unregister_sysctl_table(hv_ctl_table_hdr);
|
||||
hv_ctl_table_hdr = NULL;
|
||||
return ret;
|
||||
@ -2204,8 +2234,6 @@ static int vmbus_bus_suspend(struct device *dev)
|
||||
|
||||
vmbus_initiate_unload(false);
|
||||
|
||||
vmbus_connection.conn_state = DISCONNECTED;
|
||||
|
||||
/* Reset the event for the next resume. */
|
||||
reinit_completion(&vmbus_connection.ready_for_resume_event);
|
||||
|
||||
@ -2289,7 +2317,6 @@ static void hv_kexec_handler(void)
|
||||
{
|
||||
hv_stimer_global_cleanup();
|
||||
vmbus_initiate_unload(false);
|
||||
vmbus_connection.conn_state = DISCONNECTED;
|
||||
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
|
||||
mb();
|
||||
cpuhp_remove_state(hyperv_cpuhp_online);
|
||||
@ -2306,7 +2333,6 @@ static void hv_crash_handler(struct pt_regs *regs)
|
||||
* doing the cleanup for current CPU only. This should be sufficient
|
||||
* for kdump.
|
||||
*/
|
||||
vmbus_connection.conn_state = DISCONNECTED;
|
||||
cpu = smp_processor_id();
|
||||
hv_stimer_cleanup(cpu);
|
||||
hv_synic_disable_regs(cpu);
|
||||
|
@ -163,7 +163,7 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
|
||||
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);
|
||||
bool hv_is_hyperv_initialized(void);
|
||||
bool hv_is_hibernation_supported(void);
|
||||
|
Loading…
Reference in New Issue
Block a user