[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [XENBUS PATCH 1/4] Check for memory hypercall failure
On Wed, Aug 13, 2025 at 1:46 PM Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx> wrote:
XENMEM_decrease_reservation and XENMEM_populate_physmap can return a
negative value on failure. Add a check for these cases.
Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
include/xen.h | 18 ++++++++--------
src/xen/memory.c | 40 ++++++++++++++++++++++++++++++------
src/xenbus/balloon.c | 49 +++++++++++++++++++++++++++++---------------
src/xenbus/fdo.c | 24 ++++++++++++++++++----
4 files changed, 96 insertions(+), 35 deletions(-)
diff --git a/include/xen.h b/include/xen.h
index 6f28e55..7016c86 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -140,20 +140,22 @@ MemoryRemoveFromPhysmap(
_Check_return_
XEN_API
-ULONG
+NTSTATUS
MemoryDecreaseReservation(
- _In_ ULONG Order,
- _In_ ULONG Count,
- _In_ PPFN_NUMBER PfnArray
+ _In_ ULONG Order,
+ _In_ ULONG Count,
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Result
);
_Check_return_
XEN_API
-ULONG
+NTSTATUS
MemoryPopulatePhysmap(
- _In_ ULONG Order,
- _In_ ULONG Count,
- _In_ PPFN_NUMBER PfnArray
+ _In_ ULONG Order,
+ _In_ ULONG Count,
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Result
);
// EVENT CHANNEL
diff --git a/src/xen/memory.c b/src/xen/memory.c
index 6a3a3d0..114e9ac 100644
--- a/src/xen/memory.c
+++ b/src/xen/memory.c
@@ -112,15 +112,17 @@ fail1:
_Check_return_
XEN_API
-ULONG
+NTSTATUS
MemoryDecreaseReservation(
_In_ ULONG Order,
_In_ ULONG Count,
- _In_ PPFN_NUMBER PfnArray
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Result
)
{
struct xen_memory_reservation op;
LONG_PTR rc;
+ NTSTATUS status;
set_xen_guest_handle(op.extent_start, PfnArray);
op.extent_order = Order;
@@ -130,20 +132,34 @@ MemoryDecreaseReservation(
rc = MemoryOp(XENMEM_decrease_reservation, &op);
- return (ULONG)rc;
+ if (rc < 0) {
+ ERRNO_TO_STATUS(-rc, status);
+ goto fail1;
+ }
+
+ *Result = (ULONG)rc;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
}
_Check_return_
XEN_API
-ULONG
+NTSTATUS
MemoryPopulatePhysmap(
_In_ ULONG Order,
_In_ ULONG Count,
- _In_ PPFN_NUMBER PfnArray
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Result
)
{
struct xen_memory_reservation op;
LONG_PTR rc;
+ NTSTATUS status;
set_xen_guest_handle(op.extent_start, PfnArray);
op.extent_order = Order;
@@ -153,5 +169,17 @@ MemoryPopulatePhysmap(
rc = MemoryOp(XENMEM_populate_physmap, &op);
- return (ULONG)rc;
+ if (rc < 0) {
+ ERRNO_TO_STATUS(-rc, status);
+ goto fail1;
+ }
+
+ *Result = (ULONG)rc;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
}
diff --git a/src/xenbus/balloon.c b/src/xenbus/balloon.c
index 4affef5..fb4fceb 100644
--- a/src/xenbus/balloon.c
+++ b/src/xenbus/balloon.c
@@ -369,10 +369,11 @@ done:
return Count;
}
-static ULONG
+static NTSTATUS
BalloonPopulatePhysmap(
_In_ ULONG Requested,
- _In_ PPFN_NUMBER PfnArray
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Populated
)
{
LARGE_INTEGER Start;
@@ -380,12 +381,18 @@ BalloonPopulatePhysmap(
ULONGLONG TimeDelta;
ULONGLONG Rate;
ULONG Count;
+ NTSTATUS status;
ASSERT(Requested != 0);
KeQuerySystemTime(&Start);
- Count = MemoryPopulatePhysmap(PAGE_ORDER_4K, Requested, PfnArray);
+ status = MemoryPopulatePhysmap(PAGE_ORDER_4K,
+ Requested,
+ PfnArray,
+ &Count);
+ if (!NT_SUCCESS(status))
+ return status;
KeQuerySystemTime(&End);
TimeDelta = __max(((End.QuadPart - Start.QuadPart) / 10000ull), 1);
@@ -393,7 +400,8 @@ BalloonPopulatePhysmap(
Rate = (ULONGLONG)(Count * 1000) / TimeDelta;
Info("%u page(s) at %llu pages/s\n", Count, Rate);
- return Count;
+ *Populated = Count;
+ return STATUS_SUCCESS;
}
static ULONG
@@ -408,6 +416,7 @@ BalloonPopulatePfnArray(
ULONGLONG Rate;
ULONG Index;
ULONG Count;
+ NTSTATUS status;
ASSERT(Requested != 0);
ASSERT3U(Requested, <=, XENBUS_BALLOON_PFN_ARRAY_SIZE);
@@ -417,7 +426,6 @@ BalloonPopulatePfnArray(
for (Index = 0; Index < Requested; Index++) {
LONGLONG Pfn;
- NTSTATUS status;
status = XENBUS_RANGE_SET(Pop,
&Context->RangeSetInterface,
@@ -429,12 +437,12 @@ BalloonPopulatePfnArray(
Context->PfnArray[Index] = (PFN_NUMBER)Pfn;
}
- Count = BalloonPopulatePhysmap(Requested, Context->PfnArray);
+ status = BalloonPopulatePhysmap(Requested, Context->PfnArray, &Count);
+ if (!NT_SUCCESS(status))
+ Count = 0;
Index = Count;
while (Index < Requested) {
- NTSTATUS status;
-
status = XENBUS_RANGE_SET(Put,
&Context->RangeSetInterface,
Context->RangeSet,
@@ -456,10 +464,11 @@ BalloonPopulatePfnArray(
return Count;
}
-static ULONG
+static NTSTATUS
BalloonDecreaseReservation(
_In_ ULONG Requested,
- _In_ PPFN_NUMBER PfnArray
+ _In_ PPFN_NUMBER PfnArray,
+ _Out_ PULONG Decreased
)
{
LARGE_INTEGER Start;
@@ -467,12 +476,18 @@ BalloonDecreaseReservation(
ULONGLONG TimeDelta;
ULONGLONG Rate;
ULONG Count;
+ NTSTATUS status;
ASSERT(Requested != 0);
KeQuerySystemTime(&Start);
- Count = MemoryDecreaseReservation(PAGE_ORDER_4K, Requested, PfnArray);
+ status = MemoryDecreaseReservation(PAGE_ORDER_4K,
+ Requested,
+ PfnArray,
+ &Count);
+ if (!NT_SUCCESS(status))
+ return status;
KeQuerySystemTime(&End);
TimeDelta = __max(((End.QuadPart - Start.QuadPart) / 10000ull), 1);
@@ -480,7 +495,8 @@ BalloonDecreaseReservation(
Rate = (ULONGLONG)(Count * 1000) / TimeDelta;
Info("%u page(s) at %llu pages/s\n", Count, Rate);
- return Count;
+ *Decreased = Count;
+ return STATUS_SUCCESS;
}
static ULONG
@@ -495,6 +511,7 @@ BalloonReleasePfnArray(
ULONGLONG Rate;
ULONG Index;
ULONG Count;
+ NTSTATUS status;
ASSERT3U(Requested, <=, XENBUS_BALLOON_PFN_ARRAY_SIZE);
@@ -506,8 +523,6 @@ BalloonReleasePfnArray(
Index = 0;
while (Index < Requested) {
- NTSTATUS status;
-
status = XENBUS_RANGE_SET(Put,
&Context->RangeSetInterface,
Context->RangeSet,
@@ -520,13 +535,13 @@ BalloonReleasePfnArray(
}
Requested = Index;
- Count = BalloonDecreaseReservation(Requested, Context->PfnArray);
+ status = BalloonDecreaseReservation(Requested, Context->PfnArray, &Count);
+ if (!NT_SUCCESS(status))
+ Count = 0;
RtlZeroMemory(Context->PfnArray, Count * sizeof (PFN_NUMBER));
for (Index = Count; Index < Requested; Index++) {
- NTSTATUS status;
-
status = XENBUS_RANGE_SET(Get,
&Context->RangeSetInterface,
Context->RangeSet,
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 92a83b6..4e87727 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -3400,6 +3400,7 @@ FdoMemoryHoleAllocate(
{
PMDL Mdl;
PPFN_NUMBER PfnArray;
+ ULONG Decreased;
NTSTATUS status;
UNREFERENCED_PARAMETER(Fdo);
@@ -3412,12 +3413,21 @@ FdoMemoryHoleAllocate(
PfnArray = MmGetMdlPfnArray(Mdl);
- status = STATUS_UNSUCCESSFUL;
- if (MemoryDecreaseReservation(PAGE_ORDER_4K, Count, PfnArray) != Count)
+ status = MemoryDecreaseReservation(PAGE_ORDER_4K,
+ Count,
+ PfnArray,
+ &Decreased);
+ if (!NT_SUCCESS(status))
goto fail2;
+ status = STATUS_UNSUCCESSFUL;
+ if (Decreased != Count)
+ goto fail3;
+
return Mdl;
+fail3:
+
fail2:
Error("fail2\n");
@@ -3437,14 +3447,20 @@ FdoMemoryHoleFree(
{
ULONG Count;
PPFN_NUMBER PfnArray;
+ ULONG Populated;
+ NTSTATUS status;
UNREFERENCED_PARAMETER(Fdo);
Count = Mdl->ByteCount >> PAGE_SHIFT;
PfnArray = MmGetMdlPfnArray(Mdl);
- if (MemoryPopulatePhysmap(PAGE_ORDER_4K, Count, PfnArray) != Count)
- BUG("FAILED TO RE-POPULATE HOLE");
+ status = MemoryPopulatePhysmap(PAGE_ORDER_4K,
+ Count,
+ PfnArray,
+ &Populated);
+ BUG_ON(!NT_SUCCESS(status));
+ BUG_ON(Populated != Count);
__FreePages(Mdl);
}
--
2.50.1.windows.1
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|