The HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY status indicates that the
hypervisor lacks sufficient contiguous memory for its internal allocations.

When this status is encountered, allocate and deposit
HV_MAX_CONTIGUOUS_ALLOCATION_PAGES contiguous pages to the hypervisor.
HV_MAX_CONTIGUOUS_ALLOCATION_PAGES is defined in the hypervisor headers, a
deposit of this size will always satisfy the hypervisor's requirements.

Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
 drivers/hv/hv_common.c      |    1 +
 drivers/hv/hv_proc.c        |    4 ++++
 include/hyperv/hvgdk_mini.h |    1 +
 include/hyperv/hvhdk_mini.h |    2 ++
 4 files changed, 8 insertions(+)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 0a3ab7efed46..c7f63c9de503 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -791,6 +791,7 @@ static const struct hv_status_info hv_status_infos[] = {
        _STATUS_INFO(HV_STATUS_UNKNOWN_PROPERTY,                -EIO),
        _STATUS_INFO(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE,     -EIO),
        _STATUS_INFO(HV_STATUS_INSUFFICIENT_MEMORY,             -ENOMEM),
+       _STATUS_INFO(HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY,  -ENOMEM),
        _STATUS_INFO(HV_STATUS_INVALID_PARTITION_ID,            -EINVAL),
        _STATUS_INFO(HV_STATUS_INVALID_VP_INDEX,                -EINVAL),
        _STATUS_INFO(HV_STATUS_NOT_FOUND,                       -EIO),
diff --git a/drivers/hv/hv_proc.c b/drivers/hv/hv_proc.c
index c0c2bfc80d77..ac21e16f9348 100644
--- a/drivers/hv/hv_proc.c
+++ b/drivers/hv/hv_proc.c
@@ -119,6 +119,9 @@ int hv_deposit_memory_node(int node, u64 partition_id,
        case HV_STATUS_INSUFFICIENT_MEMORY:
                num_pages = 1;
                break;
+       case HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY:
+               num_pages = HV_MAX_CONTIGUOUS_ALLOCATION_PAGES;
+               break;
        default:
                hv_status_err(hv_status, "Unexpected!\n");
                return -ENOMEM;
@@ -131,6 +134,7 @@ bool hv_result_oom(u64 status)
 {
        switch (hv_result(status)) {
        case HV_STATUS_INSUFFICIENT_MEMORY:
+       case HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY:
                return true;
        }
        return false;
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 04b18d0e37af..70f22ef44948 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -38,6 +38,7 @@ struct hv_u128 {
 #define HV_STATUS_INVALID_LP_INDEX                 0x41
 #define HV_STATUS_INVALID_REGISTER_VALUE           0x50
 #define HV_STATUS_OPERATION_FAILED                 0x71
+#define HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY    0x75
 #define HV_STATUS_TIME_OUT                         0x78
 #define HV_STATUS_CALL_PENDING                     0x79
 #define HV_STATUS_VTL_ALREADY_ENABLED              0x86
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 0f7178fa88a8..c5cfe13fae57 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -7,6 +7,8 @@
 
 #include "hvgdk_mini.h"
 
+#define HV_MAX_CONTIGUOUS_ALLOCATION_PAGES     8
+
 /*
  * Doorbell connection_info flags.
  */



Reply via email to