Compare commits

..
Author SHA1 Message Date
Michal Kubecek 7f41ad47c8 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.
2020-05-30 02:58:53 +02:00
Michal Kubecek 89dd7f9c95 vmmon: use standard definition of MSR_TSX_FORCE_ABORT if available
The MSR_TSX_FORCE_ABORT macro is defined in mainline since commit
52f64909409c ("x86: Add TSX Force Abort CPUID/MSR") in v5.1-rc1.
2020-05-30 02:58:53 +02:00
Michal Kubecek b1932e4565 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 since
commit c766d1472c70 ("y2038: hide timeval/timespec/itimerval/itimerspec
types") in v5.6-rc3, struct timeval should no longer be used in kernel
code.

Convert the do_gettimeofday() relics in VNetBridge (which are only compiled
with LOGLEVEL >= 4) completely to ktime based interface.
2020-05-30 02:58:29 +02:00
Michal Kubecek 62defb4cdc vmmon: check presence of file_operations::poll()
Commit 11c5ad0ec441 ("eventpoll: switch to ->poll_mask") in v4.18-rc1, made
eventpoll switch from ->poll() to ->poll_mask(), resulting in a null
pointer dereference as vmmon calls the callback directly without checking
its availability.

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.

Note: even if the commit revealing the problem was reverted in 4.18-rc3
(and is unlikely to go back in the same form) so that vmmon no longer
crashes with 4.18 kernel, calling the callback without a check is a bad
practice so let's keep the patch in place.
2020-05-30 02:57:49 +02:00
Michal Kubecek 9eaf7f92ac 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek 4afafaa6d3 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek 7f158e4ce9 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.
2020-05-30 02:57:49 +02:00
Theo Bertacchini cf7e20ba3a 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 was created by build since
kernel v4.15-rc1, commit 3298b690b21c ("kbuild: Add a cache for generated
variables") until the feature was removed in v4.18-rc1, commit e08d6de4e532
("kbuild: remove kbuild cache").
2020-05-30 02:57:49 +02:00
Michal Kubecek 75ac365cc8 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek afb98b4983 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek db81a381d0 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek cd660d0dbe 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.
2020-05-30 02:57:49 +02:00
Michal Kubecek 2c723cea23 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.
2020-05-30 02:56:37 +02:00
Michal Kubecek a8a060c095 modules: do not override CC command line options
Workstation/Player 15.5.0 tries to guess the right retpoline (Spectre)
related compiler command line options, resulting in objtool warnings like

  warning: objtool: .text.__x86_indirect_thunk_rbp+0x0: unsupported intra-function call
  warning: objtool: If this is a retpoline, please patch it in with alternatives and annotate

e.g. in vmmon-only/common/memtrack.o (but also many others).

This seems wrong; out-of-tree modules should be built with the same
compiler options that were used to build the kernel they are built against.
Distribution kernel devel packages usually make sure this is the way so let
them do their job.
2020-05-30 02:56:37 +02:00
Michal Kubecek 60c5393399 vmmon: fix wrong VMX86_DEVEL test
If VMX86_DEVEL macro is not defined, preprocessor warns when it is tested
with "#if" in vmmon-only/linux/driver.c. As VMX86_DEVEL is tested with
"#ifdef" everywhere else, change this one test to match the rest.
2020-05-30 02:56:37 +02:00
Michal Kubecek 7fd1a58863 import Player 15.5.5 module sources 2020-05-30 02:30:43 +02:00
Michal Kubecek cbd3374fd0 import Player 15.5.2 module sources 2020-03-14 09:59:24 +01:00
Michal Kubecek 87feab5f03 import Player 15.5.1 module sources 2019-11-14 07:56:57 +01:00
Michal Kubecek 6daa6921e7 import Player 15.5.0 module sources 2019-09-21 00:11:26 +02:00
Michal Kubecek 193db5638c Merge branch 'master' into player 2019-09-21 00:10:31 +02:00
Michal Kubecek 1f8ca44e74 import Player 15.1.0 module sources 2019-05-15 07:06:02 +02:00
Michal Kubecek 3686288fcb import Player 15.0.1 module sources 2018-11-12 07:48:28 +01:00
Michal Kubecek 3d8f309653 import Player 15.0.0 module sources 2018-10-02 19:09:36 +02:00
Michal Kubecek 56b2ba7686 import Player 14.1.3 module sources 2018-08-20 07:28:17 +02:00
Michal Kubecek 7c61516e73 Merge branch 'master' into player 2018-05-27 16:13:48 +02:00
Michal Kubecek 7ee6cd4520 import Player 14.1.2 module sources 2018-05-23 18:14:05 +02:00
Michal Kubecek 5791987f56 Merge branch 'master' into player 2018-04-02 15:37:18 +02:00
Michal Kubecek 0b2713797e Merge branch 'master' into player 2018-02-04 21:50:37 +01:00
Michal Kubecek 3e445144a1 import Player 14.1.1 module sources 2018-01-12 13:51:34 +01:00
Michal Kubecek 82f569a212 import Player 14.1.0 module sources 2017-12-25 09:47:38 +01:00
Michal Kubecek 455d4d9368 import Player 14.0.0 module sources 2017-09-30 20:31:15 +02:00
Michal Kubecek 027dd56418 import Player 12.5.7 module sources 2017-06-30 19:11:22 +02:00
Michal Kubecek 0e634ffbf1 import Player 12.5.6 module sources 2017-05-31 10:06:51 +02:00
Michal Kubecek c62c78e908 import Player 12.5.5 module sources 2017-05-31 09:20:00 +02:00
Michal Kubecek 4f648692e4 import Player 12.5.2 module sources 2017-05-31 09:19:26 +02:00
2 changed files with 50 additions and 122 deletions

No files matched your search

+40 -97
View File
@@ -47,16 +47,13 @@
#include <asm/asm.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/irq_vectors.h>
#include <linux/capability.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/hrtimer.h>
#include <linux/signal.h>
#include <linux/taskstats_kern.h> // For linux/sched/signal.h without version check
#include <linux/eventfd.h>
#include "vmware.h"
#include "x86apic.h"
@@ -618,15 +615,6 @@ 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
/*
*----------------------------------------------------------------------
@@ -647,29 +635,7 @@ static int crosspage_set_exec(pte_t *pte, unsigned long addr, void *data)
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
}
@@ -1773,11 +1739,8 @@ HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
#else
lockedPages += global_page_state(NR_PAGETABLE);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
/* NR_SLAB_* converted to byte counters in 5.9 */
lockedPages += global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
/* NR_SLAB_* moved from zone to node in 4.13. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
lockedPages += global_node_page_state(NR_SLAB_UNRECLAIMABLE);
#else
lockedPages += global_page_state(NR_SLAB_UNRECLAIMABLE);
@@ -2408,27 +2371,6 @@ 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, 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
/*
*----------------------------------------------------------------------
*
@@ -2448,11 +2390,15 @@ static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
static Bool
isVAReadable(VA r) // IN:
{
mm_segment_t old_fs;
uint32 dummy;
long ret;
int ret;
old_fs = get_fs();
set_fs(KERNEL_DS);
r = APICR_TO_ADDR(r, APICR_VERSION);
ret = compat_copy_from_kernel_nofault(&dummy, r, sizeof(dummy));
ret = HostIF_CopyFromUser(&dummy, r, sizeof dummy);
set_fs(old_fs);
return ret == 0;
}
@@ -2608,12 +2554,11 @@ 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;
ASSERT(vcpuid < vm->numVCPUs);
@@ -2622,29 +2567,33 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
return MX_WAITERROR;
}
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;
old_fs = get_fs();
set_fs(KERNEL_DS);
{
struct poll_wqueues table;
unsigned int mask;
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);
}
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.
*/
#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
res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
if (res == sizeof value) {
res = MX_WAITNORMAL;
} else {
@@ -2653,6 +2602,7 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
}
}
set_fs(old_fs);
fput(file);
/*
@@ -2739,8 +2689,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
@@ -2750,34 +2700,22 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
return MX_WAITERROR;
}
/*
* 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;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
/*
* 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.
*/
#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
res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
if (res == sizeof value) {
res = MX_WAITNORMAL;
}
set_fs(old_fs);
fput(file);
/*
@@ -3324,9 +3262,12 @@ static int
HostIFFastClockThread(void *unused) // IN:
{
int res;
mm_segment_t oldFS;
unsigned int rate = 0;
unsigned int prevRate = 0;
oldFS = get_fs();
set_fs(KERNEL_DS);
allow_signal(SIGKILL);
while ((rate = linuxState.fastClockRate) > MIN_RATE) {
@@ -3349,6 +3290,8 @@ HostIFFastClockThread(void *unused) // IN:
}
out:
set_fs(oldFS);
/*
* Do not exit thread until we are told to do so.
*/
+10 -25
View File
@@ -87,24 +87,6 @@ extern unsigned int vnet_max_qlen;
# define skb_frag_off(frag) (frag)->page_offset
#endif
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0)
static inline
__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
/*
*-----------------------------------------------------------------------------
*
@@ -566,6 +548,7 @@ 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;
@@ -578,9 +561,10 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
return -EINVAL;
}
csum = compat_csum_and_copy_to_user(skb->data + offset, curr, len);
if (!csum)
return -EFAULT;
csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err);
if (err) {
return err;
}
curr += len;
for (frag = skb_shinfo(skb)->frags;
@@ -591,12 +575,13 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
const void *vaddr;
vaddr = kmap(skb_frag_page(frag));
tmpCsum = compat_csum_and_copy_to_user(vaddr + skb_frag_off(frag),
curr, skb_frag_size(frag));
tmpCsum = csum_and_copy_to_user(vaddr + skb_frag_off(frag),
curr, skb_frag_size(frag), 0, &err);
kunmap(skb_frag_page(frag));
if (!tmpCsum)
return -EFAULT;
if (err) {
return err;
}
csum = csum_block_add(csum, tmpCsum, curr - buf);
curr += skb_frag_size(frag);
}