--- a/vmnet/Makefile +++ b/vmnet/Makefile @@ -43,7 +43,11 @@ INCLUDE += -I$(SRCROOT)/shared endif +ifdef KVERSION +VM_UNAME = $(KVERSION) +else VM_UNAME = $(shell uname -r) +endif # Header directory for the running kernel ifdef LINUXINCLUDE --- a/vmnet/userif.c +++ b/vmnet/userif.c # Fixing VMWare Player on Linux when using DHCP addresses: https://www.nikhef.nl/~janjust/vmnet/ @@ -998,6 +998,9 @@ userIf = (VNetUserIF *)port->jack.private; hubJack = port->jack.peer; + /* never send link down events */ + if (!linkUp) return 0; + if (port->jack.state == FALSE || hubJack == NULL) { return -EINVAL; } From 9a6a17fe0bc6d1ab9e0e0dfa8d587b12a21cd49e Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Sun, 17 Oct 2021 17:06:26 +0200 Subject: [PATCH] modules: include when available Workstation/Player code changes between 16.1.2 and 16.2.0 added some includes of which is interpreted as regular (userspace) header file in /usr/include. Shortly before that, mainline commit c0891ac15f04 ("isystem: ship and use stdarg.h") added minimalistic kernel version of stdarg.h to avoid including userspace headers from kernel code. As the kernel version is sometimes included via other header files, build against 5.15 kernel results in a lot of warnings (about redefined va_* macros). Include when building against kernel < 5.15 and when building against kernel >= 5.15. --- vmmon-only/include/vm_assert.h | 4 ++++ vmnet-only/vm_assert.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/vmnet-only/vm_assert.h b/vmnet-only/vm_assert.h index cf34446..430c74d 100644 --- a/vmnet-only/vm_assert.h +++ b/vmnet-only/vm_assert.h @@ -40,7 +40,11 @@ // XXX not necessary except some places include vm_assert.h improperly #include "vm_basic_types.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) #include +#else +#include +#endif #ifdef __cplusplus extern "C" { From 4232f780eb114f22498f3274eaeef81d8c63f2ab Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Tue, 9 Nov 2021 09:01:57 +0100 Subject: [PATCH] modules: fix stddef.h include After mainline commit 04e85bbf71c9 ("isystem: delete global -isystem compile option") in 5.16-rc1, vm_basic_types.h in both vmmon and vmnet does not find (userspace) stddef.h any more. As it should not include this header anyway, fix the include directives to include stddef.h from kernel. Kernel version of stddef.h has been available since the beginning of git so that it is safe to include it regardless of kernel version. --- vmmon-only/include/vm_basic_defs.h | 2 +- vmnet-only/vm_basic_defs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vmnet-only/vm_basic_defs.h b/vmnet-only/vm_basic_defs.h index 0ec30b3..b920e2d 100644 --- a/vmnet-only/vm_basic_defs.h +++ b/vmnet-only/vm_basic_defs.h @@ -51,7 +51,7 @@ * C90 7.17, C99 7.19, C11 7.19 */ #if !defined(VMKERNEL) -# include +# include #else /* * Vmkernel's bogus __FreeBSD__ value causes gcc to break. From 4af1a71978962f9805fe2e7e6ceb05c24f42c7f0 Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Tue, 11 Jan 2022 17:25:45 +0100 Subject: [PATCH] vmnet: use accessors for net_device::dev_addr Mainline commit adeef3e32146 ("net: constify netdev->dev_addr") in 5.17-rc1 makes dev_addr member of struct net_device const but accessors should be used to modify it since 5.15 to make sure rbtree with hardware address list is updated properly. Use dev_addr_set() and __dev_addr_set() in VNetNetifSetMAC() and VNetNetIf_Create(). For kernels before 5.15 provide our own version of the accessors. As SMAC_SetMac() only reads dev_addr, constify the corresponding argument. --- vmnet-only/netif.c | 18 +++++++++++++++--- vmnet-only/smac.c | 2 +- vmnet-only/smac.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/vmnet-only/netif.c b/vmnet-only/netif.c index c70f7f4..8c3bbf8 100644 --- a/vmnet-only/netif.c +++ b/vmnet-only/netif.c @@ -44,7 +44,6 @@ #include "compat_netdevice.h" #include "vmnetInt.h" - /* * Default min MTU value as defined by kernel versions >= 4.10.0. * Use the same value for earlier versions of the kernel which do not @@ -86,6 +85,19 @@ static int VNetNetIfProcRead(char *page, char **start, off_t off, static int VNetNetifChangeMtu(struct net_device *dev, int new_mtu); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) +static void +__dev_addr_set(struct net_device *dev, const void *addr, size_t len) +{ + memcpy(dev->dev_addr, addr, len); +} + +static void dev_addr_set(struct net_device *dev, const u8 *addr) +{ + __dev_addr_set(dev, addr, dev->addr_len); +} +#endif + /* *---------------------------------------------------------------------- @@ -253,7 +265,7 @@ VNetNetIf_Create(char *devName, // IN: memset(&netIf->stats, 0, sizeof netIf->stats); - memcpy(dev->dev_addr, netIf->port.paddr, sizeof netIf->port.paddr); + __dev_addr_set(dev, netIf->port.paddr, sizeof(netIf->port.paddr)); if (register_netdev(dev) != 0) { LOG(0, (KERN_NOTICE "%s: could not register network device\n", @@ -532,7 +544,7 @@ VNetNetifSetMAC(struct net_device *dev, // IN: return -EINVAL; } memcpy(netIf->port.paddr, addr->sa_data, dev->addr_len); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + dev_addr_set(dev, addr->sa_data); return 0; } diff --git a/vmnet-only/smac.c b/vmnet-only/smac.c index f18be8a..7f38e7a 100644 --- a/vmnet-only/smac.c +++ b/vmnet-only/smac.c @@ -4116,7 +4116,7 @@ SMAC_InitState(SMACState **ptr) // OUT: pointer to alloced/inited state void SMACINT SMAC_SetMac(SMACState *state, // IN: state to update - uint8 *mac) // IN: pointer to host adapter's MAC + const uint8 *mac) // IN: pointer to host adapter's MAC { VNETKdPrintCall(("SMAC_SetMac")); ASSERT(state); diff --git a/vmnet-only/smac.h b/vmnet-only/smac.h index c8df9d2..f03fd3f 100644 --- a/vmnet-only/smac.h +++ b/vmnet-only/smac.h @@ -72,7 +72,7 @@ Bool BridgeIPv4MatchAddrMAC(const ULONG ipAddr, const uint8 *mac); void SMACINT SMAC_InitState(struct SMACState **ptr); // IN: state to alloc/init void SMACINT -SMAC_SetMac(struct SMACState *state, uint8 *mac); // IN: state, and host MAC +SMAC_SetMac(struct SMACState *state, const uint8 *mac); // IN: state, and host MAC void SMACINT SMAC_CleanupState(struct SMACState **ptr); // IN: state to cleanup/dealloc From 409623bd4693afada659af82e823a6291f70797a Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Mon, 4 Apr 2022 02:05:17 +0200 Subject: [PATCH] vmnet: use netif_rx() on newer kernels In mainline 5.18-rc1, commit baebdf48c360 ("net: dev: Makes sure netif_rx() can be invoked in any context.") allows calling netif_rx() from any context and commit 2655926aea9b ("net: Remove netif_rx_any_context() and netif_rx_ni().") drops netif_rx_ni() as it is no longer needed. Replace calls of netif_rx_ni() in VNetBridgeReceiveFromVNet() and VNetNetIfReceive() by netif_rx() when building against kernel 5.18 and newer. --- vmnet-only/bridge.c | 2 +- vmnet-only/compat_netdevice.h | 9 +++++++++ vmnet-only/netif.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/vmnet-only/bridge.c b/vmnet-only/bridge.c index c84f8ee..d6bd3c4 100644 --- a/vmnet-only/bridge.c +++ b/vmnet-only/bridge.c @@ -691,7 +691,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack * not do it, or netif_rx_ni() will deadlock on the cli() lock --hpreg */ - netif_rx_ni(clone); + compat_netif_rx_ni(clone); # if LOGLEVEL >= 4 do_gettimeofday(&vnetTime); # endif diff --git a/vmnet-only/compat_netdevice.h b/vmnet-only/compat_netdevice.h index bb5001b..c6cc706 100644 --- a/vmnet-only/compat_netdevice.h +++ b/vmnet-only/compat_netdevice.h @@ -196,4 +196,13 @@ typedef u32 compat_netdev_features_t; #define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0) #endif +static inline int compat_netif_rx_ni(struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) + return netif_rx(skb); +#else + return netif_rx_ni(skb); +#endif +} + #endif /* __COMPAT_NETDEVICE_H__ */ diff --git a/vmnet-only/netif.c b/vmnet-only/netif.c index 8c3bbf8..35256a0 100644 --- a/vmnet-only/netif.c +++ b/vmnet-only/netif.c @@ -357,7 +357,7 @@ VNetNetIfReceive(VNetJack *this, // IN: jack /* send to the host interface */ skb->dev = netIf->dev; skb->protocol = eth_type_trans(skb, netIf->dev); - netif_rx_ni(skb); + compat_netif_rx_ni(skb); netIf->stats.rx_packets++; return; From e02b540ab528917c1afd7848ef64ca146a634994 Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Tue, 31 May 2022 23:29:42 +0200 Subject: [PATCH] vmnet: open code csum_and_copy_to_user on kernel >= 5.19 Mainline commit 6308499b5e99 ("net: unexport csum_and_copy_{from,to}_user") in 5.19-rc1 unexports csum_and_copy_to_user as no in-tree module is using it. A clean solution would probably be rewriting the code to use iovec iterator as csum_and_copy_to_iter() is still exported (or perhaps skb_copy_and_csum_datagram() might be used instead). Anything like this would be way too intrusive so it would have to wait for VMware developers. For now, use the simplest solution and replace the calls to csum_and_copy_to_user() on 5.19 and newer with open coded implementation. As the optimized x86 version uses csum_partial_copy_generic() which is not exported on x86_64 either, copy the generic one from include/net/checksum.h instead. This will be less efficient but hopefully the performace hit will not be noticeable. --- vmnet-only/userif.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/vmnet-only/userif.c b/vmnet-only/userif.c index e99c436..2c5a24a 100644 --- a/vmnet-only/userif.c +++ b/vmnet-only/userif.c @@ -87,6 +87,33 @@ extern unsigned int vnet_max_qlen; # define skb_frag_off(frag) (frag)->page_offset #endif +#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) +static inline unsigned int +compat_csum_and_copy_to_user(const void *src, void __user *dst, int len, + int *err) +{ + return csum_and_copy_to_user(src, dst, len, 0, err); +} +#else +static inline unsigned int +compat_csum_and_copy_to_user(const void *src, void __user *dst, int len, + int *err) +{ + unsigned int csum; + +#if COMPAT_LINUX_VERSION_CHECK_LT(5, 19, 0) + csum = csum_and_copy_to_user(src, dst, len); +#else + csum = csum_partial(src, len, ~0U); + if (copy_to_user(dst, src, len)) + csum = 0; +#endif /* 5.19 */ + + *err = (csum == 0 ? -EFAULT : 0); + return csum; +} +#endif /* 5.10 */ + /* *----------------------------------------------------------------------------- * @@ -561,12 +588,7 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy return -EINVAL; } -#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) - csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err); -#else - csum = csum_and_copy_to_user(skb->data + offset, curr, len); - err = (csum == 0) ? -EFAULT : 0; -#endif + csum = compat_csum_and_copy_to_user(skb->data + offset, curr, len, &err); if (err) { return err; } @@ -580,14 +602,9 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy const void *vaddr; vaddr = kmap(skb_frag_page(frag)); -#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0) - tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), - curr, skb_frag_size(frag), 0, &err); -#else - tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag), - curr, skb_frag_size(frag)); - err = (tmpCsum == 0) ? -EFAULT : 0; -#endif + tmpCsum = compat_csum_and_copy_to_user(vaddr + skb_frag_off(frag), + curr, skb_frag_size(frag), + &err); kunmap(skb_frag_page(frag)); if (err) {