diff --git a/hw/acpi.c b/hw/acpi.c
index 7c4e8d3..8eb53da 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -840,7 +840,7 @@ struct acpi_table_header
 } __attribute__((packed));
 
 char *acpi_tables;
-size_t acpi_tables_len;
+size_t acpi_tables_len, acpi_tables_prev_len;
 
 static int acpi_checksum(const uint8_t *data, int len)
 {
@@ -851,13 +851,44 @@ static int acpi_checksum(const uint8_t *data, int len)
     return (-sum) & 0xff;
 }
 
-int acpi_table_add(const char *t)
+void *acpi_alloc_table(size_t size)
+{
+    void *ptr;
+
+    if (!acpi_tables) {
+        acpi_tables_len = sizeof(uint16_t);
+        acpi_tables = qemu_mallocz(acpi_tables_len);
+    }
+    acpi_tables_prev_len = acpi_tables_len;
+    acpi_tables_len += sizeof(uint16_t) + size;
+    acpi_tables = qemu_realloc(acpi_tables, acpi_tables_len);
+    ptr = acpi_tables + acpi_tables_prev_len;
+
+    *(uint16_t *) ptr = size;
+
+    return ptr + sizeof(uint16_t);
+}
+
+void acpi_commit_table(void *buf)
+{
+    struct acpi_table_header *acpi_hdr = buf;
+    size_t size = acpi_tables_len - acpi_tables_prev_len - sizeof(uint16_t);
+
+    acpi_hdr->length = cpu_to_le32(size);
+    acpi_hdr->checksum = acpi_checksum(buf, size);
+
+    /* increase number of tables */
+    (*(uint16_t *) acpi_tables) =
+	    cpu_to_le32(le32_to_cpu(*(uint16_t *) acpi_tables) + 1);
+}
+
+int acpi_table_cmdline_add(const char *t)
 {
     static const char *dfl_id = "QEMUQEMU";
     char buf[1024], *p, *f;
     struct acpi_table_header acpi_hdr;
     unsigned long val;
-    size_t newlen, off;
+    size_t size, off;
 
     memset(&acpi_hdr, 0, sizeof(acpi_hdr));
   
@@ -915,7 +946,7 @@ int acpi_table_add(const char *t)
          buf[0] = '\0';
     }
 
-    acpi_hdr.length = sizeof(acpi_hdr);
+    size = sizeof(acpi_hdr);
 
     f = buf;
     while (buf[0]) {
@@ -927,27 +958,17 @@ int acpi_table_add(const char *t)
             fprintf(stderr, "Can't stat file '%s': %s\n", f, strerror(errno));
             goto out;
         }
-        acpi_hdr.length += s.st_size;
+        size += s.st_size;
         if (!n)
             break;
         *n = ':';
         f = n + 1;
     }
 
-    if (!acpi_tables) {
-        acpi_tables_len = sizeof(uint16_t);
-        acpi_tables = qemu_mallocz(acpi_tables_len);
-    }
-    newlen = acpi_tables_len + sizeof(uint16_t) + acpi_hdr.length;
-    acpi_tables = qemu_realloc(acpi_tables, newlen);
-    p = acpi_tables + acpi_tables_len;
-    acpi_tables_len = newlen;
+    p = acpi_alloc_table(size);
+    off = sizeof(struct acpi_table_header);
 
-    acpi_hdr.length = cpu_to_le32(acpi_hdr.length);
-    *(uint16_t*)p = acpi_hdr.length;
-    p += sizeof(uint16_t);
-    memcpy(p, &acpi_hdr, sizeof(acpi_hdr));
-    off = sizeof(acpi_hdr);
+    memcpy(p, &acpi_hdr, off);
 
     f = buf;
     while (buf[0]) {
@@ -983,10 +1004,8 @@ int acpi_table_add(const char *t)
         f = n + 1;
     }
 
-    ((struct acpi_table_header*)p)->checksum = acpi_checksum((uint8_t*)p, off);
-    /* increase number of tables */
-    (*(uint16_t*)acpi_tables) =
-	    cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1);
+    acpi_commit_table(p);
+
     return 0;
 out:
     if (acpi_tables) {
@@ -995,3 +1014,4 @@ out:
     }
     return -1;
 }
+
diff --git a/hw/pc.h b/hw/pc.h
index b599564..0cef140 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -108,7 +108,9 @@ extern char *acpi_tables;
 extern size_t acpi_tables_len;
 
 void acpi_bios_init(void);
-int acpi_table_add(const char *table_desc);
+void *acpi_alloc_table(size_t size);
+void acpi_commit_table(void *buf);
+int acpi_table_cmdline_add(const char *table_desc);
 
 /* acpi_piix.c */
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
diff --git a/vl.c b/vl.c
index d959fdb..0efba90 100644
--- a/vl.c
+++ b/vl.c
@@ -5492,7 +5492,7 @@ int main(int argc, char **argv, char **envp)
                 rtc_td_hack = 1;
                 break;
             case QEMU_OPTION_acpitable:
-                if(acpi_table_add(optarg) < 0) {
+                if(acpi_table_cmdline_add(optarg) < 0) {
                     fprintf(stderr, "Wrong acpi table provided\n");
                     exit(1);
                 }
