diff --git a/alpine/kernel/patches/0001-virtio-make-find_vqs-checkpatch.pl-friendly.patch b/alpine/kernel/patches/0001-virtio-make-find_vqs-checkpatch.pl-friendly.patch index f0988ed04..a02581d9b 100644 --- a/alpine/kernel/patches/0001-virtio-make-find_vqs-checkpatch.pl-friendly.patch +++ b/alpine/kernel/patches/0001-virtio-make-find_vqs-checkpatch.pl-friendly.patch @@ -1,7 +1,7 @@ From 31adb74f5668e7e44615a2854742f8726a818533 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 17 Dec 2015 16:53:43 +0800 -Subject: [PATCH 01/28] virtio: make find_vqs() checkpatch.pl-friendly +Subject: [PATCH 01/40] virtio: make find_vqs() checkpatch.pl-friendly checkpatch.pl wants arrays of strings declared as follows: diff --git a/alpine/kernel/patches/0002-VSOCK-constify-vmci_transport_notify_ops-structures.patch b/alpine/kernel/patches/0002-VSOCK-constify-vmci_transport_notify_ops-structures.patch index 3b53086cb..7345602e1 100644 --- a/alpine/kernel/patches/0002-VSOCK-constify-vmci_transport_notify_ops-structures.patch +++ b/alpine/kernel/patches/0002-VSOCK-constify-vmci_transport_notify_ops-structures.patch @@ -1,7 +1,7 @@ From 4b274b13e7dfe4ac54072f324738c487a36b78b8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2015 18:39:17 +0100 -Subject: [PATCH 02/28] VSOCK: constify vmci_transport_notify_ops structures +Subject: [PATCH 02/40] VSOCK: constify vmci_transport_notify_ops structures The vmci_transport_notify_ops structures are never modified, so declare them as const. diff --git a/alpine/kernel/patches/0003-AF_VSOCK-Shrink-the-area-influenced-by-prepare_to_wa.patch b/alpine/kernel/patches/0003-AF_VSOCK-Shrink-the-area-influenced-by-prepare_to_wa.patch index 0918f9a53..752818be3 100644 --- a/alpine/kernel/patches/0003-AF_VSOCK-Shrink-the-area-influenced-by-prepare_to_wa.patch +++ b/alpine/kernel/patches/0003-AF_VSOCK-Shrink-the-area-influenced-by-prepare_to_wa.patch @@ -1,7 +1,7 @@ From 31fb7962193b46e8f7e24ac350e3efc486f0fd90 Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Tue, 22 Mar 2016 17:05:52 +0100 -Subject: [PATCH 03/28] AF_VSOCK: Shrink the area influenced by prepare_to_wait +Subject: [PATCH 03/40] AF_VSOCK: Shrink the area influenced by prepare_to_wait When a thread is prepared for waiting by calling prepare_to_wait, sleeping is not allowed until either the wait has taken place or finish_wait has diff --git a/alpine/kernel/patches/0004-VSOCK-transport-specific-vsock_transport-functions.patch b/alpine/kernel/patches/0004-VSOCK-transport-specific-vsock_transport-functions.patch index df80a31ea..3354d6b0f 100644 --- a/alpine/kernel/patches/0004-VSOCK-transport-specific-vsock_transport-functions.patch +++ b/alpine/kernel/patches/0004-VSOCK-transport-specific-vsock_transport-functions.patch @@ -1,7 +1,7 @@ From 891b9c6111fc77750b261cc03f8ac7a80441701a Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 17 Dec 2015 11:10:21 +0800 -Subject: [PATCH 04/28] VSOCK: transport-specific vsock_transport functions +Subject: [PATCH 04/40] VSOCK: transport-specific vsock_transport functions struct vsock_transport contains function pointers called by AF_VSOCK core code. The transport may want its own transport-specific function diff --git a/alpine/kernel/patches/0005-VSOCK-Introduce-virtio_vsock_common.ko.patch b/alpine/kernel/patches/0005-VSOCK-Introduce-virtio_vsock_common.ko.patch index 8b5dd6b91..b480f3cc2 100644 --- a/alpine/kernel/patches/0005-VSOCK-Introduce-virtio_vsock_common.ko.patch +++ b/alpine/kernel/patches/0005-VSOCK-Introduce-virtio_vsock_common.ko.patch @@ -1,7 +1,7 @@ From a27fee87d915bfb9edf720f9068c3aed6649aa0c Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 13 Jun 2013 18:27:00 +0800 -Subject: [PATCH 05/28] VSOCK: Introduce virtio_vsock_common.ko +Subject: [PATCH 05/40] VSOCK: Introduce virtio_vsock_common.ko This module contains the common code and header files for the following virtio_transporto and vhost_vsock kernel modules. diff --git a/alpine/kernel/patches/0006-VSOCK-Introduce-virtio_transport.ko.patch b/alpine/kernel/patches/0006-VSOCK-Introduce-virtio_transport.ko.patch index ed787f0b0..01b72d9a9 100644 --- a/alpine/kernel/patches/0006-VSOCK-Introduce-virtio_transport.ko.patch +++ b/alpine/kernel/patches/0006-VSOCK-Introduce-virtio_transport.ko.patch @@ -1,7 +1,7 @@ From 19cfdea4fa3fa9136c234ac695f628fce73b40c2 Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 13 Jun 2013 18:28:48 +0800 -Subject: [PATCH 06/28] VSOCK: Introduce virtio_transport.ko +Subject: [PATCH 06/40] VSOCK: Introduce virtio_transport.ko VM sockets virtio transport implementation. This driver runs in the guest. diff --git a/alpine/kernel/patches/0007-VSOCK-Introduce-vhost_vsock.ko.patch b/alpine/kernel/patches/0007-VSOCK-Introduce-vhost_vsock.ko.patch index 32451488e..924fffa62 100644 --- a/alpine/kernel/patches/0007-VSOCK-Introduce-vhost_vsock.ko.patch +++ b/alpine/kernel/patches/0007-VSOCK-Introduce-vhost_vsock.ko.patch @@ -1,7 +1,7 @@ From fd467c3335938b8eca0489008c390ad16a01aee7 Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 13 Jun 2013 18:29:21 +0800 -Subject: [PATCH 07/28] VSOCK: Introduce vhost_vsock.ko +Subject: [PATCH 07/40] VSOCK: Introduce vhost_vsock.ko VM sockets vhost transport implementation. This driver runs on the host. diff --git a/alpine/kernel/patches/0008-VSOCK-Add-Makefile-and-Kconfig.patch b/alpine/kernel/patches/0008-VSOCK-Add-Makefile-and-Kconfig.patch index 2205ecbfe..4d4e8718d 100644 --- a/alpine/kernel/patches/0008-VSOCK-Add-Makefile-and-Kconfig.patch +++ b/alpine/kernel/patches/0008-VSOCK-Add-Makefile-and-Kconfig.patch @@ -1,7 +1,7 @@ From 5d2849bde15e969b8cf1eb2f5e818b62ec2181ec Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 13 Jun 2013 18:30:19 +0800 -Subject: [PATCH 08/28] VSOCK: Add Makefile and Kconfig +Subject: [PATCH 08/40] VSOCK: Add Makefile and Kconfig Enable virtio-vsock and vhost-vsock. diff --git a/alpine/kernel/patches/0009-VSOCK-Only-allow-host-network-namespace-to-use-AF_VS.patch b/alpine/kernel/patches/0009-VSOCK-Only-allow-host-network-namespace-to-use-AF_VS.patch index fa975cc19..28866ab3a 100644 --- a/alpine/kernel/patches/0009-VSOCK-Only-allow-host-network-namespace-to-use-AF_VS.patch +++ b/alpine/kernel/patches/0009-VSOCK-Only-allow-host-network-namespace-to-use-AF_VS.patch @@ -1,7 +1,7 @@ From 81b78a051aa8c61743abcc266eb9c7511dd19a62 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 4 Apr 2016 14:50:10 +0100 -Subject: [PATCH 09/28] VSOCK: Only allow host network namespace to use +Subject: [PATCH 09/40] VSOCK: Only allow host network namespace to use AF_VSOCK. The VSOCK addressing schema does not really lend itself to simply creating an diff --git a/alpine/kernel/patches/0010-drivers-hv-Define-the-channel-type-for-Hyper-V-PCI-E.patch b/alpine/kernel/patches/0010-drivers-hv-Define-the-channel-type-for-Hyper-V-PCI-E.patch new file mode 100644 index 000000000..fd7540beb --- /dev/null +++ b/alpine/kernel/patches/0010-drivers-hv-Define-the-channel-type-for-Hyper-V-PCI-E.patch @@ -0,0 +1,63 @@ +From b5a27dd334aa0f8e857e751c81f79b1ed482459c Mon Sep 17 00:00:00 2001 +From: Jake Oshins +Date: Mon, 14 Dec 2015 16:01:41 -0800 +Subject: [PATCH 10/40] drivers:hv: Define the channel type for Hyper-V PCI + Express pass-through + +This defines the channel type for PCI front-ends in Hyper-V VMs. + +Signed-off-by: Jake Oshins +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 3053c762444a83ec6a8777f9476668b23b8ab180) +--- + drivers/hv/channel_mgmt.c | 3 +++ + include/linux/hyperv.h | 11 +++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 652afd1..a77646b 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -358,6 +358,7 @@ enum { + SCSI, + NIC, + ND_NIC, ++ PCIE, + MAX_PERF_CHN, + }; + +@@ -375,6 +376,8 @@ static const struct hv_vmbus_device_id hp_devs[] = { + { HV_NIC_GUID, }, + /* NetworkDirect Guest RDMA */ + { HV_ND_GUID, }, ++ /* PCI Express Pass Through */ ++ { HV_PCIE_GUID, }, + }; + + +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index ae6a711..10dda1e 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -1156,6 +1156,17 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + } + + /* ++ * PCI Express Pass Through ++ * {44C4F61D-4444-4400-9D52-802E27EDE19F} ++ */ ++ ++#define HV_PCIE_GUID \ ++ .guid = { \ ++ 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ ++ 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ ++ } ++ ++/* + * Common header for Hyper-V ICs + */ + +-- +2.8.2 + diff --git a/alpine/kernel/patches/0011-Drivers-hv-vmbus-Use-uuid_le-type-consistently.patch b/alpine/kernel/patches/0011-Drivers-hv-vmbus-Use-uuid_le-type-consistently.patch new file mode 100644 index 000000000..9e5076eb8 --- /dev/null +++ b/alpine/kernel/patches/0011-Drivers-hv-vmbus-Use-uuid_le-type-consistently.patch @@ -0,0 +1,297 @@ +From 02c6472ed9ae7498a0510d76dd4840349f4c7e92 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Mon, 14 Dec 2015 16:01:43 -0800 +Subject: [PATCH 11/40] Drivers: hv: vmbus: Use uuid_le type consistently + +Consistently use uuid_le type in the Hyper-V driver code. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit af3ff643ea91ba64dd8d0b1cbed54d44512f96cd) +--- + drivers/hv/channel_mgmt.c | 2 +- + drivers/hv/vmbus_drv.c | 10 ++--- + include/linux/hyperv.h | 92 ++++++++++++++--------------------------- + include/linux/mod_devicetable.h | 2 +- + scripts/mod/file2alias.c | 2 +- + 5 files changed, 40 insertions(+), 68 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index a77646b..38470aa 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -408,7 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui + struct cpumask *alloced_mask; + + for (i = IDE; i < MAX_PERF_CHN; i++) { +- if (!memcmp(type_guid->b, hp_devs[i].guid, ++ if (!memcmp(type_guid->b, &hp_devs[i].guid, + sizeof(uuid_le))) { + perf_chn = true; + break; +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index f19b6f7..e64934e 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -531,7 +531,7 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) + + static const uuid_le null_guid; + +-static inline bool is_null_guid(const __u8 *guid) ++static inline bool is_null_guid(const uuid_le *guid) + { + if (memcmp(guid, &null_guid, sizeof(uuid_le))) + return false; +@@ -544,9 +544,9 @@ static inline bool is_null_guid(const __u8 *guid) + */ + static const struct hv_vmbus_device_id *hv_vmbus_get_id( + const struct hv_vmbus_device_id *id, +- const __u8 *guid) ++ const uuid_le *guid) + { +- for (; !is_null_guid(id->guid); id++) ++ for (; !is_null_guid(&id->guid); id++) + if (!memcmp(&id->guid, guid, sizeof(uuid_le))) + return id; + +@@ -563,7 +563,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) + struct hv_driver *drv = drv_to_hv_drv(driver); + struct hv_device *hv_dev = device_to_hv_device(device); + +- if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b)) ++ if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type)) + return 1; + + return 0; +@@ -580,7 +580,7 @@ static int vmbus_probe(struct device *child_device) + struct hv_device *dev = device_to_hv_device(child_device); + const struct hv_vmbus_device_id *dev_id; + +- dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b); ++ dev_id = hv_vmbus_get_id(drv->id_table, &dev->dev_type); + if (drv->probe) { + ret = drv->probe(dev, dev_id); + if (ret != 0) +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 10dda1e..4712d7d 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -1012,6 +1012,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ + g8, g9, ga, gb, gc, gd, ge, gf }, + ++ ++ + /* + * GUID definitions of various offer types - services offered to the guest. + */ +@@ -1021,118 +1023,94 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + * {f8615163-df3e-46c5-913f-f2d2f965ed0e} + */ + #define HV_NIC_GUID \ +- .guid = { \ +- 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \ +- 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \ +- } ++ .guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \ ++ 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e) + + /* + * IDE GUID + * {32412632-86cb-44a2-9b5c-50d1417354f5} + */ + #define HV_IDE_GUID \ +- .guid = { \ +- 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ +- 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \ +- } ++ .guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \ ++ 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) + + /* + * SCSI GUID + * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} + */ + #define HV_SCSI_GUID \ +- .guid = { \ +- 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ +- 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \ +- } ++ .guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \ ++ 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) + + /* + * Shutdown GUID + * {0e0b6031-5213-4934-818b-38d90ced39db} + */ + #define HV_SHUTDOWN_GUID \ +- .guid = { \ +- 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \ +- 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \ +- } ++ .guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \ ++ 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb) + + /* + * Time Synch GUID + * {9527E630-D0AE-497b-ADCE-E80AB0175CAF} + */ + #define HV_TS_GUID \ +- .guid = { \ +- 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \ +- 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \ +- } ++ .guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \ ++ 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) + + /* + * Heartbeat GUID + * {57164f39-9115-4e78-ab55-382f3bd5422d} + */ + #define HV_HEART_BEAT_GUID \ +- .guid = { \ +- 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \ +- 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \ +- } ++ .guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \ ++ 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) + + /* + * KVP GUID + * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6} + */ + #define HV_KVP_GUID \ +- .guid = { \ +- 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \ +- 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \ +- } ++ .guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \ ++ 0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6) + + /* + * Dynamic memory GUID + * {525074dc-8985-46e2-8057-a307dc18a502} + */ + #define HV_DM_GUID \ +- .guid = { \ +- 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \ +- 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \ +- } ++ .guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \ ++ 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02) + + /* + * Mouse GUID + * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a} + */ + #define HV_MOUSE_GUID \ +- .guid = { \ +- 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \ +- 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \ +- } ++ .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \ ++ 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) + + /* + * VSS (Backup/Restore) GUID + */ + #define HV_VSS_GUID \ +- .guid = { \ +- 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ +- 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ +- } ++ .guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \ ++ 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40) + /* + * Synthetic Video GUID + * {DA0A7802-E377-4aac-8E77-0558EB1073F8} + */ + #define HV_SYNTHVID_GUID \ +- .guid = { \ +- 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \ +- 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \ +- } ++ .guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \ ++ 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8) + + /* + * Synthetic FC GUID + * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda} + */ + #define HV_SYNTHFC_GUID \ +- .guid = { \ +- 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \ +- 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \ +- } ++ .guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \ ++ 0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda) + + /* + * Guest File Copy Service +@@ -1140,20 +1118,16 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + */ + + #define HV_FCOPY_GUID \ +- .guid = { \ +- 0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \ +- 0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \ +- } ++ .guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \ ++ 0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92) + + /* + * NetworkDirect. This is the guest RDMA service. + * {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501} + */ + #define HV_ND_GUID \ +- .guid = { \ +- 0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \ +- 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \ +- } ++ .guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \ ++ 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01) + + /* + * PCI Express Pass Through +@@ -1161,10 +1135,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + */ + + #define HV_PCIE_GUID \ +- .guid = { \ +- 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ +- 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ +- } ++ .guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \ ++ 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f) + + /* + * Common header for Hyper-V ICs +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index 64f36e0..6e4c645 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -404,7 +404,7 @@ struct virtio_device_id { + * For Hyper-V devices we use the device guid as the id. + */ + struct hv_vmbus_device_id { +- __u8 guid[16]; ++ uuid_le guid; + kernel_ulong_t driver_data; /* Data private to the driver */ + }; + +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 5b96206..8adca44 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -917,7 +917,7 @@ static int do_vmbus_entry(const char *filename, void *symval, + char guid_name[(sizeof(*guid) + 1) * 2]; + + for (i = 0; i < (sizeof(*guid) * 2); i += 2) +- sprintf(&guid_name[i], "%02x", TO_NATIVE((*guid)[i/2])); ++ sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); + + strcpy(alias, "vmbus:"); + strcat(alias, guid_name); +-- +2.8.2 + diff --git a/alpine/kernel/patches/0012-Drivers-hv-vmbus-Use-uuid_le_cmp-for-comparing-GUIDs.patch b/alpine/kernel/patches/0012-Drivers-hv-vmbus-Use-uuid_le_cmp-for-comparing-GUIDs.patch new file mode 100644 index 000000000..7a1a94e76 --- /dev/null +++ b/alpine/kernel/patches/0012-Drivers-hv-vmbus-Use-uuid_le_cmp-for-comparing-GUIDs.patch @@ -0,0 +1,55 @@ +From d8a7b4073f802509ad00164b1d6967ba9ebb9d7f Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Mon, 14 Dec 2015 16:01:44 -0800 +Subject: [PATCH 12/40] Drivers: hv: vmbus: Use uuid_le_cmp() for comparing + GUIDs + +Use uuid_le_cmp() for comparing GUIDs. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 4ae9250893485f380275e7d5cb291df87c4d9710) +--- + drivers/hv/channel_mgmt.c | 3 +-- + drivers/hv/vmbus_drv.c | 4 ++-- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 38470aa..dc4fb0b 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -408,8 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui + struct cpumask *alloced_mask; + + for (i = IDE; i < MAX_PERF_CHN; i++) { +- if (!memcmp(type_guid->b, &hp_devs[i].guid, +- sizeof(uuid_le))) { ++ if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) { + perf_chn = true; + break; + } +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index e64934e..aa4d8cc 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -533,7 +533,7 @@ static const uuid_le null_guid; + + static inline bool is_null_guid(const uuid_le *guid) + { +- if (memcmp(guid, &null_guid, sizeof(uuid_le))) ++ if (uuid_le_cmp(*guid, null_guid)) + return false; + return true; + } +@@ -547,7 +547,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id( + const uuid_le *guid) + { + for (; !is_null_guid(&id->guid); id++) +- if (!memcmp(&id->guid, guid, sizeof(uuid_le))) ++ if (!uuid_le_cmp(id->guid, *guid)) + return id; + + return NULL; +-- +2.8.2 + diff --git a/alpine/kernel/patches/0010-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch b/alpine/kernel/patches/0013-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch similarity index 95% rename from alpine/kernel/patches/0010-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch rename to alpine/kernel/patches/0013-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch index f8c233dc6..f22ed56d4 100644 --- a/alpine/kernel/patches/0010-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch +++ b/alpine/kernel/patches/0013-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch @@ -1,7 +1,7 @@ -From c4795172e48b3229b24b3816c4c0d822c2cd2b88 Mon Sep 17 00:00:00 2001 +From e24d6e93c8ee5110240547663c88b909fbed3575 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:47 -0800 -Subject: [PATCH 10/28] Drivers: hv: vmbus: serialize process_chn_event() and +Subject: [PATCH 13/40] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal() process_chn_event(), running in the tasklet, can race with diff --git a/alpine/kernel/patches/0011-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch b/alpine/kernel/patches/0014-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch similarity index 91% rename from alpine/kernel/patches/0011-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch rename to alpine/kernel/patches/0014-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch index 4dbeac398..d68afca55 100644 --- a/alpine/kernel/patches/0011-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch +++ b/alpine/kernel/patches/0014-Drivers-hv-vmbus-do-sanity-check-of-channel-state-in.patch @@ -1,7 +1,7 @@ -From db7c4decfd08e194c3fe7647ebc0903c5fee33b7 Mon Sep 17 00:00:00 2001 +From d744926ed8c8f1b717d7ab04adf0d86aa78b1160 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:48 -0800 -Subject: [PATCH 11/28] Drivers: hv: vmbus: do sanity check of channel state in +Subject: [PATCH 14/40] Drivers: hv: vmbus: do sanity check of channel state in vmbus_close_internal() This fixes an incorrect assumption of channel state in the function. diff --git a/alpine/kernel/patches/0012-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch b/alpine/kernel/patches/0015-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch similarity index 95% rename from alpine/kernel/patches/0012-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch rename to alpine/kernel/patches/0015-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch index e500269e7..3e79598b0 100644 --- a/alpine/kernel/patches/0012-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch +++ b/alpine/kernel/patches/0015-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch @@ -1,7 +1,7 @@ -From 92aa99cab10f5beb241635eee20fd1709fb63196 Mon Sep 17 00:00:00 2001 +From ae5614842c1b80193552aeabb57f6cc37c5ca848 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:49 -0800 -Subject: [PATCH 12/28] Drivers: hv: vmbus: fix rescind-offer handling for +Subject: [PATCH 15/40] Drivers: hv: vmbus: fix rescind-offer handling for device without a driver In the path vmbus_onoffer_rescind() -> vmbus_device_unregister() -> @@ -55,7 +55,7 @@ index b3c14ca..2889d97 100644 tasklet_enable(tasklet); diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index 652afd1..bd2e9f6 100644 +index dc4fb0b..7903acc 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -191,6 +191,8 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) @@ -79,7 +79,7 @@ index 652afd1..bd2e9f6 100644 vmbus_device_unregister(channel->device_obj); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c -index f19b6f7..7e46a48 100644 +index aa4d8cc..5a71b2a 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -602,23 +602,11 @@ static int vmbus_remove(struct device *child_device) diff --git a/alpine/kernel/patches/0013-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch b/alpine/kernel/patches/0016-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch similarity index 90% rename from alpine/kernel/patches/0013-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch rename to alpine/kernel/patches/0016-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch index a066302bd..91b2b1e5e 100644 --- a/alpine/kernel/patches/0013-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch +++ b/alpine/kernel/patches/0016-Drivers-hv-vmbus-release-relid-on-error-in-vmbus_pro.patch @@ -1,7 +1,7 @@ -From c0e232b85b7cf4387788962085fed314e01b5e8c Mon Sep 17 00:00:00 2001 +From 28d0ed01c7b183c6af5991351de65046c183f392 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:50 -0800 -Subject: [PATCH 13/28] Drivers: hv: vmbus: release relid on error in +Subject: [PATCH 16/40] Drivers: hv: vmbus: release relid on error in vmbus_process_offer() We want to simplify vmbus_onoffer_rescind() by not invoking @@ -16,7 +16,7 @@ Signed-off-by: Greg Kroah-Hartman 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index bd2e9f6..df76a71 100644 +index 7903acc..9c9da3a 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -177,19 +177,22 @@ static void percpu_channel_deq(void *arg) @@ -56,7 +56,7 @@ index bd2e9f6..df76a71 100644 spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_del(&newchannel->listentry); spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); -@@ -585,7 +590,11 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -587,7 +592,11 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) channel = relid2channel(rescind->child_relid); if (channel == NULL) { diff --git a/alpine/kernel/patches/0014-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch b/alpine/kernel/patches/0017-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch similarity index 96% rename from alpine/kernel/patches/0014-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch rename to alpine/kernel/patches/0017-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch index 706283058..04899a66f 100644 --- a/alpine/kernel/patches/0014-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch +++ b/alpine/kernel/patches/0017-Drivers-hv-vmbus-channge-vmbus_connection.channel_lo.patch @@ -1,7 +1,7 @@ -From 2991041546570f369440c4837ae5ef0518e4d839 Mon Sep 17 00:00:00 2001 +From 9aa8a05fcf39739b23f8e2f502c3ffa370521cba Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 14 Dec 2015 16:01:51 -0800 -Subject: [PATCH 14/28] Drivers: hv: vmbus: channge +Subject: [PATCH 17/40] Drivers: hv: vmbus: channge vmbus_connection.channel_lock to mutex spinlock is unnecessary here. @@ -18,7 +18,7 @@ Signed-off-by: Greg Kroah-Hartman 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index df76a71..bd4f084 100644 +index 9c9da3a..d013171 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -206,9 +206,9 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) diff --git a/alpine/kernel/patches/0018-Drivers-hv-remove-code-duplication-between-vmbus_rec.patch b/alpine/kernel/patches/0018-Drivers-hv-remove-code-duplication-between-vmbus_rec.patch new file mode 100644 index 000000000..bf3c469a5 --- /dev/null +++ b/alpine/kernel/patches/0018-Drivers-hv-remove-code-duplication-between-vmbus_rec.patch @@ -0,0 +1,126 @@ +From 86e233fbb4c41b03096f498b26cdbfbdf9e5723e Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 14 Dec 2015 19:02:00 -0800 +Subject: [PATCH 18/40] Drivers: hv: remove code duplication between + vmbus_recvpacket()/vmbus_recvpacket_raw() + +vmbus_recvpacket() and vmbus_recvpacket_raw() are almost identical but +there are two discrepancies: +1) vmbus_recvpacket() doesn't propagate errors from hv_ringbuffer_read() + which looks like it is not desired. +2) There is an error message printed in packetlen > bufferlen case in + vmbus_recvpacket(). I'm removing it as it is usless for users to see + such messages and /vmbus_recvpacket_raw() doesn't have it. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 667d374064b0cc48b6122101b287908d1b392bdb) +--- + drivers/hv/channel.c | 65 ++++++++++++++++++---------------------------------- + 1 file changed, 22 insertions(+), 43 deletions(-) + +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 2889d97..dd6de7f 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -922,8 +922,10 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer); + * + * Mainly used by Hyper-V drivers. + */ +-int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, +- u32 bufferlen, u32 *buffer_actual_len, u64 *requestid) ++static inline int ++__vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, ++ u32 bufferlen, u32 *buffer_actual_len, u64 *requestid, ++ bool raw) + { + struct vmpacket_descriptor desc; + u32 packetlen; +@@ -941,27 +943,34 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, + return 0; + + packetlen = desc.len8 << 3; +- userlen = packetlen - (desc.offset8 << 3); ++ if (!raw) ++ userlen = packetlen - (desc.offset8 << 3); ++ else ++ userlen = packetlen; + + *buffer_actual_len = userlen; + +- if (userlen > bufferlen) { +- +- pr_err("Buffer too small - got %d needs %d\n", +- bufferlen, userlen); +- return -ETOOSMALL; +- } ++ if (userlen > bufferlen) ++ return -ENOBUFS; + + *requestid = desc.trans_id; + + /* Copy over the packet to the user buffer */ + ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen, +- (desc.offset8 << 3), &signal); ++ raw ? 0 : desc.offset8 << 3, &signal); + + if (signal) + vmbus_setevent(channel); + +- return 0; ++ return ret; ++} ++ ++int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, ++ u32 bufferlen, u32 *buffer_actual_len, ++ u64 *requestid) ++{ ++ return __vmbus_recvpacket(channel, buffer, bufferlen, ++ buffer_actual_len, requestid, false); + } + EXPORT_SYMBOL(vmbus_recvpacket); + +@@ -972,37 +981,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, + u32 bufferlen, u32 *buffer_actual_len, + u64 *requestid) + { +- struct vmpacket_descriptor desc; +- u32 packetlen; +- int ret; +- bool signal = false; +- +- *buffer_actual_len = 0; +- *requestid = 0; +- +- +- ret = hv_ringbuffer_peek(&channel->inbound, &desc, +- sizeof(struct vmpacket_descriptor)); +- if (ret != 0) +- return 0; +- +- +- packetlen = desc.len8 << 3; +- +- *buffer_actual_len = packetlen; +- +- if (packetlen > bufferlen) +- return -ENOBUFS; +- +- *requestid = desc.trans_id; +- +- /* Copy over the entire packet to the user buffer */ +- ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0, +- &signal); +- +- if (signal) +- vmbus_setevent(channel); +- +- return ret; ++ return __vmbus_recvpacket(channel, buffer, bufferlen, ++ buffer_actual_len, requestid, true); + } + EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); +-- +2.8.2 + diff --git a/alpine/kernel/patches/0019-Drivers-hv-vmbus-fix-the-building-warning-with-hyper.patch b/alpine/kernel/patches/0019-Drivers-hv-vmbus-fix-the-building-warning-with-hyper.patch new file mode 100644 index 000000000..266903a18 --- /dev/null +++ b/alpine/kernel/patches/0019-Drivers-hv-vmbus-fix-the-building-warning-with-hyper.patch @@ -0,0 +1,72 @@ +From 934477d473ecb1facd9f69cfc4b4591598f3b0ed Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Mon, 21 Dec 2015 12:21:22 -0800 +Subject: [PATCH 19/40] Drivers: hv: vmbus: fix the building warning with + hyperv-keyboard + +With the recent change af3ff643ea91ba64dd8d0b1cbed54d44512f96cd +(Drivers: hv: vmbus: Use uuid_le type consistently), we always get this +warning: + + CC [M] drivers/input/serio/hyperv-keyboard.o +drivers/input/serio/hyperv-keyboard.c:427:2: warning: missing braces around + initializer [-Wmissing-braces] + { HV_KBD_GUID, }, + ^ +drivers/input/serio/hyperv-keyboard.c:427:2: warning: (near initialization + for .id_table[0].guid.b.) [-Wmissing-braces] + +The patch fixes the warning. + +Signed-off-by: Dexuan Cui +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 2048157ad02e65f6327118dd4a7b9c9f1fd12f77) +--- + drivers/input/serio/hyperv-keyboard.c | 10 ---------- + include/linux/hyperv.h | 8 ++++++++ + 2 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c +index e74e5d6..c948866 100644 +--- a/drivers/input/serio/hyperv-keyboard.c ++++ b/drivers/input/serio/hyperv-keyboard.c +@@ -412,16 +412,6 @@ static int hv_kbd_remove(struct hv_device *hv_dev) + return 0; + } + +-/* +- * Keyboard GUID +- * {f912ad6d-2b17-48ea-bd65-f927a61c7684} +- */ +-#define HV_KBD_GUID \ +- .guid = { \ +- 0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \ +- 0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \ +- } +- + static const struct hv_vmbus_device_id id_table[] = { + /* Keyboard guid */ + { HV_KBD_GUID, }, +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 4712d7d..9e2de6a 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -1091,6 +1091,14 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) + + /* ++ * Keyboard GUID ++ * {f912ad6d-2b17-48ea-bd65-f927a61c7684} ++ */ ++#define HV_KBD_GUID \ ++ .guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \ ++ 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84) ++ ++/* + * VSS (Backup/Restore) GUID + */ + #define HV_VSS_GUID \ +-- +2.8.2 + diff --git a/alpine/kernel/patches/0020-Drivers-hv-vmbus-Treat-Fibre-Channel-devices-as-perf.patch b/alpine/kernel/patches/0020-Drivers-hv-vmbus-Treat-Fibre-Channel-devices-as-perf.patch new file mode 100644 index 000000000..431abd58a --- /dev/null +++ b/alpine/kernel/patches/0020-Drivers-hv-vmbus-Treat-Fibre-Channel-devices-as-perf.patch @@ -0,0 +1,42 @@ +From e952f2c22a0a2dbf6b56f732ce265aa6c9f461b2 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Tue, 15 Dec 2015 16:27:27 -0800 +Subject: [PATCH 20/40] Drivers: hv: vmbus: Treat Fibre Channel devices as + performance critical + +For performance critical devices, we distribute the incoming +channel interrupt load across available CPUs in the guest. +Include Fibre channel devices in the set of devices for which +we would distribute the interrupt load. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 879a650a273bc3efb9d472886b8ced12630ea8ed) +--- + drivers/hv/channel_mgmt.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index d013171..1c1ad47 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -361,6 +361,7 @@ err_free_chan: + enum { + IDE = 0, + SCSI, ++ FC, + NIC, + ND_NIC, + PCIE, +@@ -377,6 +378,8 @@ static const struct hv_vmbus_device_id hp_devs[] = { + { HV_IDE_GUID, }, + /* Storage - SCSI */ + { HV_SCSI_GUID, }, ++ /* Storage - FC */ ++ { HV_SYNTHFC_GUID, }, + /* Network */ + { HV_NIC_GUID, }, + /* NetworkDirect Guest RDMA */ +-- +2.8.2 + diff --git a/alpine/kernel/patches/0021-Drivers-hv-vmbus-Add-vendor-and-device-atttributes.patch b/alpine/kernel/patches/0021-Drivers-hv-vmbus-Add-vendor-and-device-atttributes.patch new file mode 100644 index 000000000..32b66fcc7 --- /dev/null +++ b/alpine/kernel/patches/0021-Drivers-hv-vmbus-Add-vendor-and-device-atttributes.patch @@ -0,0 +1,355 @@ +From cd2ba91482cea0e0979336c7e174224c39ab4537 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Fri, 25 Dec 2015 20:00:30 -0800 +Subject: [PATCH 21/40] Drivers: hv: vmbus: Add vendor and device atttributes + +Add vendor and device attributes to VMBUS devices. These will be used +by Hyper-V tools as well user-level RDMA libraries that will use the +vendor/device tuple to discover the RDMA device. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7047f17d70fc0599563d30d0791692cb5fe42ae6) +--- + Documentation/ABI/stable/sysfs-bus-vmbus | 14 +++ + drivers/hv/channel_mgmt.c | 166 +++++++++++++++++++++++-------- + drivers/hv/vmbus_drv.c | 21 ++++ + include/linux/hyperv.h | 28 ++++++ + 4 files changed, 186 insertions(+), 43 deletions(-) + +diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus +index 636e938..5d0125f 100644 +--- a/Documentation/ABI/stable/sysfs-bus-vmbus ++++ b/Documentation/ABI/stable/sysfs-bus-vmbus +@@ -27,3 +27,17 @@ Description: The mapping of which primary/sub channels are bound to which + Virtual Processors. + Format: + Users: tools/hv/lsvmbus ++ ++What: /sys/bus/vmbus/devices/vmbus_*/device ++Date: Dec. 2015 ++KernelVersion: 4.5 ++Contact: K. Y. Srinivasan ++Description: The 16 bit device ID of the device ++Users: tools/hv/lsvmbus and user level RDMA libraries ++ ++What: /sys/bus/vmbus/devices/vmbus_*/vendor ++Date: Dec. 2015 ++KernelVersion: 4.5 ++Contact: K. Y. Srinivasan ++Description: The 16 bit vendor ID of the device ++Users: tools/hv/lsvmbus and user level RDMA libraries +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 1c1ad47..107d72f 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -32,8 +32,122 @@ + + #include "hyperv_vmbus.h" + +-static void init_vp_index(struct vmbus_channel *channel, +- const uuid_le *type_guid); ++static void init_vp_index(struct vmbus_channel *channel, u16 dev_type); ++ ++static const struct vmbus_device vmbus_devs[] = { ++ /* IDE */ ++ { .dev_type = HV_IDE, ++ HV_IDE_GUID, ++ .perf_device = true, ++ }, ++ ++ /* SCSI */ ++ { .dev_type = HV_SCSI, ++ HV_SCSI_GUID, ++ .perf_device = true, ++ }, ++ ++ /* Fibre Channel */ ++ { .dev_type = HV_FC, ++ HV_SYNTHFC_GUID, ++ .perf_device = true, ++ }, ++ ++ /* Synthetic NIC */ ++ { .dev_type = HV_NIC, ++ HV_NIC_GUID, ++ .perf_device = true, ++ }, ++ ++ /* Network Direct */ ++ { .dev_type = HV_ND, ++ HV_ND_GUID, ++ .perf_device = true, ++ }, ++ ++ /* PCIE */ ++ { .dev_type = HV_PCIE, ++ HV_PCIE_GUID, ++ .perf_device = true, ++ }, ++ ++ /* Synthetic Frame Buffer */ ++ { .dev_type = HV_FB, ++ HV_SYNTHVID_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Synthetic Keyboard */ ++ { .dev_type = HV_KBD, ++ HV_KBD_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Synthetic MOUSE */ ++ { .dev_type = HV_MOUSE, ++ HV_MOUSE_GUID, ++ .perf_device = false, ++ }, ++ ++ /* KVP */ ++ { .dev_type = HV_KVP, ++ HV_KVP_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Time Synch */ ++ { .dev_type = HV_TS, ++ HV_TS_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Heartbeat */ ++ { .dev_type = HV_HB, ++ HV_HEART_BEAT_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Shutdown */ ++ { .dev_type = HV_SHUTDOWN, ++ HV_SHUTDOWN_GUID, ++ .perf_device = false, ++ }, ++ ++ /* File copy */ ++ { .dev_type = HV_FCOPY, ++ HV_FCOPY_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Backup */ ++ { .dev_type = HV_BACKUP, ++ HV_VSS_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Dynamic Memory */ ++ { .dev_type = HV_DM, ++ HV_DM_GUID, ++ .perf_device = false, ++ }, ++ ++ /* Unknown GUID */ ++ { .dev_type = HV_UNKOWN, ++ .perf_device = false, ++ }, ++}; ++ ++static u16 hv_get_dev_type(const uuid_le *guid) ++{ ++ u16 i; ++ ++ for (i = HV_IDE; i < HV_UNKOWN; i++) { ++ if (!uuid_le_cmp(*guid, vmbus_devs[i].guid)) ++ return i; ++ } ++ pr_info("Unknown GUID: %pUl\n", guid); ++ return i; ++} + + /** + * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message +@@ -251,6 +365,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + struct vmbus_channel *channel; + bool fnew = true; + unsigned long flags; ++ u16 dev_type; + + /* Make sure this is a new offer */ + mutex_lock(&vmbus_connection.channel_mutex); +@@ -288,7 +403,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + goto err_free_chan; + } + +- init_vp_index(newchannel, &newchannel->offermsg.offer.if_type); ++ dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type); ++ ++ init_vp_index(newchannel, dev_type); + + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); +@@ -325,6 +442,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + if (!newchannel->device_obj) + goto err_deq_chan; + ++ newchannel->device_obj->device_id = dev_type; + /* + * Add the new device to the bus. This will kick off device-driver + * binding which eventually invokes the device driver's AddDevice() +@@ -358,37 +476,6 @@ err_free_chan: + free_channel(newchannel); + } + +-enum { +- IDE = 0, +- SCSI, +- FC, +- NIC, +- ND_NIC, +- PCIE, +- MAX_PERF_CHN, +-}; +- +-/* +- * This is an array of device_ids (device types) that are performance critical. +- * We attempt to distribute the interrupt load for these devices across +- * all available CPUs. +- */ +-static const struct hv_vmbus_device_id hp_devs[] = { +- /* IDE */ +- { HV_IDE_GUID, }, +- /* Storage - SCSI */ +- { HV_SCSI_GUID, }, +- /* Storage - FC */ +- { HV_SYNTHFC_GUID, }, +- /* Network */ +- { HV_NIC_GUID, }, +- /* NetworkDirect Guest RDMA */ +- { HV_ND_GUID, }, +- /* PCI Express Pass Through */ +- { HV_PCIE_GUID, }, +-}; +- +- + /* + * We use this state to statically distribute the channel interrupt load. + */ +@@ -405,22 +492,15 @@ static int next_numa_node_id; + * For pre-win8 hosts or non-performance critical channels we assign the + * first CPU in the first NUMA node. + */ +-static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid) ++static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) + { + u32 cur_cpu; +- int i; +- bool perf_chn = false; ++ bool perf_chn = vmbus_devs[dev_type].perf_device; + struct vmbus_channel *primary = channel->primary_channel; + int next_node; + struct cpumask available_mask; + struct cpumask *alloced_mask; + +- for (i = IDE; i < MAX_PERF_CHN; i++) { +- if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) { +- perf_chn = true; +- break; +- } +- } + if ((vmbus_proto_version == VERSION_WS2008) || + (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) { + /* +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index 5a71b2a..3b83dfe 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -478,6 +478,24 @@ static ssize_t channel_vp_mapping_show(struct device *dev, + } + static DEVICE_ATTR_RO(channel_vp_mapping); + ++static ssize_t vendor_show(struct device *dev, ++ struct device_attribute *dev_attr, ++ char *buf) ++{ ++ struct hv_device *hv_dev = device_to_hv_device(dev); ++ return sprintf(buf, "0x%x\n", hv_dev->vendor_id); ++} ++static DEVICE_ATTR_RO(vendor); ++ ++static ssize_t device_show(struct device *dev, ++ struct device_attribute *dev_attr, ++ char *buf) ++{ ++ struct hv_device *hv_dev = device_to_hv_device(dev); ++ return sprintf(buf, "0x%x\n", hv_dev->device_id); ++} ++static DEVICE_ATTR_RO(device); ++ + /* Set up per device attributes in /sys/bus/vmbus/devices/ */ + static struct attribute *vmbus_attrs[] = { + &dev_attr_id.attr, +@@ -503,6 +521,8 @@ static struct attribute *vmbus_attrs[] = { + &dev_attr_in_read_bytes_avail.attr, + &dev_attr_in_write_bytes_avail.attr, + &dev_attr_channel_vp_mapping.attr, ++ &dev_attr_vendor.attr, ++ &dev_attr_device.attr, + NULL, + }; + ATTRIBUTE_GROUPS(vmbus); +@@ -957,6 +977,7 @@ struct hv_device *vmbus_device_create(const uuid_le *type, + memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le)); + memcpy(&child_device_obj->dev_instance, instance, + sizeof(uuid_le)); ++ child_device_obj->vendor_id = 0x1414; /* MSFT vendor ID */ + + + return child_device_obj; +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 9e2de6a..51c98fd 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -635,6 +635,32 @@ enum hv_signal_policy { + HV_SIGNAL_POLICY_EXPLICIT, + }; + ++enum vmbus_device_type { ++ HV_IDE = 0, ++ HV_SCSI, ++ HV_FC, ++ HV_NIC, ++ HV_ND, ++ HV_PCIE, ++ HV_FB, ++ HV_KBD, ++ HV_MOUSE, ++ HV_KVP, ++ HV_TS, ++ HV_HB, ++ HV_SHUTDOWN, ++ HV_FCOPY, ++ HV_BACKUP, ++ HV_DM, ++ HV_UNKOWN, ++}; ++ ++struct vmbus_device { ++ u16 dev_type; ++ uuid_le guid; ++ bool perf_device; ++}; ++ + struct vmbus_channel { + /* Unique channel id */ + int id; +@@ -961,6 +987,8 @@ struct hv_device { + + /* the device instance id of this device */ + uuid_le dev_instance; ++ u16 vendor_id; ++ u16 device_id; + + struct device device; + +-- +2.8.2 + diff --git a/alpine/kernel/patches/0022-Drivers-hv-vmbus-avoid-infinite-loop-in-init_vp_inde.patch b/alpine/kernel/patches/0022-Drivers-hv-vmbus-avoid-infinite-loop-in-init_vp_inde.patch new file mode 100644 index 000000000..5aba4d76f --- /dev/null +++ b/alpine/kernel/patches/0022-Drivers-hv-vmbus-avoid-infinite-loop-in-init_vp_inde.patch @@ -0,0 +1,49 @@ +From 38a40857bb22894545830b22fb593241f2fabf4d Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Wed, 27 Jan 2016 22:29:34 -0800 +Subject: [PATCH 22/40] Drivers: hv: vmbus: avoid infinite loop in + init_vp_index() + +When we pick a CPU to use for a new subchannel we try find a non-used one +on the appropriate NUMA node, we keep track of them with the +primary->alloced_cpus_in_node mask. Under normal circumstances we don't run +out of available CPUs but it is possible when we we don't initialize some +cpus in Linux, e.g. when we boot with 'nr_cpus=' limitation. + +Avoid the infinite loop in init_vp_index() by checking that we still have +non-used CPUs in the alloced_cpus_in_node mask and resetting it in case +we don't. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 79fd8e706637a5c7c41f9498fe0fbfb437abfdc8) +--- + drivers/hv/channel_mgmt.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 107d72f..af1d82e 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -549,6 +549,17 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) + cpumask_of_node(primary->numa_node)); + + cur_cpu = -1; ++ ++ /* ++ * Normally Hyper-V host doesn't create more subchannels than there ++ * are VCPUs on the node but it is possible when not all present VCPUs ++ * on the node are initialized by guest. Clear the alloced_cpus_in_node ++ * to start over. ++ */ ++ if (cpumask_equal(&primary->alloced_cpus_in_node, ++ cpumask_of_node(primary->numa_node))) ++ cpumask_clear(&primary->alloced_cpus_in_node); ++ + while (true) { + cur_cpu = cpumask_next(cur_cpu, &available_mask); + if (cur_cpu >= nr_cpu_ids) { +-- +2.8.2 + diff --git a/alpine/kernel/patches/0023-Drivers-hv-vmbus-avoid-scheduling-in-interrupt-conte.patch b/alpine/kernel/patches/0023-Drivers-hv-vmbus-avoid-scheduling-in-interrupt-conte.patch new file mode 100644 index 000000000..adf5366ea --- /dev/null +++ b/alpine/kernel/patches/0023-Drivers-hv-vmbus-avoid-scheduling-in-interrupt-conte.patch @@ -0,0 +1,99 @@ +From 22945cbc393c06b0b55c553623b595fc1e6d2598 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Wed, 27 Jan 2016 22:29:35 -0800 +Subject: [PATCH 23/40] Drivers: hv: vmbus: avoid scheduling in interrupt + context in vmbus_initiate_unload() + +We have to call vmbus_initiate_unload() on crash to make kdump work but +the crash can also be happening in interrupt (e.g. Sysrq + c results in +such) where we can't schedule or the following will happen: + +[ 314.905786] bad: scheduling from the idle thread! + +Just skipping the wait (and even adding some random wait here) won't help: +to make host-side magic working we're supposed to receive CHANNELMSG_UNLOAD +(and actually confirm the fact that we received it) but we can't use +interrupt-base path (vmbus_isr()-> vmbus_on_msg_dpc()). Implement a simple +busy wait ignoring all the other messages and use it if we're in an +interrupt context. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 415719160de3fae3bb9cbc617664649919cd00d0) +--- + drivers/hv/channel_mgmt.c | 44 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index af1d82e..d6c6114 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + + #include "hyperv_vmbus.h" +@@ -589,6 +590,40 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) + channel->target_vp = hv_context.vp_index[cur_cpu]; + } + ++static void vmbus_wait_for_unload(void) ++{ ++ int cpu = smp_processor_id(); ++ void *page_addr = hv_context.synic_message_page[cpu]; ++ struct hv_message *msg = (struct hv_message *)page_addr + ++ VMBUS_MESSAGE_SINT; ++ struct vmbus_channel_message_header *hdr; ++ bool unloaded = false; ++ ++ while (1) { ++ if (msg->header.message_type == HVMSG_NONE) { ++ mdelay(10); ++ continue; ++ } ++ ++ hdr = (struct vmbus_channel_message_header *)msg->u.payload; ++ if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE) ++ unloaded = true; ++ ++ msg->header.message_type = HVMSG_NONE; ++ /* ++ * header.message_type needs to be written before we do ++ * wrmsrl() below. ++ */ ++ mb(); ++ ++ if (msg->header.message_flags.msg_pending) ++ wrmsrl(HV_X64_MSR_EOM, 0); ++ ++ if (unloaded) ++ break; ++ } ++} ++ + /* + * vmbus_unload_response - Handler for the unload response. + */ +@@ -614,7 +649,14 @@ void vmbus_initiate_unload(void) + hdr.msgtype = CHANNELMSG_UNLOAD; + vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header)); + +- wait_for_completion(&vmbus_connection.unload_event); ++ /* ++ * vmbus_initiate_unload() is also called on crash and the crash can be ++ * happening in an interrupt context, where scheduling is impossible. ++ */ ++ if (!in_interrupt()) ++ wait_for_completion(&vmbus_connection.unload_event); ++ else ++ vmbus_wait_for_unload(); + } + + /* +-- +2.8.2 + diff --git a/alpine/kernel/patches/0015-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch b/alpine/kernel/patches/0024-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch similarity index 80% rename from alpine/kernel/patches/0015-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch rename to alpine/kernel/patches/0024-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch index 8bd2df33d..6da28a7d8 100644 --- a/alpine/kernel/patches/0015-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch +++ b/alpine/kernel/patches/0024-Drivers-hv-vmbus-add-a-helper-function-to-set-a-chan.patch @@ -1,7 +1,7 @@ -From 38bad476ce53b8b305d5629cfa5fe013c82f5a97 Mon Sep 17 00:00:00 2001 +From 73d794b62769667baebc92515da11aa2ef687bf3 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:37 -0800 -Subject: [PATCH 15/28] Drivers: hv: vmbus: add a helper function to set a +Subject: [PATCH 24/40] Drivers: hv: vmbus: add a helper function to set a channel's pending send size This will be used by the coming net/hvsock driver. @@ -15,10 +15,10 @@ Signed-off-by: Greg Kroah-Hartman 1 file changed, 6 insertions(+) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index ae6a711..fda6310 100644 +index 51c98fd..934542a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h -@@ -792,6 +792,12 @@ static inline void *get_per_channel_state(struct vmbus_channel *c) +@@ -818,6 +818,12 @@ static inline void *get_per_channel_state(struct vmbus_channel *c) return c->per_channel_state; } diff --git a/alpine/kernel/patches/0016-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch b/alpine/kernel/patches/0025-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch similarity index 85% rename from alpine/kernel/patches/0016-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch rename to alpine/kernel/patches/0025-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch index 5015f3570..f4a91aa39 100644 --- a/alpine/kernel/patches/0016-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch +++ b/alpine/kernel/patches/0025-Drivers-hv-vmbus-define-the-new-offer-type-for-Hyper.patch @@ -1,7 +1,7 @@ -From 34e3731c0ba650cc5e7c15517da15f76e438b031 Mon Sep 17 00:00:00 2001 +From 57b533b03fea1344ff846c76738cd919678778c1 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:38 -0800 -Subject: [PATCH 16/28] Drivers: hv: vmbus: define the new offer type for +Subject: [PATCH 25/40] Drivers: hv: vmbus: define the new offer type for Hyper-V socket (hvsock) A helper function is also added. @@ -15,7 +15,7 @@ Signed-off-by: Greg Kroah-Hartman 1 file changed, 7 insertions(+) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index fda6310..9fb2130 100644 +index 934542a..a4f105d 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -237,6 +237,7 @@ struct vmbus_channel_offer { @@ -26,7 +26,7 @@ index fda6310..9fb2130 100644 struct vmpacket_descriptor { u16 type; -@@ -771,6 +772,12 @@ struct vmbus_channel { +@@ -797,6 +798,12 @@ struct vmbus_channel { enum hv_signal_policy signal_policy; }; diff --git a/alpine/kernel/patches/0017-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch b/alpine/kernel/patches/0026-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch similarity index 90% rename from alpine/kernel/patches/0017-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch rename to alpine/kernel/patches/0026-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch index eaf0f0ed7..8fdf70135 100644 --- a/alpine/kernel/patches/0017-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch +++ b/alpine/kernel/patches/0026-Drivers-hv-vmbus-vmbus_sendpacket_ctl-hvsock-avoid-u.patch @@ -1,7 +1,7 @@ -From 53e57822a7f9d6c6fc221c21cfbbe9da2965c059 Mon Sep 17 00:00:00 2001 +From 3f1df935d1b5caad3f00a43eb50714375bc32547 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:39 -0800 -Subject: [PATCH 17/28] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid +Subject: [PATCH 26/40] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid unnecessary signaling When the hvsock channel's outbound ringbuffer is full (i.e., @@ -17,7 +17,7 @@ Signed-off-by: Greg Kroah-Hartman 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c -index 2889d97..a7f9e3e 100644 +index dd6de7f..128dcf2 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -659,6 +659,9 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, diff --git a/alpine/kernel/patches/0018-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch b/alpine/kernel/patches/0027-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch similarity index 89% rename from alpine/kernel/patches/0018-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch rename to alpine/kernel/patches/0027-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch index f98864942..0b1da9061 100644 --- a/alpine/kernel/patches/0018-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch +++ b/alpine/kernel/patches/0027-Drivers-hv-vmbus-define-a-new-VMBus-message-type-for.patch @@ -1,7 +1,7 @@ -From 7e8defd74db9d20fc2c1b98946f5f1e5ad96e33c Mon Sep 17 00:00:00 2001 +From 75650dcb326987e017209a61107f341447a88de5 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:40 -0800 -Subject: [PATCH 18/28] Drivers: hv: vmbus: define a new VMBus message type for +Subject: [PATCH 27/40] Drivers: hv: vmbus: define a new VMBus message type for hvsock A function to send the type of message is also added. @@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman 3 files changed, 32 insertions(+) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c -index a7f9e3e..239b072 100644 +index 128dcf2..415f6c7 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -219,6 +219,21 @@ error0: @@ -46,10 +46,10 @@ index a7f9e3e..239b072 100644 * create_gpadl_header - Creates a gpadl for the specified buffer */ diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index bd4f084..4d61f41 100644 +index d6c6114..60ca25b 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c -@@ -820,6 +820,10 @@ struct vmbus_channel_message_table_entry +@@ -958,6 +958,10 @@ struct vmbus_channel_message_table_entry {CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response}, {CHANNELMSG_UNLOAD, 0, NULL}, {CHANNELMSG_UNLOAD_RESPONSE, 1, vmbus_unload_response}, @@ -61,7 +61,7 @@ index bd4f084..4d61f41 100644 /* diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index 9fb2130..3f485a4 100644 +index a4f105d..191bc5d 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -394,6 +394,10 @@ enum vmbus_channel_message_type { @@ -89,7 +89,7 @@ index 9fb2130..3f485a4 100644 struct vmbus_channel_version_response { struct vmbus_channel_message_header header; u8 version_supported; -@@ -1276,4 +1287,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); +@@ -1295,4 +1306,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); extern __u32 vmbus_proto_version; diff --git a/alpine/kernel/patches/0019-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch b/alpine/kernel/patches/0028-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch similarity index 84% rename from alpine/kernel/patches/0019-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch rename to alpine/kernel/patches/0028-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch index 9e1738d82..be78b7e9c 100644 --- a/alpine/kernel/patches/0019-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch +++ b/alpine/kernel/patches/0028-Drivers-hv-vmbus-add-a-hvsock-flag-in-struct-hv_driv.patch @@ -1,7 +1,7 @@ -From 1d19451adec149cefc135c442b4cb2241d87607a Mon Sep 17 00:00:00 2001 +From f32ca7e520ca07ec5294e852248522c3ac0d145f Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:41 -0800 -Subject: [PATCH 19/28] Drivers: hv: vmbus: add a hvsock flag in struct +Subject: [PATCH 28/40] Drivers: hv: vmbus: add a hvsock flag in struct hv_driver Only the coming hv_sock driver has a "true" value for this flag. @@ -20,10 +20,10 @@ Signed-off-by: Greg Kroah-Hartman 2 files changed, 18 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c -index 7e46a48..7d607ad 100644 +index 3b83dfe..d76a65f 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c -@@ -563,6 +563,10 @@ static int vmbus_match(struct device *device, struct device_driver *driver) +@@ -583,6 +583,10 @@ static int vmbus_match(struct device *device, struct device_driver *driver) struct hv_driver *drv = drv_to_hv_drv(driver); struct hv_device *hv_dev = device_to_hv_device(device); @@ -31,14 +31,14 @@ index 7e46a48..7d607ad 100644 + if (is_hvsock_channel(hv_dev->channel)) + return drv->hvsock; + - if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b)) + if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type)) return 1; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index 3f485a4..9ee79af 100644 +index 191bc5d..05966e2 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h -@@ -966,6 +966,20 @@ extern void vmbus_ontimer(unsigned long data); +@@ -992,6 +992,20 @@ extern void vmbus_ontimer(unsigned long data); struct hv_driver { const char *name; diff --git a/alpine/kernel/patches/0028-hv_sock-Don-t-touch-the-socket-state-when-the-other-.patch b/alpine/kernel/patches/0028-hv_sock-Don-t-touch-the-socket-state-when-the-other-.patch deleted file mode 100644 index b5e46d8b5..000000000 --- a/alpine/kernel/patches/0028-hv_sock-Don-t-touch-the-socket-state-when-the-other-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 89a360504f1683d1be642506a14c9f59ea2c9771 Mon Sep 17 00:00:00 2001 -From: Rolf Neugebauer -Date: Sun, 15 May 2016 10:56:16 +0100 -Subject: [PATCH 28/28] hv_sock: Don't touch the socket state when the other - end closes - -This cause a NULL pointer de-reference when the client closes the connection -before accept() is called by the server. - -Signed-off-by: Rolf Neugebauer ---- - net/hv_sock/af_hvsock.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/net/hv_sock/af_hvsock.c b/net/hv_sock/af_hvsock.c -index 013d684..0b7ab8a 100644 ---- a/net/hv_sock/af_hvsock.c -+++ b/net/hv_sock/af_hvsock.c -@@ -616,7 +616,6 @@ static void hvsock_close_connection(struct vmbus_channel *channel) - if (!sk) - goto out; - -- sk->sk_socket->state = SS_UNCONNECTED; - sk->sk_state = SS_UNCONNECTED; - sock_set_flag(sk, SOCK_DONE); - --- -2.8.2 - diff --git a/alpine/kernel/patches/0020-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch b/alpine/kernel/patches/0029-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch similarity index 83% rename from alpine/kernel/patches/0020-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch rename to alpine/kernel/patches/0029-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch index 1b73235c1..0da893981 100644 --- a/alpine/kernel/patches/0020-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch +++ b/alpine/kernel/patches/0029-Drivers-hv-vmbus-add-a-per-channel-rescind-callback.patch @@ -1,7 +1,7 @@ -From 14935b1d81d62a8aee055d8b762a745338e445b2 Mon Sep 17 00:00:00 2001 +From 91bc38269cbba8c6ffc4db837f22267f72cfcd35 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:42 -0800 -Subject: [PATCH 20/28] Drivers: hv: vmbus: add a per-channel rescind callback +Subject: [PATCH 29/40] Drivers: hv: vmbus: add a per-channel rescind callback This will be used by the coming hv_sock driver. @@ -15,10 +15,10 @@ Signed-off-by: Greg Kroah-Hartman 2 files changed, 20 insertions(+) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index 4d61f41..421e3dd 100644 +index 60ca25b..76864c9 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c -@@ -603,6 +603,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -741,6 +741,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) spin_unlock_irqrestore(&channel->lock, flags); if (channel->device_obj) { @@ -29,7 +29,7 @@ index 4d61f41..421e3dd 100644 /* * We will have to unregister this device from the * driver core. -@@ -972,3 +976,10 @@ bool vmbus_are_subchannels_present(struct vmbus_channel *primary) +@@ -1110,3 +1114,10 @@ bool vmbus_are_subchannels_present(struct vmbus_channel *primary) return ret; } EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present); @@ -41,10 +41,10 @@ index 4d61f41..421e3dd 100644 +} +EXPORT_SYMBOL_GPL(vmbus_set_chn_rescind_callback); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index 9ee79af..09e9ec1 100644 +index 05966e2..ad04017 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h -@@ -742,6 +742,12 @@ struct vmbus_channel { +@@ -768,6 +768,12 @@ struct vmbus_channel { void (*sc_creation_callback)(struct vmbus_channel *new_sc); /* @@ -57,7 +57,7 @@ index 9ee79af..09e9ec1 100644 * The spinlock to protect the structure. It is being used to protect * test-and-set access to various attributes of the structure as well * as all sc_list operations. -@@ -827,6 +833,9 @@ int vmbus_request_offers(void); +@@ -853,6 +859,9 @@ int vmbus_request_offers(void); void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel, void (*sc_cr_cb)(struct vmbus_channel *new_sc)); diff --git a/alpine/kernel/patches/0021-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch b/alpine/kernel/patches/0030-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch similarity index 84% rename from alpine/kernel/patches/0021-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch rename to alpine/kernel/patches/0030-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch index d4c19efe4..c94de4ee3 100644 --- a/alpine/kernel/patches/0021-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch +++ b/alpine/kernel/patches/0030-Drivers-hv-vmbus-add-an-API-vmbus_hvsock_device_unre.patch @@ -1,7 +1,7 @@ -From 080b343d4e73684e9c261350703a48771eeda231 Mon Sep 17 00:00:00 2001 +From 5ffa6fad55eaaa00feecefe483a7eb3aba155ae9 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 27 Jan 2016 22:29:43 -0800 -Subject: [PATCH 21/28] Drivers: hv: vmbus: add an API +Subject: [PATCH 30/40] Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister() The hvsock driver needs this API to release all the resources related @@ -18,10 +18,10 @@ Signed-off-by: Greg Kroah-Hartman 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c -index 421e3dd..0fe9665 100644 +index 76864c9..cf311be 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c -@@ -195,6 +195,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) +@@ -310,6 +310,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) vmbus_release_relid(relid); BUG_ON(!channel->rescind); @@ -29,7 +29,7 @@ index 421e3dd..0fe9665 100644 if (channel->target_cpu != get_cpu()) { put_cpu(); -@@ -206,9 +207,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) +@@ -321,9 +322,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) } if (channel->primary_channel == NULL) { @@ -39,15 +39,15 @@ index 421e3dd..0fe9665 100644 primary_channel = channel; } else { -@@ -251,6 +250,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) - struct vmbus_channel *channel; +@@ -367,6 +366,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) bool fnew = true; unsigned long flags; + u16 dev_type; + int ret; /* Make sure this is a new offer */ mutex_lock(&vmbus_connection.channel_mutex); -@@ -330,7 +330,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) +@@ -449,7 +449,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) * binding which eventually invokes the device driver's AddDevice() * method. */ @@ -60,7 +60,7 @@ index 421e3dd..0fe9665 100644 pr_err("unable to add child device object (relid %d)\n", newchannel->offermsg.child_relid); kfree(newchannel->device_obj); -@@ -587,6 +591,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -725,6 +729,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) struct device *dev; rescind = (struct vmbus_channel_rescind_offer *)hdr; @@ -69,7 +69,7 @@ index 421e3dd..0fe9665 100644 channel = relid2channel(rescind->child_relid); if (channel == NULL) { -@@ -595,7 +601,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -733,7 +739,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) * vmbus_process_offer(), we have already invoked * vmbus_release_relid() on error. */ @@ -78,7 +78,7 @@ index 421e3dd..0fe9665 100644 } spin_lock_irqsave(&channel->lock, flags); -@@ -605,7 +611,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -743,7 +749,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) if (channel->device_obj) { if (channel->chn_rescind_callback) { channel->chn_rescind_callback(channel); @@ -87,7 +87,7 @@ index 421e3dd..0fe9665 100644 } /* * We will have to unregister this device from the -@@ -620,8 +626,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) +@@ -758,8 +764,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) hv_process_channel_removal(channel, channel->offermsg.child_relid); } @@ -136,10 +136,10 @@ index 521f48e..09c08b5 100644 return found_channel; } diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index 09e9ec1..af7ee0a 100644 +index ad04017..993318a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h -@@ -1043,6 +1043,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver, +@@ -1071,6 +1071,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver, const char *mod_name); void vmbus_driver_unregister(struct hv_driver *hv_driver); diff --git a/alpine/kernel/patches/0031-Drivers-hv-vmbus-Give-control-over-how-the-ring-acce.patch b/alpine/kernel/patches/0031-Drivers-hv-vmbus-Give-control-over-how-the-ring-acce.patch new file mode 100644 index 000000000..5cc77ea48 --- /dev/null +++ b/alpine/kernel/patches/0031-Drivers-hv-vmbus-Give-control-over-how-the-ring-acce.patch @@ -0,0 +1,208 @@ +From e648c3f4c7a150cec1c794037af051c671358d18 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Wed, 27 Jan 2016 22:29:45 -0800 +Subject: [PATCH 31/40] Drivers: hv: vmbus: Give control over how the ring + access is serialized + +On the channel send side, many of the VMBUS +device drivers explicity serialize access to the +outgoing ring buffer. Give more control to the +VMBUS device drivers in terms how to serialize +accesss to the outgoing ring buffer. +The default behavior will be to aquire the +ring lock to preserve the current behavior. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit fe760e4d64fe5c17c39e86c410d41f6587ee88bc) +--- + drivers/hv/channel.c | 15 +++++++++++---- + drivers/hv/channel_mgmt.c | 1 + + drivers/hv/hyperv_vmbus.h | 2 +- + drivers/hv/ring_buffer.c | 13 ++++++++----- + include/linux/hyperv.h | 16 ++++++++++++++++ + 5 files changed, 37 insertions(+), 10 deletions(-) + +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 415f6c7..57a1b65 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -639,6 +639,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, + u64 aligned_data = 0; + int ret; + bool signal = false; ++ bool lock = channel->acquire_ring_lock; + int num_vecs = ((bufferlen != 0) ? 3 : 1); + + +@@ -658,7 +659,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, + bufferlist[2].iov_len = (packetlen_aligned - packetlen); + + ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, +- &signal); ++ &signal, lock); + + /* + * Signalling the host is conditional on many factors: +@@ -738,6 +739,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, + struct kvec bufferlist[3]; + u64 aligned_data = 0; + bool signal = false; ++ bool lock = channel->acquire_ring_lock; + + if (pagecount > MAX_PAGE_BUFFER_COUNT) + return -EINVAL; +@@ -774,7 +776,8 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, + bufferlist[2].iov_base = &aligned_data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); + +- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); ++ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, ++ &signal, lock); + + /* + * Signalling the host is conditional on many factors: +@@ -837,6 +840,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, + struct kvec bufferlist[3]; + u64 aligned_data = 0; + bool signal = false; ++ bool lock = channel->acquire_ring_lock; + + packetlen = desc_size + bufferlen; + packetlen_aligned = ALIGN(packetlen, sizeof(u64)); +@@ -856,7 +860,8 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, + bufferlist[2].iov_base = &aligned_data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); + +- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); ++ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, ++ &signal, lock); + + if (ret == 0 && signal) + vmbus_setevent(channel); +@@ -881,6 +886,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, + struct kvec bufferlist[3]; + u64 aligned_data = 0; + bool signal = false; ++ bool lock = channel->acquire_ring_lock; + u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, + multi_pagebuffer->len); + +@@ -919,7 +925,8 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, + bufferlist[2].iov_base = &aligned_data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); + +- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); ++ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, ++ &signal, lock); + + if (ret == 0 && signal) + vmbus_setevent(channel); +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index cf311be..b40f429 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -259,6 +259,7 @@ static struct vmbus_channel *alloc_channel(void) + return NULL; + + channel->id = atomic_inc_return(&chan_num); ++ channel->acquire_ring_lock = true; + spin_lock_init(&channel->inbound_lock); + spin_lock_init(&channel->lock); + +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index d9937be..b925fa3 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -612,7 +612,7 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); + + int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, + struct kvec *kv_list, +- u32 kv_count, bool *signal); ++ u32 kv_count, bool *signal, bool lock); + + int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, + u32 buflen); +diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c +index 70a1a9a..89a428f 100644 +--- a/drivers/hv/ring_buffer.c ++++ b/drivers/hv/ring_buffer.c +@@ -388,7 +388,7 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) + * + */ + int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, +- struct kvec *kv_list, u32 kv_count, bool *signal) ++ struct kvec *kv_list, u32 kv_count, bool *signal, bool lock) + { + int i = 0; + u32 bytes_avail_towrite; +@@ -398,14 +398,15 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, + u32 next_write_location; + u32 old_write; + u64 prev_indices = 0; +- unsigned long flags; ++ unsigned long flags = 0; + + for (i = 0; i < kv_count; i++) + totalbytes_towrite += kv_list[i].iov_len; + + totalbytes_towrite += sizeof(u64); + +- spin_lock_irqsave(&outring_info->ring_lock, flags); ++ if (lock) ++ spin_lock_irqsave(&outring_info->ring_lock, flags); + + hv_get_ringbuffer_availbytes(outring_info, + &bytes_avail_toread, +@@ -416,7 +417,8 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, + /* Otherwise, the next time around, we think the ring buffer */ + /* is empty since the read index == write index */ + if (bytes_avail_towrite <= totalbytes_towrite) { +- spin_unlock_irqrestore(&outring_info->ring_lock, flags); ++ if (lock) ++ spin_unlock_irqrestore(&outring_info->ring_lock, flags); + return -EAGAIN; + } + +@@ -447,7 +449,8 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, + hv_set_next_write_location(outring_info, next_write_location); + + +- spin_unlock_irqrestore(&outring_info->ring_lock, flags); ++ if (lock) ++ spin_unlock_irqrestore(&outring_info->ring_lock, flags); + + *signal = hv_need_to_signal(old_write, outring_info); + return 0; +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 993318a..6c9695e 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -813,8 +813,24 @@ struct vmbus_channel { + * signaling control. + */ + enum hv_signal_policy signal_policy; ++ /* ++ * On the channel send side, many of the VMBUS ++ * device drivers explicity serialize access to the ++ * outgoing ring buffer. Give more control to the ++ * VMBUS device drivers in terms how to serialize ++ * accesss to the outgoing ring buffer. ++ * The default behavior will be to aquire the ++ * ring lock to preserve the current behavior. ++ */ ++ bool acquire_ring_lock; ++ + }; + ++static inline void set_channel_lock_state(struct vmbus_channel *c, bool state) ++{ ++ c->acquire_ring_lock = state; ++} ++ + static inline bool is_hvsock_channel(const struct vmbus_channel *c) + { + return !!(c->offermsg.offer.chn_flags & +-- +2.8.2 + diff --git a/alpine/kernel/patches/0032-Drivers-hv-vmbus-avoid-wait_for_completion-on-crash.patch b/alpine/kernel/patches/0032-Drivers-hv-vmbus-avoid-wait_for_completion-on-crash.patch new file mode 100644 index 000000000..66855d840 --- /dev/null +++ b/alpine/kernel/patches/0032-Drivers-hv-vmbus-avoid-wait_for_completion-on-crash.patch @@ -0,0 +1,100 @@ +From 801ca93a137e97e204c04bf648901f73d38fabc9 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 26 Feb 2016 15:13:16 -0800 +Subject: [PATCH 32/40] Drivers: hv: vmbus: avoid wait_for_completion() on + crash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +wait_for_completion() may sleep, it enables interrupts and this +is something we really want to avoid on crashes because interrupt +handlers can cause other crashes. Switch to the recently introduced +vmbus_wait_for_unload() doing busy wait instead. + +Reported-by: Radim Krcmar +Signed-off-by: Vitaly Kuznetsov +Reviewed-by: Radim Kr.má +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 75ff3a8a9168df750b5bd0589e897a6c0517a9f1) +--- + drivers/hv/channel_mgmt.c | 4 ++-- + drivers/hv/connection.c | 2 +- + drivers/hv/hyperv_vmbus.h | 2 +- + drivers/hv/vmbus_drv.c | 4 ++-- + 4 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index b40f429..f70e352 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -641,7 +641,7 @@ static void vmbus_unload_response(struct vmbus_channel_message_header *hdr) + complete(&vmbus_connection.unload_event); + } + +-void vmbus_initiate_unload(void) ++void vmbus_initiate_unload(bool crash) + { + struct vmbus_channel_message_header hdr; + +@@ -658,7 +658,7 @@ void vmbus_initiate_unload(void) + * vmbus_initiate_unload() is also called on crash and the crash can be + * happening in an interrupt context, where scheduling is impossible. + */ +- if (!in_interrupt()) ++ if (!crash) + wait_for_completion(&vmbus_connection.unload_event); + else + vmbus_wait_for_unload(); +diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c +index 09c08b5..78b8be8 100644 +--- a/drivers/hv/connection.c ++++ b/drivers/hv/connection.c +@@ -233,7 +233,7 @@ void vmbus_disconnect(void) + /* + * First send the unload request to the host. + */ +- vmbus_initiate_unload(); ++ vmbus_initiate_unload(false); + + if (vmbus_connection.work_queue) { + drain_workqueue(vmbus_connection.work_queue); +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index b925fa3..10efab0 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -751,7 +751,7 @@ void hv_vss_onchannelcallback(void *); + int hv_fcopy_init(struct hv_util_service *); + void hv_fcopy_deinit(void); + void hv_fcopy_onchannelcallback(void *); +-void vmbus_initiate_unload(void); ++void vmbus_initiate_unload(bool crash); + + static inline void hv_poll_channel(struct vmbus_channel *channel, + void (*cb)(void *)) +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index d76a65f..45ea71e 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1263,7 +1263,7 @@ static void hv_kexec_handler(void) + int cpu; + + hv_synic_clockevents_cleanup(); +- vmbus_initiate_unload(); ++ vmbus_initiate_unload(false); + for_each_online_cpu(cpu) + smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); + hv_cleanup(); +@@ -1271,7 +1271,7 @@ static void hv_kexec_handler(void) + + static void hv_crash_handler(struct pt_regs *regs) + { +- vmbus_initiate_unload(); ++ vmbus_initiate_unload(true); + /* + * In crash handler we can't schedule synic cleanup for all CPUs, + * doing the cleanup for current CPU only. This should be sufficient +-- +2.8.2 + diff --git a/alpine/kernel/patches/0033-Drivers-hv-vmbus-avoid-unneeded-compiler-optimizatio.patch b/alpine/kernel/patches/0033-Drivers-hv-vmbus-avoid-unneeded-compiler-optimizatio.patch new file mode 100644 index 000000000..8eeb9a6b5 --- /dev/null +++ b/alpine/kernel/patches/0033-Drivers-hv-vmbus-avoid-unneeded-compiler-optimizatio.patch @@ -0,0 +1,39 @@ +From 57ebe7b218a4293879c6cfcfc809bd28d1c86d0b Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 26 Feb 2016 15:13:18 -0800 +Subject: [PATCH 33/40] Drivers: hv: vmbus: avoid unneeded compiler + optimizations in vmbus_wait_for_unload() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Message header is modified by the hypervisor and we read it in a loop, +we need to prevent compilers from optimizing accesses. There are no such +optimizations at this moment, this is just a future proof. + +Suggested-by: Radim Krcmar +Signed-off-by: Vitaly Kuznetsov +Reviewed-by: Radim Kr.má +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit d452ab7b4c65dfcaee88a0d6866eeeb98a3d1884) +--- + drivers/hv/channel_mgmt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index f70e352..c892db5 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -605,7 +605,7 @@ static void vmbus_wait_for_unload(void) + bool unloaded = false; + + while (1) { +- if (msg->header.message_type == HVMSG_NONE) { ++ if (READ_ONCE(msg->header.message_type) == HVMSG_NONE) { + mdelay(10); + continue; + } +-- +2.8.2 + diff --git a/alpine/kernel/patches/0022-kcm-Kernel-Connection-Multiplexor-module.patch b/alpine/kernel/patches/0034-kcm-Kernel-Connection-Multiplexor-module.patch similarity index 99% rename from alpine/kernel/patches/0022-kcm-Kernel-Connection-Multiplexor-module.patch rename to alpine/kernel/patches/0034-kcm-Kernel-Connection-Multiplexor-module.patch index 938f45f45..f080b293e 100644 --- a/alpine/kernel/patches/0022-kcm-Kernel-Connection-Multiplexor-module.patch +++ b/alpine/kernel/patches/0034-kcm-Kernel-Connection-Multiplexor-module.patch @@ -1,7 +1,7 @@ -From 7f7ff16a50fdab9cf540ba469dd4fd9dc1c36ce8 Mon Sep 17 00:00:00 2001 +From 309de4588761836db8325d18c96048c1d57976b0 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 7 Mar 2016 14:11:06 -0800 -Subject: [PATCH 22/28] kcm: Kernel Connection Multiplexor module +Subject: [PATCH 34/40] kcm: Kernel Connection Multiplexor module This module implements the Kernel Connection Multiplexor. diff --git a/alpine/kernel/patches/0023-net-add-the-AF_KCM-entries-to-family-name-tables.patch b/alpine/kernel/patches/0035-net-add-the-AF_KCM-entries-to-family-name-tables.patch similarity index 94% rename from alpine/kernel/patches/0023-net-add-the-AF_KCM-entries-to-family-name-tables.patch rename to alpine/kernel/patches/0035-net-add-the-AF_KCM-entries-to-family-name-tables.patch index d8c86f196..3505f6740 100644 --- a/alpine/kernel/patches/0023-net-add-the-AF_KCM-entries-to-family-name-tables.patch +++ b/alpine/kernel/patches/0035-net-add-the-AF_KCM-entries-to-family-name-tables.patch @@ -1,7 +1,7 @@ -From 0f2c256a5c2d11572adb078202575c85472c23dd Mon Sep 17 00:00:00 2001 +From 1b288c812adaffa34be2dc691e559a2c1ba343fa Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 21 Mar 2016 02:51:09 -0700 -Subject: [PATCH 23/28] net: add the AF_KCM entries to family name tables +Subject: [PATCH 35/40] net: add the AF_KCM entries to family name tables This is for the recent kcm driver, which introduces AF_KCM(41) in b7ac4eb(kcm: Kernel Connection Multiplexor module). diff --git a/alpine/kernel/patches/0024-net-Add-Qualcomm-IPC-router.patch b/alpine/kernel/patches/0036-net-Add-Qualcomm-IPC-router.patch similarity index 99% rename from alpine/kernel/patches/0024-net-Add-Qualcomm-IPC-router.patch rename to alpine/kernel/patches/0036-net-Add-Qualcomm-IPC-router.patch index 9158dccd3..a459e3247 100644 --- a/alpine/kernel/patches/0024-net-Add-Qualcomm-IPC-router.patch +++ b/alpine/kernel/patches/0036-net-Add-Qualcomm-IPC-router.patch @@ -1,7 +1,7 @@ -From ff301a551f581af1f7a5b44e531f24f6706ff8a1 Mon Sep 17 00:00:00 2001 +From 2bc2ef5b66204e811990746ae362acd16519b35d Mon Sep 17 00:00:00 2001 From: Courtney Cavin Date: Wed, 27 Apr 2016 12:13:03 -0700 -Subject: [PATCH 24/28] net: Add Qualcomm IPC router +Subject: [PATCH 36/40] net: Add Qualcomm IPC router Add an implementation of Qualcomm's IPC router protocol, used to communicate with service providing remote processors. diff --git a/alpine/kernel/patches/0025-hv_sock-introduce-Hyper-V-Sockets.patch b/alpine/kernel/patches/0037-hv_sock-introduce-Hyper-V-Sockets.patch similarity index 92% rename from alpine/kernel/patches/0025-hv_sock-introduce-Hyper-V-Sockets.patch rename to alpine/kernel/patches/0037-hv_sock-introduce-Hyper-V-Sockets.patch index a054f3ab3..df614168b 100644 --- a/alpine/kernel/patches/0025-hv_sock-introduce-Hyper-V-Sockets.patch +++ b/alpine/kernel/patches/0037-hv_sock-introduce-Hyper-V-Sockets.patch @@ -1,7 +1,7 @@ -From f94eeafa1082af0972a429ca973da5230e21c5c9 Mon Sep 17 00:00:00 2001 +From e40aa678ad8d502eb916a28f5f3c35c162dcf4d2 Mon Sep 17 00:00:00 2001 From: Dexuan Cui -Date: Wed, 11 May 2016 10:52:37 -0700 -Subject: [PATCH 25/28] hv_sock: introduce Hyper-V Sockets +Date: Sun, 15 May 2016 09:53:11 -0700 +Subject: [PATCH 37/40] hv_sock: introduce Hyper-V Sockets Hyper-V Sockets (hv_sock) supplies a byte-stream based communication mechanism between the host and the guest. It's somewhat like TCP over @@ -22,7 +22,7 @@ Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Vitaly Kuznetsov Cc: Cathy Avery -Origin: http://patchwork.ozlabs.org/patch/621190/ +Origin: https://patchwork.ozlabs.org/patch/622404/ --- MAINTAINERS | 2 + include/linux/hyperv.h | 14 + @@ -33,8 +33,8 @@ Origin: http://patchwork.ozlabs.org/patch/621190/ net/Makefile | 1 + net/hv_sock/Kconfig | 10 + net/hv_sock/Makefile | 3 + - net/hv_sock/af_hvsock.c | 1484 +++++++++++++++++++++++++++++++++++++++++++ - 10 files changed, 1621 insertions(+), 1 deletion(-) + net/hv_sock/af_hvsock.c | 1520 +++++++++++++++++++++++++++++++++++++++++++ + 10 files changed, 1657 insertions(+), 1 deletion(-) create mode 100644 include/net/af_hvsock.h create mode 100644 net/hv_sock/Kconfig create mode 100644 net/hv_sock/Makefile @@ -55,10 +55,10 @@ index 9a70d2d..1021706 100644 F: Documentation/ABI/stable/sysfs-bus-vmbus diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h -index af7ee0a..9864a30 100644 +index 6c9695e..187d4bd 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h -@@ -1314,4 +1314,18 @@ extern __u32 vmbus_proto_version; +@@ -1349,4 +1349,18 @@ extern __u32 vmbus_proto_version; int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id, const uuid_le *shv_host_servie_id); @@ -102,7 +102,7 @@ index dbd81e7..6634c47 100644 /* Maximum queue length specifiable by listen. */ diff --git a/include/net/af_hvsock.h b/include/net/af_hvsock.h new file mode 100644 -index 0000000..e002397 +index 0000000..7c8c41e --- /dev/null +++ b/include/net/af_hvsock.h @@ -0,0 +1,78 @@ @@ -113,7 +113,7 @@ index 0000000..e002397 +#include +#include + -+/* Note: 3-page is the minimal recv ringbuffer size: ++/* Note: 3-page is the minimal recv ringbuffer size by default: + * + * the 1st page is used as the shared read/write index etc, rather than data: + * see hv_ringbuffer_init(); @@ -123,18 +123,18 @@ index 0000000..e002397 + * need at least 2 extra pages for ringbuffer data. + */ +#define HVSOCK_RCV_BUF_SZ PAGE_SIZE -+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_RCV (3 * PAGE_SIZE) ++#define DEF_RINGBUFFER_PAGES_HVSOCK_RCV 3 + +/* As to send, here let's make sure the hvsock_send_buf struct can be held in 1 + * page, and since we want to use 2 pages for the send ringbuffer size (this is -+ * the minimal size because the 1st page of the two is used as the shared -+ * read/write index etc, rather than data), we only have 1 page for ringbuffer -+ * data, this means: the max payload length for hvsock data is -+ * PAGE_SIZE - HVSOCK_PKT_LEN(0). Finally, let's reduce the length by 8-bytes ++ * the minimal size by default, because the 1st page of the two is used as the ++ * shared read/write index etc, rather than data), we only have 1 page for ++ * ringbuffer data, this means: the max payload length for hvsock data is ++ * PAGE_SIZE - HVSOCK_PKT_LEN(0). And, let's reduce the length by 8-bytes + * because the ringbuffer can't be 100% full: see hv_ringbuffer_write(). + */ +#define HVSOCK_SND_BUF_SZ (PAGE_SIZE - HVSOCK_PKT_LEN(0) - 8) -+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_SND (2 * PAGE_SIZE) ++#define DEF_RINGBUFFER_PAGES_HVSOCK_SND 2 + +/* We only send data when the available space is "big enough". This artificial + * value must be less than HVSOCK_SND_BUF_SZ. @@ -276,10 +276,10 @@ index 0000000..716c012 +hv_sock-y += af_hvsock.o diff --git a/net/hv_sock/af_hvsock.c b/net/hv_sock/af_hvsock.c new file mode 100644 -index 0000000..013d684 +index 0000000..b91bd60 --- /dev/null +++ b/net/hv_sock/af_hvsock.c -@@ -0,0 +1,1484 @@ +@@ -0,0 +1,1520 @@ +/* + * Hyper-V Sockets -- a socket-based communication channel between the + * Hyper-V host and the virtual machines running on it. @@ -317,6 +317,21 @@ index 0000000..013d684 +#include +#include + ++static uint send_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_SND; ++static uint recv_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_RCV; ++static uint max_socket_number = 1024; ++ ++static atomic_t total_num_hvsock = ATOMIC_INIT(0); ++ ++module_param(send_ring_page, uint, 0444); ++MODULE_PARM_DESC(send_ring_page, "Send ring buffer size (# of pages)"); ++ ++module_param(recv_ring_page, uint, 0444); ++MODULE_PARM_DESC(recv_ring_page, "Receive ring buffer size (# of pages)"); ++ ++module_param(max_socket_number, uint, 0644); ++MODULE_PARM_DESC(max_socket_number, "The max number of created sockets"); ++ +static struct proto hvsock_proto = { + .name = "HV_SOCK", + .owner = THIS_MODULE, @@ -525,6 +540,7 @@ index 0000000..013d684 + + kfree(hvsk->send); + kfree(hvsk->recv); ++ atomic_dec(&total_num_hvsock); + + if (!channel) + return; @@ -581,43 +597,48 @@ index 0000000..013d684 + return 0; +} + -+static struct sock *__hvsock_create(struct net *net, struct socket *sock, -+ gfp_t priority, unsigned short type) ++static int hvsock_create(struct net *net, struct socket *sock, ++ gfp_t priority, unsigned short type, ++ struct sock **sk) +{ + struct hvsock_send_buf *send = NULL; + struct hvsock_recv_buf *recv = NULL; -+ + struct hvsock_sock *hvsk; -+ struct sock *sk; ++ int ret = -EMFILE; ++ int num_hvsock; + -+ send = kmalloc(sizeof(struct hvsock_send_buf), GFP_KERNEL); -+ recv = kmalloc(sizeof(struct hvsock_recv_buf), GFP_KERNEL); ++ num_hvsock = atomic_inc_return(&total_num_hvsock); ++ if (num_hvsock > max_socket_number) ++ goto err; ++ ++ ret = -ENOMEM; ++ send = kmalloc(sizeof(*send), GFP_KERNEL); ++ recv = kmalloc(sizeof(*recv), GFP_KERNEL); + if (!send || !recv) + goto err; + -+ sk = sk_alloc(net, AF_HYPERV, priority, &hvsock_proto, 0); -+ if (!sk) ++ *sk = sk_alloc(net, AF_HYPERV, priority, &hvsock_proto, 0); ++ if (!*sk) + goto err; + -+ sock_init_data(sock, sk); ++ sock_init_data(sock, *sk); + -+ /* sk->sk_type is normally set in sock_init_data, but only if sock is -+ * non-NULL. We make sure that our sockets always have a type by ++ /* (*sk)->sk_type is normally set in sock_init_data, but only if sock ++ * is non-NULL. We make sure that our sockets always have a type by + * setting it here if needed. + */ + if (!sock) -+ sk->sk_type = type; ++ (*sk)->sk_type = type; + -+ -+ sk->sk_destruct = hvsock_sk_destruct; ++ (*sk)->sk_destruct = hvsock_sk_destruct; + + /* Looks stream-based socket doesn't need this. */ -+ sk->sk_backlog_rcv = NULL; ++ (*sk)->sk_backlog_rcv = NULL; + -+ sk->sk_state = 0; -+ sock_reset_flag(sk, SOCK_DONE); ++ (*sk)->sk_state = 0; ++ sock_reset_flag(*sk, SOCK_DONE); + -+ hvsk = sk_to_hvsock(sk); ++ hvsk = sk_to_hvsock(*sk); + + hvsk->send = send; + hvsk->recv = recv; @@ -636,11 +657,13 @@ index 0000000..013d684 + hvsk->recv->data_len = 0; + hvsk->recv->data_offset = 0; + -+ return sk; ++ return 0; +err: ++ atomic_dec(&total_num_hvsock); + kfree(send); + kfree(recv); -+ return NULL; ++ *sk = NULL; ++ return ret; +} + +static int hvsock_bind(struct socket *sock, struct sockaddr *addr, @@ -699,40 +722,6 @@ index 0000000..013d684 + return ret; +} + -+static int hvsock_shutdown(struct socket *sock, int mode) -+{ -+ struct sock *sk; -+ -+ if (mode < SHUT_RD || mode > SHUT_RDWR) -+ return -EINVAL; -+ /* This maps: -+ * SHUT_RD (0) -> RCV_SHUTDOWN (1) -+ * SHUT_WR (1) -> SEND_SHUTDOWN (2) -+ * SHUT_RDWR (2) -> SHUTDOWN_MASK (3) -+ */ -+ ++mode; -+ -+ if (sock->state == SS_UNCONNECTED) -+ return -ENOTCONN; -+ -+ sock->state = SS_DISCONNECTING; -+ -+ sk = sock->sk; -+ -+ lock_sock(sk); -+ -+ sk->sk_shutdown |= mode; -+ sk->sk_state_change(sk); -+ -+ /* TODO: how to send a FIN if we haven't done that? */ -+ if (mode & SEND_SHUTDOWN) -+ ; -+ -+ release_sock(sk); -+ -+ return 0; -+} -+ +static void get_ringbuffer_rw_status(struct vmbus_channel *channel, + bool *can_read, bool *can_write) +{ @@ -742,7 +731,7 @@ index 0000000..013d684 + hv_get_ringbuffer_availbytes(&channel->inbound, + &avl_read_bytes, + &dummy); -+ /* 0-size payload meaans FIN */ ++ /* 0-size payload means FIN */ + *can_read = avl_read_bytes >= HVSOCK_PKT_LEN(0); + } + @@ -765,14 +754,86 @@ index 0000000..013d684 + &dummy, + &avl_write_bytes); + -+ if (avl_write_bytes < HVSOCK_PKT_LEN(1)) ++ if (avl_write_bytes < HVSOCK_PKT_LEN(1) + HVSOCK_PKT_LEN(0)) + return 0; + -+ /* The ringbuffer can't be 100% full */ -+ ret = avl_write_bytes - HVSOCK_PKT_LEN(1); ++ /* The ringbuffer mustn't be 100% full, and we should reserve a ++ * zero-length-payload packet for the FIN: see hv_ringbuffer_write() ++ * and hvsock_shutdown(). ++ */ ++ ret = avl_write_bytes - HVSOCK_PKT_LEN(1) - HVSOCK_PKT_LEN(0); ++ + return round_down(ret, 8); +} + ++static int hvsock_send_data(struct vmbus_channel *channel, ++ struct hvsock_sock *hvsk, ++ size_t to_write) ++{ ++ hvsk->send->hdr.pkt_type = 1; ++ hvsk->send->hdr.data_size = to_write; ++ return vmbus_sendpacket(channel, &hvsk->send->hdr, ++ sizeof(hvsk->send->hdr) + to_write, ++ 0, VM_PKT_DATA_INBAND, 0); ++} ++ ++static int hvsock_recv_data(struct vmbus_channel *channel, ++ struct hvsock_sock *hvsk, ++ size_t *payload_len) ++{ ++ u32 buffer_actual_len; ++ u64 dummy_req_id; ++ int ret; ++ ++ ret = vmbus_recvpacket(channel, &hvsk->recv->hdr, ++ sizeof(hvsk->recv->hdr) + ++ sizeof(hvsk->recv->buf), ++ &buffer_actual_len, &dummy_req_id); ++ if (ret != 0 || buffer_actual_len <= sizeof(hvsk->recv->hdr)) ++ *payload_len = 0; ++ else ++ *payload_len = hvsk->recv->hdr.data_size; ++ ++ return ret; ++} ++ ++static int hvsock_shutdown(struct socket *sock, int mode) ++{ ++ struct hvsock_sock *hvsk; ++ struct sock *sk; ++ ++ if (mode < SHUT_RD || mode > SHUT_RDWR) ++ return -EINVAL; ++ /* This maps: ++ * SHUT_RD (0) -> RCV_SHUTDOWN (1) ++ * SHUT_WR (1) -> SEND_SHUTDOWN (2) ++ * SHUT_RDWR (2) -> SHUTDOWN_MASK (3) ++ */ ++ ++mode; ++ ++ if (sock->state != SS_CONNECTED) ++ return -ENOTCONN; ++ ++ sock->state = SS_DISCONNECTING; ++ ++ sk = sock->sk; ++ ++ lock_sock(sk); ++ ++ sk->sk_shutdown |= mode; ++ sk->sk_state_change(sk); ++ ++ if (mode & SEND_SHUTDOWN) { ++ hvsk = sk_to_hvsock(sk); ++ /* It can't fail: see get_ringbuffer_writable_bytes(). */ ++ (void)hvsock_send_data(hvsk->channel, hvsk, 0); ++ } ++ ++ release_sock(sk); ++ ++ return 0; ++} ++ +static unsigned int hvsock_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ @@ -898,7 +959,6 @@ index 0000000..013d684 + if (!sk) + goto out; + -+ sk->sk_socket->state = SS_UNCONNECTED; + sk->sk_state = SS_UNCONNECTED; + sock_set_flag(sk, SOCK_DONE); + @@ -932,7 +992,7 @@ index 0000000..013d684 + sk = hvsock_find_bound_socket(&hv_addr); + + if (!sk || (conn_from_host && sk->sk_state != SS_LISTEN) || -+ (!conn_from_host && sk->sk_state != SS_CONNECTING)) { ++ (!conn_from_host && sk->sk_state != SS_CONNECTING)) { + ret = -ENXIO; + goto out; + } @@ -943,12 +1003,11 @@ index 0000000..013d684 + goto out; + } + -+ new_sk = __hvsock_create(sock_net(sk), NULL, GFP_KERNEL, -+ sk->sk_type); -+ if (!new_sk) { -+ ret = -ENOMEM; ++ ret = hvsock_create(sock_net(sk), NULL, GFP_KERNEL, ++ sk->sk_type, &new_sk); ++ if (ret != 0) + goto out; -+ } ++ + new_sk->sk_state = SS_CONNECTING; + new_hvsk = sk_to_hvsock(new_sk); + new_hvsk->channel = channel; @@ -960,9 +1019,8 @@ index 0000000..013d684 + } + + set_channel_read_state(channel, false); -+ vmbus_set_chn_rescind_callback(channel, hvsock_close_connection); -+ ret = vmbus_open(channel, VMBUS_RINGBUFFER_SIZE_HVSOCK_SND, -+ VMBUS_RINGBUFFER_SIZE_HVSOCK_RCV, NULL, 0, ++ ret = vmbus_open(channel, send_ring_page * PAGE_SIZE, ++ recv_ring_page * PAGE_SIZE, NULL, 0, + hvsock_on_channel_cb, conn_from_host ? new_sk : sk); + if (ret != 0) { + if (conn_from_host) { @@ -974,6 +1032,7 @@ index 0000000..013d684 + goto out; + } + ++ vmbus_set_chn_rescind_callback(channel, hvsock_close_connection); + set_channel_pending_send_size(channel, + HVSOCK_PKT_LEN(HVSOCK_SND_THRESHOLD)); + @@ -1264,17 +1323,6 @@ index 0000000..013d684 + return ret; +} + -+static int hvsock_send_data(struct vmbus_channel *channel, -+ struct hvsock_sock *hvsk, -+ size_t to_write) -+{ -+ hvsk->send->hdr.pkt_type = 1; -+ hvsk->send->hdr.data_size = to_write; -+ return vmbus_sendpacket(channel, &hvsk->send->hdr, -+ sizeof(hvsk->send->hdr) + to_write, -+ 0, VM_PKT_DATA_INBAND, 0); -+} -+ +static +int hvsock_sendmsg_wait(struct sock *sk, struct msghdr *msg, size_t len) +{ @@ -1432,26 +1480,6 @@ index 0000000..013d684 + return ret; +} + -+static int hvsock_recv_data(struct vmbus_channel *channel, -+ struct hvsock_sock *hvsk, -+ size_t *payload_len) -+{ -+ u32 buffer_actual_len; -+ u64 dummy_req_id; -+ int ret; -+ -+ ret = vmbus_recvpacket(channel, &hvsk->recv->hdr, -+ sizeof(hvsk->recv->hdr) + -+ sizeof(hvsk->recv->buf), -+ &buffer_actual_len, &dummy_req_id); -+ if (ret != 0 || buffer_actual_len <= sizeof(hvsk->recv->hdr)) -+ *payload_len = 0; -+ else -+ *payload_len = hvsk->recv->hdr.data_size; -+ -+ return ret; -+} -+ +static int hvsock_recvmsg_wait(struct sock *sk, struct msghdr *msg, + size_t len, int flags) +{ @@ -1651,9 +1679,11 @@ index 0000000..013d684 + .sendpage = sock_no_sendpage, +}; + -+static int hvsock_create(struct net *net, struct socket *sock, -+ int protocol, int kern) ++static int hvsock_create_sock(struct net *net, struct socket *sock, ++ int protocol, int kern) +{ ++ struct sock *sk; ++ + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN)) + return -EPERM; + @@ -1670,12 +1700,12 @@ index 0000000..013d684 + + sock->state = SS_UNCONNECTED; + -+ return __hvsock_create(net, sock, GFP_KERNEL, 0) ? 0 : -ENOMEM; ++ return hvsock_create(net, sock, GFP_KERNEL, 0, &sk); +} + +static const struct net_proto_family hvsock_family_ops = { + .family = AF_HYPERV, -+ .create = hvsock_create, ++ .create = hvsock_create_sock, + .owner = THIS_MODULE, +}; + @@ -1719,6 +1749,12 @@ index 0000000..013d684 +{ + int ret; + ++ if (send_ring_page < DEF_RINGBUFFER_PAGES_HVSOCK_SND) ++ send_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_SND; ++ ++ if (recv_ring_page < DEF_RINGBUFFER_PAGES_HVSOCK_RCV) ++ recv_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_RCV; ++ + /* Hyper-V Sockets requires at least VMBus 4.0 */ + if ((vmbus_proto_version >> 16) < 4) { + pr_err("failed to load: VMBus 4 or later is required\n"); diff --git a/alpine/kernel/patches/0026-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch b/alpine/kernel/patches/0038-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch similarity index 93% rename from alpine/kernel/patches/0026-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch rename to alpine/kernel/patches/0038-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch index b41f6b992..64d6cf435 100644 --- a/alpine/kernel/patches/0026-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch +++ b/alpine/kernel/patches/0038-net-add-the-AF_HYPERV-entries-to-family-name-tables.patch @@ -1,7 +1,7 @@ -From 2cffe53eda5ea0b90968867317149b57eb6d5b13 Mon Sep 17 00:00:00 2001 +From 7034fda17f5619f598de93fecdfd0af6a96b18f4 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 21 Mar 2016 02:53:08 -0700 -Subject: [PATCH 26/28] net: add the AF_HYPERV entries to family name tables +Subject: [PATCH 38/40] net: add the AF_HYPERV entries to family name tables This is for the hv_sock driver, which introduces AF_HYPERV(42). diff --git a/alpine/kernel/patches/0027-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch b/alpine/kernel/patches/0039-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch similarity index 94% rename from alpine/kernel/patches/0027-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch rename to alpine/kernel/patches/0039-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch index 8cc32756a..e6d9148b5 100644 --- a/alpine/kernel/patches/0027-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch +++ b/alpine/kernel/patches/0039-VSOCK-do-not-disconnect-socket-when-peer-has-shutdow.patch @@ -1,7 +1,7 @@ -From 6d6ad94bf42ceff0785f28382ba2c4a2cc6725d3 Mon Sep 17 00:00:00 2001 +From 0eba2b0c75b7dddedeedd6c827d71d0f23ae00ac Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 4 May 2016 14:21:53 +0100 -Subject: [PATCH 27/28] VSOCK: do not disconnect socket when peer has shutdown +Subject: [PATCH 39/40] VSOCK: do not disconnect socket when peer has shutdown SEND only The peer may be expecting a reply having sent a request and then done a diff --git a/alpine/kernel/patches/0040-Drivers-hv-vmbus-fix-the-race-when-querying-updating.patch b/alpine/kernel/patches/0040-Drivers-hv-vmbus-fix-the-race-when-querying-updating.patch new file mode 100644 index 000000000..b024e7fe3 --- /dev/null +++ b/alpine/kernel/patches/0040-Drivers-hv-vmbus-fix-the-race-when-querying-updating.patch @@ -0,0 +1,150 @@ +From 87cb6b00e44a0d496c623ea19801e2a9415a9759 Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Mon, 16 May 2016 22:26:05 +0800 +Subject: [PATCH 40/40] Drivers: hv: vmbus: fix the race when querying & + updating the percpu list + +There is a rare race when we remove an entry from the global list +hv_context.percpu_list[cpu] in hv_process_channel_removal() -> +percpu_channel_deq() -> list_del(): at this time, if vmbus_on_event() -> +process_chn_event() -> pcpu_relid2channel() is trying to query the list, +we can get the general protection fault: + +general protection fault: 0000 [#1] SMP +... +RIP: 0010:[] [] vmbus_on_event+0xc4/0x149 + +Similarly, we also have the issue in the code path: vmbus_process_offer() -> +percpu_channel_enq(). + +We can resolve the issue by disabling the tasklet when updating the list. + +Reported-by: Rolf Neugebauer +Signed-off-by: Dexuan Cui +Origin: https://github.com/dcui/linux/commit/cef5caca69a9104988a0e1c5185f919f7adbf1d2.patch +--- + drivers/hv/channel.c | 3 +++ + drivers/hv/channel_mgmt.c | 20 +++++++++----------- + include/linux/hyperv.h | 3 +++ + 3 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 57a1b65..f66fb3c 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -546,8 +546,11 @@ static int vmbus_close_internal(struct vmbus_channel *channel) + put_cpu(); + smp_call_function_single(channel->target_cpu, reset_channel_cb, + channel, true); ++ smp_call_function_single(channel->target_cpu, ++ percpu_channel_deq, channel, true); + } else { + reset_channel_cb(channel); ++ percpu_channel_deq(channel); + put_cpu(); + } + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index c892db5..ac48fe9 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -21,6 +21,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include ++#include + #include + #include + #include +@@ -277,7 +278,7 @@ static void free_channel(struct vmbus_channel *channel) + kfree(channel); + } + +-static void percpu_channel_enq(void *arg) ++void percpu_channel_enq(void *arg) + { + struct vmbus_channel *channel = arg; + int cpu = smp_processor_id(); +@@ -285,7 +286,7 @@ static void percpu_channel_enq(void *arg) + list_add_tail(&channel->percpu_list, &hv_context.percpu_list[cpu]); + } + +-static void percpu_channel_deq(void *arg) ++void percpu_channel_deq(void *arg) + { + struct vmbus_channel *channel = arg; + +@@ -313,15 +314,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) + BUG_ON(!channel->rescind); + BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); + +- if (channel->target_cpu != get_cpu()) { +- put_cpu(); +- smp_call_function_single(channel->target_cpu, +- percpu_channel_deq, channel, true); +- } else { +- percpu_channel_deq(channel); +- put_cpu(); +- } +- + if (channel->primary_channel == NULL) { + list_del(&channel->listentry); + +@@ -363,6 +355,7 @@ void vmbus_free_channels(void) + */ + static void vmbus_process_offer(struct vmbus_channel *newchannel) + { ++ struct tasklet_struct *tasklet; + struct vmbus_channel *channel; + bool fnew = true; + unsigned long flags; +@@ -409,6 +402,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + + init_vp_index(newchannel, dev_type); + ++ tasklet = hv_context.event_dpc[newchannel->target_cpu]; ++ tasklet_disable(tasklet); + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); + smp_call_function_single(newchannel->target_cpu, +@@ -418,6 +413,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + percpu_channel_enq(newchannel); + put_cpu(); + } ++ tasklet_enable(tasklet); + + /* + * This state is used to indicate a successful open +@@ -469,6 +465,7 @@ err_deq_chan: + list_del(&newchannel->listentry); + mutex_unlock(&vmbus_connection.channel_mutex); + ++ tasklet_disable(tasklet); + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); + smp_call_function_single(newchannel->target_cpu, +@@ -477,6 +474,7 @@ err_deq_chan: + percpu_channel_deq(newchannel); + put_cpu(); + } ++ tasklet_enable(tasklet); + + err_free_chan: + free_channel(newchannel); +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 187d4bd..a69364b 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -1339,6 +1339,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *, + struct icmsg_negotiate *, u8 *, int, + int); + ++void percpu_channel_enq(void *arg); ++void percpu_channel_deq(void *arg); ++ + void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); + + /* +-- +2.8.2 +