/*
*-----------------------------------------------------------------------------
*
- * OS_ReservedPageGetPPN --
+ * OS_ReservedPageGetPA --
*
* Convert a page handle (of a physical page previously reserved with
- * OS_ReservedPageAlloc()) to a ppn.
+ * OS_ReservedPageAlloc()) to a pa.
*
* Results:
- * The ppn.
+ * The pa.
*
* Side effects:
* None.
*-----------------------------------------------------------------------------
*/
-PPN64
-OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
+PA64
+OS_ReservedPageGetPA(PageHandle handle) // IN: A valid page handle
{
- return (((vm_page_t)handle)->phys_addr) >> PAGE_SHIFT;
+ return (((vm_page_t)handle)->phys_addr);
}
*
* OS_ReservedPageGetHandle --
*
- * Convert a ppn (of a physical page previously reserved with
+ * Convert a pa (of a physical page previously reserved with
* OS_ReservedPageAlloc()) to a page handle.
*
* Results:
*/
PageHandle
-OS_ReservedPageGetHandle(PPN64 ppn) // IN
+OS_ReservedPageGetHandle(PA64 pa) // IN
{
- return (PageHandle)PHYS_TO_VM_PAGE(ppn << PAGE_SHIFT);
+ return (PageHandle)PHYS_TO_VM_PAGE(pa);
}
* Reserve a physical page for the exclusive use of this driver.
*
* Results:
- * On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
+ * On success: A valid page handle that can be passed to OS_ReservedPageGetPA()
* or OS_ReservedPageFree().
* On failure: PAGE_HANDLE_INVALID
*
status = bp.out.ax.word;
/*
- * If return code is BALLOON_SUCCESS_WITH_VERSION, then ESX is
- * sending the protocol version to be used into cx.
+ * If return code is BALLOON_SUCCESS_WITH_CAPABILITY, then ESX is
+ * sending the common capabilities supported by the monitor and the
+ * guest in cx.
*/
- if (status == BALLOON_SUCCESS_WITH_VERSION) {
- b->hypervisorProtocolVersion = bp.out.cx.word;
+ if (status == BALLOON_SUCCESS_WITH_CAPABILITIES) {
+ b->hypervisorCapabilities = bp.out.cx.word;
status = BALLOON_SUCCESS;
} else if (status == BALLOON_SUCCESS) {
- b->hypervisorProtocolVersion = BALLOON_PROTOCOL_VERSION_2;
+ b->hypervisorCapabilities = BALLOON_BASIC_CMDS;
}
/* update stats */
{
uint32 status;
Backdoor_proto bp;
+ uint32 ppn32 = (uint32)ppn;
- if (b->hypervisorProtocolVersion == BALLOON_PROTOCOL_VERSION_2) {
- /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
- uint32 ppn32 = (uint32)ppn;
- if (ppn32 != ppn) {
- return BALLOON_ERROR_PPN_INVALID;
- }
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
}
/* prepare backdoor args */
{
uint32 status;
Backdoor_proto bp;
+ uint32 ppn32 = (uint32)ppn;
- if (b->hypervisorProtocolVersion == BALLOON_PROTOCOL_VERSION_2) {
- /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
- uint32 ppn32 = (uint32)ppn;
- if (ppn32 != ppn) {
- return BALLOON_ERROR_PPN_INVALID;
- }
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
}
/* prepare backdoor args */
return status;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Backdoor_MonitorLockPagesBatched --
+ *
+ * Balloon all PPNs listed in the batch page.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Backdoor_MonitorLockPagesBatched(Balloon *b, // IN
+ PPN64 ppn, // IN
+ uint32 nPages) // IN
+{
+ uint32 status;
+ Backdoor_proto bp;
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_BATCHED_LOCK;
+ bp.in.size = (size_t)ppn;
+ bp.in.si.word = nPages;
+
+ /* invoke backdoor */
+ BackdoorBalloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.lock);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.lockFail);
+ }
+
+ return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Backdoor_MonitorUnlockPagesBatched --
+ *
+ * Unballoon all PPNs listed in the batch page.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Backdoor_MonitorUnlockPagesBatched(Balloon *b, // IN
+ PPN64 ppn, // IN
+ uint32 nPages) // IN
+{
+ uint32 status;
+ Backdoor_proto bp;
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_BATCHED_UNLOCK;
+ bp.in.size = (size_t)ppn;
+ bp.in.si.word = nPages;
+
+ /* invoke backdoor */
+ BackdoorBalloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.unlock);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.unlockFail);
+ }
+
+ return status;
+}
int Backdoor_MonitorGetTarget(Balloon *b, uint32 *target);
int Backdoor_MonitorLockPage(Balloon *b, PPN64 ppn);
int Backdoor_MonitorUnlockPage(Balloon *b, PPN64 ppn);
+int Backdoor_MonitorLockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages);
+int Backdoor_MonitorUnlockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages);
#endif /* _BACKDOOR_BALLOON_H_ */
#define BALLOON_NAME_VERBOSE "VMware memory control driver"
#if defined __linux__ || defined __FreeBSD__ || defined _WIN32
-#define BALLOON_PROTOCOL_VERSION BALLOON_PROTOCOL_VERSION_3
+/*
+ * FIXME: Even if the driver support batched commands keep using the
+ * non-batched one until more testing has been done.
+ */
+#define BALLOON_CAPABILITIES BALLOON_BASIC_CMDS
#else
-#define BALLOON_PROTOCOL_VERSION BALLOON_PROTOCOL_VERSION_2
+#define BALLOON_CAPABILITIES BALLOON_BASIC_CMDS
#endif
#define BALLOON_RATE_ADAPT 1
#define STATS_DEC(stat)
#endif
+#define PPN_2_PA(_ppn) ((_ppn) << PAGE_SHIFT)
+#define PA_2_PPN(_pa) ((_pa) >> PAGE_SHIFT)
+
#endif /* !BALLOONINT_H_ */
*********************************************************/
/*
- * balloon_def.h --
+ * balloon_def.h --
*
* Definitions for server "balloon" mechanism for reclaiming
* physical memory from a VM.
* constants
*/
-/* protocol versions */
-#define BALLOON_PROTOCOL_VERSION_2 (2)
-#define BALLOON_PROTOCOL_VERSION_3 (3)
-
/* backdoor port */
#define BALLOON_BDOOR_PORT (0x5670)
#define BALLOON_BDOOR_MAGIC (0x456c6d6f)
/*
* Backdoor commands availability:
*
- * +====================+===============+
- * | CMD | Protocol |
- * +--------------------+---------------+
- * | START | 2 (*) |
- * | TARGET | 2 |
- * | LOCK | 2 (*) |
- * | UNLOCK | 2 (*) |
- * | GUEST_ID | 2 |
- * +====================+===============+
- *
- * (*) The START, LOCK and UNLOCK has been slightly modified when
- * protocol v3 is used:
- * - START now returns BALLOON_SUCCESS_WITH_VERSION, with the protocol
- * version stored in %ecx, only if guest also support protocol v3 or
- * up.
- * - LOCK and UNLOCK are now taking a PPN of a page that contains a
- * BalloonBatchPage, instead of directly taking the PPN to
- * lock/unlock.
+ * +====================+======================+
+ * | CMD | Capabilities |
+ * +--------------------+----------------------+
+ * | START | Always available (*) |
+ * | TARGET | Always available |
+ * | LOCK | BASIC_CMDS |
+ * | UNLOCK | BASIC_CMDS |
+ * | GUEST_ID | Always available |
+ * | BATCHED_LOCK | BATCHED_CMDS |
+ * | BATCHED_UNLOCK | BATCHED_CMDS |
+ * +====================+======================+
+ *
+ * (*) The START command has been slightly modified when more than the
+ * basic commands are available: It returns
+ * BALLOON_SUCCESS_WITH_CAPABILITIES with the available capabilities
+ * stored in %ecx. Previously, a versioned protocol was used, and the
+ * protocol that should be used was also returned in %ecx. Protocol
+ * version 2 was the initial version and the only one shipped. Version 3
+ * was temporary used internally but has caused several issue due to
+ * protocol mismatch between monitor and guest.
*
*/
/* backdoor command numbers */
-#define BALLOON_BDOOR_CMD_START (0)
-#define BALLOON_BDOOR_CMD_TARGET (1)
-#define BALLOON_BDOOR_CMD_LOCK (2)
-#define BALLOON_BDOOR_CMD_UNLOCK (3)
-#define BALLOON_BDOOR_CMD_GUEST_ID (4)
+#define BALLOON_BDOOR_CMD_START (0)
+#define BALLOON_BDOOR_CMD_TARGET (1)
+#define BALLOON_BDOOR_CMD_LOCK (2)
+#define BALLOON_BDOOR_CMD_UNLOCK (3)
+#define BALLOON_BDOOR_CMD_GUEST_ID (4)
+/* The command 5 was shortly used between 1881144 and 1901153. */
+#define BALLOON_BDOOR_CMD_BATCHED_LOCK (6)
+#define BALLOON_BDOOR_CMD_BATCHED_UNLOCK (7)
+
+/* balloon capabilities */
+typedef enum {
+ /*
+ * Bit 0 is not used and shouldn't be used, due to issue with
+ * protocol v3, to avoid ambiguity between protocol v3 and
+ * capabilities, leave this bit as 0. That way, by masking guest
+ * capabilities with monitor capabilities, bit 0 will always be set
+ * to 0, and buggy v3 tool will automatically switch to unbatched
+ * LOCK and UNLOCK.
+ */
+ BALLOON_BASIC_CMDS = (1 << 1),
+ BALLOON_BATCHED_CMDS = (1 << 2)
+} BalloonCapabilities;
/* use config value for max balloon size */
#define BALLOON_MAX_SIZE_USE_CONFIG (0)
} BalloonGuest;
/* error codes */
-#define BALLOON_SUCCESS (0)
-#define BALLOON_FAILURE (-1)
-#define BALLOON_ERROR_CMD_INVALID (1)
-#define BALLOON_ERROR_PPN_INVALID (2)
-#define BALLOON_ERROR_PPN_LOCKED (3)
-#define BALLOON_ERROR_PPN_UNLOCKED (4)
-#define BALLOON_ERROR_PPN_PINNED (5)
-#define BALLOON_ERROR_PPN_NOTNEEDED (6)
-#define BALLOON_ERROR_RESET (7)
-#define BALLOON_ERROR_BUSY (8)
-/*
- * Sent on CMD_START to inform the guest to use the protocol v3 or
- * higher.
- */
-#define BALLOON_SUCCESS_WITH_VERSION (0x03000000)
+#define BALLOON_SUCCESS (0)
+#define BALLOON_FAILURE (-1)
+#define BALLOON_ERROR_CMD_INVALID (1)
+#define BALLOON_ERROR_PPN_INVALID (2)
+#define BALLOON_ERROR_PPN_LOCKED (3)
+#define BALLOON_ERROR_PPN_UNLOCKED (4)
+#define BALLOON_ERROR_PPN_PINNED (5)
+#define BALLOON_ERROR_PPN_NOTNEEDED (6)
+#define BALLOON_ERROR_RESET (7)
+#define BALLOON_ERROR_BUSY (8)
+
+#define BALLOON_SUCCESS_WITH_CAPABILITIES (0x03000000)
/*
* BatchPage.
*/
-#define BALLOON_BATCH_MAX_PAGES \
- ((PAGE_SIZE - sizeof(uint64)) / sizeof(PPN64))
-
-#define BALLOON_BATCH_STATUS_SHIFT 56
-
-typedef struct BalloonBatchPage {
- uint64 nPages;
- PPN64 pages[BALLOON_BATCH_MAX_PAGES];
-} BalloonBatchPage;
-
+#define BALLOON_BATCH_MAX_PAGES (PAGE_SIZE / sizeof(PA64))
/*
- *-----------------------------------------------------------------------------
+ * We are using the fact that for 4k pages, the 12LSB are set to 0, so
+ * we can use them and mask those bit when we need the real PA.
*
- * Balloon_BatchInit --
+ * +=============+==========+========+
+ * | | | |
+ * | Page number | Reserved | Status |
+ * | | | |
+ * +=============+==========+========+
+ * 64 PAGE_SHIFT 6 0
*
- * Results:
- * Return the number of pages that can be embedded inside the batch
- * page. If the protocol does not support batching, return 0.
+ * For now, only 4k pages are supported by the monitor, but by using
+ * reserved bit we can in the future add some flags that will indicate
+ * whether the page is a 2M page or a 1G page.
*
- * Side effects:
- * None.
+ * The reserved field should be set to 0.
*
- *-----------------------------------------------------------------------------
*/
-static INLINE uint16
-Balloon_BatchInit(uint32 protoVersion) // IN
-{
- switch (protoVersion) {
- case BALLOON_PROTOCOL_VERSION_3:
- return BALLOON_BATCH_MAX_PAGES;
- case BALLOON_PROTOCOL_VERSION_2:
- default:
- return 0;
- }
-}
-/*
- *-----------------------------------------------------------------------------
- *
- * Balloon_BatchGetNumPages --
- *
- * Return the number of pages contained in the batch page.
- *
- * Results:
- * See above.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-static INLINE uint64
-Balloon_BatchGetNumPages(BalloonBatchPage *batchPage) // IN
-{
- return batchPage->nPages;
-}
+#define BALLOON_BATCH_STATUS_MASK MASK64(5)
+#define BALLOON_BATCH_PAGE_MASK (~MASK64(PAGE_SHIFT))
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Balloon_BatchSetNumPages --
- *
- * Set the number of pages contained in the batch page.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-static INLINE void
-Balloon_BatchSetNumPages(BalloonBatchPage *batchPage, // IN
- uint64 nPages) // IN
-{
- ASSERT(nPages <= BALLOON_BATCH_MAX_PAGES);
- batchPage->nPages = nPages;
-}
+typedef struct BalloonBatchPage {
+ PA64 pages[BALLOON_BATCH_MAX_PAGES];
+} BalloonBatchPage;
/*
*-----------------------------------------------------------------------------
*
- * Balloon_BatchGetPPN --
+ * Balloon_BatchGetPA --
*
* Get the page stored in the batch page at idx.
*
*
*-----------------------------------------------------------------------------
*/
-static INLINE PPN64
-Balloon_BatchGetPPN(BalloonBatchPage *batchPage, // IN
- uint16 idx) // IN
+static INLINE PA64
+Balloon_BatchGetPA(BalloonBatchPage *batchPage, // IN
+ uint16 idx) // IN
{
- ASSERT(idx < batchPage->nPages);
- return batchPage->pages[idx] & MASK64(BALLOON_BATCH_STATUS_SHIFT);
+ ASSERT(idx < BALLOON_BATCH_MAX_PAGES);
+ return batchPage->pages[idx] & BALLOON_BATCH_PAGE_MASK;
}
Balloon_BatchGetStatus(BalloonBatchPage *batchPage, // IN
uint16 idx) // IN
{
- ASSERT(idx < batchPage->nPages);
- return (uint8)(batchPage->pages[idx] >> BALLOON_BATCH_STATUS_SHIFT);
+ ASSERT(idx < BALLOON_BATCH_MAX_PAGES);
+ return (uint8)(batchPage->pages[idx] & BALLOON_BATCH_STATUS_MASK);
}
/*
*-----------------------------------------------------------------------------
*
- * Balloon_BatchSetPPN --
+ * Balloon_BatchSetPA --
*
* Store the page in the batch page at idx.
*
*-----------------------------------------------------------------------------
*/
static INLINE void
-Balloon_BatchSetPPN(BalloonBatchPage *batchPage, // IN
- uint16 idx, // IN
- PPN64 ppn) // IN
+Balloon_BatchSetPA(BalloonBatchPage *batchPage, // IN
+ uint16 idx, // IN
+ PA64 pa) // IN
{
ASSERT(idx < BALLOON_BATCH_MAX_PAGES);
- batchPage->pages[idx] = ppn;
+ ASSERT((pa & ~BALLOON_BATCH_PAGE_MASK) == 0);
+ batchPage->pages[idx] = pa;
}
uint16 idx, // IN
int error) // IN
{
- PPN64 ppn;
-
+ PA64 pa = Balloon_BatchGetPA(batchPage, idx);
ASSERT(idx < BALLOON_BATCH_MAX_PAGES);
- ppn = Balloon_BatchGetPPN(batchPage, idx);
- ppn |= ((PPN64)error << BALLOON_BATCH_STATUS_SHIFT);
- batchPage->pages[idx] = ppn;
+ ASSERT(error <= BALLOON_ERROR_BUSY && error >= BALLOON_FAILURE);
+ batchPage->pages[idx] = pa | (PPN64)error;
}
MY_ASSERTS(BALLOON_BATCH_SIZE,
extern void OS_Yield(void);
extern unsigned long OS_ReservedPageGetLimit(void);
-extern PPN64 OS_ReservedPageGetPPN(PageHandle handle);
-extern PageHandle OS_ReservedPageGetHandle(PPN64 ppn);
+extern PA64 OS_ReservedPageGetPA(PageHandle handle);
+extern PageHandle OS_ReservedPageGetHandle(PA64 pa);
extern PageHandle OS_ReservedPageAlloc(int canSleep);
extern void OS_ReservedPageFree(PageHandle handle);
static int BalloonAdjustSize(Balloon *b, uint32 target);
static void BalloonReset(Balloon *b);
-static void BalloonAddPagev2(Balloon *b, uint16 idx, PageHandle page);
-static void BalloonAddPagev3(Balloon *b, uint16 idx, PageHandle page);
-static int BalloonLockv2(Balloon *b, uint16 nPages);
-static int BalloonLockv3(Balloon *b, uint16 nPages);
-static int BalloonUnlockv2(Balloon *b, uint16 nPages);
-static int BalloonUnlockv3(Balloon *b, uint16 nPages);
+static void BalloonAddPage(Balloon *b, uint16 idx, PageHandle page);
+static void BalloonAddPageBatched(Balloon *b, uint16 idx, PageHandle page);
+static int BalloonLock(Balloon *b, uint16 nPages);
+static int BalloonLockBatched(Balloon *b, uint16 nPages);
+static int BalloonUnlock(Balloon *b, uint16 nPages);
+static int BalloonUnlockBatched(Balloon *b, uint16 nPages);
/*
* Globals
static Balloon globalBalloon;
-static const BalloonOps balloonOpsv2 = {
- .addPage = BalloonAddPagev2,
- .lock = BalloonLockv2,
- .unlock = BalloonUnlockv2
+static const BalloonOps balloonOps = {
+ .addPage = BalloonAddPage,
+ .lock = BalloonLock,
+ .unlock = BalloonUnlock
};
-static const struct BalloonOps balloonOpsv3 = {
- .addPage = BalloonAddPagev3,
- .lock = BalloonLockv3,
- .unlock = BalloonUnlockv3
+static const struct BalloonOps balloonOpsBatched = {
+ .addPage = BalloonAddPageBatched,
+ .lock = BalloonLockBatched,
+ .unlock = BalloonUnlockBatched
};
/*
* BalloonChunk_Create --
*
* Creates a new BalloonChunk object capable of tracking
- * BALLOON_CHUNK_PAGES PPNs.
+ * BALLOON_CHUNK_PAGES PAs.
*
* We do not bother to define two versions (NOSLEEP and CANSLEEP)
* of OS_Malloc because Chunk_Create does not require a new page
}
/* Release the batch page */
- if (b->hypervisorProtocolVersion > BALLOON_PROTOCOL_VERSION_2) {
- if (b->batchPageMapping != MAPPING_INVALID) {
- OS_UnmapPage(b->batchPageMapping);
- b->batchPageMapping = MAPPING_INVALID;
- b->batchPage = NULL;
- }
+ if (b->batchPageMapping != MAPPING_INVALID) {
+ OS_UnmapPage(b->batchPageMapping);
+ b->batchPageMapping = MAPPING_INVALID;
+ b->batchPage = NULL;
+ }
- if (b->pageHandle != PAGE_HANDLE_INVALID) {
- OS_ReservedPageFree(b->pageHandle);
- b->pageHandle = PAGE_HANDLE_INVALID;
- }
+ if (b->pageHandle != PAGE_HANDLE_INVALID) {
+ OS_ReservedPageFree(b->pageHandle);
+ b->pageHandle = PAGE_HANDLE_INVALID;
}
}
static int
BalloonInitBatching(Balloon *b) // IN
{
- b->batchMaxPages = Balloon_BatchInit(b->hypervisorProtocolVersion);
- ASSERT(b->batchMaxPages != 0);
+ b->batchMaxPages = BALLOON_BATCH_MAX_PAGES;
b->pageHandle = OS_ReservedPageAlloc(BALLOON_PAGE_ALLOC_NOSLEEP);
if (b->pageHandle == PAGE_HANDLE_INVALID) {
/* free all pages, skipping monitor unlock */
Balloon_Deallocate(b);
- status = Backdoor_MonitorStart(b, BALLOON_PROTOCOL_VERSION);
+ status = Backdoor_MonitorStart(b, BALLOON_CAPABILITIES);
if (status != BALLOON_SUCCESS) {
return;
}
- if (b->hypervisorProtocolVersion > BALLOON_PROTOCOL_VERSION_2) {
+ if ((b->hypervisorCapabilities & BALLOON_BATCHED_CMDS) != 0) {
status = BalloonInitBatching(b);
if (status != BALLOON_SUCCESS) {
- status = Backdoor_MonitorStart(b, BALLOON_PROTOCOL_VERSION_2);
- if (status != BALLOON_SUCCESS) {
- return;
- }
+ /*
+ * We failed to initialize the batching in the guest, inform
+ * the monitor about that by sending a null capability.
+ *
+ * The guest will retry to init itself in one second.
+ */
+ Backdoor_MonitorStart(b, 0);
+ return;
}
}
- switch (b->hypervisorProtocolVersion) {
- case BALLOON_PROTOCOL_VERSION_3:
- b->balloonOps = &balloonOpsv3;
- break;
- case BALLOON_PROTOCOL_VERSION_2:
- default:
- b->balloonOps = &balloonOpsv2;
+ if ((b->hypervisorCapabilities & BALLOON_BATCHED_CMDS) != 0) {
+ b->balloonOps = &balloonOpsBatched;
+ } else if ((b->hypervisorCapabilities & BALLOON_BASIC_CMDS) != 0) {
+ b->balloonOps = &balloonOps;
b->batchMaxPages = 1;
- break;
}
/* clear flag */
/*
*----------------------------------------------------------------------
*
- * BalloonLockv3 --
+ * BalloonLockBatched --
*
* Lock all the batched page, previously stored by
- * BalloonAddPagev3.
+ * BalloonAddPageBatched.
*
* Results:
* BALLOON_SUCCESS or an error code.
*----------------------------------------------------------------------
*/
static int
-BalloonLockv3(Balloon *b, // IN
- uint16 nPages) // IN
+BalloonLockBatched(Balloon *b, // IN
+ uint16 nPages) // IN
{
int status;
uint32 i;
PPN64 batchPagePPN;
BalloonChunk *chunk = NULL;
- Balloon_BatchSetNumPages(b->batchPage, nPages);
- batchPagePPN = OS_ReservedPageGetPPN(b->pageHandle);
+ batchPagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
/*
* Make sure that we will always have an available chunk before doing
if (b->fallbackChunk == NULL) {
status = BALLOON_PAGE_ALLOC_FAILURE;
} else {
- status = Backdoor_MonitorLockPage(b, batchPagePPN);
+ status = Backdoor_MonitorLockPagesBatched(b, batchPagePPN, nPages);
}
if (status != BALLOON_SUCCESS) {
for (i = 0; i < nPages; i++) {
- PPN64 ppn = Balloon_BatchGetPPN(b->batchPage, i);
- handle = OS_ReservedPageGetHandle(ppn);
+ PA64 pa = Balloon_BatchGetPA(b->batchPage, i);
+ handle = OS_ReservedPageGetHandle(pa);
OS_ReservedPageFree(handle);
}
nLockedPages = 0;
for (i = 0; i < nPages; i++) {
- PPN64 ppn;
+ PA64 pa;
int error;
- ppn = Balloon_BatchGetPPN(b->batchPage, i);
- handle = OS_ReservedPageGetHandle(ppn);
+ pa = Balloon_BatchGetPA(b->batchPage, i);
+ handle = OS_ReservedPageGetHandle(pa);
error = Balloon_BatchGetStatus(b->batchPage, i);
if (error != BALLOON_SUCCESS) {
switch (error) {
/*
*----------------------------------------------------------------------
*
- * BalloonUnlockv3 --
+ * BalloonUnlockBatched --
*
* Unlock all the batched page, previously stored by
- * BalloonAddPagev3.
+ * BalloonAddPageBatched.
*
* Results:
* BALLOON_SUCCESS or an error code.
*----------------------------------------------------------------------
*/
static int
-BalloonUnlockv3(Balloon *b, // IN
- uint16 nPages) // IN
+BalloonUnlockBatched(Balloon *b, // IN
+ uint16 nPages) // IN
{
uint32 i;
int status = BALLOON_SUCCESS;
PPN64 batchPagePPN;
BalloonChunk *chunk = NULL;
- Balloon_BatchSetNumPages(b->batchPage, nPages);
- batchPagePPN = OS_ReservedPageGetPPN(b->pageHandle);
- status = Backdoor_MonitorUnlockPage(b, batchPagePPN);
+ batchPagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
+ status = Backdoor_MonitorUnlockPagesBatched(b, batchPagePPN, nPages);
if (status != BALLOON_SUCCESS) {
for (i = 0; i < nPages; i++) {
- PPN64 ppn = Balloon_BatchGetPPN(b->batchPage, i);
- PageHandle handle = OS_ReservedPageGetHandle(ppn);
+ PA64 pa = Balloon_BatchGetPA(b->batchPage, i);
+ PageHandle handle = OS_ReservedPageGetHandle(pa);
chunk = BalloonGetChunkOrFallback(b);
BalloonPageStore(chunk, handle);
nUnlockedPages = 0;
for (i = 0; i < nPages; i++) {
int status = Balloon_BatchGetStatus(b->batchPage, i);
- PPN64 ppn = Balloon_BatchGetPPN(b->batchPage, i);
- PageHandle handle = OS_ReservedPageGetHandle(ppn);
+ PA64 pa = Balloon_BatchGetPA(b->batchPage, i);
+ PageHandle handle = OS_ReservedPageGetHandle(pa);
if (status != BALLOON_SUCCESS) {
chunk = BalloonGetChunkOrFallback(b);
/*
*----------------------------------------------------------------------
*
- * BalloonAddPagev3 --
+ * BalloonAddPageBatched --
*
* Add a page to the batch page, that will be ballooned later.
*
*/
static void
-BalloonAddPagev3(Balloon *b, // IN
- uint16 idx, // IN
- PageHandle page) // IN
+BalloonAddPageBatched(Balloon *b, // IN
+ uint16 idx, // IN
+ PageHandle page) // IN
{
- PPN64 ppn = OS_ReservedPageGetPPN(page);
- Balloon_BatchSetPPN(b->batchPage, idx, ppn);
+ PA64 pa = OS_ReservedPageGetPA(page);
+ Balloon_BatchSetPA(b->batchPage, idx, pa);
}
/*
*----------------------------------------------------------------------
*
- * Balloonlockv2 --
+ * BalloonLock --
*
- * Lock a page, previously stored with a call to BalloonAddPagev2,
+ * Lock a page, previously stored with a call to BalloonAddPage,
* by notifying the monitor.
*
* Results:
*/
static int
-BalloonLockv2(Balloon *b, // IN
- uint16 nPages) // IN
+BalloonLock(Balloon *b, // IN
+ uint16 nPages) // IN
{
PPN pagePPN;
BalloonChunk *chunk;
}
/* inform monitor via backdoor */
- pagePPN = OS_ReservedPageGetPPN(b->pageHandle);
+ pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
status = Backdoor_MonitorLockPage(b, pagePPN);
if (status != BALLOON_SUCCESS) {
int old_status = status;
/*
*----------------------------------------------------------------------
*
- * BalloonUnlockv2 --
+ * BalloonUnlock --
*
* Unlock a page, previously stored with a call to
- * BalloonAddPagev2, by notifying the monitor.
+ * BalloonAddPage, by notifying the monitor.
*
* Results:
* BALLOON_SUCCESS or an error code.
*/
static int
-BalloonUnlockv2(Balloon *b, // IN
- uint16 nPages) // IN
+BalloonUnlock(Balloon *b, // IN
+ uint16 nPages) // IN
{
- PPN pagePPN = OS_ReservedPageGetPPN(b->pageHandle);
+ PPN pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
int status = Backdoor_MonitorUnlockPage(b, pagePPN);
if (status != BALLOON_SUCCESS) {
/*
*----------------------------------------------------------------------
*
- * BalloonAddPagev2 --
+ * BalloonAddPage --
*
* Add a page to be ballooned later.
*
*/
static void
-BalloonAddPagev2(Balloon *b, // IN
- uint16 idx, // IN
- PageHandle page) // IN
+BalloonAddPage(Balloon *b, // IN
+ uint16 idx, // IN
+ PageHandle page) // IN
{
b->pageHandle = page;
}
* Reset connection before deallocating memory to avoid potential for
* additional spurious resets from guest touching deallocated pages.
*/
- Backdoor_MonitorStart(b, BALLOON_PROTOCOL_VERSION);
+ Backdoor_MonitorStart(b, BALLOON_CAPABILITIES);
Balloon_Deallocate(b);
}
/* statistics */
BalloonStats stats;
- /* balloon protocol to use */
- uint32 hypervisorProtocolVersion;
+ /* hypervisor exposed capabilities */
+ BalloonCapabilities hypervisorCapabilities;
- /* balloon operations, tied to the protocol version */
+ /* balloon operations, tied to the capabilities */
const struct BalloonOps *balloonOps;
/* Either the batch page handle, or the page to lock on v2 */
/*
*-----------------------------------------------------------------------------
*
- * OS_ReservedPageGetPPN --
+ * OS_ReservedPageGetPA --
*
* Convert a page handle (of a physical page previously reserved with
- * OS_ReservedPageAlloc()) to a ppn.
+ * OS_ReservedPageAlloc()) to a pa.
*
* Results:
- * The ppn.
+ * The pa.
*
* Side effects:
* None.
*-----------------------------------------------------------------------------
*/
-PPN64
-OS_ReservedPageGetPPN(PageHandle handle) // IN: A valid page handle
+PA64
+OS_ReservedPageGetPA(PageHandle handle) // IN: A valid page handle
{
- return page_pptonum(((os_page *)handle)->pp);
+ return ptob(page_pptonum(((os_page *)handle)->pp));
}
*
* OS_ReservedPageGetHandle --
*
- * Convert a ppn (of a physical page previously reserved with
+ * Convert a pa (of a physical page previously reserved with
* OS_ReservedPageAlloc()) to a page handle.
*
* Results:
*/
PageHandle
-OS_ReservedPageGetHandle(PPN64 ppn) // IN
+OS_ReservedPageGetHandle(PA64 pa) // IN
{
- // Solaris does not use protocol v3.
+ // Solaris does not use batched commands.
NOT_IMPLEMENTED();
}
Mapping
OS_MapPageHandle(PageHandle handle) // IN
{
- // Solaris does not use protocol v3.
+ // Solaris does not use batched commands.
NOT_IMPLEMENTED();
}
void *
OS_Mapping2Addr(Mapping mapping) // IN
{
- // Solaris does not use protocol v3.
+ // Solaris does not use batched commands.
NOT_IMPLEMENTED();
}
* eliminate some of this.
*
* Results:
- * On success: A valid page handle that can be passed to OS_ReservedPageGetPPN()
+ * On success: A valid page handle that can be passed to OS_ReservedPageGetPA()
* or OS_ReservedPageFree().
* On failure: PAGE_HANDLE_INVALID
*