From 01ed100276bdac259f1b418b998904a7486b0b68 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 19 Apr 2022 13:34:27 +0200 Subject: hv: Use driver_set_override() instead of open-coding Use a helper to set driver_override to the reduce amount of duplicated code. Make the driver_override field const char, because it is not modified by the core and it matches other subsystems. Reviewed-by: Michael Kelley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220419113435.246203-5-krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index fe2e0179ed51..12e2336b23b7 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1257,7 +1257,11 @@ struct hv_device { u16 device_id; struct device device; - char *driver_override; /* Driver name to force a match */ + /* + * Driver name to force a match. Do not set directly, because core + * frees it. Use driver_set_override() to set or clear it. + */ + const char *driver_override; struct vmbus_channel *channel; struct kset *channels_kset; -- cgit v1.2.3 From 66200bbcde697dea7f48071d325ea4dec6f66b11 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Tue, 12 Apr 2022 19:49:00 -0700 Subject: Drivers: hv: vmbus: Add VMbus IMC device to unsupported list Hyper-V may offer an Initial Machine Configuration (IMC) synthetic device to guest VMs. The device may be used by Windows guests to get specialization information, such as the hostname. But the device is not used in Linux and there is no Linux driver, so it is unsupported. Currently, the IMC device GUID is not recognized by the VMbus driver, which results in an "Unknown GUID" error message during boot. Add the GUID to the list of known but unsupported devices so that the error message is not generated. Other than avoiding the error message, there is no change in guest behavior. Signed-off-by: Michael Kelley Link: https://lore.kernel.org/r/1649818140-100953-1-git-send-email-mikelley@microsoft.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index fe2e0179ed51..2d085d951ee4 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1451,12 +1451,14 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size); 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f) /* - * Linux doesn't support the 3 devices: the first two are for - * Automatic Virtual Machine Activation, and the third is for - * Remote Desktop Virtualization. + * Linux doesn't support these 4 devices: the first two are for + * Automatic Virtual Machine Activation, the third is for + * Remote Desktop Virtualization, and the fourth is Initial + * Machine Configuration (IMC) used only by Windows guests. * {f8e65716-3cb3-4a06-9a60-1889c5cccab5} * {3375baf4-9e15-4b30-b765-67acb10d607b} * {276aacf4-ac15-426c-98dd-7521ad3f01fe} + * {c376c1c3-d276-48d2-90a9-c04748072c60} */ #define HV_AVMA1_GUID \ @@ -1471,6 +1473,10 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size); .guid = GUID_INIT(0x276aacf4, 0xac15, 0x426c, 0x98, 0xdd, \ 0x75, 0x21, 0xad, 0x3f, 0x01, 0xfe) +#define HV_IMC_GUID \ + .guid = GUID_INIT(0xc376c1c3, 0xd276, 0x48d2, 0x90, 0xa9, \ + 0xc0, 0x47, 0x48, 0x07, 0x2c, 0x60) + /* * Common header for Hyper-V ICs */ -- cgit v1.2.3 From b03afa57c65e1e045e02df49777e953742745f4c Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Tue, 19 Apr 2022 14:23:22 +0200 Subject: Drivers: hv: vmbus: Introduce vmbus_sendpacket_getid() The function can be used to send a VMbus packet and retrieve the corresponding transaction ID. It will be used by hv_pci. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20220419122325.10078-4-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 2d085d951ee4..7cb8718825ee 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1161,6 +1161,13 @@ extern int vmbus_open(struct vmbus_channel *channel, extern void vmbus_close(struct vmbus_channel *channel); +extern int vmbus_sendpacket_getid(struct vmbus_channel *channel, + void *buffer, + u32 bufferLen, + u64 requestid, + u64 *trans_id, + enum vmbus_packet_type type, + u32 flags); extern int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, u32 bufferLen, -- cgit v1.2.3 From 0aadb6a7bb811554cf39318b5d18e8ec50dd9f02 Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Tue, 19 Apr 2022 14:23:23 +0200 Subject: Drivers: hv: vmbus: Introduce vmbus_request_addr_match() The function can be used to retrieve and clear/remove a transation ID from a channel requestor, provided the memory address corresponding to the ID equals a specified address. The function, and its 'lockless' variant __vmbus_request_addr_match(), will be used by hv_pci. Refactor vmbus_request_addr() to reuse the 'newly' introduced code. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20220419122325.10078-5-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 7cb8718825ee..2e4962a2fbec 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -788,6 +788,7 @@ struct vmbus_requestor { #define VMBUS_NO_RQSTOR U64_MAX #define VMBUS_RQST_ERROR (U64_MAX - 1) +#define VMBUS_RQST_ADDR_ANY U64_MAX /* NetVSC-specific */ #define VMBUS_RQST_ID_NO_RESPONSE (U64_MAX - 2) /* StorVSC-specific */ @@ -1042,6 +1043,10 @@ struct vmbus_channel { }; u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr); +u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr); +u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr); u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id); static inline bool is_hvsock_channel(const struct vmbus_channel *c) -- cgit v1.2.3 From b91eaf7267cf7aec0a4e087decf7770dfb694d78 Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Tue, 19 Apr 2022 14:23:24 +0200 Subject: Drivers: hv: vmbus: Introduce {lock,unlock}_requestor() To abtract the lock and unlock operations on the requestor spin lock. The helpers will come in handy in hv_pci. No functional change. Suggested-by: Michael Kelley Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20220419122325.10078-6-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 2e4962a2fbec..460a716f4748 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1042,6 +1042,21 @@ struct vmbus_channel { u32 max_pkt_size; }; +#define lock_requestor(channel, flags) \ +do { \ + struct vmbus_requestor *rqstor = &(channel)->requestor; \ + \ + spin_lock_irqsave(&rqstor->req_lock, flags); \ +} while (0) + +static __always_inline void unlock_requestor(struct vmbus_channel *channel, + unsigned long flags) +{ + struct vmbus_requestor *rqstor = &channel->requestor; + + spin_unlock_irqrestore(&rqstor->req_lock, flags); +} + u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr); u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, u64 rqst_addr); -- cgit v1.2.3 From dbde6d0c7a5a462a1767a07c28eadd2c3dd08fb2 Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Thu, 28 Apr 2022 16:51:05 +0200 Subject: hv_sock: Add validation for untrusted Hyper-V values For additional robustness in the face of Hyper-V errors or malicious behavior, validate all values that originate from packets that Hyper-V has sent to the guest in the host-to-guest ring buffer. Ensure that invalid values cannot cause data being copied out of the bounds of the source buffer in hvs_stream_dequeue(). Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Reviewed-by: Stefano Garzarella Link: https://lore.kernel.org/r/20220428145107.7878-4-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 460a716f4748..a01c9fd0a334 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1696,6 +1696,11 @@ static inline u32 hv_pkt_datalen(const struct vmpacket_descriptor *desc) return (desc->len8 << 3) - (desc->offset8 << 3); } +/* Get packet length associated with descriptor */ +static inline u32 hv_pkt_len(const struct vmpacket_descriptor *desc) +{ + return desc->len8 << 3; +} struct vmpacket_descriptor * hv_pkt_iter_first_raw(struct vmbus_channel *channel); -- cgit v1.2.3 From da795eb239d9e9496812e22cb582d38a71e0789a Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Thu, 28 Apr 2022 16:51:06 +0200 Subject: Drivers: hv: vmbus: Accept hv_sock offers in isolated guests So that isolated guests can communicate with the host via hv_sock channels. Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20220428145107.7878-5-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index a01c9fd0a334..b028905d8334 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1064,10 +1064,14 @@ u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, u64 rqst_addr); u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id); +static inline bool is_hvsock_offer(const struct vmbus_channel_offer_channel *o) +{ + return !!(o->offer.chn_flags & VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER); +} + static inline bool is_hvsock_channel(const struct vmbus_channel *c) { - return !!(c->offermsg.offer.chn_flags & - VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER); + return is_hvsock_offer(&c->offermsg); } static inline bool is_sub_channel(const struct vmbus_channel *c) -- cgit v1.2.3 From 1c9de08f7f952b4101f092802581344033d84429 Mon Sep 17 00:00:00 2001 From: "Andrea Parri (Microsoft)" Date: Thu, 28 Apr 2022 16:51:07 +0200 Subject: Drivers: hv: vmbus: Refactor the ring-buffer iterator functions With no users of hv_pkt_iter_next_raw() and no "external" users of hv_pkt_iter_first_raw(), the iterator functions can be refactored and simplified to remove some indirection/code. Signed-off-by: Andrea Parri (Microsoft) Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/20220428145107.7878-6-parri.andrea@gmail.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b028905d8334..c440c45887c2 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1706,55 +1706,28 @@ static inline u32 hv_pkt_len(const struct vmpacket_descriptor *desc) return desc->len8 << 3; } -struct vmpacket_descriptor * -hv_pkt_iter_first_raw(struct vmbus_channel *channel); - struct vmpacket_descriptor * hv_pkt_iter_first(struct vmbus_channel *channel); struct vmpacket_descriptor * __hv_pkt_iter_next(struct vmbus_channel *channel, - const struct vmpacket_descriptor *pkt, - bool copy); + const struct vmpacket_descriptor *pkt); void hv_pkt_iter_close(struct vmbus_channel *channel); static inline struct vmpacket_descriptor * -hv_pkt_iter_next_pkt(struct vmbus_channel *channel, - const struct vmpacket_descriptor *pkt, - bool copy) +hv_pkt_iter_next(struct vmbus_channel *channel, + const struct vmpacket_descriptor *pkt) { struct vmpacket_descriptor *nxt; - nxt = __hv_pkt_iter_next(channel, pkt, copy); + nxt = __hv_pkt_iter_next(channel, pkt); if (!nxt) hv_pkt_iter_close(channel); return nxt; } -/* - * Get next packet descriptor without copying it out of the ring buffer - * If at end of list, return NULL and update host. - */ -static inline struct vmpacket_descriptor * -hv_pkt_iter_next_raw(struct vmbus_channel *channel, - const struct vmpacket_descriptor *pkt) -{ - return hv_pkt_iter_next_pkt(channel, pkt, false); -} - -/* - * Get next packet descriptor from iterator - * If at end of list, return NULL and update host. - */ -static inline struct vmpacket_descriptor * -hv_pkt_iter_next(struct vmbus_channel *channel, - const struct vmpacket_descriptor *pkt) -{ - return hv_pkt_iter_next_pkt(channel, pkt, true); -} - #define foreach_vmbus_pkt(pkt, channel) \ for (pkt = hv_pkt_iter_first(channel); pkt; \ pkt = hv_pkt_iter_next(channel, pkt)) -- cgit v1.2.3 From a6b94c6b49198266eaf78095a632df7245ef5196 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Mon, 2 May 2022 09:36:28 -0700 Subject: Drivers: hv: vmbus: Remove support for Hyper-V 2008 and Hyper-V 2008R2/Win7 The VMbus driver has special case code for running on the first released versions of Hyper-V: 2008 and 2008 R2/Windows 7. These versions are now out of support (except for extended security updates) and lack the performance features needed for effective production usage of Linux guests. Simplify the code by removing the negotiation of the VMbus protocol versions required for these releases of Hyper-V, and by removing the special case code for handling these VMbus protocol versions. Signed-off-by: Michael Kelley Reviewed-by: Andrea Parri (Microsoft) Link: https://lore.kernel.org/r/1651509391-2058-2-git-send-email-mikelley@microsoft.com Signed-off-by: Wei Liu --- include/linux/hyperv.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux/hyperv.h') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index c440c45887c2..a2464295c14a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -230,15 +230,19 @@ static inline u32 hv_get_avail_to_write_percent( * two 16 bit quantities: major_number. minor_number. * * 0 . 13 (Windows Server 2008) - * 1 . 1 (Windows 7) - * 2 . 4 (Windows 8) - * 3 . 0 (Windows 8 R2) + * 1 . 1 (Windows 7, WS2008 R2) + * 2 . 4 (Windows 8, WS2012) + * 3 . 0 (Windows 8.1, WS2012 R2) * 4 . 0 (Windows 10) * 4 . 1 (Windows 10 RS3) * 5 . 0 (Newer Windows 10) * 5 . 1 (Windows 10 RS4) * 5 . 2 (Windows Server 2019, RS5) * 5 . 3 (Windows Server 2022) + * + * The WS2008 and WIN7 versions are listed here for + * completeness but are no longer supported in the + * Linux kernel. */ #define VERSION_WS2008 ((0 << 16) | (13)) -- cgit v1.2.3