From: Dexuan Cui <decui@xxxxxxxxxxxxx> Sent: Monday, July 8, 2019 10:30 PM > > This is needed when we resume the old kernel from the "current" kernel. Perhaps a bit more descriptive commit message could be supplied? > > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > --- > drivers/hv/connection.c | 3 +-- > drivers/hv/hyperv_vmbus.h | 2 ++ > drivers/hv/vmbus_drv.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 43 insertions(+), 2 deletions(-) > > diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c > index 09829e1..806319c 100644 > --- a/drivers/hv/connection.c > +++ b/drivers/hv/connection.c > @@ -59,8 +59,7 @@ static __u32 vmbus_get_next_version(__u32 current_version) > } > } > > -static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, > - __u32 version) > +int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version) > { > int ret = 0; > unsigned int cur_cpu; > diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h > index 26ea161..e657197 100644 > --- a/drivers/hv/hyperv_vmbus.h > +++ b/drivers/hv/hyperv_vmbus.h > @@ -274,6 +274,8 @@ struct vmbus_msginfo { > > extern struct vmbus_connection vmbus_connection; > > +int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version); > + > static inline void vmbus_send_interrupt(u32 relid) > { > sync_set_bit(relid, vmbus_connection.send_int_page); > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > index 1c2d935..1730e7b 100644 > --- a/drivers/hv/vmbus_drv.c > +++ b/drivers/hv/vmbus_drv.c > @@ -2045,6 +2045,41 @@ static int vmbus_acpi_add(struct acpi_device *device) > return ret_val; > } > > +static int vmbus_bus_suspend(struct device *dev) > +{ > + vmbus_initiate_unload(false); > + > + vmbus_connection.conn_state = DISCONNECTED; > + > + return 0; > +} > + > +static int vmbus_bus_resume(struct device *dev) > +{ > + struct vmbus_channel_msginfo *msginfo; > + size_t msgsize; > + int ret; > + > + msgsize = sizeof(*msginfo) + > + sizeof(struct vmbus_channel_initiate_contact); > + > + msginfo = kzalloc(msgsize, GFP_KERNEL); > + > + if (msginfo == NULL) > + return -ENOMEM; > + > + ret = vmbus_negotiate_version(msginfo, vmbus_proto_version); I think this code answers my earlier question: Upon resume, we negotiate the same VMbus protocol version we had at time of hibernation, even if running on a newer version of Hyper-V that might support newer protocol versions. Hence the offer messages should not have any previously reserved fields now being used. A comment to this effect would be useful. > + > + kfree(msginfo); > + > + if (ret != 0) > + return ret; > + > + vmbus_request_offers(); > + > + return 0; > +} > + > static const struct acpi_device_id vmbus_acpi_device_ids[] = { > {"VMBUS", 0}, > {"VMBus", 0}, > @@ -2052,6 +2087,10 @@ static int vmbus_acpi_add(struct acpi_device *device) > }; > MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); > > +static const struct dev_pm_ops vmbus_bus_pm = { > + SET_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) > +}; > + > static struct acpi_driver vmbus_acpi_driver = { > .name = "vmbus", > .ids = vmbus_acpi_device_ids, > @@ -2059,6 +2098,7 @@ static int vmbus_acpi_add(struct acpi_device *device) > .add = vmbus_acpi_add, > .remove = vmbus_acpi_remove, > }, > + .drv.pm = &vmbus_bus_pm, > }; > > static void hv_kexec_handler(void) > -- > 1.8.3.1