Files
vmware-host-modules/vmmon-only/include/monitorAction_exported.h
T

165 lines
4.7 KiB
C

/*********************************************************
* Copyright (C) 2010-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
* 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 _MONITORACTION_EXPORTED_H_
#define _MONITORACTION_EXPORTED_H_
#define INCLUDE_ALLOW_VMX
#define INCLUDE_ALLOW_VMCORE
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMKERNEL
#define INCLUDE_ALLOW_DISTRIBUTE
#include "includeCheck.h"
#include "vm_assert.h"
#include "vm_atomic.h"
#include "vm_basic_types.h"
#if defined __cplusplus
extern "C" {
#endif
/*
* Please bump the version number if your change will break the
* compatability to the drivers.
*/
#define ACTION_EXPORTED_VERSION 2
#define ACTION_WORD_SIZE (sizeof(uint64) * 8)
#define ACTION_NUM_WORDS (2)
#define ACTION_NUM_IDS (ACTION_NUM_WORDS * ACTION_WORD_SIZE)
#define MONACTION_INVALID MAX_UINT32
typedef uint32 MonitorIdemAction;
/*
* Representation of a set of actions.
*/
typedef struct MonitorActionSet {
volatile uint64 word[ACTION_NUM_WORDS];
} MonitorActionSet;
#ifndef __cplusplus
typedef enum MonitorActionSetName MonitorActionSetName;
#endif
/*
* Summary of action and interrupt states.
*/
typedef struct MonitorActionIntr {
MonitorActionSet pendingSet;
volatile Bool action;
Bool intr;
Bool nmi;
Bool db;
uint32 _pad;
} MonitorActionIntr;
/*
*------------------------------------------------------------------------
* MonitorActionSet_AtomicInclude --
*
* This function atomically adds an action to an action set.
*
* Results:
* TRUE if the action being added did not exist in the action set.
* FALSE otherwise.
*
* Side effects:
* The given action set will be updated.
*------------------------------------------------------------------------
*/
static INLINE Bool
MonitorActionSet_AtomicInclude(MonitorActionSet *set, const uint32 actionID)
{
Atomic_uint64 *atomicSet =
Atomic_VolatileToAtomic64(&set->word[actionID / ACTION_WORD_SIZE]);
uint64 mask = (uint64)1 << (actionID % ACTION_WORD_SIZE);
uint64 oldWord;
uint64 newWord;
ASSERT_ON_COMPILE((ACTION_WORD_SIZE & (ACTION_WORD_SIZE - 1)) == 0);
#ifdef VMX86_DEBUG
/* If ASSERT is not desirable, do explicit check. Please see PR 567811. */
#ifdef MODULE
if (UNLIKELY(actionID / ACTION_WORD_SIZE >= ACTION_NUM_WORDS)) {
return FALSE;
}
#else
ASSERT(actionID / ACTION_WORD_SIZE < ACTION_NUM_WORDS);
#endif // MODULE
#endif // VMX86_DEBUG
do {
oldWord = Atomic_Read64(atomicSet);
newWord = oldWord | mask;
} while (!Atomic_CMPXCHG64(atomicSet, oldWord, newWord));
return (oldWord & mask) == 0;
}
/*
*----------------------------------------------------------------------------
* MonitorAction_SetBits --
*
* The core logic for posting an action. Update the set of pending
* actions of the target VCPU in the shared area to mark the action
* as present. Make sure the bit is set in the pendingSet first to
* avoid a race with the drain loop.
*
* It's the responsibility of the callers to ensure that the change
* to actionIntr->action is globally visible before any IPI is sent
* (the change to pendingSet is pushed out by the cmpxchg in
* MonitorActionSet_AtomicInclude).
*
* Results:
* TRUE if the action being posted was not pending before.
* FALSE otherwise (other threads could have posted the same action).
*
* Side effects:
* None.
*----------------------------------------------------------------------------
*/
static INLINE Bool
MonitorAction_SetBits(MonitorActionIntr *actionIntr, MonitorIdemAction actionID)
{
/* Careful if optimizing this: see PR70016. */
Bool newAction =
MonitorActionSet_AtomicInclude(&actionIntr->pendingSet, actionID);
actionIntr->action = TRUE;
return newAction;
}
/*
* C1 states entered by monitor while waiting for an action
*/
typedef enum {
VMM_C1_STATE_INVALID = 0,
VMM_C1_STATE_HLT,
VMM_C1_STATE_MWAIT,
VMM_C1_STATE_PAUSE
} vmmC1StateType;
#if defined __cplusplus
} // extern "C"
#endif
#endif // _MONITORACTION_EXPORTED_H_