Compare commits

...
3 Commits
26 changed files with 406 additions and 2413 deletions

No files matched your search

+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)
+8 -8
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2014 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
@@ -122,14 +122,10 @@ EXTERN MPN HostIF_GetNextAnonPage(VMDriver *vm, MPN mpn);
EXTERN int HostIF_GetLockedPageList(VMDriver *vm, VA64 uAddr,
unsigned int numPages);
EXTERN int HostIF_ReadPage(MPN mpn, VA64 addr, Bool kernelBuffer);
EXTERN int HostIF_WritePage(MPN mpn, VA64 addr, Bool kernelBuffer);
#ifdef _WIN32
/* Add a HostIF_ReadMachinePage() if/when needed */
EXTERN int HostIF_ReadPage(VMDriver *vm, MPN mpn, VA64 addr, Bool kernelBuffer);
EXTERN int HostIF_WritePage(VMDriver *vm, MPN mpn, VA64 addr,
Bool kernelBuffer);
EXTERN int HostIF_WriteMachinePage(MPN mpn, VA64 addr);
#else
#define HostIF_WriteMachinePage(_a, _b) HostIF_WritePage((_a), (_b), TRUE)
#endif
#if defined __APPLE__
// There is no need for a fast clock lock on Mac OS.
#define HostIF_FastClockLock(_callerID) do {} while (0)
@@ -145,4 +141,8 @@ EXTERN void HostIF_FreeMachinePage(MPN mpn);
EXTERN int HostIF_SafeRDMSR(uint32 msr, uint64 *val);
#if defined __APPLE__
EXTERN void HostIF_PageUnitTest(void);
#endif
#endif // ifdef _HOSTIF_H_
+11 -13
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
@@ -88,6 +88,7 @@
#include "vmware.h"
#include "hostif.h"
#include "vmx86.h"
#include "memtrack.h"
@@ -146,12 +147,11 @@ typedef struct MemTrackHT {
typedef uint64 MemTrackHTKey;
typedef struct MemTrack {
VMDriver *vm; /* The VM instance. */
unsigned numPages; /* Number of pages tracked. */
MemTrackDir1 dir1; /* First level directory. */
MemTrackHT vpnHashTable; /* VPN to entry hashtable. */
#if defined(MEMTRACK_MPN_LOOKUP)
MemTrackHT mpnHashTable; /* MPN to entry hashtable. */
#endif
} MemTrack;
/*
@@ -304,11 +304,9 @@ MemTrackCleanup(MemTrack *mt) // IN
if (mt->vpnHashTable.pages[idx] != NULL) {
HostIF_FreePage(mt->vpnHashTable.pages[idx]);
}
#if defined(MEMTRACK_MPN_LOOKUP)
if (mt->mpnHashTable.pages[idx] != NULL) {
HostIF_FreePage(mt->mpnHashTable.pages[idx]);
}
#endif
}
HostIF_FreeKernelMem(mt);
@@ -332,7 +330,7 @@ MemTrackCleanup(MemTrack *mt) // IN
*/
MemTrack *
MemTrack_Init(void)
MemTrack_Init(VMDriver *vm) // IN:
{
MemTrack *mt;
unsigned idx;
@@ -349,6 +347,7 @@ MemTrack_Init(void)
goto error;
}
memset(mt, 0, sizeof *mt);
mt->vm = vm;
for (idx = 0; idx < MEMTRACK_HT_PAGES; idx++) {
MemTrackHTPage *htPage = MemTrackAllocPage();
@@ -360,7 +359,6 @@ MemTrack_Init(void)
mt->vpnHashTable.pages[idx] = htPage;
}
#if defined(MEMTRACK_MPN_LOOKUP)
for (idx = 0; idx < MEMTRACK_HT_PAGES; idx++) {
MemTrackHTPage *htPage = MemTrackAllocPage();
@@ -370,7 +368,6 @@ MemTrack_Init(void)
}
mt->mpnHashTable.pages[idx] = htPage;
}
#endif
return mt;
@@ -409,6 +406,8 @@ MemTrack_Add(MemTrack *mt, // IN
MemTrackDir3 *dir3;
MEMTRACK_IDX2DIR(idx, p1, p2, p3);
ASSERT(HostIF_VMLockIsHeld(mt->vm));
if (p1 >= MEMTRACK_DIR1_ENTRIES ||
p2 >= MEMTRACK_DIR2_ENTRIES ||
p3 >= MEMTRACK_DIR3_ENTRIES) {
@@ -430,9 +429,7 @@ MemTrack_Add(MemTrack *mt, // IN
ent->mpn = mpn;
MemTrackHTInsert(&mt->vpnHashTable, ent, &ent->vpnChain, ent->vpn);
#if defined(MEMTRACK_MPN_LOOKUP)
MemTrackHTInsert(&mt->mpnHashTable, ent, &ent->mpnChain, ent->mpn);
#endif
mt->numPages++;
@@ -461,6 +458,7 @@ MemTrack_LookupVPN(MemTrack *mt, // IN
VPN64 vpn) // IN
{
MemTrackEntry *next = *MemTrackHTLookup(&mt->vpnHashTable, vpn);
ASSERT(HostIF_VMLockIsHeld(mt->vm));
while (next != NULL) {
if (next->vpn == vpn) {
@@ -473,7 +471,6 @@ MemTrack_LookupVPN(MemTrack *mt, // IN
}
#if defined(MEMTRACK_MPN_LOOKUP)
/*
*----------------------------------------------------------------------
*
@@ -493,7 +490,9 @@ MemTrackEntry *
MemTrack_LookupMPN(MemTrack *mt, // IN
MPN mpn) // IN
{
MemTrackEntry *next = *MemTrackHTLookup(&mt->mpnHashTable, mpn);
MemTrackEntry *next;
ASSERT(HostIF_VMLockIsHeld(mt->vm));
next = *MemTrackHTLookup(&mt->mpnHashTable, mpn);
while (next != NULL) {
if (next->mpn == mpn) {
@@ -504,7 +503,6 @@ MemTrack_LookupMPN(MemTrack *mt, // IN
return NULL;
}
#endif
/*
+2 -10
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
@@ -31,30 +31,22 @@
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"
#if defined(VMX86_DEBUG)
#define MEMTRACK_MPN_LOOKUP
#endif
struct MemTrack;
typedef struct MemTrackEntry {
VPN64 vpn;
MPN mpn;
struct MemTrackEntry *vpnChain;
#if defined(MEMTRACK_MPN_LOOKUP)
struct MemTrackEntry *mpnChain;
#endif
} MemTrackEntry;
typedef void (MemTrackCleanupCb)(void *cData, MemTrackEntry *entry);
extern struct MemTrack *MemTrack_Init(void);
extern struct MemTrack *MemTrack_Init(VMDriver *vm);
extern unsigned MemTrack_Cleanup(struct MemTrack *mt, MemTrackCleanupCb *cb,
void *cbData);
extern MemTrackEntry *MemTrack_Add(struct MemTrack *mt, VPN64 vpn, MPN mpn);
extern MemTrackEntry *MemTrack_LookupVPN(struct MemTrack *mt, VPN64 vpn);
#if defined(MEMTRACK_MPN_LOOKUP)
extern MemTrackEntry *MemTrack_LookupMPN(struct MemTrack *mt, MPN mpn);
#endif
#endif // _MEMTRACK_H_
+62 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2016 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
@@ -39,6 +39,9 @@
# include <linux/string.h> /* memset() in the kernel */
# define EXPORT_SYMTAB
# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
# define LINUX_GDT_IS_RO
# endif
#else
# include <string.h>
#endif
@@ -60,6 +63,13 @@
#include "apic.h"
#include "x86perfctr.h"
#ifdef LINUX_GDT_IS_RO
# include <asm/desc.h>
# define default_rw_gdt get_current_gdt_rw()
#else
# define default_rw_gdt NULL
#endif
#if defined(_WIN64)
# include "x86.h"
# include "vmmon-asm-x86-64.h"
@@ -69,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)
@@ -691,11 +704,28 @@ TaskRestoreHostGDTTRLDT(Descriptor *tempGDTBase,
*/
desc = (Descriptor *)((VA)HOST_KERNEL_LA_2_VA(hostGDT64.offset + tr));
#ifdef LINUX_GDT_IS_RO
/*
* If GDT is read-only, we must always load TR from alternative gdt,
* otherwise CPU gets page fault when marking TR busy.
*/
{
DTR64 rwGDT64;
rwGDT64.offset = (unsigned long)tempGDTBase;
rwGDT64.limit = hostGDT64.limit;
Desc_SetType((Descriptor *)((unsigned long)tempGDTBase + tr), TASK_DESC);
_Set_GDT((DTR *)&rwGDT64);
SET_TR(tr);
_Set_GDT((DTR *)&hostGDT64);
}
#else
if (Desc_Type(desc) == TASK_DESC_BUSY) {
Desc_SetType(desc, TASK_DESC);
}
_Set_GDT((DTR *)&hostGDT64);
SET_TR(tr);
#endif
SET_LDT(ldt);
}
}
@@ -1737,6 +1767,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);
@@ -1747,7 +1782,8 @@ Task_Switch(VMDriver *vm, // IN
ASSERT(pCPU < ARRAYSIZE(hvRootPage) && pCPU < ARRAYSIZE(tmpGDT));
hvRootMPN = Atomic_Read64(&hvRootPage[pCPU]);
tempGDTBase = USE_TEMPORARY_GDT ? Atomic_ReadPtr(&tmpGDT[pCPU]) : NULL;
tempGDTBase = USE_TEMPORARY_GDT ? Atomic_ReadPtr(&tmpGDT[pCPU])
: default_rw_gdt;
/*
* We can't allocate memory with interrupts disabled on all hosts
@@ -1945,6 +1981,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);
@@ -1952,6 +1996,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.
@@ -2085,6 +2139,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
+30 -1
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
@@ -720,6 +720,35 @@ cleanup:
}
/*
*----------------------------------------------------------------------
*
* Vmx86_LookupUserMPN --
*
* Look up the MPN of a locked user page by user VA under the VM lock.
*
* Results:
* A status code and the MPN on success.
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
int
Vmx86_LookupUserMPN(VMDriver *vm, // IN: VMDriver
VA64 uAddr, // IN: user VA of the page
MPN *mpn) // OUT
{
int ret;
HostIF_VMLock(vm, 38);
ret = HostIF_LookupUserMPN(vm, uAddr, mpn);
HostIF_VMUnlock(vm, 38);
return ret;
}
/*
*----------------------------------------------------------------------
*
+2 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2013,2015-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
@@ -106,6 +106,7 @@ extern PseudoTSC pseudoTSC;
#define MAX_LOCKED_PAGES (-1)
extern VMDriver *Vmx86_CreateVM(void);
extern int Vmx86_LookupUserMPN(VMDriver *vm, VA64 uAddr, MPN *mpn);
extern int Vmx86_ReleaseVM(VMDriver *vm);
extern int Vmx86_InitVM(VMDriver *vm, InitBlock *initParams);
extern int Vmx86_LateInitVM(VMDriver *vm);
+22 -74
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 2002 VMware, Inc. All rights reserved.
* Copyright (C) 2002-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
@@ -30,80 +30,32 @@
#include <asm/pgtable.h>
/* pte_page() API modified in 2.3.23 to return a struct page * --hpreg */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
# define compat_pte_page pte_page
#else
# include "compat_page.h"
# define compat_pte_page(_pte) virt_to_page(pte_page(_pte))
#endif
/* Appeared in 2.5.5 --hpreg */
#ifndef pte_offset_map
/* Appeared in SuSE 8.0's 2.4.18 --hpreg */
# ifdef pte_offset_atomic
# define pte_offset_map pte_offset_atomic
# define pte_unmap pte_kunmap
# else
# define pte_offset_map pte_offset
# define pte_unmap(_pte)
# endif
#endif
/* Appeared in 2.5.74-mmX --petr */
#ifndef pmd_offset_map
# define pmd_offset_map(pgd, address) pmd_offset(pgd, address)
# define pmd_unmap(pmd)
#endif
/*
* Appeared in 2.6.10-rc2-mm1. Older kernels did L4 page tables as
* part of pgd_offset, or they did not have L4 page tables at all.
* In 2.6.11 pml4 -> pgd -> pmd -> pte hierarchy was replaced by
* pgd -> pud -> pmd -> pte hierarchy.
* p4d level appeared in 4.12.
*/
#ifdef PUD_MASK
# define compat_pgd_offset(mm, address) pgd_offset(mm, address)
# define compat_pgd_present(pgd) pgd_present(pgd)
# define compat_pud_offset(pgd, address) pud_offset(pgd, address)
# define compat_pud_present(pud) pud_present(pud)
typedef pgd_t compat_pgd_t;
typedef pud_t compat_pud_t;
#elif defined(pml4_offset)
# define compat_pgd_offset(mm, address) pml4_offset(mm, address)
# define compat_pgd_present(pml4) pml4_present(pml4)
# define compat_pud_offset(pml4, address) pml4_pgd_offset(pml4, address)
# define compat_pud_present(pgd) pgd_present(pgd)
typedef pml4_t compat_pgd_t;
typedef pgd_t compat_pud_t;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
# define compat_p4d_offset(pgd, address) p4d_offset(pgd, address)
# define compat_p4d_present(p4d) p4d_present(p4d)
# define compat_p4d_large(p4d) p4d_large(p4d)
# define compat_p4d_pfn(p4d) p4d_pfn(p4d)
# define COMPAT_P4D_MASK P4D_MASK
typedef p4d_t compat_p4d_t;
#else
# define compat_pgd_offset(mm, address) pgd_offset(mm, address)
# define compat_pgd_present(pgd) pgd_present(pgd)
# define compat_pud_offset(pgd, address) (pgd)
# define compat_pud_present(pud) (1)
typedef pgd_t compat_pgd_t;
typedef pgd_t compat_pud_t;
# define compat_p4d_offset(pgd, address) (pgd)
# define compat_p4d_present(p4d) (1)
# define compat_p4d_large(p4d) (0)
# define compat_p4d_pfn(p4d) INVALID_MPN /* Not used */
# define COMPAT_P4D_MASK 0 /* Not used */
typedef pgd_t compat_p4d_t;
#endif
#define compat_pgd_offset_k(mm, address) pgd_offset_k(address)
/* Introduced somewhere in 2.6.0, + backported to some 2.4 RedHat kernels */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pte_pfn)
# define pte_pfn(pte) page_to_pfn(compat_pte_page(pte))
/* p[gu]d_large did not exist before 2.6.25 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
# define pud_large(pud) 0
# define pgd_large(pgd) 0
#endif
/* A page_table_lock field is added to struct mm_struct in 2.3.10 --hpreg */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 10)
# define compat_get_page_table_lock(_mm) (&(_mm)->page_table_lock)
#else
# define compat_get_page_table_lock(_mm) NULL
/* pud_pfn did not exist before 3.8. */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
# define pud_pfn(pud) INVALID_MPN
#endif
@@ -128,12 +80,8 @@ typedef pgd_t compat_pud_t;
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL
#endif
#else
#ifdef PAGE_KERNEL_EXECUTABLE
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXECUTABLE
#else
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXEC
#endif
#endif
#endif /* __COMPAT_PGTABLE_H__ */
+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)
+56 -296
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 2002,2014 VMware, Inc. All rights reserved.
* Copyright (C) 2002,2014-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
@@ -26,154 +26,14 @@
#include "compat_spinlock.h"
#include "compat_page.h"
/*
*-----------------------------------------------------------------------------
*
* PgtblPte2MPN --
*
* Returns the page structure associated to a Page Table Entry.
*
* This function is not allowed to schedule() because it can be called while
* holding a spinlock --hpreg
*
* Results:
* INVALID_MPN on failure
* mpn on success
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblPte2MPN(pte_t *pte) // IN
{
MPN mpn;
if (pte_present(*pte) == 0) {
return INVALID_MPN;
}
mpn = pte_pfn(*pte);
if (mpn >= INVALID_MPN) {
return INVALID_MPN;
}
return mpn;
}
/*
*-----------------------------------------------------------------------------
*
* PgtblPte2Page --
*
* Returns the page structure associated to a Page Table Entry.
*
* This function is not allowed to schedule() because it can be called while
* holding a spinlock --hpreg
*
* Results:
* The page structure if the page table entry points to a physical page
* NULL if the page table entry does not point to a physical page
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblPte2Page(pte_t *pte) // IN
{
if (pte_present(*pte) == 0) {
return NULL;
}
return compat_pte_page(*pte);
}
/*
*-----------------------------------------------------------------------------
*
* PgtblPGD2PTELocked --
*
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address.
*
* Results:
* pte. Caller must call pte_unmap if valid pte returned.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE pte_t *
PgtblPGD2PTELocked(compat_pgd_t *pgd, // IN: PGD to start with
VA addr) // IN: Address in the virtual address
// space of that process
{
compat_pud_t *pud;
pmd_t *pmd;
pte_t *pte;
if (compat_pgd_present(*pgd) == 0) {
return NULL;
}
pud = compat_pud_offset(pgd, addr);
if (compat_pud_present(*pud) == 0) {
return NULL;
}
pmd = pmd_offset_map(pud, addr);
if (pmd_present(*pmd) == 0) {
pmd_unmap(pmd);
return NULL;
}
pte = pte_offset_map(pmd, addr);
pmd_unmap(pmd);
return pte;
}
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2PTELocked --
*
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address.
*
* Results:
* pte. Caller must call pte_unmap if valid pte returned.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE pte_t *
PgtblVa2PTELocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
// space of that process
{
return PgtblPGD2PTELocked(compat_pgd_offset(mm, addr), addr);
}
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2MPNLocked --
*
* Retrieve MPN for a given va.
*
* Caller must call pte_unmap if valid pte returned. The mm->page_table_lock
* must be held, so this function is not allowed to schedule() --hpreg
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address. Then maps PTE to MPN.
*
* Results:
* INVALID_MPN on failure
@@ -188,89 +48,64 @@ PgtblVa2PTELocked(struct mm_struct *mm, // IN: Mm structure of a process
static INLINE MPN
PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
// space of that process
{
pte_t *pte;
pgd_t *pgd;
compat_p4d_t *p4d;
MPN mpn;
pte = PgtblVa2PTELocked(mm, addr);
if (pte != NULL) {
MPN mpn = PgtblPte2MPN(pte);
pte_unmap(pte);
return mpn;
pgd = pgd_offset(mm, addr);
if (pgd_present(*pgd) == 0) {
return INVALID_MPN;
}
return INVALID_MPN;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
/*
*-----------------------------------------------------------------------------
*
* PgtblKVa2MPNLocked --
*
* Retrieve MPN for a given kernel va.
*
* Caller must call pte_unmap if valid pte returned. The mm->page_table_lock
* must be held, so this function is not allowed to schedule() --hpreg
*
* Results:
* INVALID_MPN on failure
* mpn on success
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblKVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a caller
VA addr) // IN: Address in the virtual address
{
pte_t *pte;
pte = PgtblPGD2PTELocked(compat_pgd_offset_k(mm, addr), addr);
if (pte != NULL) {
MPN mpn = PgtblPte2MPN(pte);
pte_unmap(pte);
return mpn;
if (pgd_large(*pgd)) {
/* Linux kernel does not support PGD huge pages. */
/* return pgd_pfn(*pgd) + ((addr & PGD_MASK) >> PAGE_SHIFT); */
return INVALID_MPN;
}
return INVALID_MPN;
}
#endif
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2PageLocked --
*
* Return the "page" struct for a given va.
*
* Results:
* struct page or NULL. The mm->page_table_lock must be held, so this
* function is not allowed to schedule() --hpreg
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblVa2PageLocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
{
pte_t *pte;
pte = PgtblVa2PTELocked(mm, addr);
if (pte != NULL) {
struct page *page = PgtblPte2Page(pte);
pte_unmap(pte);
return page;
p4d = compat_p4d_offset(pgd, addr);
if (compat_p4d_present(*p4d) == 0) {
return INVALID_MPN;
}
if (compat_p4d_large(*p4d)) {
mpn = compat_p4d_pfn(*p4d) + ((addr & ~COMPAT_P4D_MASK) >> PAGE_SHIFT);
} else {
return NULL;
pud_t *pud;
pud = pud_offset(p4d, addr);
if (pud_present(*pud) == 0) {
return INVALID_MPN;
}
if (pud_large(*pud)) {
mpn = pud_pfn(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
} else {
pmd_t *pmd;
pmd = pmd_offset(pud, addr);
if (pmd_present(*pmd) == 0) {
return INVALID_MPN;
}
if (pmd_large(*pmd)) {
mpn = pmd_pfn(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
} else {
pte_t *pte;
pte = pte_offset_map(pmd, addr);
if (pte_present(*pte) == 0) {
pte_unmap(pte);
return INVALID_MPN;
}
mpn = pte_pfn(*pte);
pte_unmap(pte);
}
}
}
}
if (mpn >= INVALID_MPN) {
mpn = INVALID_MPN;
}
return mpn;
}
/*
@@ -298,85 +133,10 @@ PgtblVa2MPN(VA addr) // IN
/* current->mm is NULL for kernel threads, so use active_mm. */
mm = current->active_mm;
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
spin_lock(&mm->page_table_lock);
mpn = PgtblVa2MPNLocked(mm, addr);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
spin_unlock(&mm->page_table_lock);
return mpn;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
/*
*-----------------------------------------------------------------------------
*
* PgtblKVa2MPN --
*
* Walks through the hardware page tables of the current process to try to
* find the page structure associated to a virtual address.
*
* Results:
* Same as PgtblVa2MPNLocked()
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblKVa2MPN(VA addr) // IN
{
struct mm_struct *mm = current->active_mm;
MPN mpn;
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
mpn = PgtblKVa2MPNLocked(mm, addr);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
return mpn;
}
#endif
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2Page --
*
* Walks through the hardware page tables of the current process to try to
* find the page structure associated to a virtual address.
*
* Results:
* Same as PgtblVa2PageLocked()
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblVa2Page(VA addr) // IN
{
struct mm_struct *mm = current->active_mm;
struct page *page;
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
page = PgtblVa2PageLocked(mm, addr);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
return page;
}
#endif /* __PGTBL_H__ */
+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
+5 -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
@@ -79,6 +79,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,6 +107,7 @@ MSRQuery;
#define MSR_TSC_AUX 0xc0000103
#define MSR_BD_TSC_RATIO 0xc0000104
#define MSR_MISC_FEATURES_ENABLES 0x140
/* Intel Core Architecture and later: use only architected counters. */
@@ -342,6 +344,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.
+4 -7
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
@@ -1358,7 +1358,6 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
case IOCTL_VMX86_CREATE_VM:
case IOCTL_VMX86_INIT_CROSSGDT:
case IOCTL_VMX86_SET_UID:
case IOCTL_VMX86_LOOK_UP_MPN:
case IOCTL_VMX86_GET_NUM_VMS:
case IOCTL_VMX86_GET_TOTAL_MEM_USAGE:
case IOCTL_VMX86_SET_HARD_LIMIT:
@@ -1368,8 +1367,6 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
case IOCTL_VMX86_GET_KHZ_ESTIMATE:
case IOCTL_VMX86_GET_ALL_CPUID:
case IOCTL_VMX86_GET_ALL_MSRS:
case IOCTL_VMX86_READ_PAGE:
case IOCTL_VMX86_WRITE_PAGE:
case IOCTL_VMX86_SET_POLL_TIMEOUT_PTR:
case IOCTL_VMX86_GET_KERNEL_CLOCK_RATE:
case IOCTL_VMX86_GET_REFERENCE_CLOCK_HZ:
@@ -1530,7 +1527,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
args.ret.status = HostIF_LookupUserMPN(vm, args.uAddr, &args.ret.mpn);
args.ret.status = Vmx86_LookupUserMPN(vm, args.uAddr, &args.ret.mpn);
retval = HostIF_CopyToUser((void *)ioarg, &args, sizeof args);
break;
}
@@ -1849,7 +1846,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
retval = HostIF_ReadPage(req.mpn, req.uAddr, FALSE);
retval = HostIF_ReadPage(vm, req.mpn, req.uAddr, FALSE);
break;
}
@@ -1860,7 +1857,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
retval = HostIF_WritePage(req.mpn, req.uAddr, FALSE);
retval = HostIF_WritePage(vm, req.mpn, req.uAddr, FALSE);
break;
}
+119 -14
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2014 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
@@ -82,13 +82,13 @@
#include "x86apic.h"
#include "vm_asm.h"
#include "modulecall.h"
#include "driver.h"
#include "memtrack.h"
#include "phystrack.h"
#include "cpuid.h"
#include "cpuid_info.h"
#include "hostif.h"
#include "hostif_priv.h"
#include "driver.h"
#include "vmhost.h"
#include "x86msr.h"
#include "apic.h"
@@ -1009,7 +1009,7 @@ HostIF_FreeLockedPages(VMDriver *vm, // IN: VM instance pointer
int
HostIF_Init(VMDriver *vm) // IN:
{
vm->memtracker = MemTrack_Init();
vm->memtracker = MemTrack_Init(vm);
if (vm->memtracker == NULL) {
return -1;
}
@@ -2001,15 +2001,15 @@ HostIF_MapCrossPage(VMDriver *vm, // IN
return NULL;
}
vPgAddr = (VA) MapCrossPage(page);
HostIF_GlobalLock(16);
HostIF_VMLock(vm, 27);
if (vm->vmhost->crosspagePagesCount >= MAX_INITBLOCK_CPUS) {
HostIF_GlobalUnlock(16);
HostIF_VMUnlock(vm, 27);
UnmapCrossPage(page, (void*)vPgAddr);
return NULL;
}
vm->vmhost->crosspagePages[vm->vmhost->crosspagePagesCount++] = page;
HostIF_GlobalUnlock(16);
HostIF_VMUnlock(vm, 27);
ret = vPgAddr | (((VA)p) & (PAGE_SIZE - 1));
@@ -2817,13 +2817,75 @@ HostIF_CallOnEachCPU(void (*func)(void*), // IN: function to call
}
/*
*-----------------------------------------------------------------------------
*
* HostIFCheckTrackedMPN --
*
* Check if a given MPN is tracked for the specified VM.
*
* Result:
* TRUE if the MPN is tracked in one of the trackers for the specified VM,
* FALSE otherwise.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
HostIFCheckTrackedMPN(VMDriver *vm, // IN: The VM instance
MPN mpn) // IN: The MPN
{
VMHost * const vmh = vm->vmhost;
if (vmh == NULL) {
return FALSE;
}
HostIF_VMLock(vm, 32); // Debug version of PhysTrack wants VM's lock.
if (vmh->lockedPages) {
if (PhysTrack_Test(vmh->lockedPages, mpn)) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
if (vmh->AWEPages) {
if (PhysTrack_Test(vmh->AWEPages, mpn)) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
if (vm->memtracker) {
if (MemTrack_LookupMPN(vm->memtracker, mpn) != NULL) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
HostIF_VMUnlock(vm, 32);
if (vmx86_debug) {
/*
* The monitor may have old KSeg mappings to pages which it no longer
* owns. Minimize customer noise by only logging this for developers.
*/
Log("%s: MPN %" FMT64 "x not owned by this VM\n", __FUNCTION__, mpn);
}
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* HostIF_ReadPage --
*
* puts the content of a machine page into a kernel or user mode
* buffer.
* Reads one page of data from a machine page and returns it in the
* specified kernel or user buffer. The machine page must be owned by
* the specified VM.
*
* Results:
* 0 on success
@@ -2836,7 +2898,8 @@ HostIF_CallOnEachCPU(void (*func)(void*), // IN: function to call
*/
int
HostIF_ReadPage(MPN mpn, // MPN of the page
HostIF_ReadPage(VMDriver *vm, // IN: The VM instance
MPN mpn, // MPN of the page
VA64 addr, // buffer for data
Bool kernelBuffer) // is the buffer in kernel space?
{
@@ -2848,6 +2911,9 @@ HostIF_ReadPage(MPN mpn, // MPN of the page
if (mpn == INVALID_MPN) {
return -EFAULT;
}
if (HostIFCheckTrackedMPN(vm, mpn) == FALSE) {
return -EFAULT;
}
page = pfn_to_page(mpn);
ptr = kmap(page);
@@ -2871,8 +2937,8 @@ HostIF_ReadPage(MPN mpn, // MPN of the page
*
* HostIF_WritePage --
*
* Put the content of a kernel or user mode buffer into a machine
* page.
* Writes one page of data from a kernel or user buffer onto the specified
* machine page. The machine page must be owned by the specified VM.
*
* Results:
* 0 on success
@@ -2885,9 +2951,9 @@ HostIF_ReadPage(MPN mpn, // MPN of the page
*/
int
HostIF_WritePage(MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
HostIFWritePageWork(MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
{
void const *buf = VA64ToPtr(addr);
int ret = 0;
@@ -2914,6 +2980,45 @@ HostIF_WritePage(MPN mpn, // MPN of the page
return ret;
}
int
HostIF_WritePage(VMDriver *vm, // IN: The VM instance
MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
{
if (HostIFCheckTrackedMPN(vm, mpn) == FALSE) {
return -EFAULT;
}
return HostIFWritePageWork(mpn, addr, kernelBuffer);
}
/*
*-----------------------------------------------------------------------------
*
* HostIF_WriteMachinePage --
*
* Puts the content of a machine page into a kernel or user mode
* buffer. This should only be used for host-global pages, not any
* VM-owned pages.
*
* Results:
* On success: 0
* On failure: a negative error code
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
int
HostIF_WriteMachinePage(MPN mpn, // IN: MPN of the page
VA64 addr) // IN: data to write to the page
{
return HostIFWritePageWork(mpn, addr, TRUE);
}
/*
*----------------------------------------------------------------------
+3 -1
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2015 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
@@ -205,11 +205,13 @@ skipTaskSwitch:;
uint32 nPages = (uint32)crosspage->args[1];
VA64 uAddr = (VA64)VPN_2_VA(vpn);
ASSERT(nPages <= MODULECALL_NUM_ARGS);
HostIF_VMLock(vm, 38);
for (i = 0; i < nPages; i++) {
MPN mpn;
HostIF_LookupUserMPN(vm, uAddr + i * PAGE_SIZE, &mpn);
crosspage->args[i] = mpn;
}
HostIF_VMUnlock(vm, 38);
break;
}
+10 -5
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2013 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2013, 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
@@ -1104,7 +1104,7 @@ VNetBridgeNotifyLogBridgeUpError(int errno, // IN: the error number
case -ENODEV:
LOG(0, (KERN_WARNING "bridge-%s: interface %s not found or not "
"up\n", bridgeName, devName));
break;
break;
case -EINVAL:
LOG(0, (KERN_WARNING "bridge-%s: interface %s is not a valid "
"Ethernet interface\n", bridgeName, devName));
@@ -1143,11 +1143,16 @@ VNetBridgeNotifyLogBridgeUpError(int errno, // IN: the error number
static int
VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
u_long msg, // IN: type of event
void *data) // IN: device pertaining to event
void *data) // IN: net_device or notifier info
{
VNetBridge *bridge = list_entry(this, VNetBridge, notifier);
struct net_device *dev = (struct net_device *) data;
struct net_device *dev;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
dev = netdev_notifier_info_to_dev(data);
#else
dev = (struct net_device *)data;
#endif
switch (msg) {
case NETDEV_UNREGISTER:
LOG(2, (KERN_DEBUG "bridge-%s: interface %s is unregistering\n",
@@ -1179,7 +1184,7 @@ VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
LOG(1, (KERN_DEBUG "bridge-%s: enabling the bridge on dev up\n",
bridge->name));
errno = VNetBridgeUp(bridge, FALSE);
errno = VNetBridgeUp(bridge, FALSE);
if (errno != 0) {
VNetBridgeNotifyLogBridgeUpError(errno, bridge->name, dev->name);
}
+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)
+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