/* format size info */
len += snprintf(buf + len, sizeof(buf) - len,
- "target: %8d pages\n"
- "current: %8d pages\n",
+ "target: %8"FMT64"u pages\n"
+ "current: %8"FMT64"u pages\n",
stats->nPagesTarget,
stats->nPages);
/*********************************************************
- * Copyright (C) 2012,2014 VMware, Inc. All rights reserved.
+ * Copyright (C) 2012,2014,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 Lesser General Public License as published
static int
BackdoorCmd(uint16 cmd, // IN
- size_t arg1, // IN
+ uint64 arg1, // IN
uint32 arg2, // IN
- uint32 *out, // OUT
+ uint64 *out, // OUT
int *resetFlag) // OUT
{
Backdoor_proto bp;
/* prepare backdoor args */
bp.in.cx.halfs.low = cmd;
- bp.in.size = arg1;
+ bp.in.size = (size_t)arg1;
+ ASSERT(bp.in.size == arg1);
bp.in.si.word = arg2;
/* invoke backdoor */
}
if (out) {
+#ifdef VM_X86_64
+ if (cmd == BALLOON_BDOOR_CMD_START) {
+ *out = bp.out.cx.quad;
+ } else {
+ *out = bp.out.bx.quad;
+ }
+#else
if (cmd == BALLOON_BDOOR_CMD_START) {
*out = bp.out.cx.word;
} else {
*out = bp.out.bx.word;
}
+#endif
}
return status;
Backdoor_MonitorStart(Balloon *b, // IN/OUT
uint32 protoVersion) // IN
{
- uint32 capabilities;
+ uint64 capabilities;
int status = BackdoorCmd(BALLOON_BDOOR_CMD_START, protoVersion, 0,
&capabilities, &b->resetFlag);
/*
}
+static Bool
+BackdoorHasCapability(Balloon *b,
+ uint32 capability)
+{
+ return (b->hypervisorCapabilities & capability) == capability;
+}
+
+
/*
*----------------------------------------------------------------------
*
int
Backdoor_MonitorGetTarget(Balloon *b, // IN/OUT
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
- unsigned long limit;
- uint32 limit32;
+ uint64 limit;
int status;
limit = OS_ReservedPageGetLimit();
- /* Ensure limit fits in 32-bits */
- limit32 = (uint32)limit;
- if (limit32 != limit) {
- return BALLOON_FAILURE;
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ uint32 limit32;
+ /* Ensure limit fits in 32-bits */
+ limit32 = (uint32)limit;
+ if (limit32 != limit) {
+ return BALLOON_FAILURE;
+ }
}
status = BackdoorCmd(BALLOON_BDOOR_CMD_TARGET, limit, 0, target,
&b->resetFlag);
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ *target = MAX(MAX_UINT32, *target);
+ }
+
/* update stats */
STATS_INC(b->stats.target);
if (status != BALLOON_SUCCESS) {
int
Backdoor_MonitorLockPage(Balloon *b, // IN/OUT
PPN64 ppn, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
int status;
- uint32 ppn32 = (uint32)ppn;
- /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
- if (ppn32 != ppn) {
- return BALLOON_ERROR_PPN_INVALID;
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ uint32 ppn32 = (uint32)ppn;
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
+ }
}
- status = BackdoorCmd(BALLOON_BDOOR_CMD_LOCK, ppn32, 0, target,
+ status = BackdoorCmd(BALLOON_BDOOR_CMD_LOCK, ppn, 0, target,
&b->resetFlag);
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ *target = MAX(MAX_UINT32, *target);
+ }
/* update stats */
STATS_INC(b->stats.lock[FALSE]);
int
Backdoor_MonitorUnlockPage(Balloon *b, // IN/OUT
PPN64 ppn, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
int status;
- uint32 ppn32 = (uint32)ppn;
- /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
- if (ppn32 != ppn) {
- return BALLOON_ERROR_PPN_INVALID;
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ uint32 ppn32 = (uint32)ppn;
+
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
+ }
}
- status = BackdoorCmd(BALLOON_BDOOR_CMD_UNLOCK, ppn32, 0, target,
+ status = BackdoorCmd(BALLOON_BDOOR_CMD_UNLOCK, ppn, 0, target,
&b->resetFlag);
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ *target = MAX(MAX_UINT32, *target);
+ }
/* update stats */
STATS_INC(b->stats.unlock[FALSE]);
PPN64 ppn, // IN
uint32 nPages, // IN
int isLargePage, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
int status;
uint16 cmd;
}
status = BackdoorCmd(cmd, (size_t)ppn, nPages, target, &b->resetFlag);
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ *target = MAX(MAX_UINT32, *target);
+ }
/* update stats */
STATS_INC(b->stats.lock[isLargePage]);
PPN64 ppn, // IN
uint32 nPages, // IN
int isLargePage, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
int status;
uint16 cmd;
}
status = BackdoorCmd(cmd, (size_t)ppn, nPages, target, &b->resetFlag);
+ if (!BackdoorHasCapability(b, BALLOON_64_BIT_TARGET)) {
+ *target = MAX(MAX_UINT32, *target);
+ }
/* update stats */
STATS_INC(b->stats.unlock[isLargePage]);
/*********************************************************
- * Copyright (C) 2007,2014 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007,2014,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 Lesser General Public License as published
int Backdoor_MonitorStart(Balloon *b, uint32 protoVersion);
int Backdoor_MonitorGuestType(Balloon *b);
-int Backdoor_MonitorGetTarget(Balloon *b, uint32 *target);
-int Backdoor_MonitorLockPage(Balloon *b, PPN64 ppn, uint32 *target);
-int Backdoor_MonitorUnlockPage(Balloon *b, PPN64 ppn, uint32 *target);
+int Backdoor_MonitorGetTarget(Balloon *b, uint64 *target);
+int Backdoor_MonitorLockPage(Balloon *b, PPN64 ppn, uint64 *target);
+int Backdoor_MonitorUnlockPage(Balloon *b, PPN64 ppn, uint64 *target);
int Backdoor_MonitorLockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages,
- int isLargePages, uint32 *target);
+ int isLargePages, uint64 *target);
int Backdoor_MonitorUnlockPagesBatched(Balloon *b, PPN64 ppn, uint32 nPages,
- int isLargePages, uint32 *target);
+ int isLargePages, uint64 *target);
#endif /* _BACKDOOR_BALLOON_H_ */
* Balloon operations
*/
static void BalloonPageFree(Balloon *b, int isLargePage);
-static void BalloonAdjustSize(Balloon *b, uint32 target);
+static void BalloonAdjustSize(Balloon *b, uint64 target);
static void BalloonReset(Balloon *b);
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, int isLargePage,
- uint32 *target);
+ uint64 *target);
static int BalloonLockBatched(Balloon *b, uint16 nPages, int isLargePages,
- uint32 *target);
+ uint64 *target);
static int BalloonUnlock(Balloon *b, uint16 nPages, int isLargePages,
- uint32 *target);
+ uint64 *target);
static int BalloonUnlockBatched(Balloon *b, uint16 nPages, int IsLargePages,
- uint32 *target);
+ uint64 *target);
/*
* Globals
Balloon_QueryAndExecute(void)
{
Balloon *b = &globalBalloon;
- uint32 target = 0; // Silence compiler warning.
+ uint64 target = 0; // Silence compiler warning.
int status;
/* update stats */
static void
BalloonInflate(Balloon *b, // IN/OUT
- uint32 target) // IN
+ uint64 target) // IN
{
uint32 nEntries;
unsigned int rate;
BalloonLockBatched(Balloon *b, // IN/OUT
uint16 nEntries, // IN
int isLargePages, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
int status;
uint32 i;
BalloonUnlockBatched(Balloon *b, // IN/OUT
uint16 nEntries, // IN
int isLargePages, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
uint32 i;
int status = BALLOON_SUCCESS;
BalloonLock(Balloon *b, // IN/OUT
uint16 nPages, // IN
int isLargePage, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
- PPNTMP pagePPN;
+ PPN64 pagePPN;
BalloonChunk *chunk;
int status;
BalloonUnlock(Balloon *b, // IN/OUT
uint16 nPages, // IN
int isLargePage, // IN
- uint32 *target) // OUT
+ uint64 *target) // OUT
{
- PPNTMP pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
+ PPN64 pagePPN = PA_2_PPN(OS_ReservedPageGetPA(b->pageHandle));
int status = Backdoor_MonitorUnlockPage(b, pagePPN, target);
ASSERT(!isLargePage);
static void
BalloonDeflateInt(Balloon *b, // IN/OUT
- uint32 target, // IN
+ uint64 target, // IN
int isLargePages) // IN
{
int status = BALLOON_SUCCESS;
static void
BalloonDeflate(Balloon *b, // IN/OUT
- uint32 target) // IN
+ uint64 target) // IN
{
/* Prefer to unlock small pages over unlocking large pages */
BalloonDeflateInt(b, target, FALSE);
static void
BalloonAdjustSize(Balloon *b, // IN/OUT
- uint32 target) // IN
+ uint64 target) // IN
{
/*
* When we only deal with large pages it can happen that we overshoot our
/*********************************************************
- * Copyright (C) 2000-2012,2014 VMware, Inc. All rights reserved.
+ * Copyright (C) 2000-2012,2014,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 Lesser General Public License as published
typedef struct {
/* current status */
- uint32 nPages;
- uint32 nPagesTarget;
+ uint64 nPages;
+ uint64 nPagesTarget;
/* adjustment rates */
uint32 rateNoSleepAlloc;
BalloonGuest guestType;
/* balloon size (in small pages) */
- int nPages;
+ uint64 nPages;
/* target balloon size (in small pages) */
- int nPagesTarget;
+ uint64 nPagesTarget;
/* reset flag */
int resetFlag;
typedef struct BalloonOps {
void (*addPage)(Balloon *b, uint16 idx, PageHandle entries);
- int (*lock)(Balloon *b, uint16 nPages, int isLargePages, uint32 *target);
- int (*unlock)(Balloon *b, uint16 nPages, int isLargePages, uint32 *target);
+ int (*lock)(Balloon *b, uint16 nPages, int isLargePages, uint64 *target);
+ int (*unlock)(Balloon *b, uint16 nPages, int isLargePages, uint64 *target);
} BalloonOps;
/*