diff options
author | Ben White | 2018-02-09 07:02:32 +0100 |
---|---|---|
committer | Ben White | 2018-02-09 07:02:32 +0100 |
commit | da362b4d3d0a46f34c791dc2f2620704ae3c4acd (patch) | |
tree | 5a2ea163d66acfa110a0799d0c00295f0ddd3911 | |
parent | f3ed20877e73b3d3c2d20f3edc1ba9eb97b9b4c6 (diff) | |
download | aur-da362b4d3d0a46f34c791dc2f2620704ae3c4acd.tar.gz |
It is working again. Use vmware-unpatch or reinstall vmware if necessary and always reboot.
-rw-r--r-- | PKGBUILD | 11 | ||||
-rw-r--r-- | vmci-12.5.9-4.15.1.patch | 232 | ||||
-rw-r--r-- | vmmon-12.5.9-4.15.1.patch | 192 | ||||
-rw-r--r-- | vmnet-12.5.9-4.15.1.patch | 13 | ||||
-rw-r--r-- | vmware-patch.sh | 8 |
5 files changed, 453 insertions, 3 deletions
@@ -3,7 +3,7 @@ pkgname=vmware-patch pkgver=14.0.0 -pkgrel=6 +pkgrel=7 pkgdesc="A post-install configuration solution for VMware Workstation (Pro) and Player (Plus and Pro)" arch=('i686' 'x86_64') url="https://wiki.archlinux.org/index.php/VMware#Configuration" @@ -16,6 +16,10 @@ source=('vmware-patch.sh' 'vmware-unpatch.sh' 'common-functions.sh' 'vmware.serv 'vmmon-14.0.0-4.13.3.patch' 'vmnet-14.0.0-4.13.3.patch' 'vmci-14.0.0-4.13.3.patch' + # Workstation Pro/Player 12.5.9 + 'vmmon-12.5.9-4.15.1.patch' + 'vmnet-12.5.9-4.15.1.patch' + 'vmci-12.5.9-4.15.1.patch' # Workstation Pro/Player 12.5.8 'vmnet-12.5.8-4.13.12.patch' 'vmmon-12.5.8-4.13.12.patch' @@ -71,7 +75,7 @@ package() { } # Generated using 'updpkgsums' -md5sums=('5242a190e20e6366fd90a745a2b8410c' +md5sums=('eea90d7b8053d996d6e02653409a3634' 'ba054b375308442d43a408dbae5e9401' 'ca1382966804d694894539c7bcac6bbb' 'c12e765985b324585a548718a6ac9b43' @@ -80,6 +84,9 @@ md5sums=('5242a190e20e6366fd90a745a2b8410c' '3c165edb6847fc9bfa04657f346ac4cc' 'eca2542e4c484ea2ca06b7e9c065b8af' 'ced58cf32a21adfe21d612366c52116a' + '3316750fdc46fee3c167421924aa2ef8' + '05932f9797d1c3cca52f4d523d6f759d' + 'd5bf82487a40369477e2bd71739ce708' '05932f9797d1c3cca52f4d523d6f759d' '3c165edb6847fc9bfa04657f346ac4cc' '3c165edb6847fc9bfa04657f346ac4cc' diff --git a/vmci-12.5.9-4.15.1.patch b/vmci-12.5.9-4.15.1.patch new file mode 100644 index 000000000000..b3e6078fd8e0 --- /dev/null +++ b/vmci-12.5.9-4.15.1.patch @@ -0,0 +1,232 @@ +diff --git a/vmci-only/linux/driver.c b/vmci-only/linux/driver.c +index 1da7ab7..6eb5d09 10064 +--- vmci-only/linux/driver.c ++++ vmci-only/linux/driver.c +@@ -26,6 +26,7 @@ + + #include <linux/file.h> + #include <linux/fs.h> ++#include <linux/vmalloc.h> + #include <linux/init.h> + #if defined(__x86_64__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) + # include <linux/ioctl32.h> +@@ -1467,7 +1468,13 @@ VMCIUserVALockPage(VA addr) // IN: + + down_read(¤t->mm->mmap_sem); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) +- retval = get_user_pages(addr, 1, 1, 0, &page, NULL); ++ retval = get_user_pages(addr, 1, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) ++ 1, 0, ++#else ++ FOLL_WRITE, ++#endif ++ &page, NULL); + #else + retval = get_user_pages(current, current->mm, addr, + 1, 1, 0, &page, NULL); +@@ -1686,7 +1693,7 @@ vmci_guest_init(void) + /* This should be last to make sure we are done initializing. */ + retval = pci_register_driver(&vmci_driver); + if (retval < 0) { +- vfree(data_buffer); ++ kvfree(data_buffer); + data_buffer = NULL; + return retval; + } +@@ -1722,12 +1729,25 @@ vmci_enable_msix(struct pci_dev *pdev) // IN + vmci_dev.msix_entries[i].vector = i; + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + result = pci_enable_msix(pdev, vmci_dev.msix_entries, VMCI_MAX_INTRS); + if (!result) { + vmci_dev.exclusive_vectors = TRUE; + } else if (result > 0) { + result = pci_enable_msix(pdev, vmci_dev.msix_entries, 1); + } ++#else ++ result = pci_enable_msix_range(pdev, vmci_dev.msix_entries, VMCI_MAX_INTRS, ++ VMCI_MAX_INTRS); ++ if (result > 0) { ++ vmci_dev.exclusive_vectors = TRUE; ++ } else if (result == -ENOSPC) { ++ result = pci_enable_msix_range(pdev, vmci_dev.msix_entries, 1, 1); ++ } ++ ++ if (result > 0) ++ result = 0; ++#endif + return result; + } + +@@ -2473,7 +2493,7 @@ vmci_exit(void) + + if (guestDeviceInit) { + pci_unregister_driver(&vmci_driver); +- vfree(data_buffer); ++ kvfree(data_buffer); + guestDeviceInit = FALSE; + } + +@@ -2482,7 +2502,7 @@ vmci_exit(void) + + VMCI_HostCleanup(); + +- retval = misc_deregister(&linuxState.misc); ++ retval = compat_misc_deregister(&linuxState.misc); + if (retval) { + Warning(LGPFX "Module %s: error unregistering\n", VMCI_MODULE_NAME); + } else { +diff --git a/a/vmci-only/linux/vmciKernelIf.c b/b/vmci-only/linux/vmciKernelIf.c +index 3fba8b6..a09e44e 100644 +--- vmci-only/linux/vmciKernelIf.c ++++ vmci-only/linux/vmciKernelIf.c +@@ -40,6 +40,10 @@ + #include <linux/socket.h> /* For memcpy_{to,from}iovec(). */ + #include <linux/vmalloc.h> + #include <linux/wait.h> ++#include <linux/skbuff.h> ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) ++#include <linux/sched/signal.h> ++#endif + + #include "compat_highmem.h" + #include "compat_interrupt.h" +@@ -1197,20 +1201,20 @@ __VMCIMemcpyToQueue(VMCIQueue *queue, // OUT: + toCopy = size - bytesCopied; + } + ++ /* Code cloned from kernels drivers/misc/vmw_vmci/vmci_queue_pair.c */ + if (isIovec) { +- struct iovec *iov = (struct iovec *)src; +- int err; +- +- /* The iovec will track bytesCopied internally. */ +- err = memcpy_fromiovec((uint8 *)va + pageOffset, iov, toCopy); +- if (err != 0) { +- if (kernelIf->host) { +- kunmap(kernelIf->u.h.page[pageIndex]); +- } +- return VMCI_ERROR_INVALID_ARGS; +- } +- } else { +- memcpy((uint8 *)va + pageOffset, (uint8 *)src + bytesCopied, toCopy); ++ struct msghdr *msg = (struct msghdr *)src; ++ int err; ++ ++ /* The iovec will track bytes_copied internally. */ ++ err = memcpy_from_msg((u8 *)va + pageOffset, msg, toCopy); ++ if (err != 0) { ++ if (kernelIf->host) ++ kunmap(kernelIf->u.h.page[pageIndex]); ++ return VMCI_ERROR_INVALID_ARGS; ++ } ++ } else { ++ memcpy((u8 *)va + pageOffset,(u8 *)src + bytesCopied, toCopy); + } + + bytesCopied += toCopy; +@@ -1273,11 +1277,11 @@ __VMCIMemcpyFromQueue(void *dest, // OUT: + } + + if (isIovec) { +- struct iovec *iov = (struct iovec *)dest; ++ struct msghdr *msg = (struct msghdr *)dest; + int err; + + /* The iovec will track bytesCopied internally. */ +- err = memcpy_toiovec(iov, (uint8 *)va + pageOffset, toCopy); ++ err = memcpy_to_msg(msg, (uint8 *)va + pageOffset, toCopy); + if (err != 0) { + if (kernelIf->host) { + kunmap(kernelIf->u.h.page[pageIndex]); +@@ -1834,7 +1838,11 @@ VMCIReleasePages(struct page **pages, // IN + if (dirty) { + set_page_dirty(pages[i]); + } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 99) ++ put_page(pages[i]); ++#else + page_cache_release(pages[i]); ++#endif + pages[i] = NULL; + } + } +@@ -2050,19 +2058,20 @@ VMCIHost_GetUserMemory(VA64 produceUVA, // IN + down_write(¤t->mm->mmap_sem); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + retval = get_user_pages((VA)produceUVA, +- produceQ->kernelIf->numPages, +- 1, 0, +- produceQ->kernelIf->u.h.headerPage, +- NULL); + #else + retval = get_user_pages(current, + current->mm, + (VA)produceUVA, ++#endif + produceQ->kernelIf->numPages, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + 1, 0, ++#else ++ FOLL_WRITE, ++#endif + produceQ->kernelIf->u.h.headerPage, + NULL); +-#endif ++ + if (retval < produceQ->kernelIf->numPages) { + Log("get_user_pages(produce) failed (retval=%d)\n", retval); + VMCIReleasePages(produceQ->kernelIf->u.h.headerPage, retval, FALSE); +@@ -2070,11 +2079,19 @@ VMCIHost_GetUserMemory(VA64 produceUVA, // IN + goto out; + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) ++ retval = get_user_pages((VA)consumeUVA, ++#else + retval = get_user_pages(current, + current->mm, + (VA)consumeUVA, ++#endif + consumeQ->kernelIf->numPages, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + 1, 0, ++#else ++ FOLL_WRITE, ++#endif + consumeQ->kernelIf->u.h.headerPage, + NULL); + if (retval < consumeQ->kernelIf->numPages) { +diff --git a/a/vmci-only/shared/compat_module.h b/b/vmci-only/shared/compat_module.h +index 2af7372..9df784c 100644 +--- vmci-only/shared/compat_module.h ++++ vmci-only/shared/compat_module.h +@@ -80,4 +80,13 @@ static const char __module_cat(tag, __LINE__)[] \ + typedef int compat_mod_param_bool; + #endif + ++/* ++ * Linux kernel >= 4.2.99 does not return anything from misc_deregister ++ */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) ++#define compat_misc_deregister(misc) misc_deregister(misc) ++#else ++#define compat_misc_deregister(misc) ({misc_deregister(misc);0;}) ++#endif ++ + #endif /* __COMPAT_MODULE_H__ */ +diff --git a/a/vmci-only/shared/vmci_kernel_if.h b/b/vmci-only/shared/vmci_kernel_if.h +index 9def671..082fe59 100644 +--- vmci-only/shared/vmci_kernel_if.h ++++ vmci-only/shared/vmci_kernel_if.h +@@ -93,7 +93,7 @@ + typedef Semaphore VMCIEvent; + typedef Semaphore VMCIMutex; + typedef World_ID VMCIHostVmID; +- typedef uint32 VMCIHostUser; ++ typedef uint32_t VMCIHostUser; + typedef PPN *VMCIQPGuestMem; + #elif defined(linux) + typedef spinlock_t VMCILock; diff --git a/vmmon-12.5.9-4.15.1.patch b/vmmon-12.5.9-4.15.1.patch new file mode 100644 index 000000000000..fb7ced74e7c8 --- /dev/null +++ b/vmmon-12.5.9-4.15.1.patch @@ -0,0 +1,192 @@ + +diff --git a/vmmon-only/include/compat_timer.h b/vmmon-only/include/compat_timer.h +index e69de29..b68d9b2 100644 +--- vmmon-only/include/compat_timer.h ++++ vmmon-only/include/compat_timer.h +@@ -0,0 +1,26 @@ ++#ifndef __COMPAT_TIMER_H__ ++# define __COMPAT_TIMER_H__ ++ ++#include <linux/timer.h> ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) && !defined(timer_setup) ++ ++typedef unsigned long compat_timer_arg_t; ++ ++static inline void timer_setup(struct timer_list *timer, ++ void (*func)(compat_timer_arg_t), ++ unsigned int flags) ++{ ++ init_timer(timer); ++ timer->function = func; ++ timer->data = 0; ++ timer->flags = flags; ++} ++ ++#else /* new timer interface since 4.15 */ ++ ++typedef struct timer_list *compat_timer_arg_t; ++ ++#endif /* new timer interface since 4.15 */ ++ ++#endif /* __COMPAT_TIMER_H__ */ +diff --git a/vmmon-only/linux/driver.c b/vmmon-only/linux/driver.c +index 3595237..1056695 100644 +--- vmmon-only/linux/driver.c ++++ vmmon-only/linux/driver.c +@@ -21,6 +21,7 @@ + + #define EXPORT_SYMTAB + ++#include "compat_timer.h" + #include <linux/file.h> + #include <linux/highmem.h> + #include <linux/poll.h> +@@ -115,7 +116,7 @@ static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, + #endif + static int LinuxDriverMmap(struct file *filp, struct vm_area_struct *vma); + +-static void LinuxDriverPollTimeout(unsigned long clientData); ++static void LinuxDriverPollTimeout(compat_timer_arg_t unused); + static unsigned int LinuxDriverEstimateTSCkHz(void); + + static struct vm_operations_struct vmuser_mops = { +@@ -227,7 +228,7 @@ LinuxDriverEstimateTSCkHz(void) + *---------------------------------------------------------------------- + */ + static void +-LinuxDriverEstimateTSCkHzDeferred(unsigned long data) ++LinuxDriverEstimateTSCkHzDeferred(compat_timer_arg_t unused) + { + LinuxDriverEstimateTSCkHz(); + } +@@ -265,9 +266,7 @@ LinuxDriverInitTSCkHz(void) + } + + Vmx86_ReadTSCAndUptime(&tsckHzStartTime); +- tscTimer.function = LinuxDriverEstimateTSCkHzDeferred; + tscTimer.expires = jiffies + 4 * HZ; +- tscTimer.data = 0; + add_timer(&tscTimer); + } + +@@ -309,9 +308,7 @@ init_module(void) + */ + + init_waitqueue_head(&linuxState.pollQueue); +- init_timer(&linuxState.pollTimer); +- linuxState.pollTimer.data = 0; +- linuxState.pollTimer.function = LinuxDriverPollTimeout; ++ timer_setup(&linuxState.pollTimer, LinuxDriverPollTimeout, 0); + + linuxState.fastClockThread = NULL; + linuxState.fastClockFile = NULL; +@@ -360,7 +357,7 @@ init_module(void) + linuxState.deviceName, linuxState.major, linuxState.minor); + + HostIF_InitUptime(); +- init_timer(&tscTimer); ++ timer_setup(&tscTimer, LinuxDriverEstimateTSCkHzDeferred, 0); + LinuxDriverInitTSCkHz(); + Vmx86_InitIDList(); + +@@ -858,7 +855,7 @@ LinuxDriverPoll(struct file *filp, // IN: + */ + + static void +-LinuxDriverPollTimeout(unsigned long clientData) // IN: ++LinuxDriverPollTimeout(compat_timer_arg_t unused) // IN: + { + LinuxDriverWakeUp(FALSE); + } +diff --git a/a/vmmon-only/linux/hostif.c b/b/vmmon-only/linux/hostif.c +index 80b5787..dc113f2 100644 +--- vmmon-only/linux/hostif.c ++++ vmmon-only/linux/hostif.c +@@ -29,6 +29,7 @@ + #include "driver-config.h" + + /* Must come before vmware.h --hpreg */ ++#include "compat_timer.h" + #include "compat_page.h" + #include <linux/binfmts.h> + #include <linux/delay.h> +@@ -99,6 +100,37 @@ + #include "vmmonInt.h" + #include "versioned_atomic.h" + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) ++#define global_zone_page_state global_page_state ++#endif ++ ++static unsigned long get_nr_slab_unreclaimable(void) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) ++ return global_node_page_state(NR_SLAB_UNRECLAIMABLE); ++#else ++ return global_page_state(NR_SLAB_UNRECLAIMABLE); ++#endif ++} ++ ++static unsigned long get_nr_unevictable(void) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) ++ return global_node_page_state(NR_UNEVICTABLE); ++#else ++ return global_page_state(NR_UNEVICTABLE); ++#endif ++} ++ ++static unsigned long get_nr_anon_mapped(void) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) ++ return global_node_page_state(NR_ANON_MAPPED); ++#else ++ return global_page_state(NR_ANON_PAGES); ++#endif ++} ++ + /* + * Determine if we can use high resolution timers. + */ +@@ -1594,16 +1626,11 @@ HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN + unsigned int reservedPages = MEMDEFAULTS_MIN_HOST_PAGES; + unsigned int hugePages = (vm == NULL) ? 0 : + BYTES_2_PAGES(vm->memInfo.hugePageBytes); +- unsigned int lockedPages = global_page_state(NR_PAGETABLE) + +- global_page_state(NR_SLAB_UNRECLAIMABLE) + +- global_page_state(NR_UNEVICTABLE) + +- hugePages + reservedPages; +- unsigned int anonPages = +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +- global_page_state(NR_ANON_MAPPED); +-#else +- global_page_state(NR_ANON_PAGES); +-#endif ++ unsigned int lockedPages = global_zone_page_state(NR_PAGETABLE) + ++ get_nr_slab_unreclaimable() + ++ get_nr_unevictable() + ++ hugePages + reservedPages; ++ unsigned int anonPages = get_nr_anon_mapped(); + unsigned int swapPages = BYTES_2_PAGES(linuxState.swapSize); + + if (anonPages > swapPages) { +@@ -1767,7 +1794,7 @@ HostIFReadUptimeWork(unsigned long *j) // OUT: current jiffies + */ + + static void +-HostIFUptimeResyncMono(unsigned long data) // IN: ignored ++HostIFUptimeResyncMono(compat_timer_arg_t unused) // IN: ignored + { + unsigned long jifs; + uintptr_t flags; +@@ -1829,8 +1856,7 @@ HostIF_InitUptime(void) + -(tv.tv_usec * (UPTIME_FREQ / 1000000) + + tv.tv_sec * UPTIME_FREQ)); + +- init_timer(&uptimeState.timer); +- uptimeState.timer.function = HostIFUptimeResyncMono; ++ timer_setup(&uptimeState.timer, HostIFUptimeResyncMono, 0); + mod_timer(&uptimeState.timer, jiffies + HZ); + } + diff --git a/vmnet-12.5.9-4.15.1.patch b/vmnet-12.5.9-4.15.1.patch new file mode 100644 index 000000000000..ccbac9721fd4 --- /dev/null +++ b/vmnet-12.5.9-4.15.1.patch @@ -0,0 +1,13 @@ +diff --git a/bridge.c b/bridge.c2 +index 8cdaf11..83ae152 100644 +--- vmnet-only/bridge.c ++++ vmnet-only/bridge.c +@@ -636,7 +636,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack + unsigned long flags; + int i; + +- atomic_inc(&clone->users); ++ clone = skb_get(clone); + + clone->dev = dev; + clone->protocol = eth_type_trans(clone, dev); diff --git a/vmware-patch.sh b/vmware-patch.sh index 0e8d4ee28e0f..a64898bf9142 100644 --- a/vmware-patch.sh +++ b/vmware-patch.sh @@ -29,7 +29,7 @@ while [[ $1 ]]; do -a* | --all-kernels) all=1 ;; -f* | --force) force=1 ;; -k* | --kernel) kernel=1 ;; - -v* | --verbose) verbose=1 ;; + -v* | --verbose) verbose=1; ;; -V* | --version) print_version; exit 0 ;; -h* | --help) usage; exit 0 ;; -*) echo "$(basename $0): error: bad argument: $opt" @@ -138,6 +138,9 @@ for kernel in ${kernels[@]}; do # Detect applicable patches (/usr/lib/vmware/modules/patches/[mod]-[ver]-[kernel].patch) unset patches + if [[ $verbose ]]; then + printf '# Computer status: Patch: %s, Kernel: %s\n' "$ver" "$kernel" + fi for patch in patches/*; do # Some variables ver_patch=$(echo $patch | cut -d "-" -f2) @@ -151,6 +154,9 @@ for kernel in ${kernels[@]}; do ver2=$major.${ver#*.} fi + if [[ $verbose ]]; then + printf '# Checking Patch: %s, Kernel: %s\n' "$ver2" "$kernel_major" + fi # Is product version not lower and kernel version not higher in patch name? if (( $(vercmp "$ver_patch" "$ver2") == 0 )) && (( $(vercmp "$kernel_patch" "$kernel_major") >= 0 )); then printf 'Patch: %s, %s\n' "$ver_patch" "$ver2" |