libxl/arm: Add the size of ACPI tables to maxmem
authorShannon Zhao <shannon.zhao@linaro.org>
Thu, 29 Sep 2016 01:19:02 +0000 (18:19 -0700)
committerWei Liu <wei.liu2@citrix.com>
Fri, 30 Sep 2016 10:47:27 +0000 (11:47 +0100)
Here it adds the ACPI tables size to set the target maxmem to avoid
providing less available memory for guest.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Wei Liu <wei.liu2@citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl_arch.h
tools/libxl/libxl_arm.c
tools/libxl/libxl_arm.h
tools/libxl/libxl_arm_acpi.c
tools/libxl/libxl_arm_no_acpi.c
tools/libxl/libxl_dom.c
tools/libxl/libxl_internal.h
tools/libxl/libxl_x86.c

index 997d94c4742dd4e99ced1efe5cc72f871b996aba..a46b82798e9f13f6f347c08b66698745584f74b4 100644 (file)
@@ -17,6 +17,7 @@
 #include "libxl_osdeps.h"
 
 #include "libxl_internal.h"
+#include "libxl_arch.h"
 
 #define PAGE_TO_MEMKB(pages) ((pages) * 4)
 #define BACKEND_STRING_SIZE 5
@@ -4022,10 +4023,11 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint64_t max_memkb)
 {
     GC_INIT(ctx);
     char *mem, *endptr;
-    uint64_t memorykb;
+    uint64_t memorykb, size;
     char *dompath = libxl__xs_get_dompath(gc, domid);
     int rc = 1;
     libxl__domain_userdata_lock *lock = NULL;
+    libxl_domain_config d_config;
 
     CTX_LOCK;
 
@@ -4051,11 +4053,24 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint64_t max_memkb)
              "memory_static_max must be greater than or or equal to memory_dynamic_max");
         goto out;
     }
-    rc = xc_domain_setmaxmem(ctx->xch, domid, max_memkb + LIBXL_MAXMEM_CONSTANT);
+
+    rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config);
+    if (rc < 0) {
+        LOGE(ERROR, "unable to retrieve domain configuration");
+        goto out;
+    }
+
+    rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
+    if (rc < 0) {
+        LOGE(ERROR, "Couldn't get arch extra constant memory size");
+        goto out;
+    }
+
+    rc = xc_domain_setmaxmem(ctx->xch, domid, max_memkb + size);
     if (rc != 0) {
         LOGE(ERROR,
              "xc_domain_setmaxmem domid=%d memkb=%"PRIu64" failed ""rc=%d\n",
-             domid, max_memkb + LIBXL_MAXMEM_CONSTANT, rc);
+             domid, max_memkb + size, rc);
         goto out;
     }
 
@@ -4149,7 +4164,7 @@ int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
 {
     GC_INIT(ctx);
     int rc, r, lrc, abort_transaction = 0;
-    uint64_t memorykb;
+    uint64_t memorykb, size;
     uint64_t videoram = 0;
     uint64_t current_target_memkb = 0, new_target_memkb = 0;
     uint64_t current_max_memkb = 0;
@@ -4160,6 +4175,7 @@ int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
     char *uuid;
     xs_transaction_t t;
     libxl__domain_userdata_lock *lock;
+    libxl_domain_config d_config;
 
     CTX_LOCK;
 
@@ -4169,6 +4185,18 @@ int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
         goto out_no_transaction;
     }
 
+    rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config);
+    if (rc < 0) {
+        LOGE(ERROR, "unable to retrieve domain configuration");
+        goto out_no_transaction;
+    }
+
+    rc = libxl__arch_extra_memory(gc, &d_config.b_info, &size);
+    if (rc < 0) {
+        LOGE(ERROR, "Couldn't get arch extra constant memory size");
+        goto out_no_transaction;
+    }
+
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
 
@@ -4246,13 +4274,12 @@ retry_transaction:
 
     if (enforce) {
         memorykb = new_target_memkb + videoram;
-        r = xc_domain_setmaxmem(ctx->xch, domid, memorykb +
-                LIBXL_MAXMEM_CONSTANT);
+        r = xc_domain_setmaxmem(ctx->xch, domid, memorykb + size);
         if (r != 0) {
             LOGE(ERROR,
                  "xc_domain_setmaxmem domid=%u memkb=%"PRIu64" failed ""rc=%d\n",
                  domid,
-                 memorykb + LIBXL_MAXMEM_CONSTANT,
+                 memorykb + size,
                  r);
             abort_transaction = 1;
             rc = ERROR_FAIL;
@@ -4261,12 +4288,12 @@ retry_transaction:
     }
 
     r = xc_domain_set_pod_target(ctx->xch, domid,
-            (new_target_memkb + LIBXL_MAXMEM_CONSTANT) / 4, NULL, NULL, NULL);
+            (new_target_memkb + size) / 4, NULL, NULL, NULL);
     if (r != 0) {
         LOGE(ERROR,
              "xc_domain_set_pod_target domid=%d, memkb=%"PRIu64" failed rc=%d\n",
              domid,
-             new_target_memkb / 4,
+             (new_target_memkb + size) / 4,
              r);
         abort_transaction = 1;
         rc = ERROR_FAIL;
index fff05548ef0cf89f2febca752c47235d72800b89..5e1fc6060eab06ed1bb5a5e2f018d44ef509fc83 100644 (file)
@@ -66,6 +66,11 @@ _hidden
 void libxl__arch_domain_build_info_acpi_setdefault(
                                         libxl_domain_build_info *b_info);
 
+_hidden
+int libxl__arch_extra_memory(libxl__gc *gc,
+                             const libxl_domain_build_info *info,
+                             uint64_t *out);
+
 #if defined(__i386__) || defined(__x86_64__)
 
 #define LAPIC_BASE_ADDRESS  0xfee00000
index 5f5ff0366e9336ed52bc2a073f26a93fdf821fd5..d842d888ebcf8db33d139173986a1cd95010bb18 100644 (file)
@@ -106,6 +106,26 @@ int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
     return 0;
 }
 
+int libxl__arch_extra_memory(libxl__gc *gc,
+                             const libxl_domain_build_info *info,
+                             uint64_t *out)
+{
+    int rc = 0;
+    uint64_t size = 0;
+
+    if (libxl_defbool_val(info->acpi)) {
+        rc = libxl__get_acpi_size(gc, info, &size);
+        if (rc < 0) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+    }
+
+    *out = LIBXL_MAXMEM_CONSTANT + DIV_ROUNDUP(size, 1024);
+out:
+    return rc;
+}
+
 static struct arch_info {
     const char *guest_type;
     const char *timer_compat;
index 7097defad7a257aee3c184d5a5f2ef22c06018ec..8aef210d4ca0ae19d6306081cbee7383e5f2b7f0 100644 (file)
@@ -23,6 +23,11 @@ _hidden
 int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
                         struct xc_dom_image *dom);
 
+_hidden
+int libxl__get_acpi_size(libxl__gc *gc,
+                         const libxl_domain_build_info *info,
+                         uint64_t *out);
+
 static inline uint64_t libxl__compute_mpdir(unsigned int cpuid)
 {
     /*
index 6c713acd590763e1abe5d148a4e4c8c752666f88..db113dbf85efc7aee714cdec597e79ea6312b760 100644 (file)
@@ -94,6 +94,29 @@ static int libxl__estimate_madt_size(libxl__gc *gc,
     return rc;
 }
 
+int libxl__get_acpi_size(libxl__gc *gc,
+                         const libxl_domain_build_info *info,
+                         uint64_t *out)
+{
+    uint64_t size;
+    int rc = 0;
+
+
+    rc = libxl__estimate_madt_size(gc, info, &size);
+    if (rc < 0)
+        goto out;
+
+    *out = ROUNDUP(size, 3) +
+           ROUNDUP(sizeof(struct acpi_table_rsdp), 3) +
+           ROUNDUP(sizeof(struct acpi_table_xsdt), 3) +
+           ROUNDUP(sizeof(struct acpi_table_gtdt), 3) +
+           ROUNDUP(sizeof(struct acpi_table_fadt), 3) +
+           ROUNDUP(sizeof(dsdt_anycpu_arm_len), 3);
+
+out:
+    return rc;
+}
+
 static int libxl__allocate_acpi_tables(libxl__gc *gc,
                                        libxl_domain_build_info *info,
                                        struct xc_dom_image *dom,
index 88ebbb6662760388ae214dc2730e45ddad0b771e..5dde0cddee12148f0c37444eb52095e206e3d9aa 100644 (file)
@@ -24,6 +24,13 @@ int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
     return ERROR_FAIL;
 }
 
+int libxl__get_acpi_size(libxl__gc *gc,
+                         const libxl_domain_build_info *info,
+                         uint64_t *out)
+{
+    return ERROR_FAIL;
+}
+
 /*
  * Local variables:
  * mode: C
index 29246298ba42114587ec4e45e6d18b6206ef2398..d519c8d4408037d52542910a75b43c23edeed01a 100644 (file)
@@ -302,6 +302,7 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *xs_domid, *con_domid;
     int rc;
+    uint64_t size;
 
     if (xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus) != 0) {
         LOG(ERROR, "Couldn't set max vcpu count");
@@ -408,8 +409,14 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
         }
     }
 
-    if (xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb +
-        LIBXL_MAXMEM_CONSTANT) < 0) {
+
+    rc = libxl__arch_extra_memory(gc, info, &size);
+    if (rc < 0) {
+        LOGE(ERROR, "Couldn't get arch extra constant memory size");
+        return ERROR_FAIL;
+    }
+
+    if (xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + size) < 0) {
         LOGE(ERROR, "Couldn't set max memory");
         return ERROR_FAIL;
     }
index cb6d9e0c6bbb5fb7a4a1f8ec3b01541f0c3a4320..8366fee25f048cde6bab9f482efd31420c20f4b0 100644 (file)
 #define ROUNDUP(_val, _order)                                           \
     (((unsigned long)(_val)+(1UL<<(_order))-1) & ~((1UL<<(_order))-1))
 
+#define DIV_ROUNDUP(n, d) (((n) + (d) - 1) / (d))
+
 #define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m)))
 #define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m))
 
index 84493df8ef254598eaffe917a4fa50786d590269..e1844c859d35b8f1f87a546cbce8ca57aa6fb30c 100644 (file)
@@ -359,6 +359,15 @@ out:
     return ret;
 }
 
+int libxl__arch_extra_memory(libxl__gc *gc,
+                             const libxl_domain_build_info *info,
+                             uint64_t *out)
+{
+    *out = LIBXL_MAXMEM_CONSTANT;
+
+    return 0;
+}
+
 int libxl__arch_domain_init_hw_description(libxl__gc *gc,
                                            libxl_domain_build_info *info,
                                            libxl__domain_build_state *state,