9ae3a8
From e660f3651e349f658fe393917bab3ef8da44448c Mon Sep 17 00:00:00 2001
9ae3a8
From: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Date: Fri, 7 Nov 2014 17:18:10 +0100
9ae3a8
Subject: [PATCH 23/41] dump: eliminate DumpState.page_size ("guest's page
9ae3a8
 size")
9ae3a8
9ae3a8
Message-id: <1415380693-16593-24-git-send-email-lersek@redhat.com>
9ae3a8
Patchwork-id: 62211
9ae3a8
O-Subject: [RHEL-7.1 qemu-kvm PATCH 23/26] dump: eliminate DumpState.page_size ("guest's page size")
9ae3a8
Bugzilla: 1157798
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
9ae3a8
RH-Acked-by: dgibson <dgibson@redhat.com>
9ae3a8
9ae3a8
Use TARGET_PAGE_SIZE and ~TARGET_PAGE_MASK instead.
9ae3a8
9ae3a8
"DumpState.page_size" has type "size_t", whereas TARGET_PAGE_SIZE has type
9ae3a8
"int". TARGET_PAGE_MASK is of type "int" and has negative value. The patch
9ae3a8
affects the implicit type conversions as follows:
9ae3a8
9ae3a8
- create_header32() and create_header64(): assigned to "block_size", which
9ae3a8
  has type "uint32_t". No change.
9ae3a8
9ae3a8
- get_next_page(): "block->target_start", "block->target_end" and "addr"
9ae3a8
  have type "hwaddr" (uint64_t).
9ae3a8
9ae3a8
  Before the patch,
9ae3a8
  - if "size_t" was "uint64_t", then no additional conversion was done as
9ae3a8
    part of the usual arithmetic conversions,
9ae3a8
  - If "size_t" was "uint32_t", then it was widened to uint64_t as part of
9ae3a8
    the usual arithmetic conversions,
9ae3a8
  for the remainder and addition operators.
9ae3a8
9ae3a8
  After the patch,
9ae3a8
  - "~TARGET_PAGE_MASK" expands to  ~~((1 << TARGET_PAGE_BITS) - 1). It
9ae3a8
    has type "int" and positive value (only least significant bits set).
9ae3a8
    That's converted (widened) to "uint64_t" for the bit-ands. No visible
9ae3a8
    change.
9ae3a8
  - The same holds for the (addr + TARGET_PAGE_SIZE) addition.
9ae3a8
9ae3a8
- write_dump_pages():
9ae3a8
  - TARGET_PAGE_SIZE passed as argument to a bunch of functions that all
9ae3a8
    have prototypes. No change.
9ae3a8
9ae3a8
  - When incrementing "offset_data" (of type "off_t"): given that we never
9ae3a8
    build for ILP32_OFF32 (see "-D_FILE_OFFSET_BITS=64" in configure),
9ae3a8
    "off_t" is always "int64_t", and we only need to consider:
9ae3a8
    - ILP32_OFFBIG: "size_t" is "uint32_t".
9ae3a8
      - before: int64_t += uint32_t. Page size converted to int64_t for
9ae3a8
        the addition.
9ae3a8
      - after:  int64_t += int32_t. No change.
9ae3a8
    - LP64_OFF64: "size_t" is "uint64_t".
9ae3a8
      - before: int64_t += uint64_t. Offset converted to uint64_t for the
9ae3a8
        addition, then the uint64_t result is converted to int64_t for
9ae3a8
        storage.
9ae3a8
      - after:  int64_t += int32_t. Same as the ILP32_OFFBIG/after case.
9ae3a8
        No visible change.
9ae3a8
9ae3a8
  - (size_out < s->page_size) comparisons, and (size_out = s->page_size)
9ae3a8
    assignment:
9ae3a8
    - before: "size_out" is of type "size_t", no implicit conversion for
9ae3a8
              either operator.
9ae3a8
    - after: TARGET_PAGE_SIZE (of type "int" and positive value) is
9ae3a8
             converted to "size_t" (for the relop because the latter is
9ae3a8
             one of "uint32_t" and "uint64_t"). No visible change.
9ae3a8
9ae3a8
- dump_init():
9ae3a8
  - DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size): The
9ae3a8
    innermost "DumpState.max_mapnr" field has type uint64_t, which
9ae3a8
    propagates through all implicit conversions at hand:
9ae3a8
9ae3a8
    #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
9ae3a8
9ae3a8
    regardless of the page size macro argument's type. In the outer macro
9ae3a8
    replacement, the page size is converted from uint32_t and int32_t
9ae3a8
    alike to uint64_t.
9ae3a8
9ae3a8
  - (tmp * s->page_size) multiplication: "tmp" has size "uint64_t"; the
9ae3a8
    RHS is converted to that type from uint32_t and int32_t just the same
9ae3a8
    if it's not uint64_t to begin with.
9ae3a8
9ae3a8
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
9ae3a8
(cherry picked from commit 2f859f80c2077e00237ea1dfae2523ebd8377f5f)
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 dump.c | 51 +++++++++++++++++++++++++--------------------------
9ae3a8
 1 file changed, 25 insertions(+), 26 deletions(-)
9ae3a8
9ae3a8
diff --git a/dump.c b/dump.c
9ae3a8
index bc82b55..f8e0fd7 100644
9ae3a8
--- a/dump.c
9ae3a8
+++ b/dump.c
9ae3a8
@@ -90,7 +90,6 @@ typedef struct DumpState {
9ae3a8
     uint8_t *note_buf;          /* buffer for notes */
9ae3a8
     size_t note_buf_offset;     /* the writing place in note_buf */
9ae3a8
     uint32_t nr_cpus;           /* number of guest's cpu */
9ae3a8
-    size_t page_size;           /* guest's page size */
9ae3a8
     uint64_t max_mapnr;         /* the biggest guest's phys-mem's number */
9ae3a8
     size_t len_dump_bitmap;     /* the size of the place used to store
9ae3a8
                                    dump_bitmap in vmcore */
9ae3a8
@@ -811,7 +810,7 @@ static int create_header32(DumpState *s)
9ae3a8
 
9ae3a8
     strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
9ae3a8
     dh->header_version = cpu_convert_to_target32(6, endian);
9ae3a8
-    block_size = s->page_size;
9ae3a8
+    block_size = TARGET_PAGE_SIZE;
9ae3a8
     dh->block_size = cpu_convert_to_target32(block_size, endian);
9ae3a8
     sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
9ae3a8
     sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
9ae3a8
@@ -918,7 +917,7 @@ static int create_header64(DumpState *s)
9ae3a8
 
9ae3a8
     strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
9ae3a8
     dh->header_version = cpu_convert_to_target32(6, endian);
9ae3a8
-    block_size = s->page_size;
9ae3a8
+    block_size = TARGET_PAGE_SIZE;
9ae3a8
     dh->block_size = cpu_convert_to_target32(block_size, endian);
9ae3a8
     sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
9ae3a8
     sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
9ae3a8
@@ -1089,8 +1088,8 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
9ae3a8
     if (!block) {
9ae3a8
         block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
9ae3a8
         *blockptr = block;
9ae3a8
-        assert(block->target_start % s->page_size == 0);
9ae3a8
-        assert(block->target_end % s->page_size == 0);
9ae3a8
+        assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
9ae3a8
+        assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
9ae3a8
         *pfnptr = paddr_to_pfn(block->target_start);
9ae3a8
         if (bufptr) {
9ae3a8
             *bufptr = block->host_addr;
9ae3a8
@@ -1102,7 +1101,7 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
9ae3a8
     addr = pfn_to_paddr(*pfnptr);
9ae3a8
 
9ae3a8
     if ((addr >= block->target_start) &&
9ae3a8
-        (addr + s->page_size <= block->target_end)) {
9ae3a8
+        (addr + TARGET_PAGE_SIZE <= block->target_end)) {
9ae3a8
         buf = block->host_addr + (addr - block->target_start);
9ae3a8
     } else {
9ae3a8
         /* the next page is in the next block */
9ae3a8
@@ -1111,8 +1110,8 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
9ae3a8
         if (!block) {
9ae3a8
             return false;
9ae3a8
         }
9ae3a8
-        assert(block->target_start % s->page_size == 0);
9ae3a8
-        assert(block->target_end % s->page_size == 0);
9ae3a8
+        assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
9ae3a8
+        assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
9ae3a8
         *pfnptr = paddr_to_pfn(block->target_start);
9ae3a8
         buf = block->host_addr;
9ae3a8
     }
9ae3a8
@@ -1297,7 +1296,7 @@ static int write_dump_pages(DumpState *s)
9ae3a8
     prepare_data_cache(&page_data, s, offset_data);
9ae3a8
 
9ae3a8
     /* prepare buffer to store compressed data */
9ae3a8
-    len_buf_out = get_len_buf_out(s->page_size, s->flag_compress);
9ae3a8
+    len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress);
9ae3a8
     if (len_buf_out == 0) {
9ae3a8
         dump_error(s, "dump: failed to get length of output buffer.\n");
9ae3a8
         goto out;
9ae3a8
@@ -1313,19 +1312,19 @@ static int write_dump_pages(DumpState *s)
9ae3a8
      * init zero page's page_desc and page_data, because every zero page
9ae3a8
      * uses the same page_data
9ae3a8
      */
9ae3a8
-    pd_zero.size = cpu_convert_to_target32(s->page_size, endian);
9ae3a8
+    pd_zero.size = cpu_convert_to_target32(TARGET_PAGE_SIZE, endian);
9ae3a8
     pd_zero.flags = cpu_convert_to_target32(0, endian);
9ae3a8
     pd_zero.offset = cpu_convert_to_target64(offset_data, endian);
9ae3a8
     pd_zero.page_flags = cpu_convert_to_target64(0, endian);
9ae3a8
-    buf = g_malloc0(s->page_size);
9ae3a8
-    ret = write_cache(&page_data, buf, s->page_size, false);
9ae3a8
+    buf = g_malloc0(TARGET_PAGE_SIZE);
9ae3a8
+    ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
9ae3a8
     g_free(buf);
9ae3a8
     if (ret < 0) {
9ae3a8
         dump_error(s, "dump: failed to write page data(zero page).\n");
9ae3a8
         goto out;
9ae3a8
     }
9ae3a8
 
9ae3a8
-    offset_data += s->page_size;
9ae3a8
+    offset_data += TARGET_PAGE_SIZE;
9ae3a8
 
9ae3a8
     /*
9ae3a8
      * dump memory to vmcore page by page. zero page will all be resided in the
9ae3a8
@@ -1333,7 +1332,7 @@ static int write_dump_pages(DumpState *s)
9ae3a8
      */
9ae3a8
     while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
9ae3a8
         /* check zero page */
9ae3a8
-        if (is_zero_page(buf, s->page_size)) {
9ae3a8
+        if (is_zero_page(buf, TARGET_PAGE_SIZE)) {
9ae3a8
             ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
9ae3a8
                               false);
9ae3a8
             if (ret < 0) {
9ae3a8
@@ -1354,8 +1353,9 @@ static int write_dump_pages(DumpState *s)
9ae3a8
              */
9ae3a8
              size_out = len_buf_out;
9ae3a8
              if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
9ae3a8
-                    (compress2(buf_out, (uLongf *)&size_out, buf, s->page_size,
9ae3a8
-                    Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) {
9ae3a8
+                 (compress2(buf_out, (uLongf *)&size_out, buf,
9ae3a8
+                            TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
9ae3a8
+                 (size_out < TARGET_PAGE_SIZE)) {
9ae3a8
                 pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,
9ae3a8
                                                    endian);
9ae3a8
                 pd.size  = cpu_convert_to_target32(size_out, endian);
9ae3a8
@@ -1367,9 +1367,9 @@ static int write_dump_pages(DumpState *s)
9ae3a8
                 }
9ae3a8
 #ifdef CONFIG_LZO
9ae3a8
             } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
9ae3a8
-                    (lzo1x_1_compress(buf, s->page_size, buf_out,
9ae3a8
+                    (lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out,
9ae3a8
                     (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
9ae3a8
-                    (size_out < s->page_size)) {
9ae3a8
+                    (size_out < TARGET_PAGE_SIZE)) {
9ae3a8
                 pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,
9ae3a8
                                                    endian);
9ae3a8
                 pd.size  = cpu_convert_to_target32(size_out, endian);
9ae3a8
@@ -1382,9 +1382,9 @@ static int write_dump_pages(DumpState *s)
9ae3a8
 #endif
9ae3a8
 #ifdef CONFIG_SNAPPY
9ae3a8
             } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
9ae3a8
-                    (snappy_compress((char *)buf, s->page_size,
9ae3a8
+                    (snappy_compress((char *)buf, TARGET_PAGE_SIZE,
9ae3a8
                     (char *)buf_out, &size_out) == SNAPPY_OK) &&
9ae3a8
-                    (size_out < s->page_size)) {
9ae3a8
+                    (size_out < TARGET_PAGE_SIZE)) {
9ae3a8
                 pd.flags = cpu_convert_to_target32(
9ae3a8
                                         DUMP_DH_COMPRESSED_SNAPPY, endian);
9ae3a8
                 pd.size  = cpu_convert_to_target32(size_out, endian);
9ae3a8
@@ -1398,13 +1398,13 @@ static int write_dump_pages(DumpState *s)
9ae3a8
             } else {
9ae3a8
                 /*
9ae3a8
                  * fall back to save in plaintext, size_out should be
9ae3a8
-                 * assigned to s->page_size
9ae3a8
+                 * assigned TARGET_PAGE_SIZE
9ae3a8
                  */
9ae3a8
                 pd.flags = cpu_convert_to_target32(0, endian);
9ae3a8
-                size_out = s->page_size;
9ae3a8
+                size_out = TARGET_PAGE_SIZE;
9ae3a8
                 pd.size = cpu_convert_to_target32(size_out, endian);
9ae3a8
 
9ae3a8
-                ret = write_cache(&page_data, buf, s->page_size, false);
9ae3a8
+                ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
9ae3a8
                 if (ret < 0) {
9ae3a8
                     dump_error(s, "dump: failed to write page data.\n");
9ae3a8
                     goto out;
9ae3a8
@@ -1616,13 +1616,12 @@ static int dump_init(DumpState *s, int fd, bool has_format,
9ae3a8
     }
9ae3a8
 
9ae3a8
     s->nr_cpus = nr_cpus;
9ae3a8
-    s->page_size = TARGET_PAGE_SIZE;
9ae3a8
 
9ae3a8
     get_max_mapnr(s);
9ae3a8
 
9ae3a8
     uint64_t tmp;
9ae3a8
-    tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
9ae3a8
-    s->len_dump_bitmap = tmp * s->page_size;
9ae3a8
+    tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE);
9ae3a8
+    s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;
9ae3a8
 
9ae3a8
     /* init for kdump-compressed format */
9ae3a8
     if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8