Repository navigation
Expand file tree
/
Copy pathpatch-vmware-kernel7.sh
More file actions
194 lines (160 loc) · 9.49 KB
/
Copy pathpatch-vmware-kernel7.sh
File metadata and controls
194 lines (160 loc) · 9.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env bash
# =============================================================================
# patch-vmware-kernel7.sh
# VMware Workstation 17.6.4 kernel module patch for Linux kernel 7.0.x
#
# Fixes the following kernel 7.0 API breakages:
# - driver-config.h not found (EXTRA_CFLAGS → ccflags-y)
# - del_timer_sync → timer_delete_sync
# - rdmsrl_safe → rdmsrq_safe
# - pgd_large/p4d_large/pud_large/pmd_large → *_leaf equivalents
# - dev_base_lock removed (replaced with rtnl_lock/rtnl_unlock)
# - random_get_entropy_fallback removed from kernel timex.h header
#
# Tested on:
# Host OS : Ubuntu 26.04 LTS (Resolute)
# Kernel : 7.0.0-15-generic
# VMware : Workstation Pro 17.6.4 (build-24832109)
# CPU : Intel i5-2450M (Sandy Bridge) — no AVX2/AVX-512
#
# Author : Adejoh Caleb G. <github.com/caleb173>
# License: MIT
# =============================================================================
set -euo pipefail
# ── Colour helpers ────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
info() { echo -e "${CYAN}[INFO]${RESET} $*"; }
success() { echo -e "${GREEN}[OK]${RESET} $*"; }
warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
die() { echo -e "${RED}[ERROR]${RESET} $*" >&2; exit 1; }
# ── Preflight checks ──────────────────────────────────────────────────────────
echo -e "\n${BOLD}=== VMware Kernel 7.0 Module Patcher ===${RESET}\n"
[[ $EUID -ne 0 ]] && die "Run this script as root: sudo bash $0"
KERNEL=$(uname -r)
info "Kernel: $KERNEL"
HEADERS="/usr/src/linux-headers-${KERNEL}"
[[ -d "$HEADERS" ]] || die "Kernel headers not found at $HEADERS. Run: sudo apt install linux-headers-$(uname -r)"
command -v vmware-modconfig &>/dev/null || die "VMware is not installed or vmware-modconfig not in PATH."
VMWARE_VER=$(vmware-modconfig --version 2>/dev/null | head -1 || true)
info "VMware: $VMWARE_VER"
VMWARE_SOURCES="/usr/lib/vmware/modules/source"
[[ -d "$VMWARE_SOURCES" ]] || die "VMware module sources not found at $VMWARE_SOURCES."
# ── Backup ────────────────────────────────────────────────────────────────────
BACKUP_DIR="${VMWARE_SOURCES}/backup-$(date +%Y%m%d-%H%M%S)"
info "Creating backup at $BACKUP_DIR ..."
mkdir -p "$BACKUP_DIR"
cp "$VMWARE_SOURCES/vmmon.tar" "$BACKUP_DIR/vmmon.tar"
cp "$VMWARE_SOURCES/vmnet.tar" "$BACKUP_DIR/vmnet.tar"
success "Backup created."
# ── Build workspace ───────────────────────────────────────────────────────────
WORKDIR=$(mktemp -d /tmp/vmware_patch_XXXXXX)
info "Working directory: $WORKDIR"
trap 'rm -rf "$WORKDIR"' EXIT
VMMON_DIR="$WORKDIR/vmmon-only"
VMNET_DIR="$WORKDIR/vmnet-only"
# Extract sources from backup so we always patch clean originals
tar xf "$BACKUP_DIR/vmmon.tar" -C "$WORKDIR"
tar xf "$BACKUP_DIR/vmnet.tar" -C "$WORKDIR"
# ── Patch: vmmon ──────────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Patching vmmon ---${RESET}"
# 1. EXTRA_CFLAGS → ccflags-y
# Modern kernels ignore EXTRA_CFLAGS in out-of-tree builds;
# the correct variable is ccflags-y since kernel ~5.0.
info "[vmmon] EXTRA_CFLAGS → ccflags-y"
sed -i "s/EXTRA_CFLAGS := \$(CC_OPTS) \$(INCLUDE)/ccflags-y := \$(CC_OPTS) \$(INCLUDE)/" \
"$VMMON_DIR/Makefile.kernel"
# 2. Hardcode absolute include paths in INCLUDE
# SRCROOT resolves incorrectly when the kernel build system changes
# directories internally, breaking relative -I paths. We substitute
# absolute paths directly into the INCLUDE variable.
info "[vmmon] Hardcoding absolute include paths"
sed -i "s|INCLUDE := .*|INCLUDE := -I${VMMON_DIR}/include -I${VMMON_DIR}/include/x86 -I${VMMON_DIR}/common -I${VMMON_DIR}/linux|" \
"$VMMON_DIR/Makefile.kernel"
# 3. del_timer_sync → timer_delete_sync
# Renamed in kernel 6.15 (commit 97a32539b956).
info "[vmmon] del_timer_sync → timer_delete_sync"
sed -i "s/del_timer_sync/timer_delete_sync/g" \
"$VMMON_DIR/linux/hostif.c" \
"$VMMON_DIR/linux/driver.c"
# 4. rdmsrl_safe → rdmsrq_safe
# Renamed in kernel 7.0 as part of the MSR API cleanup.
info "[vmmon] rdmsrl_safe → rdmsrq_safe"
sed -i "s/rdmsrl_safe/rdmsrq_safe/g" "$VMMON_DIR/linux/hostif.c"
# 5. pgd_large/p4d_large/pud_large/pmd_large → *_leaf
# These functions were renamed to *_leaf in kernel 6.x to better
# reflect their meaning (a "large" page is a "leaf" in the page table).
info "[vmmon] *_large → *_leaf (page table functions)"
sed -i "s/pgd_large/pgd_leaf/g" "$VMMON_DIR/include/pgtbl.h"
sed -i "s/pud_large/pud_leaf/g" "$VMMON_DIR/include/pgtbl.h"
sed -i "s/pmd_large/pmd_leaf/g" "$VMMON_DIR/include/pgtbl.h"
sed -i "s/p4d_large/p4d_leaf/g" "$VMMON_DIR/include/compat_pgtable.h"
sed -i "s/compat_p4d_large/compat_p4d_leaf/g" "$VMMON_DIR/include/pgtbl.h"
sed -i "s/compat_p4d_large/compat_p4d_leaf/g" "$VMMON_DIR/include/compat_pgtable.h"
# 6. Patch broken kernel header: random_get_entropy_fallback removed
# Ubuntu 26.04's linux-headers-7.0.0 shipped timex.h referencing
# random_get_entropy_fallback() which was removed. We stub it out.
# This is a kernel packaging bug, not a VMware bug.
TIMEX_H="${HEADERS}/arch/x86/include/asm/timex.h"
if grep -q "random_get_entropy_fallback" "$TIMEX_H" 2>/dev/null; then
info "[kernel-header] Patching broken random_get_entropy_fallback in timex.h"
sed -i "s/return random_get_entropy_fallback();/return 0; \/\* random_get_entropy_fallback removed in kernel 7.0 — stubbed \*\//" \
"$TIMEX_H"
success "timex.h patched."
else
info "[kernel-header] timex.h looks clean, skipping."
fi
# ── Patch: vmnet ──────────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Patching vmnet ---${RESET}"
# 1. EXTRA_CFLAGS → ccflags-y (same reason as vmmon)
info "[vmnet] EXTRA_CFLAGS → ccflags-y"
sed -i "s/EXTRA_CFLAGS/ccflags-y/g" "$VMNET_DIR/Makefile.kernel"
# 2. dev_base_lock removed
# dev_base_lock (a global rwlock for the net device list) was removed
# in kernel 6.x. The correct replacement for iterating/locking the
# device list is the RTNL (Routing Netlink) lock: rtnl_lock/rtnl_unlock.
info "[vmnet] dev_base_lock → rtnl_lock/rtnl_unlock"
sed -i "s/read_lock(&dev_base_lock)/rtnl_lock()/g" "$VMNET_DIR/vmnetInt.h"
sed -i "s/read_unlock(&dev_base_lock)/rtnl_unlock()/g" "$VMNET_DIR/vmnetInt.h"
# ── Build vmmon ───────────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Building vmmon ---${RESET}"
cd "$VMMON_DIR"
if make VM_UNAME="$KERNEL" -j"$(nproc)" 2>&1; then
success "vmmon.ko built successfully."
else
die "vmmon build failed. See output above."
fi
# ── Build vmnet ───────────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Building vmnet ---${RESET}"
cd "$VMNET_DIR"
if make VM_UNAME="$KERNEL" -j"$(nproc)" 2>&1; then
success "vmnet.ko built successfully."
else
die "vmnet build failed. See output above."
fi
# ── Install modules ───────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Installing modules ---${RESET}"
MODULES_DIR="/lib/modules/${KERNEL}/updates"
mkdir -p "$MODULES_DIR"
install -m 644 "$VMMON_DIR/vmmon.ko" "$MODULES_DIR/vmmon.ko"
install -m 644 "$VMNET_DIR/vmnet.ko" "$MODULES_DIR/vmnet.ko"
success "Modules installed to $MODULES_DIR"
# Also repack patched tarballs back into VMware's source dir
# so vmware-modconfig doesn't overwrite our work on next run
cd "$WORKDIR"
tar cf vmmon.tar vmmon-only
tar cf vmnet.tar vmnet-only
cp vmmon.tar "$VMWARE_SOURCES/vmmon.tar"
cp vmnet.tar "$VMWARE_SOURCES/vmnet.tar"
success "Patched tarballs saved to $VMWARE_SOURCES"
# ── Load modules ──────────────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Loading modules ---${RESET}"
depmod -a
modprobe -r vmnet 2>/dev/null || true
modprobe -r vmmon 2>/dev/null || true
modprobe vmmon && success "vmmon loaded."
modprobe vmnet && success "vmnet loaded."
# ── Start VMware services ─────────────────────────────────────────────────────
echo -e "\n${BOLD}--- Starting VMware services ---${RESET}"
systemctl start vmware && success "VMware services started."
echo -e "\n${GREEN}${BOLD}All done. Run 'vmware' to launch VMware Workstation.${RESET}\n"