[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XENBUS PATCH 1/4] Check for memory hypercall failure



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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.