diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 997d94c..a46b827 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -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;
diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
index fff0554..5e1fc60 100644
--- a/tools/libxl/libxl_arch.h
+++ b/tools/libxl/libxl_arch.h
@@ -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
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 5f5ff03..d842d88 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -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;
diff --git a/tools/libxl/libxl_arm.h b/tools/libxl/libxl_arm.h
index 7097def..8aef210 100644
--- a/tools/libxl/libxl_arm.h
+++ b/tools/libxl/libxl_arm.h
@@ -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)
 {
     /*
diff --git a/tools/libxl/libxl_arm_acpi.c b/tools/libxl/libxl_arm_acpi.c
index 6c713ac..db113db 100644
--- a/tools/libxl/libxl_arm_acpi.c
+++ b/tools/libxl/libxl_arm_acpi.c
@@ -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,
diff --git a/tools/libxl/libxl_arm_no_acpi.c b/tools/libxl/libxl_arm_no_acpi.c
index 88ebbb6..5dde0cd 100644
--- a/tools/libxl/libxl_arm_no_acpi.c
+++ b/tools/libxl/libxl_arm_no_acpi.c
@@ -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
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 2924629..d519c8d 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -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;
     }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index cb6d9e0..8366fee 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -128,6 +128,8 @@
 #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))
 
diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index 84493df..e1844c8 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -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,
