Compare commits

...
52 Commits
Author SHA1 Message Date
Michal Kubecek b2de0cb3b0 vmmon: avoid using alloc_vm_area() for crosspage allocation
Mainline commit 301fa9f2ddf7 ("mm: remove alloc_vm_area") in v5.10-rc1
removed alloc_vm_area() function used to allow allocating crosspage as
executable after vmap() started silently setting NX flag in kernel 5.8.

Similar to what upstream did in Xen code, use apply_to_page_range() to fix
the crosspage flags, except we don't need to use get_vm_area() which is not
exported. Thanks to virtualbox for the hint that current->mm can be used
instead of init_mm (which is not exported either).
2020-12-09 11:20:45 +01:00
Michal Kubecek 6af30addc0 vmmon: avoid kernel writes to eventfd
Starting with mainline commit 4d03e3cc5982 ("fs: don't allow kernel reads
and writes without iter ops") in 5.10-rc1, kernel writes are only allowed
for files providing ->write_iter() callback which eventfd does not.

As an attempt to address this issue on kernel side by providing
->write_iter() callback to eventfd was met with a pushback and it is
unlikely to be accepted any time soon, let's use a specific eventfd
interface eventfd_signal() instead. However, as the comments in
HostIF_SemaphoreSignal() indicate that the file descriptor may also be
a pipe (without telling when), let's keep kernel_write() as a fallback in
case the file descriptor is not eventfd.
2020-12-09 11:20:45 +01:00
Michal Kubecek 958895c49e vmmon: avoid set_fs() in HostIFFastClockThread()
The set_fs() function was dropped on x86_64 architecture by commit
47058bb54b57 ("x86: remove address space overrides using set_fs()") in
5.10-rc1. The only purpose of set_fs(KERNEL_DS) in HostIFFastClockThread()
seems to be to allow using ->read() file operation on /dev/rtc device.
There is also ioctl() but neither of the two (RTC_IRQP_SET and RTC_PIE_ON)
interprets its argument as a (user) pointer: RTC_IRQP_SET interprets it as
unsigned long, RTC_PIE_ON ignores it.

Replace the direct call to ->read() file op with kernel_read() wrapper
like we did/do in other places and drop the temporary set_fs(KERNEL_DS)
trick as it doesn't seem to be needed any more.
2020-12-09 11:20:45 +01:00
Michal Kubecek 4bd2fa1cbf vmmon: avoid set_fs() in isVAReadable()
The set_fs() function was dropped on x86_64 architecture by commit
47058bb54b57 ("x86: remove address space overrides using set_fs()") in
5.10-rc1. In isVAReadable() it is used to check if a kernel address can be
read from without risking a pagefault if the answer is negative by using
set_fs() to pretend it's a userspace address and checking with
copy_from_user(). Starting with 5.8, copy_from_kernel_nofault() does can be
used to copy from a kernel address with access check but without an actual
pagefault.
2020-12-09 11:20:45 +01:00
Michal Kubecek 1b40eae1af vmmon: avoid set_fs() in HostIF_SemaphoreWait() and HostIF_SemaphoreSignal()
The set_fs() function was dropped on x86_64 architecture by commit
47058bb54b57 ("x86: remove address space overrides using set_fs()") in
5.10-rc1. In HostIF_SemaphoreWait() it is used to allow calling read() file
op on a kernel pointer, in HostIF_SemaphoreSignal() to allow calling
write() file op on a kernel pointer. This is only the case for pre-5.8
kernels as we need to use kernel_read() and kernel_write() helpers on 5.8
and newer anyway.

Use kernel_read() and kernel_write() always, like Workstation 16.0.0 does,
so that we no longer need the set_fs(KERNEL_DS) trick. Make the code of
both functions look exactly like in Workstation 16.0.0 to make future
backports easier.
2020-12-09 11:20:45 +01:00
Michal Kubecek 44c7e02bc1 vmnet: use new compat_csum_and_copy_to_user() calling convention
Part of bigger csum_and_copy rework, commit c693cc4676a0 ("saner calling
conventions for csum_and_copy_..._user()") in 5.10-rc1 drops last two
arguments and changes the way errors are reported.

Provide a compat wrapper with new calling convention and rewrite callers in
vmnet to use it. Unfortunately there doesn't seem to be a way to recognize
which calling convention kernel has so version check is used.
2020-12-09 11:20:45 +01:00
Jan Andres 0ea341be15 Fix NULL pointer dereference in eventfd read call
Starting with commit 12aceb89b0bc ("eventfd: convert to f_op->read_iter()")
in 5.8-rc1, the "read" function pointer in eventfd's file_operations is
NULL, "read_iter" is available instead.

Use kernel_read() and kernel_write() instead of directly calling the
function pointers to handle this correctly. We can do that safely for
kernel 4.14 and newer (older versions have different arguments of
kernel_read() and kernel_write()).
2020-09-19 22:09:19 +02:00
Jan Andres 2252a21e80 Fix NX bit handling for Linux 5.8+
Do not use vmap() to map the cross page, it needs to be executable and
vmap() unconditionally sets the NX bit starting with commit cca98e9f8b5e
("mm: enforce that vmap can't map pages executable") in 5.8-rc1.

Emulate previous behavior of vmap() by using alloc_vm_area() and
explicitly setting the PTE.
2020-09-19 22:09:19 +02:00
Michal Kubecek 20c8c330ba vmmon: include <asm/irq_vectors.h> explicitly
After mainline commit 13c01139b171 ("x86/headers: Remove APIC headers from
<asm/smp.h>") in 5.9-rc1, APIC headers are no longer included via
<asm/smp.h> so that linux/hostif.c will lack the definition of
SPURIOUS_APIC_VECTOR.

Include <asm/irq_vectors.h> in linux/hostif.c explicitly to avoid that.

Note: unlike newer versions, Workstation 12.5.9 does not really need this
include as <asm/irq_vectors.h> is included via other kernel header files
but that might change if some more headers cleanup are done in mainline so
better include it here explicitly as well.
2020-08-20 12:11:58 +02:00
Michal Kubecek 3f5c9d694b vmmon: handle change of vmstat slab counters to bytes
Mainline commit d42f3245c7e2 ("mm: memcg: convert vmstat slab counters to
bytes") in kernel 5.9-rc1 changed vmstat accounting of slab to byte
counters. Unfortunately there doesn't seem to be any obvious way to check
for this change except version check.
2020-08-20 12:11:58 +02:00
Michal Kubecek 5d3d9347f4 modules: adapt to new mmap locking API
In 5.8-rc1, mmap locking was reworked to use wrappers around mmap_sem
(which was also renamed to mmap_lock). All code is now supposed to use
these wrappers as the internal implementation of the lock may change in
the future.

Add the wrappers to older kernels to keep the conditionals out of regular
code.
2020-06-12 11:15:02 +02:00
Michal Kubecek f4f6964c1f vmmon: get rid of do_gettimeofday() in linux/driver.c
The do_gettimeofday() helper was removed by commit e4b92b108c6c
("timekeeping: remove obsolete time accessors") in v5.0-rc1 and commit
c766d1472c70 ("y2038: hide timeval/timespec/itimerval/itimerspec types")
in v5.6-rc3 hides struct timeval from kernel code.

Replace the use of do_gettimeofday() and struct timeval in linux/driver.c.
While ktime_get_real_ns() would match do_gettimeofday() better, monotonic
timer seems more appropriate for poll timeouts so use ktime_get_ns()
instead.
2020-02-24 11:08:26 +01:00
Michal Kubecek c2ffc6093b vmmon: clean up the uptime handling
The do_gettimeofday() helper was removed by commit e4b92b108c6c
("timekeeping: remove obsolete time accessors") in v5.0-rc1 and commit
c766d1472c70 ("y2038: hide timeval/timespec/itimerval/itimerspec types") in
v5.6-rc3 hides struct timeval from kernel code.

Rather than copying what newer 15.5.x versions do, clean up the whole mess
of simultaneous crosschecking between jiffies and wall time. Apparently
this was introduced once to work around the absence of a high resolution
monotonic timer. As kernel provides one at least since version 2.6.17 and
64-bit interface for it since 3.17 and VMware is unlikely to ever release
any update for Workstation/Player 14.1.x or 12.5.x anyway, let's just drop
all of it and use ktime_get_ns() instead.
2020-02-24 11:08:26 +01:00
Michal Kubecek 093dd4fc3c vmnet: convert VNetBridge debugging code to ktime_get_ns()
The do_gettimeofday() helper was removed by commit e4b92b108c6c
("timekeeping: remove obsolete time accessors") in v5.0-rc1 and commit
c766d1472c70 ("y2038: hide timeval/timespec/itimerval/itimerspec types") in
v5.6-rc3 hides struct timeval from kernel code.

Convert the do_gettimeofday() relics in VNetBridge (which are only compiled
with LOGLEVEL >= 4) completely to ktime based interface.
2020-02-24 11:08:26 +01:00
Michal Kubecek b24f99bc14 vmnet: convert from file_operations to proc_ops
Manline commit 97a32539b956 ("proc: convert everything to "struct
proc_ops"") in v5.6-rc1 introduces struct proc_ops and converts procfs file
operations to it. Convert vmnet to do the same.

As the same commit also introduces DEFINE_PROC_SHOW_ATTRIBUTE macro, we can
use it for detection rather than rely on version comparison.
2020-02-10 07:12:11 +01:00
Michal Kubecek d1c9f72082 vmmon: replace ioremap_nocache() with ioremap()
Mainline commit 4bdc0d676a64 ("remove ioremap_nocache and
devm_ioremap_nocache") in v5.6-rc1 removes ioremap_nocache() and replaces
all uses with ioremap(). As the commit message says that "ioremap has
provided non-cached semantics by default since the Linux 2.6", do the same
unconditionally.
2020-02-10 07:12:11 +01:00
Michal Kubecek 18c2fe502a vmnet: work around skb_frag_t build failure for SLE15-SP2 and openSUSE-15.2
The kernels used in (upcoming) SLE15 SP2 and openSUSE Leap 15.2 are based
on upstream version 5.3 but have a backport of the skb_frag_t conversion to
bio_vec which reached mainline in v5.4-rc1. As we cannot easily check
availability compat_skb_frag_off() (which was also added in v5.4-rc1) and
have to resort to version check, add an exception for SLE15-SP2 and
openSUSE-15.2 kernels.
2019-11-25 08:25:50 +01:00
Michal Kubecek 7329228887 vmnet: handle switch of skb_frag_t to bio_vec
The switch from custom skb_frag_t implementation to bio_vec in v5.4-rc1 is
mostly transparent for modules which use accessor for skb_frag_t members.
Unfortunately many users access the members directly and function
VNetCsumCopyDatagram() in vmnet is one of those.

Use accessors everywhere so that vmnet code is compatible with kernel 5.4
and newer. Use "compat_" prefix to avoid clashes with backports adding the
accessors to older codebase.
2019-09-30 21:33:56 +02:00
Michal Kubecek 9f39254000 Merge branch 'master' into player-12.5.9 2019-09-09 08:42:55 +02:00
Michal Kubecek 85ede6aae9 misc: fix wrong directory name in INSTALL (fixes #36)
Fix wrong directory name in one of the examples.
2019-09-09 08:38:27 +02:00
Michal Kubecek 4f3ac281ee vmmon: mark expected switch fall through
Since v5.3-rc2, kernel is built with -Wimplicit-fallthrough by default
so that compiler warns about switch fall thgrough unless it is marked as
expected. Add comment to mark one existing fall through as expected.

Note: this function is no longer present in 15.1.0 and it is probably
dead code anyway as hash2() is only called from HashFunc_HashPage()
which does not seem to be called anywhere. But to keep the code as close
to upstream as reasonably possible, just mark the fall through and keep
both functions in place.
2019-07-31 13:59:39 +02:00
Michal Kubecek 5ecf2faaa6 vmmon: fix HostIF_SetFastClockRate() not to use force_sig()
Commit 3cf5d076fb4d ("signal: Remove task parameter from force_sig") in
v5.3-rc1 drops second argument of force_sig(); before that, all callers
which passed something else than current task as second argument were
fixed, mostly to use send_sig() instead.

The situation in HostIF_SetFastClockRate() is the same as e.g. in bpfilter
call fixed by commit 1dfd1711de29 ("signal/bpfilter: Fix bpfilter_kernl to
use send_sig not force_sig"): locking in force_sig_info() cannot handle
task exiting and using force_sig() for SIGKILL is pointless anyway as this
signal cannot be blocked.

As send_sig() is present with unchanged signature since the pre-git era, we
can use send_sig() unconditionally, regardless of kernel version.
2019-07-22 06:57:54 +02:00
Michal Kubecek 48812705d7 vmmon: fix return type of vm_operations_struct::fault handler
Commit 3d3539018d2c ("mm: create the new vm_fault_t type") in mainline
5.1-rc1 changed the definition of vm_fault_t type to unsigned to catch
vm_operations_struct::fault handlers which still have int as return value.
LinuxDriverFault() in vmmon module is one of those.

As handler return type was changed by commit 1c8f422059ae ("mm: change
return type to vm_fault_t") in 4.17-rc1, make LinuxDriverFault() always
return vm_fault_t and define vm_fault_t as int when building against
a pre-4.17 kernel. (Except for the branch for really old kernels where
the handler was vm_operations_struct::nopage and returned a pointer to
struct page.)
2019-03-17 21:48:09 +01:00
Michal Kubecek c43ae31438 vmmon: use KERNEL_DS rather than get_ds()
Commit 736706bee329 ("get rid of legacy 'get_ds()' function") in v5.1-rc1
removed get_ds() helper. As this helper always returned KERNEL_DS on x86_64
since the architecture was introduced (and even on i386, it did so since
v2.1.0), simply use KERNEL_DS regardless of kernel version.
2019-03-17 21:48:09 +01:00
Michal Kubecek 6a5ae5be25 modules: handle access_ok() with two arguments
Since commit 96d4f267e40f ("Remove 'type' argument from access_ok()
function") in v5.0-rc1, the type argument of access_ok() was dropped.
The same commit also dropped macros VERIFY_READ and VERIFY_WRITE so check
for their existence on pre-5.0 kernels to allow build against kernels with
this change backported.
2019-01-07 13:55:34 +01:00
Michal Kubecek 688ba2efb3 vmmon: bring back the do_gettimeofday() helper
The do_gettimeofday() helper was removed by commit e4b92b108c6c
("timekeeping: remove obsolete time accessors") in v5.0-rc1. Bring it back
for users in vmmon-only/linux/hostif.c.

This feels like a quick and clumsy band aid to allow build with post-4.20
kernels. On a closer look, the whole gymnastics around uptimeState and
HostIFReadUptimeWork() with jiffies and wall time checking and correcting
each other seems to be a workaround for an absence of high resolution
monotonic time. Considering ktime_get_ts64() is available since 3.17 and
before that, ktime_get_ts() since 2.6.17, perhaps the time has come to
clean all this machinery up. But something like this would be beyond the
scope of this repository.
2019-01-07 13:55:34 +01:00
Michal Kubecek 95fa769616 vmmon: totalram_pages is a function since 5.0
Since commit ca79b0c211af ("mm: convert totalram_pages and totalhigh_pages
variables to atomic") in v5.0-rc1, totalram_pages() is an accessor function
and the actual variable is an atomic.
2019-01-07 13:55:34 +01:00
Michal Kubecek 8a9708499f modules: replace SUBDIRS with M
Since commit 0126be38d988 ("kbuild: announce removal of SUBDIRS if used")
in v5.0-rc1, using SUBDIRS when building out of tree modules produces
a deprecation warning. As M used to work since pretty much ever, use it
unconditionally.
2019-01-07 13:55:34 +01:00
Michal Kubecek aad370a5e2 vmmon: compatibility with eventpoll switch to poll_mask()
Since commit 11c5ad0ec441 ("eventpoll: switch to ->poll_mask") in
v4.18-rc1, eventpoll switched from ->poll() to ->poll_mask(). Rather than
calling the callback directly (which would result in null pointer
dereference), use vfs_poll() wrapper. As this wrapper is only available
since 4.18-rc1 cycle as well, provide a copy to use when building against
older kernels.
2018-06-17 15:57:46 +02:00
Michal Kubecek 5923003b57 Merge branch 'master' into player-12.5.9 2018-05-27 16:13:44 +02:00
Michal Kubecek 16c49e52d4 misc: clean copies of vmmon.o and vmnet.o in top level makefile
Makefiles in *-only copy the object file module is created from into the
parent directory but do not delete them on "make clean". Clean these files
up in "clean" target of top level makefile.
2018-05-27 16:08:30 +02:00
Theo Bertacchini f6af9290e7 modules: remove .cache.mk on make clean
Remove .cache.mk inside vmmon-only and vmnet-only when executing
"make clean". This file can cause issues when upgrading gcc as make will
still look for includes inside older gcc includes directory.

File .cache.mk with cache of generated variables is created by build since
kernel v4.15-rc1, commit 3298b690b21c ("kbuild: Add a cache for generated
variables").
2018-05-27 16:07:00 +02:00
Michal Kubecek f9b614fbf9 Merge branch 'master' into player-12.5.9 2018-04-02 15:37:24 +02:00
Michal Kubecek 77a6966b97 misc: warn if branch is marked as retired
When "make" or "make install is issued on branch marked as retired, warn
user about the fact.
2018-04-02 15:31:34 +02:00
Michal Kubecek b7b47d354b vmmon: fix indirect call with retpoline build
Build against kernel with retpoline support issues warning

  objtool: Task_Switch()+0x425: indirect call found in RETPOLINE build

This is because an indirect call in TaskSwitchToMonitor() is encoded using
inline assembler so that it bypasses retpoline generation. For this
purpose, macro CALL_NOSPEC exists since v4.15-rc8 (and has been backported
into some distribution kernels with the rest of retpoline support). Use the
macro if available and fallback to the original code if not.
2018-03-26 14:30:57 +02:00
Michal Kubecek 1eea8af1f8 vmmon: fix always_inline attribute usage
Function declared with __attribute__((always_inline)) should also be
declared as inline, otherwise gcc issues a warning "always_inline function
might not be inlinable". It's just cosmetic but getting rid of known
harmless warnings makes it easier to spot actual problems. Use the
__always_inline macro for LinuxDriverSyncReadTSCs() as this is how always
inline functions should be declared in kernel code.
2018-03-22 13:50:21 +01:00
Michal Kubecek a11ba8d6c6 vmmon: use standard definition of MSR_K7_HWCR_SMMLOCK if available
The MSR_K7_HWCR_SMMLOCK macro is defined in mainline since commit
18c71ce9c882 ("x86/CPU/AMD: Add the Secure Encrypted Virtualization CPU
feature") in v4.16-rc1.
2018-02-11 01:24:55 +01:00
Michal Kubecek d907ced352 Merge branch 'master' into player-12.5.9 2018-02-04 21:50:45 +01:00
Michal Kubecek 625084e96a misc: add INSTALL document
Add file INSTALL explaining how to use the repository (get patched sources,
build the modules and install them).
2018-02-04 21:48:58 +01:00
Michal Kubecek 1d91cc5b6a misc: add top level makefile
Add a top level makefile to make common tasks easier. Supported targets:

  make           - build modules
  make install   - install modules (honors DESTDIR)
  make clean     - clean up
  make tarballs  - create source tarballs from current HEAD

Note: "make tarballs" uses "git archive" so that it only works in a local
copy of the git repository, not in a directory created by unpacking
a tarball.

Add *.tar to .gitignore to hide tarballs created by "make tarballs".
2018-02-04 21:48:58 +01:00
Michal Kubecek 6fd497d954 misc: update README
Fix a type and clarify the part about building against older kernels.
2018-02-02 18:09:09 +01:00
Michal Kubecek 3fc524fd27 misc: ignore .cache.mk
Add .cache.mk files to .gitignore.
2018-02-02 18:08:41 +01:00
Michal Kubecek 1497314820 vmmon: convert timers to use timer_setup()
With version 4.15-rc1, conversion to new timer interface is finished and
old interface using init_timer() is no longer available. Convert all users
to new one.
2018-01-18 08:25:44 +01:00
Michal Kubecek 446f5092d7 vmmon: quick workaround for objtool warnings
As discussed in

  https://bugzilla.suse.com/show_bug.cgi?id=1059674

the reason for multiple objtool warnings is the fact that vmmon module
defines its own Panic() function which never returns. While it is marked as
such which is used by the compiler for optimization, there is no way to
find this from object file.

While this seems innocuous, it might result in problems with unwinder
later. The quickest way around is to replace vmmon's own Panic() with
standard kernel panic() until a cleaner solution is found.
2018-01-18 08:25:44 +01:00
Michal Kubecek 7af65d06e9 vmmon: fix page accounting
global_page_state() was renamed to global_zone_page_state() by commit
c41f012ade0b ("mm: rename global_page_state to global_zone_page_state").
However, some more changes are needed (and were in fact needed even with
kernels older than 4.14.

Since commit 385386cff4c6 ("mm: vmstat: move slab statistics from zone to
node counters") in v4.13-rc1, NR_SLAB_UNRECLAIMABLE needs to be used with
global_node_page_state(), in-tree callers were fixed by commit d507e2ebd2c7
("mm: fix global NR_SLAB_.*CLAIMABLE counter reads").

Since commit 599d0c954f91 ("mm, vmscan: move LRU lists to node") in
v4.8-rc1, NR_UNEVICTABLE needs global_node_page_state() rather than
global_page_state().

Since commit 50658e2e04c1 ("mm: move page mapped accounting to the node")
in v4.8-rc1, NR_ANON_PAGES needs global_node_page_state() as well. This was
shortly before it was renamed to NR_ANON_MAPPED but as both got into
mainline in v4.8-rc1, we can do with one #ifdef.

To keep HostIF_EstimateLockedPageLimit() readable, extract the version
dependent calls into inline helpers.
2018-01-18 08:25:44 +01:00
Michal Kubecek b09b058b57 vmmon: use standard definition of CR3_PCID_MASK if available
The CR3_PCID_MASK is defined in mainline asm/processor-flags.h since
commit 6c690ee1039b ("x86/mm: Split read_cr3() into read_cr3_pa() and
__read_cr3()") in v4.13-rc1.
2018-01-18 08:25:44 +01:00
Michal Kubecek 383dbae078 vmnet: do not open code skb_get()
With commit 633547973ffc ("net: convert sk_buff.users from atomic_t to
refcount_t") in v4.13-rc1, sk_buff::users changed its type from atomic_t
to refcount_t. Use skb_get() to increment the counter as that's going to
work on both old and new kernels.
2018-01-18 08:25:44 +01:00
Michal Kubecek 8a6a4706e7 vmmon: use standard definition of MSR_MISC_FEATURES_ENABLES if available
The MSR_MISC_FEATURES_ENABLES macro is defined in mainline since commit
ab6d9468631a ("x86/msr: Rename MISC_FEATURE_ENABLES to
MISC_FEATURES_ENABLES") in v4.12-rc1.

The MSR_MISC_FEATURES_ENABLES_CPUID_FAULT macro is defined in mainline
since commit e9ea1e7f53b8 ("x86/arch_prctl: Add ARCH_[GET|SET]_CPUID") in
v4.12-rc1.
2018-01-18 08:25:44 +01:00
Michal Kubecek 666525a919 vmnet: use standard definition of PCI_VENDOR_ID_VMWARE_VMXNET3 if available
The PCI_DEVICE_ID_VMWARE_VMXNET3 macro is defined in mainline pci_ids.h
since commit b1226c7db1d9 ("vmxnet3: Move PCI Id to pci_ids.h") in
v4.10-rc1.
2018-01-18 08:25:44 +01:00
Michal Kubecek b5aff64550 vmnet: use standard definition of PCI_VENDOR_ID_VMWARE if available
The PCI_VENDOR_ID_VMWARE macro is defined in mainline pci_ids.h since
commit 94e57fea6202 ("PCI: Move PCI_VENDOR_ID_VMWARE to pci_ids.h")
in v3.18-rc1.
2018-01-18 08:25:44 +01:00
Michal Kubecek 3635eff81d import Player 12.5.9 module sources 2018-01-18 07:42:13 +01:00
Michal Kubecek 84f16afb1f import Player 12.5.8 module sources 2017-11-18 00:21:40 +01:00
36 changed files with 803 additions and 2268 deletions

No files matched your search

+2
View File
@@ -3,6 +3,8 @@
*.ko
*.ko.cmd
*.mod.c
*.tar
.tmp_versions
.cache.mk
Module.symvers
modules.order
+197
View File
@@ -0,0 +1,197 @@
This document explains how to use the repository to retrieve the module
source, build modules and install them. There are two basic methods: we can
either build the modules from source and install them ourselves or replace
VMware provided source tarballs with patched ones and let it use its own
vmware-modconfig tool.
0. Quick guide for impatient
----------------------------
First method (build and install):
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
tar -xzf workstation-14.1.1.tar.gz
cd vmware-host-modules-workstation-14.1.1
make
make install
Last command must be executed with root privileges (first four shouldn't).
Based on your VMware product, replace "14.1.1" with your installed version
and/or "workstation" with "player".
Second method (replace original tarballs):
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
tar -xzf workstation-14.1.1.tar.gz
cd vmware-host-modules-workstation-14.1.1
tar -cf vmmon.tar vmmon-only
tar -cf vmnet.tar vmnet-only
cp -v vmmon.tar vmnet.tar /usr/lib/vmware/modules/source/
vmware-modconfig --console --install-all
In this case, last two commands require root privileges.
1a. Retrieve the source - with git
----------------------------------
Using git is preferrable as it allows an easy switch to sources for
different product/version or update for newer kernel version. Without git,
you can only download one particular source snapshot.
First, clone the repository from GitHub either using HTTPS
git clone https://github.com/mkubecek/vmware-host-modules.git
or using SSH
git clone git@github.com:mkubecek/vmware-host-modules.git
Using SSH is preferrable if you already have an account on GitHub, use
HTTPS if you don't.
Branch "master" cannot be used to build modules, it contains only common
files so that changes in them can be merged into all other branches easily.
To get actual sources, checkout a "real" branch, e.g.
git checkout workstation-14.1.1
Branch name consists of "workstation" (for Workstation) or "player" (for
Player), a dash and version number ("14.1.1" here). Always use correct
product and version, the modules check if internal source version matches
installed product and refuse to load otherwise. Actually, in all recent
versions, "workstation" and "player" sources have been identical but there
is no guarantee it will always be the case.
To pull out updated branch (if there are new commits), run "git pull", to
switch to a new branch run "git fetch" and "git checkout ...".
1b. Retrieve the source - without git
-------------------------------------
GitHub allows to download a particular snapshot (branch or tag) directly
without git:
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
where "workstation" and "14.1.1" have the same meaning as in section 1a.
Any other tool can be used to retrieve the URL, of course. It's also
possible to download directly from the web interface, switch to the branch
you are interested in, click the "Clone or download" button and then
"Download ZIP".
Unpack the downloaded archive
tar -xzf workstation-14.1.1.tar.gz
or
unzip vmware-host-modules-workstation-14.1.1.zip
depending on archive type. Then change to the resulting directory.
2a. Build and install modules - directly
----------------------------------------
To build modules against currently running kernel, just run "make" in top
level directory. It creates two module files vmmon-only/vmmon.ko and
vmnet-only/vmnet.ko (unstripped). To build against a different kernel, set
variable VM_UNAME, e.g.
make VM_UNAME='4.14.15-5-default'
As name suggests, this variable should be set to what "uname -r" would show
when that kernel is booted (it's the same as name of the subdirectory under
/lib/modules with modules of that kernel).
To install built modules for currently running kernel, run "make install".
This command needs to be run as user with permissions to write into the
directory with kernel modules (under normal circumstances, this should be
only root). The VM_UNAME variable can be used to install for a different
kernel. Unless you know well what are you doing and why, the same value
should be always used for "make" and "make install". That's why makefile
checks if vermagic tag of the moudules match VM_UNAME (or current kernel if
VM_UNAME isn't set).
If DESTDIR is not set (or is empty), "make install" also runs depmod to
update module dependency cache.
Note that "make install" replaces existing module files but it does not
replace modules in running kernel if they are already loaded. Reloading the
modules can be enforced e.g. by
/etc/init.d/vmware restart
All running VMs should be turned off before this.
2b. Build and install modules - replacing the original source tarballs
----------------------------------------------------------------------
Manual build and installation of host modules may be natural for developers
and power users but those who prefer to "just use" would appreciate if they
could rely on standard VMware tools. To this goal, we need to replace the
module source tarballs with patched versions.
In local checked out repository, the replacement tarballs can be created
with
make tarballs
This command creates files vmmon.tar and vmnet.tar which can be used to
replace the original tarballs provided with the VMware product. Note that
this command creates the tarball from current HEAD (in git language), i.e.
they do not contain any uncommited local changes (e.g. files created by
test build).
When using a downloaded tarball, simply run
tar -cf vmmon.tar vmmon-only
tar -cf vmnet.tar vmnet-only
to create the tarballs. In this case, there is no protection against
unwanted local changes.
Whatever way you used to create the tarballs, replace the original ones
provided by VMware
/usr/lib/vmware/modules/source/vmmon.tar
/usr/lib/vmware/modules/source/vmnet.tar
by patched versions. It is highly recommended to backup the original
tarballs before replacing them.
Once patched tarballs are installed, you can rebuild the modules as usual:
vmware-modconfig --console --install-all
or let the GUI run the command for you.
Replacing the original tarballs prevents having to rebuild and install the
modules manually with every new kernel version. However, once the VMware
product is upgraded or reinstalled, tarballs are replaced so that if the
new VMware version doesn't build/work with a recent kernel, you still need
to repeat the process. The same also holds if there is a new kernel which
requires updated version of the patches.
3. Final notes
--------------
Always make sure that you are using a branch matching the Workstation or
Player version you are running. VMware software may refuse to start if
module intended for different version is loaded. And unless you have
a reason not to, use current head of that branch; even if the module
builds, there may still be later fixes which may be important.
In some web forums, one can comments suggesting to rip out one patched file
and use it as replacement for the corresponding file with VMware tarballs.
Please don't do this - and if you do, don't complain if something doesn't
work. A commit fixing some problem is meant to be used as a whole; picking
just changes in one file can lead to rather unpredictable results. While
picking just one commit (or some of the commits) in a branch is perfectly
fine (you should still know what are you doing and why), picking just one
patched file rarely makes sense.
+49
View File
@@ -0,0 +1,49 @@
MODULES = vmmon vmnet
SUBDIRS = $(MODULES:%=%-only)
TARBALLS = $(MODULES:%=%.tar)
MODFILES = $(foreach mod,$(MODULES),$(mod)-only/$(mod).ko)
VM_UNAME = $(shell uname -r)
MODDIR = /lib/modules/$(VM_UNAME)/misc
MODINFO = /sbin/modinfo
DEPMOD = /sbin/depmod
%.tar: FORCE gitcleancheck
git archive -o $@ --format=tar HEAD $(@:.tar=-only)
.PHONY: FORCE subdirs $(SUBDIRS) clean tarballs
subdirs: retiredcheck $(SUBDIRS)
FORCE:
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
gitcheck:
@git status >/dev/null 2>&1 \
|| ( echo "This only works in a git repository."; exit 1 )
gitcleancheck: gitcheck
@git diff --exit-code HEAD >/dev/null 2>&1 \
|| echo "Warning: tarballs will reflect current HEAD (no uncommited changes)"
retiredcheck:
@test -f RETIRED && cat RETIRED || true
install: retiredcheck $(MODFILES)
@for f in $(MODFILES); do \
mver=$$($(MODINFO) -F vermagic $$f);\
mver=$${mver%% *};\
test "$${mver}" = "$(VM_UNAME)" \
|| ( echo "Version mismatch: module $$f $${mver}, kernel $(VM_UNAME)" ; exit 1 );\
done
install -D -t $(DESTDIR)$(MODDIR) $(MODFILES)
strip --strip-debug $(MODULES:%=$(DESTDIR)$(MODDIR)/%.ko)
if test -z "$(DESTDIR)"; then $(DEPMOD) -a $(VM_UNAME); fi
clean: $(SUBDIRS)
rm -f *.o
tarballs: $(TARBALLS)
+8 -3
View File
@@ -12,12 +12,17 @@ a particular version of Player or Workstation.
From these tags, branches "player-${version}" and "workstation-${version}"
are forked. These branches track changes needed to build these modules
against recent kernel versions. Tag "p${ver}-k${ver}" marks the set of
changes needed to build modules from Player ${ver} against kernel ${ver},
against recent kernel versions. Tag "p${ver}-k${kver}" marks the set of
changes needed to build modules from Player ${ver} against kernel ${kver},
e.g. p12.5.5-k4.11 is for Player 12.5.5 and kernel 4.11; similar naming
scheme "w${ver}-k${kver}" is used for Workstation modules. In general,
later points in the branch should also work with older kernels (e.g.
p12.5.5-k4.11 with kernel 4.10) but it's not completely reliable.
p12.5.5-k4.11 with kernel 4.10) but it's not guaranteed; it may happen that
a fix for new kernel version may be too complicated to make also work with
older versions.
At the moment, changes are tested to build against all (vanilla) kernel
releases starting with 4.9.
This repository is provided "as is" with no guarantees. Use the contents on
your own risk.
+1 -1
View File
@@ -117,7 +117,7 @@ prebuild:: ;
postbuild:: ;
$(DRIVER_KO): prebuild
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
+1 -1
View File
@@ -33,7 +33,7 @@ $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, \
$(wildcard $(SRCROOT)/linux/*.c $(SRCROOT)/common/*.c $(SRCROOT)/vmcore/*.c)))
clean:
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions .cache.mk \
Module.symvers Modules.symvers Module.markers modules.order \
$(foreach dir,linux/ common/ vmcore/ \
./,$(addprefix $(dir),.*.cmd .*.o.flags *.o)))
+28 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998 VMware, Inc. All rights reserved.
* Copyright (C) 1998,2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -35,6 +35,7 @@
uint32 cpuidFeatures;
static CpuidVendor vendor = CPUID_NUM_VENDORS;
static uint32 version;
static Bool hasSpecCtrl;
/*
@@ -97,6 +98,9 @@ CPUID_Init(void)
Warning("VMMON CPUID: Unrecognized CPU\n");
vendor = CPUID_VENDOR_UNKNOWN;
}
__GET_CPUID2(7, 0, &regs);
hasSpecCtrl = vendor == CPUID_VENDOR_INTEL && ((regs.edx >> 26) & 0x3) != 0;
}
@@ -207,3 +211,26 @@ CPUID_AddressSizeSupported(void)
return result;
}
/*
*-----------------------------------------------------------------------------
*
* CPUID_HostSupportsSpecCtrl --
*
* Determine whether the processor supports MSR_SPEC_CTRL.
*
* Results:
* True iff the processor supports the required features.
*
* Side effects:
* None.
*
*-----------------------------------------------------------------------------
*/
Bool
CPUID_HostSupportsSpecCtrl(void)
{
return hasSpecCtrl;
}
+2 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998,2016 VMware, Inc. All rights reserved.
* Copyright (C) 1998,2016,2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -39,6 +39,7 @@ uint32 CPUID_GetVersion(void);
Bool CPUID_SyscallSupported(void);
Bool CPUID_LongModeSupported(void);
Bool CPUID_AddressSizeSupported(void);
Bool CPUID_HostSupportsSpecCtrl(void);
static INLINE uint32
CPUID_GetFeatures(void)
+44 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -79,6 +79,9 @@
# define USE_TEMPORARY_GDT 0
#endif
/* Cycle through values of SPEC_CTRL and verify they survive world switch. */
#undef CYCLE_SPEC_CTRL
#define TS_ASSERT(t) do { \
DEBUG_ONLY(if (!(t)) TaskAssertFail(__LINE__);) \
} while (0)
@@ -1594,12 +1597,23 @@ TaskSwitchToMonitor(VMCrossPage *crosspage)
{
uint64 raxGetsWiped, rcxGetsWiped;
#ifdef CALL_NOSPEC
__asm__ __volatile__(CALL_NOSPEC
: "=a" (raxGetsWiped),
"=c" (rcxGetsWiped)
: "0" (codePtr),
"1" (crosspage),
THUNK_TARGET(codePtr)
: "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
#else
__asm__ __volatile__("call *%%rax"
: "=a" (raxGetsWiped),
"=c" (rcxGetsWiped)
: "0" (codePtr),
"1" (crosspage)
: "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
#endif
}
#elif defined(_MSC_VER)
/*
@@ -1764,6 +1778,11 @@ Task_Switch(VMDriver *vm, // IN
uint32 pCPU;
MPN hvRootMPN;
Descriptor *tempGDTBase;
#ifdef CYCLE_SPEC_CTRL
Bool specCtrlEqual = FALSE;
uint64 readSpecCtrlValue = 0;
static volatile uint64 currentSpecCtrlValue = 0;
#endif
ASSERT_ON_COMPILE(sizeof(VMCrossPage) == PAGE_SIZE);
TaskDisableNMI(&vm->hostAPIC, &lint0NMI, &lint1NMI, &pcNMI, &thermalNMI);
@@ -1973,6 +1992,14 @@ Task_Switch(VMDriver *vm, // IN
TS_ASSERT(SELECTOR_TABLE(ds) == SELECTOR_GDT);
TS_ASSERT(SELECTOR_TABLE(ss) == SELECTOR_GDT);
if (CPUID_HostSupportsSpecCtrl()) {
#ifdef CYCLE_SPEC_CTRL
currentSpecCtrlValue = (currentSpecCtrlValue + 1) % 4;
__SET_MSR(MSR_SPEC_CTRL, currentSpecCtrlValue);
#endif
crosspage->crosspageData.specCtrl = __GET_MSR(MSR_SPEC_CTRL);
}
DEBUG_ONLY(crosspage->crosspageData.tinyStack[0] = 0xDEADBEEF;)
/* Running in host context prior to TaskSwitchToMonitor() */
TaskSwitchToMonitor(crosspage);
@@ -1980,6 +2007,16 @@ Task_Switch(VMDriver *vm, // IN
TS_ASSERT(crosspage->crosspageData.tinyStack[0] == 0xDEADBEEF);
#ifdef CYCLE_SPEC_CTRL
if (CPUID_HostSupportsSpecCtrl()) {
readSpecCtrlValue = __GET_MSR(MSR_SPEC_CTRL);
specCtrlEqual = readSpecCtrlValue ==
crosspage->crosspageData.specCtrl;
/* Do not leak cycling SPEC_CTRL value back to host. */
__SET_MSR(MSR_SPEC_CTRL, 0);
}
#endif
/*
* Temporarily disable single-step stress as VMX/VMCS change code
* ASSERTS on RFLAGS content without allowing TF/RF to be set.
@@ -2113,6 +2150,12 @@ Task_Switch(VMDriver *vm, // IN
if (UNLIKELY(TaskGotException(crosspage, EXC_UD))) {
Warning("#UD occurred on switch back to host; dumping core");
}
#ifdef CYCLE_SPEC_CTRL
if (UNLIKELY(!specCtrlEqual)) {
Warning("SpecCtrl not equal: expected %"FMT64"x, got %"FMT64"x\n",
crosspage->crosspageData.specCtrl, readSpecCtrlValue);
}
#endif
/*
* The NMI/MCE checks above are special cases for interrupts
* received during worldswitch. Here is the more generic case
+34
View File
@@ -0,0 +1,34 @@
#ifndef __COMPAT_MMAP_LOCK_H__
#define __COMPAT_MMAP_LOCK_H__
#include <linux/mm.h>
/*
* In 5.8-rc1, mmap locking was reworked to use wrappers around mmap_sem
* (which was also renamed to mmap_lock). All code is now supposed to use
* these wrappers as the internal implementation of the lock may change in
* the future.
*
* Check also _LINUX_MMAP_LOCK_H to handle possible backports to distribution
* pre-5.8 kernel. This macro is defined in <linux/mmap_lock.h> which is also
* included in <linux/mm.h> since the commit introducing the wrappers so that
* we should have it defined in any kernel providing the new API.
*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) || defined(_LINUX_MMAP_LOCK_H)
#include <linux/mmap_lock.h>
#else
static inline void mmap_read_lock(struct mm_struct *mm)
{
down_read(&mm->mmap_sem);
}
static inline void mmap_read_unlock(struct mm_struct *mm)
{
up_read(&mm->mmap_sem);
}
#endif /* 5.8.0 */
#endif /* __COMPAT_MMAP_LOCK_H__ */
+30
View File
@@ -0,0 +1,30 @@
#ifndef __COMPAT_POLL_H__
#define __COMPAT_POLL_H__
#include <linux/poll.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0))
#ifndef __poll_t
typedef unsigned int __poll_t;
#endif
static inline __poll_t compat_vfs_poll(struct file *file,
struct poll_table_struct *pt)
{
if (unlikely(!file->f_op->poll))
return DEFAULT_POLLMASK;
return file->f_op->poll(file, pt);
}
#else
static inline __poll_t compat_vfs_poll(struct file *file,
struct poll_table_struct *pt)
{
return vfs_poll(file, pt);
}
#endif
#endif /* __COMPAT_POLL_H__ */
+33
View File
@@ -0,0 +1,33 @@
#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 compat_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;
static inline void compat_timer_setup(struct timer_list *timer,
void (*func)(compat_timer_arg_t),
unsigned int flags)
{
timer_setup(timer, func, flags);
}
#endif /* new timer interface since 4.15 */
#endif /* __COMPAT_TIMER_H__ */
+1
View File
@@ -251,6 +251,7 @@ static INLINE ub8 hash2(register const ub8 *k, /* the key */
{
/* c is reserved for the length */
case 2: b+=k[1];
/* fall through */
case 1: a+=k[0];
/* case 0: nothing left to add */
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2015,2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -133,7 +133,7 @@ PtrToVA64(void const *ptr) // IN
*
*/
#define VMMON_VERSION (308 << 16 | 0)
#define VMMON_VERSION (309 << 16 | 0)
#define VMMON_VERSION_MAJOR(v) ((uint32) (v) >> 16)
#define VMMON_VERSION_MINOR(v) ((uint16) (v))
+3 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2015,2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -421,6 +421,7 @@ struct VMCrossPageData {
*/
uint8 switchHostIDT [sizeof(Gate64) * NUM_EXCEPTIONS]; // hostCS:hostVA
uint8 switchMon64IDT[sizeof(Gate64) * NUM_EXCEPTIONS]; // 64-bit monCS:monVA
uint64 specCtrl; /* host MSR_SPEC_CTRL value before world switch. */
}
#include "vmware_pack_end.h"
VMCrossPageData;
@@ -474,7 +475,7 @@ struct VMCrossPage {
#include "vmware_pack_end.h"
VMCrossPage;
#define CROSSPAGE_VERSION_BASE 0xbf1 /* increment by 1 */
#define CROSSPAGE_VERSION_BASE 0xbf2 /* increment by 1 */
#define CROSSPAGE_VERSION ((CROSSPAGE_VERSION_BASE << 1) + WS_INTR_STRESS)
#if !defined(VMX86_SERVER) && defined(VMM)
+2 -1
View File
@@ -67,6 +67,7 @@ extern "C" {
#if defined (VMKPANIC)
#include "vmk_assert.h"
#else /* !VMKPANIC */
#include <linux/kernel.h>
#define _ASSERT_PANIC(name) \
Panic(_##name##Fmt "\n", __FILE__, __LINE__)
#define _ASSERT_PANIC_BUG(bug, name) \
@@ -118,7 +119,7 @@ NORETURN void Panic_NoSaveNoReturn(const char *fmt, ...) PRINTF_DECL(1, 2);
} while(0)
#else
NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
#define Panic panic
#endif
void LogThrottled(uint32 *count, const char *fmt, ...) PRINTF_DECL(2, 3);
+4
View File
@@ -35,6 +35,8 @@
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"
#include <asm/processor-flags.h>
#define X86_MAX_INSTR_LEN 15 /* Max byte length of an x86 instruction. */
#define NUM_IDT_VECTORS 256
@@ -62,7 +64,9 @@
#define CR3_PDB_MASK 0xfffff000
#define CR3_IGNORE 0xFFF
#define PAE_CR3_IGNORE 0x1F
#ifndef CR3_PCID_MASK
#define CR3_PCID_MASK 0xFFF
#endif
#define CR3_NO_FLUSH (1ULL << 63)
#define CR4_VME 0x00000001
+9 -3
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2016 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -419,6 +419,10 @@ FIELD( 6, 0, EBX, 0, 4, NUM_INTR_THRESHOLDS, NA, FALSE) \
FLAG( 6, 0, ECX, 0, 1, HW_COORD_FEEDBACK, NA, FALSE) \
FLAG( 6, 0, ECX, 3, 1, ENERGY_PERF_BIAS, NA, FALSE)
#define CPUID_7_EDX_26 \
FLAG( 7, 0, EDX, 26, 1, LEVEL7EDX_RSVD1, NO, FALSE)
#define CPUID_7_EDX_27 \
FLAG( 7, 0, EDX, 27, 1, LEVEL7EDX_RSVD2, NO, FALSE)
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */
#define CPUID_FIELD_DATA_LEVEL_7 \
@@ -440,8 +444,9 @@ FLAG( 7, 0, EBX, 18, 1, RDSEED, YES, TRUE) \
FLAG( 7, 0, EBX, 19, 1, ADX, YES, TRUE) \
FLAG( 7, 0, EBX, 20, 1, SMAP, YES, FALSE) \
FLAG( 7, 0, EBX, 25, 1, PT, NO, FALSE) \
FLAG( 7, 0, ECX, 0, 1, PREFETCHWT1, NO, TRUE)
FLAG( 7, 0, ECX, 0, 1, PREFETCHWT1, NO, TRUE) \
CPUID_7_EDX_26 \
CPUID_7_EDX_27
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */
#define CPUID_FIELD_DATA_LEVEL_A \
@@ -708,6 +713,7 @@ FIELD( 84, 0, EBX, 0, 32, LEAF84_BRAND_STRING_EBX, NA, FALSE) \
FIELD( 84, 0, ECX, 0, 32, LEAF84_BRAND_STRING_ECX, NA, FALSE) \
FIELD( 84, 0, EDX, 0, 32, LEAF84_BRAND_STRING_EDX, NA, FALSE)
#define CPUID_8A_EDX_11 \
FLAG( 8A, 0, EDX, 11, 1, SVMEDX_RSVD1, NO, FALSE)
#define CPUID_8A_EDX_14_31 \
+24 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 2003-2015 VMware, Inc. All rights reserved.
* Copyright (C) 2003-2015,2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -63,6 +63,14 @@ extern "C" {
*/
void __cpuid(int regs[4], int eax);
#pragma intrinsic(__cpuid)
/*
* __cpuidex has been supported since VS2008
*/
#if _MSC_VER >= 1500
void __cpuidex(int regs[4], int eax, int ecx);
#pragma intrinsic(__cpuidex)
#endif /* _MSC_VER >= 1500 */
#endif /* VM_X86_64 */
#ifdef __cplusplus
@@ -247,6 +255,20 @@ __GET_CPUID(int input, CPUIDRegs *regs)
#ifdef VM_X86_64
#if _MSC_VER >= 1500
/*
* __cpuidex has been supported since VS2008
*/
static INLINE void
__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs)
{
__cpuidex((int *)regs, inputEax, inputEcx);
}
#else // _MSC_VER >= 1500
/*
* No inline assembly in Win64. Implemented in bora/lib/misc in
* cpuidMasm64.asm.
@@ -254,6 +276,7 @@ __GET_CPUID(int input, CPUIDRegs *regs)
extern void
__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs);
#endif // _MSC_VER >= 1500
#else // VM_X86_64
+14 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2018 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -24,6 +24,7 @@
#ifndef _X86MSR_H_
#define _X86MSR_H_
#include <asm/msr-index.h>
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMX
@@ -79,6 +80,7 @@ MSRQuery;
#define MSR_SMI_COUNT 0x00000034 // Intel Nehalem Family
#define MSR_FEATCTL 0x0000003a
#define MSR_TSC_ADJUST 0x0000003b
#define MSR_SPEC_CTRL 0x00000048
#define MSR_BIOS_UPDT_TRIG 0x00000079
#define MSR_BIOS_SIGN_ID 0x0000008b
#define MSR_PERFCTR0 0x000000c1
@@ -106,7 +108,10 @@ MSRQuery;
#define MSR_TSC_AUX 0xc0000103
#define MSR_BD_TSC_RATIO 0xc0000104
#ifndef MSR_MISC_FEATURES_ENABLES
#define MSR_MISC_FEATURES_ENABLES 0x140
#endif
/* Intel Core Architecture and later: use only architected counters. */
#define IA32_MSR_PERF_CAPABILITIES 0x345
@@ -300,7 +305,9 @@ typedef enum {
#define MSR_K7_HWCR_SSEDIS 0x00008000ULL // Disable SSE bit
#define MSR_K7_HWCR_MONMWAITUSEREN 0x00000400ULL // Enable MONITOR/MWAIT CPL>0
#define MSR_K7_HWCR_TLBFFDIS 0x00000040ULL // Disable TLB Flush Filter
#ifndef MSR_K7_HWCR_SMMLOCK
#define MSR_K7_HWCR_SMMLOCK 0x00000001ULL // Lock SMM environment
#endif
#ifndef MSR_K8_SYSCFG
#define MSR_K8_SYSCFG 0xc0010010
@@ -342,6 +349,8 @@ typedef enum {
#define MSR_VM_CR_SVME_DISABLE 0x0000000000000010ULL
#define MSR_VM_CR_RESERVED 0xffffffffffffffe0ULL
#define MSR_AMD_DE_CFG 0xc0011029 // Decode configuration
#define MSR_AMD_DE_CFG_BIT1 (1ULL<<1)
/* Syscall/Sysret related MSRs (x86_64) */
#define MSR_STAR 0xc0000081 // Also present on Athlons.
@@ -475,7 +484,11 @@ typedef enum {
/*
* MISC_FEATURES_ENABLES bits
*/
#ifdef MSR_MISC_FEATURES_ENABLES_CPUID_FAULT
#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULTING MSR_MISC_FEATURES_ENABLES_CPUID_FAULT
#else
#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULTING 1
#endif
+18 -22
View File
@@ -21,6 +21,7 @@
#define EXPORT_SYMTAB
#include "compat_timer.h"
#include <linux/file.h>
#include <linux/highmem.h>
#include <linux/poll.h>
@@ -80,6 +81,9 @@ static Bool LinuxDriverCheckPadding(void);
struct VMXLinuxState linuxState;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
typedef int vm_fault_t;
#endif
/*
*----------------------------------------------------------------------
@@ -105,9 +109,9 @@ long LinuxDriver_Ioctl(struct file *filp, u_int iocmd,
static int LinuxDriver_Close(struct inode *inode, struct file *filp);
static unsigned int LinuxDriverPoll(struct file *file, poll_table *wait);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static int LinuxDriverFault(struct vm_fault *fault);
static vm_fault_t LinuxDriverFault(struct vm_fault *fault);
#elif defined(VMW_NOPAGE_2624)
static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
static vm_fault_t LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
#else
static struct page *LinuxDriverNoPage(struct vm_area_struct *vma,
unsigned long address,
@@ -115,7 +119,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 +231,7 @@ LinuxDriverEstimateTSCkHz(void)
*----------------------------------------------------------------------
*/
static void
LinuxDriverEstimateTSCkHzDeferred(unsigned long data)
LinuxDriverEstimateTSCkHzDeferred(compat_timer_arg_t unused)
{
LinuxDriverEstimateTSCkHz();
}
@@ -265,9 +269,7 @@ LinuxDriverInitTSCkHz(void)
}
Vmx86_ReadTSCAndUptime(&tsckHzStartTime);
tscTimer.function = LinuxDriverEstimateTSCkHzDeferred;
tscTimer.expires = jiffies + 4 * HZ;
tscTimer.data = 0;
add_timer(&tscTimer);
}
@@ -309,9 +311,7 @@ init_module(void)
*/
init_waitqueue_head(&linuxState.pollQueue);
init_timer(&linuxState.pollTimer);
linuxState.pollTimer.data = 0;
linuxState.pollTimer.function = LinuxDriverPollTimeout;
compat_timer_setup(&linuxState.pollTimer, LinuxDriverPollTimeout, 0);
linuxState.fastClockThread = NULL;
linuxState.fastClockFile = NULL;
@@ -360,7 +360,7 @@ init_module(void)
linuxState.deviceName, linuxState.major, linuxState.minor);
HostIF_InitUptime();
init_timer(&tscTimer);
compat_timer_setup(&tscTimer, LinuxDriverEstimateTSCkHzDeferred, 0);
LinuxDriverInitTSCkHz();
Vmx86_InitIDList();
@@ -741,14 +741,12 @@ void
LinuxDriverWakeUp(Bool selective) // IN:
{
if (selective && linuxState.pollList != NULL) {
struct timeval tv;
VmTimeType now;
VMLinux *p;
VMLinux *next;
HostIF_PollListLock(1);
do_gettimeofday(&tv);
now = tv.tv_sec * 1000000ULL + tv.tv_usec;
now = ktime_get_ns() / NSEC_PER_USEC;
for (p = linuxState.pollList; p != NULL; p = next) {
next = p->pollForw;
@@ -815,12 +813,10 @@ LinuxDriverPoll(struct file *filp, // IN:
}
} else {
if (linuxState.fastClockThread && vmLinux->pollTimeoutPtr != NULL) {
struct timeval tv;
u64 now = ktime_get_ns() / NSEC_PER_USEC;
do_gettimeofday(&tv);
poll_wait(filp, &vmLinux->pollQueue, wait);
vmLinux->pollTime = *vmLinux->pollTimeoutPtr +
tv.tv_sec * 1000000ULL + tv.tv_usec;
vmLinux->pollTime = *vmLinux->pollTimeoutPtr + now;
if (vmLinux->pollBack == NULL) {
HostIF_PollListLock(2);
if (vmLinux->pollBack == NULL) {
@@ -858,7 +854,7 @@ LinuxDriverPoll(struct file *filp, // IN:
*/
static void
LinuxDriverPollTimeout(unsigned long clientData) // IN:
LinuxDriverPollTimeout(compat_timer_arg_t unused) // IN:
{
LinuxDriverWakeUp(FALSE);
}
@@ -884,11 +880,11 @@ LinuxDriverPollTimeout(unsigned long clientData) // IN:
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static int
static vm_fault_t
LinuxDriverFault(struct vm_fault *fault) //IN/OUT
#elif defined(VMW_NOPAGE_2624)
static int LinuxDriverFault(struct vm_area_struct *vma, //IN
struct vm_fault *fault) //IN/OUT
static vm_fault_t LinuxDriverFault(struct vm_area_struct *vma, //IN
struct vm_fault *fault) //IN/OUT
#else
static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, //IN
unsigned long address, //IN
@@ -1287,7 +1283,7 @@ LinuxDriverReadTSC(void *data, // OUT: TSC values
*-----------------------------------------------------------------------------
*/
__attribute__((always_inline)) static Bool
__always_inline static Bool
LinuxDriverSyncReadTSCs(uint64 *delta) // OUT: TSC max - TSC min
{
TSCDelta tscDelta;
+169 -227
View File
@@ -30,6 +30,7 @@
/* Must come before vmware.h --hpreg */
#include "compat_page.h"
#include "compat_timer.h"
#include <linux/binfmts.h>
#include <linux/delay.h>
#include <linux/file.h>
@@ -68,7 +69,10 @@
#endif
#include <asm/io.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/irq_vectors.h>
#include <linux/mc146818rtc.h>
#include <linux/capability.h>
#include <linux/kthread.h>
@@ -77,6 +81,7 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/taskstats_kern.h> // For linux/sched/signal.h without version check
#endif
#include <linux/eventfd.h>
#include "vmware.h"
#include "x86apic.h"
@@ -98,6 +103,41 @@
#include "pgtbl.h"
#include "vmmonInt.h"
#include "versioned_atomic.h"
#include "compat_poll.h"
#include "compat_mmap_lock.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(5, 9, 0)
return global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
#elif 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.
@@ -142,13 +182,7 @@ static DECLARE_TASKLET(timerTasklet, HostIFWakeupClockThread, 0);
*/
#define LOCKED_PAGE_SLACK 10000
static struct {
Atomic_uint64 uptimeBase;
VersionedAtomic version;
uint64 monotimeBase;
unsigned long jiffiesBase;
struct timer_list timer;
} uptimeState;
u64 uptime_base;
/*
* First Page Locking strategy
@@ -207,6 +241,21 @@ static struct {
uint8 monitorIPIVector;
uint8 hvIPIVector;
static unsigned long compat_totalram_pages(void)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
return totalram_pages;
#else
return totalram_pages();
#endif
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) && defined(VERIFY_WRITE)
#define write_access_ok(addr, size) access_ok(VERIFY_WRITE, addr, size)
#else
#define write_access_ok(addr, size) access_ok(addr, size)
#endif
/*
*-----------------------------------------------------------------------------
*
@@ -629,6 +678,15 @@ HostIF_FastClockUnlock(int callerID) // IN
MutexUnlock(&fastClockMutex, callerID);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
static int crosspage_set_exec(pte_t *pte, unsigned long addr, void *data)
{
struct page *p = data;
set_pte(pte, mk_pte(p, VM_PAGE_KERNEL_EXEC));
return 0;
}
#endif
/*
*-----------------------------------------------------------------------------
@@ -695,7 +753,29 @@ HostIF_PollListUnlock(int callerID) // IN
static void *
MapCrossPage(struct page *p) // IN:
{
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 8, 0)
return vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
#else
void *addr;
addr = vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
if (!addr)
return NULL;
/* Starting with 5.8, vmap() always sets the NX bit, but the cross
* page needs to be executable. */
if (apply_to_page_range(current->mm, (unsigned long)addr, PAGE_SIZE,
crosspage_set_exec, p)) {
vunmap(addr);
return NULL;
}
preempt_disable();
__flush_tlb_all();
preempt_enable();
return addr;
#endif
}
@@ -1164,7 +1244,7 @@ HostIFGetUserPages(void *uvAddr, // IN
{
int retval;
down_read(&current->mm->mmap_sem);
mmap_read_lock(current->mm);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
retval = get_user_pages((unsigned long)uvAddr, numPages, 0, ppages, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
@@ -1173,7 +1253,7 @@ HostIFGetUserPages(void *uvAddr, // IN
retval = get_user_pages(current, current->mm, (unsigned long)uvAddr,
numPages, 0, 0, ppages, NULL);
#endif
up_read(&current->mm->mmap_sem);
mmap_read_unlock(current->mm);
return retval != numPages;
}
@@ -1569,14 +1649,7 @@ unsigned int
HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
unsigned int currentlyLockedPages) // IN
{
/*
* This variable is available and exported to modules,
* since at least 2.6.0.
*/
extern unsigned long totalram_pages;
unsigned int totalPhysicalPages = totalram_pages;
unsigned int totalPhysicalPages = compat_totalram_pages();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
return MemDefaults_CalcMaxLockedPages(totalPhysicalPages);
@@ -1594,16 +1667,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) +
unsigned int lockedPages = global_zone_page_state(NR_PAGETABLE) +
get_nr_slab_unreclaimable() +
get_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 anonPages = get_nr_anon_mapped();
unsigned int swapPages = BYTES_2_PAGES(linuxState.swapSize);
if (anonPages > swapPages) {
@@ -1661,146 +1729,6 @@ HostIF_WaitForFreePages(unsigned int timeoutMs) // IN:
}
/*
*----------------------------------------------------------------------
*
* HostIFReadUptimeWork --
*
* Reads the current uptime. The uptime is based on getimeofday,
* which provides the needed high resolution. However, we don't
* want uptime to be warped by e.g. calls to settimeofday. So, we
* use a jiffies based monotonic clock to sanity check the uptime.
* If the uptime is more than one second from the monotonic time,
* we assume that the time of day has been set, and recalculate the
* uptime base to get uptime back on track with monotonic time. On
* the other hand, we do expect jiffies based monotonic time and
* timeofday to have small drift (due to NTP rate correction, etc).
* We handle this by rebasing the jiffies based monotonic clock
* every second (see HostIFUptimeResyncMono).
*
* Results:
* The uptime, in units of UPTIME_FREQ. Also returns the jiffies
* value that was used in the monotonic time calculation.
*
* Side effects:
* May reset the uptime base in the case gettimeofday warp was
* detected.
*
*----------------------------------------------------------------------
*/
static uint64
HostIFReadUptimeWork(unsigned long *j) // OUT: current jiffies
{
struct timeval tv;
uint64 monotime, uptime, upBase, monoBase;
int64 diff;
uint32 version;
unsigned long jifs, jifBase;
unsigned int attempts = 0;
/* Assert that HostIF_InitUptime has been called. */
ASSERT(uptimeState.timer.function);
retry:
do {
version = VersionedAtomic_BeginTryRead(&uptimeState.version);
jifs = jiffies;
jifBase = uptimeState.jiffiesBase;
monoBase = uptimeState.monotimeBase;
} while (!VersionedAtomic_EndTryRead(&uptimeState.version, version));
do_gettimeofday(&tv);
upBase = Atomic_Read64(&uptimeState.uptimeBase);
monotime = (uint64)(jifs - jifBase) * (UPTIME_FREQ / HZ);
monotime += monoBase;
uptime = tv.tv_usec * (UPTIME_FREQ / 1000000) + tv.tv_sec * UPTIME_FREQ;
uptime += upBase;
/*
* Use the jiffies based monotonic time to sanity check gettimeofday.
* If they differ by more than one second, assume the time of day has
* been warped, and use the jiffies time to undo (most of) the warp.
*/
diff = uptime - monotime;
if (UNLIKELY(diff < -UPTIME_FREQ || diff > UPTIME_FREQ)) {
/* Compute a new uptimeBase to get uptime back on track. */
uint64 newUpBase = monotime - (uptime - upBase);
attempts++;
if (!Atomic_CMPXCHG64(&uptimeState.uptimeBase, &upBase, &newUpBase) &&
attempts < 5) {
/* Another thread updated uptimeBase. Recalculate uptime. */
goto retry;
}
uptime = monotime;
Log("%s: detected settimeofday: fixed uptimeBase old %"FMT64"u "
"new %"FMT64"u attempts %u\n", __func__,
upBase, newUpBase, attempts);
}
*j = jifs;
return uptime;
}
/*
*----------------------------------------------------------------------
*
* HostIFUptimeResyncMono --
*
* Timer that fires ever second to resynchronize the jiffies based
* monotonic time with the uptime.
*
* Results:
* None
*
* Side effects:
* Resets the monotonic time bases so that jiffies based monotonic
* time does not drift from gettimeofday over the long term.
*
*----------------------------------------------------------------------
*/
static void
HostIFUptimeResyncMono(unsigned long data) // IN: ignored
{
unsigned long jifs;
uintptr_t flags;
/*
* Read the uptime and the corresponding jiffies value. This will
* also correct the uptime (which is based on time of day) if needed
* before we rebase monotonic time (which is based on jiffies).
*/
uint64 uptime = HostIFReadUptimeWork(&jifs);
/*
* Every second, recalculate monoBase and jiffiesBase to squash small
* drift between gettimeofday and jiffies. Also, this prevents
* (jiffies - jiffiesBase) wrap on 32-bits.
*/
SAVE_FLAGS(flags);
CLEAR_INTERRUPTS();
VersionedAtomic_BeginWrite(&uptimeState.version);
uptimeState.monotimeBase = uptime;
uptimeState.jiffiesBase = jifs;
VersionedAtomic_EndWrite(&uptimeState.version);
RESTORE_FLAGS(flags);
/* Reschedule this timer to expire in one second. */
mod_timer(&uptimeState.timer, jifs + HZ);
}
/*
*----------------------------------------------------------------------
*
@@ -1812,8 +1740,7 @@ HostIFUptimeResyncMono(unsigned long data) // IN: ignored
* None
*
* Side effects:
* Sets the initial values for the uptime state, and schedules
* the uptime timer.
* Sets the initial value for the uptime base.
*
*----------------------------------------------------------------------
*/
@@ -1821,17 +1748,7 @@ HostIFUptimeResyncMono(unsigned long data) // IN: ignored
void
HostIF_InitUptime(void)
{
struct timeval tv;
uptimeState.jiffiesBase = jiffies;
do_gettimeofday(&tv);
Atomic_Write64(&uptimeState.uptimeBase,
-(tv.tv_usec * (UPTIME_FREQ / 1000000) +
tv.tv_sec * UPTIME_FREQ));
init_timer(&uptimeState.timer);
uptimeState.timer.function = HostIFUptimeResyncMono;
mod_timer(&uptimeState.timer, jiffies + HZ);
uptime_base = ktime_get_ns();
}
@@ -1840,13 +1757,13 @@ HostIF_InitUptime(void)
*
* HostIF_CleanupUptime --
*
* Cleanup uptime state, called at module unloading time.
* No-op, left for backward compatibility.
*
* Results:
* None
*
* Side effects:
* Deschedule the uptime timer.
* None
*
*----------------------------------------------------------------------
*/
@@ -1854,7 +1771,6 @@ HostIF_InitUptime(void)
void
HostIF_CleanupUptime(void)
{
del_timer_sync(&uptimeState.timer);
}
@@ -1878,9 +1794,10 @@ HostIF_CleanupUptime(void)
uint64
HostIF_ReadUptime(void)
{
unsigned long jifs;
u64 tm;
return HostIFReadUptimeWork(&jifs);
tm = ktime_get_ns();
return (tm - uptime_base) / (NSEC_PER_SEC / UPTIME_FREQ);
}
@@ -2227,6 +2144,27 @@ HostIF_VMLockIsHeld(VMDriver *vm) // IN
#if defined(CONFIG_SMP) || defined(CONFIG_X86_UP_IOAPIC) || \
defined(CONFIG_X86_UP_APIC) || defined(CONFIG_X86_LOCAL_APIC)
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 8, 0)
static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
{
mm_segment_t old_fs;
long ret;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = HostIF_CopyFromUser(dst, (const void *)src, size);
set_fs(old_fs);
return ret;
}
#else
static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
{
return copy_from_kernel_nofault(dst, (const void *)src, size);
}
#endif
/*
*----------------------------------------------------------------------
*
@@ -2246,15 +2184,11 @@ HostIF_VMLockIsHeld(VMDriver *vm) // IN
static Bool
isVAReadable(VA r) // IN:
{
mm_segment_t old_fs;
uint32 dummy;
int ret;
old_fs = get_fs();
set_fs(get_ds());
long ret;
r = APICR_TO_ADDR(r, APICR_VERSION);
ret = HostIF_CopyFromUser(&dummy, (void*)r, sizeof(dummy));
set_fs(old_fs);
ret = compat_copy_from_kernel_nofault(&dummy, r, sizeof(dummy));
return ret == 0;
}
@@ -2284,7 +2218,7 @@ SetVMAPICAddr(VMDriver *vm, // IN/OUT: driver state
volatile void *hostapic;
ASSERT_ON_COMPILE(APICR_SIZE <= PAGE_SIZE);
hostapic = (volatile void *) ioremap_nocache(ma, PAGE_SIZE);
hostapic = (volatile void *) ioremap(ma, PAGE_SIZE);
if (hostapic) {
if ((APIC_VERSIONREG(hostapic) & 0xF0) == 0x10) {
vm->hostAPIC.base = (volatile uint32 (*)[4]) hostapic;
@@ -2440,44 +2374,41 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
uint64 *args) // IN:
{
struct file *file;
mm_segment_t old_fs;
int res;
int waitFD = args[0];
int timeoutms = args[2];
uint64 value;
struct poll_wqueues table;
unsigned int mask;
file = vmware_fget(waitFD);
if (file == NULL) {
return MX_WAITERROR;
}
old_fs = get_fs();
set_fs(get_ds());
{
struct poll_wqueues table;
unsigned int mask;
poll_initwait(&table);
current->state = TASK_INTERRUPTIBLE;
mask = file->f_op->poll(file, &table.pt);
if (!(mask & (POLLIN | POLLERR | POLLHUP))) {
vm->vmhost->vcpuSemaTask[vcpuid] = current;
schedule_timeout(timeoutms * HZ / 1000); // convert to Hz
vm->vmhost->vcpuSemaTask[vcpuid] = NULL;
}
current->state = TASK_RUNNING;
poll_freewait(&table);
poll_initwait(&table);
current->state = TASK_INTERRUPTIBLE;
mask = compat_vfs_poll(file, &table.pt);
if (!(mask & (POLLIN | POLLERR | POLLHUP))) {
vm->vmhost->vcpuSemaTask[vcpuid] = current;
schedule_timeout(timeoutms * HZ / 1000); // convert to Hz
vm->vmhost->vcpuSemaTask[vcpuid] = NULL;
}
current->state = TASK_RUNNING;
poll_freewait(&table);
/*
* Userland only writes in multiples of sizeof(uint64). This will allow
* the code to happily deal with a pipe or an eventfd. We only care about
* reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
*
* Upstream Linux changed the function parameter types/ordering in 4.14.0.
*/
res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
res = kernel_read(file, file->f_pos, (char *)&value, sizeof value);
#else
res = kernel_read(file, &value, sizeof value, &file->f_pos);
#endif
if (res == sizeof value) {
res = MX_WAITNORMAL;
} else {
@@ -2486,7 +2417,6 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
}
}
set_fs(old_fs);
fput(file);
/*
@@ -2569,8 +2499,8 @@ HostIF_SemaphoreForceWakeup(VMDriver *vm, // IN:
int
HostIF_SemaphoreSignal(uint64 *args) // IN:
{
struct eventfd_ctx *eventfd;
struct file *file;
mm_segment_t old_fs;
int res;
int signalFD = args[1];
uint64 value = 1; // make an eventfd happy should it be there
@@ -2580,22 +2510,34 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
return MX_WAITERROR;
}
old_fs = get_fs();
set_fs(get_ds());
/*
* If it's eventfd, use specific eventfd interface as kernel writes
* to eventfd may not be allowed in kernel 5.10 and later.
*/
eventfd = eventfd_ctx_fileget(file);
if (!IS_ERR(eventfd)) {
eventfd_signal(eventfd, 1);
fput(file);
return MX_WAITNORMAL;
}
/*
* Always write sizeof(uint64) bytes. This works fine for eventfd and
* pipes. The data written is formatted to make an eventfd happy should
* it be present.
*
* Upstream Linux changed the function parameter types/ordering in 4.14.0.
*/
res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
res = kernel_write(file, (char *)&value, sizeof value, file->f_pos);
#else
res = kernel_write(file, &value, sizeof value, &file->f_pos);
#endif
if (res == sizeof value) {
res = MX_WAITNORMAL;
}
set_fs(old_fs);
fput(file);
/*
@@ -3325,7 +3267,11 @@ HostIFStartTimer(Bool rateChanged, //IN: Did rate change?
return -1;
}
}
res = filp->f_op->read(filp, (void *) &buf, sizeof(buf), &pos);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
res = kernel_read(filp, pos, (char *)&buf, sizeof(buf));
#else
res = kernel_read(filp, &buf, sizeof(buf), &pos);
#endif
if (res <= 0) {
if (res != -ERESTARTSYS) {
Log("/dev/rtc read failed: %d\n", res);
@@ -3364,12 +3310,9 @@ HostIFFastClockThread(void *data) // IN:
{
struct file *filp = (struct file *) data;
int res;
mm_segment_t oldFS;
unsigned int rate = 0;
unsigned int prevRate = 0;
oldFS = get_fs();
set_fs(KERNEL_DS);
allow_signal(SIGKILL);
set_user_nice(current, linuxState.fastClockPriority);
@@ -3403,7 +3346,6 @@ HostIFFastClockThread(void *data) // IN:
out:
LinuxDriverWakeUp(TRUE);
set_fs(oldFS);
/*
* Do not exit thread until we are told to do so.
@@ -3524,7 +3466,7 @@ HostIF_SetFastClockRate(unsigned int rate) // IN: Frequency in Hz.
}
} else {
if (linuxState.fastClockThread) {
force_sig(SIGKILL, linuxState.fastClockThread);
send_sig(SIGKILL, linuxState.fastClockThread, 1);
kthread_stop(linuxState.fastClockThread);
close_rtc(linuxState.fastClockFile, current->files);
@@ -3572,7 +3514,7 @@ HostIF_MapUserMem(VA addr, // IN: User memory virtual address
ASSERT(handle);
if (!access_ok(VERIFY_WRITE, p, size)) {
if (!write_access_ok(p, size)) {
printk(KERN_ERR "%s: Couldn't verify write to uva 0x%p with size %"
FMTSZ"u\n", __func__, p, size);
+1 -1
View File
@@ -117,7 +117,7 @@ prebuild:: ;
postbuild:: ;
$(DRIVER_KO): prebuild
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
+1 -1
View File
@@ -35,6 +35,6 @@ $(DRIVER)-y := driver.o hub.o userif.o netif.o bridge.o procfs.o smac_compat.o \
####
clean:
rm -rf $(DRIVER).o $(DRIVER).mod.o $(DRIVER).mod.c $(DRIVER).ko \
rm -rf $(DRIVER).o $(DRIVER).mod.o $(DRIVER).mod.c $(DRIVER).ko .cache.mk \
.tmp_versions Module.symvers Modules.symvers Module.markers \
modules.order $($(DRIVER)-y) .*.cmd .*.o.flags
+7 -8
View File
@@ -65,7 +65,7 @@
#endif
#if LOGLEVEL >= 4
static struct timeval vnetTime;
static u64 vnetTime;
#endif
typedef struct VNetBridge VNetBridge;
@@ -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);
@@ -696,7 +696,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
netif_rx_ni(clone);
# if LOGLEVEL >= 4
do_gettimeofday(&vnetTime);
vnetTime = ktime_get_ns();
# endif
}
}
@@ -1661,12 +1661,11 @@ VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
# if LOGLEVEL >= 4
{
struct timeval now;
do_gettimeofday(&now);
u64 now;
now = ktime_get_ns();
LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
bridge->name,
(int)((now.tv_sec * 1000000 + now.tv_usec)
- (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
bridge->name, (int)((now - vnetTime) / NSEC_PER_USEC)));
}
# endif
+34
View File
@@ -0,0 +1,34 @@
#ifndef __COMPAT_MMAP_LOCK_H__
#define __COMPAT_MMAP_LOCK_H__
#include <linux/mm.h>
/*
* In 5.8-rc1, mmap locking was reworked to use wrappers around mmap_sem
* (which was also renamed to mmap_lock). All code is now supposed to use
* these wrappers as the internal implementation of the lock may change in
* the future.
*
* Check also _LINUX_MMAP_LOCK_H to handle possible backports to distribution
* pre-5.8 kernel. This macro is defined in <linux/mmap_lock.h> which is also
* included in <linux/mm.h> since the commit introducing the wrappers so that
* we should have it defined in any kernel providing the new API.
*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) || defined(_LINUX_MMAP_LOCK_H)
#include <linux/mmap_lock.h>
#else
static inline void mmap_read_lock(struct mm_struct *mm)
{
down_read(&mm->mmap_sem);
}
static inline void mmap_read_unlock(struct mm_struct *mm)
{
up_read(&mm->mmap_sem);
}
#endif /* 5.8.0 */
#endif /* __COMPAT_MMAP_LOCK_H__ */
+2 -1
View File
@@ -337,7 +337,8 @@ typedef netdev_features_t compat_netdev_features_t;
typedef u32 compat_netdev_features_t;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= 0x0704)
#define compat_netif_trans_update(d) netif_trans_update(d)
#else
#define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0)
+9
View File
@@ -161,6 +161,14 @@ VNetProcOpen(struct inode *inode, // IN:
}
/* Our procfs callbacks. We only need to specialize open. */
#ifdef DEFINE_PROC_SHOW_ATTRIBUTE
static const struct proc_ops fops = {
.proc_open = VNetProcOpen,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = single_release,
};
#else
static struct file_operations fops = {
.open = VNetProcOpen,
.read = seq_read,
@@ -168,6 +176,7 @@ static struct file_operations fops = {
.release = single_release,
};
#endif
#endif
/*
+63 -21
View File
@@ -47,6 +47,7 @@
#include "vnetInt.h"
#include "compat_skbuff.h"
#include "compat_mmap_lock.h"
#include "vmnetInt.h"
#include "vm_atomic.h"
#include "vm_assert.h"
@@ -84,11 +85,55 @@ static int VNetUserIfSetUplinkState(VNetPort *port, uint8 linkUp);
extern unsigned int vnet_max_qlen;
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
# define compat_kmap(page) kmap(page)
# define compat_kunmap(page) kunmap(page)
# define compat_kmap_frag(frag) kmap((frag)->page)
# define compat_kunmap_frag(page) kunmap((frag)->page)
#else
# define compat_kmap(page) kmap((page).p)
# define compat_kunmap(page) kunmap((page).p)
# define compat_kmap_frag(frag) kmap(skb_frag_page(frag))
# define compat_kunmap_frag(frag) kunmap(skb_frag_page(frag))
#endif
static unsigned int compat_skb_frag_size(const skb_frag_t *frag)
{
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
return frag->size;
#else
return skb_frag_size(frag);
#endif
}
static unsigned int compat_skb_frag_off(const skb_frag_t *frag)
{
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 4, 0) && \
!(defined(CONFIG_SUSE_VERSION) && CONFIG_SUSE_VERSION == 15 && \
defined(CONFIG_SUSE_PATCHLEVEL) && CONFIG_SUSE_PATCHLEVEL >= 2)
return frag->page_offset;
#else
return skb_frag_off(frag);
#endif
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) && defined(VERIFY_WRITE)
#define write_access_ok(addr, size) access_ok(VERIFY_WRITE, addr, size)
#else
#define write_access_ok(addr, size) access_ok(addr, size)
#endif
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0)
static inline
__wsum compat_csum_and_copy_to_user(const void *src, void __user *dst, int len)
{
int err;
__wsum ret;
ret = csum_and_copy_to_user(src, dst, len, 0, &err);
return err ? 0 : ret;
}
#else
static inline
__wsum compat_csum_and_copy_to_user(const void *src, void __user *dst, int len)
{
return csum_and_copy_to_user(src, dst, len);
}
#endif
/*
@@ -115,7 +160,7 @@ UserifLockPage(VA addr) // IN
struct page *page = NULL;
int retval;
down_read(&current->mm->mmap_sem);
mmap_read_lock(current->mm);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
retval = get_user_pages(addr, 1, FOLL_WRITE, &page, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
@@ -124,7 +169,7 @@ UserifLockPage(VA addr) // IN
retval = get_user_pages(current, current->mm, addr,
1, 1, 0, &page, NULL);
#endif
up_read(&current->mm->mmap_sem);
mmap_read_unlock(current->mm);
if (retval != 1) {
return NULL;
@@ -157,7 +202,7 @@ VNetUserIfMapPtr(VA uAddr, // IN: pointer to user memory
struct page **p, // OUT: locked page
void **ptr) // OUT: kernel mapped pointer
{
if (!access_ok(VERIFY_WRITE, (void *)uAddr, size) ||
if (!write_access_ok((void *)uAddr, size) ||
(((uAddr + size - 1) & ~(PAGE_SIZE - 1)) !=
(uAddr & ~(PAGE_SIZE - 1)))) {
return -EINVAL;
@@ -572,7 +617,6 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
char *buf) // OUT: where to copy data
{
unsigned int csum;
int err = 0;
int len = skb_headlen(skb) - offset;
char *curr = buf;
const skb_frag_t *frag;
@@ -585,29 +629,27 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
return -EINVAL;
}
csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err);
if (err) {
return err;
}
csum = compat_csum_and_copy_to_user(skb->data + offset, curr, len);
if (!csum)
return -EFAULT;
curr += len;
for (frag = skb_shinfo(skb)->frags;
frag != skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
frag++) {
if (frag->size > 0) {
if (compat_skb_frag_size(frag) > 0) {
unsigned int tmpCsum;
const void *vaddr;
vaddr = compat_kmap(frag->page);
tmpCsum = csum_and_copy_to_user(vaddr + frag->page_offset,
curr, frag->size, 0, &err);
compat_kunmap(frag->page);
vaddr = compat_kmap_frag(frag);
tmpCsum = compat_csum_and_copy_to_user(vaddr + compat_skb_frag_off(frag),
curr, compat_skb_frag_size(frag));
compat_kunmap_frag(frag);
if (err) {
return err;
}
if (!tmpCsum)
return -EFAULT;
csum = csum_block_add(csum, tmpCsum, curr - buf);
curr += frag->size;
curr += compat_skb_frag_size(frag);
}
}
+9
View File
@@ -35,6 +35,8 @@
#endif
#endif
#include <linux/pci_ids.h>
/* LSILogic 53C1030 Parallel SCSI controller
* LSILogic SAS1068 SAS controller
*/
@@ -53,7 +55,10 @@
* VMware HD Audio codec
* VMware HD Audio controller
*/
#ifndef PCI_VENDOR_ID_VMWARE
#define PCI_VENDOR_ID_VMWARE 0x15AD
#endif
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
#define PCI_DEVICE_ID_VMWARE_VGA 0x0711
@@ -70,7 +75,11 @@
#define PCI_DEVICE_ID_VMWARE_1394 0x0780
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
#ifndef PCI_DEVICE_ID_VMWARE_VMXNET3
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
#endif
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
#define PCI_DEVICE_ID_VMWARE_82574 0x07D0
#define PCI_DEVICE_ID_VMWARE_AHCI 0x07E0
+2 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998 VMware, Inc. All rights reserved.
* Copyright (C) 1998, 2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -77,7 +77,7 @@
extern struct proto vmnet_proto;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) || defined(sk_net_refcnt)
# define compat_sk_alloc(_bri, _pri) sk_alloc(&init_net, \
PF_NETLINK, _pri, &vmnet_proto, 1)
#elif defined(VMW_NETDEV_HAS_NET)
-43
View File
@@ -1,43 +0,0 @@
/*********************************************************
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*********************************************************/
/*
* vmware_pack_begin.h --
*
* Begin of structure packing. See vmware_pack_init.h for details.
*
* Note that we do not use the following construct in this include file,
* because we want to emit the code every time the file is included --hpreg
*
* #ifndef foo
* # define foo
* ...
* #endif
*
*/
#include "vmware_pack_init.h"
#ifdef _MSC_VER
# pragma pack(push, 1)
#elif __GNUC__
#else
# error Compiler packing...
#endif
-44
View File
@@ -1,44 +0,0 @@
/*********************************************************
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*********************************************************/
/*
* vmware_pack_end.h --
*
* End of structure packing. See vmware_pack_init.h for details.
*
* Note that we do not use the following construct in this include file,
* because we want to emit the code every time the file is included --hpreg
*
* #ifndef foo
* # define foo
* ...
* #endif
*
*/
#include "vmware_pack_init.h"
#ifdef _MSC_VER
# pragma pack(pop)
#elif __GNUC__
__attribute__((__packed__))
#else
# error Compiler packing...
#endif
-65
View File
@@ -1,65 +0,0 @@
/*********************************************************
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*********************************************************/
#ifndef __VMWARE_PACK_INIT_H__
# define __VMWARE_PACK_INIT_H__
/*
* vmware_pack_init.h --
*
* Platform-independent code to make the compiler pack (i.e. have them
* occupy the smallest possible space) structure definitions. The following
* constructs are known to work --hpreg
*
* #include "vmware_pack_begin.h"
* struct foo {
* ...
* }
* #include "vmware_pack_end.h"
* ;
*
* typedef
* #include "vmware_pack_begin.h"
* struct foo {
* ...
* }
* #include "vmware_pack_end.h"
* foo;
*/
#ifdef _MSC_VER
/*
* MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
* not balanced within 1 included file. That is annoying because our scheme
* is based on the pairing being balanced between 2 included files.
*
* So we disable this warning, but this is safe because the compiler will also
* emit warning 4161 when there is more pops than pushes within 1 main
* file --hpreg
*/
# pragma warning(disable:4103)
#elif __GNUC__
#else
# error Compiler packing...
#endif
#endif /* __VMWARE_PACK_INIT_H__ */
View File
Whitespace-only changes.
File diff suppressed because it is too large. Load diff