Skip to content
  • Laszlo Ersek's avatar
    2f859f80
    dump: eliminate DumpState.page_size ("guest's page size") · 2f859f80
    Laszlo Ersek authored
    
    
    Use TARGET_PAGE_SIZE and ~TARGET_PAGE_MASK instead.
    
    "DumpState.page_size" has type "size_t", whereas TARGET_PAGE_SIZE has type
    "int". TARGET_PAGE_MASK is of type "int" and has negative value. The patch
    affects the implicit type conversions as follows:
    
    - create_header32() and create_header64(): assigned to "block_size", which
      has type "uint32_t". No change.
    
    - get_next_page(): "block->target_start", "block->target_end" and "addr"
      have type "hwaddr" (uint64_t).
    
      Before the patch,
      - if "size_t" was "uint64_t", then no additional conversion was done as
        part of the usual arithmetic conversions,
      - If "size_t" was "uint32_t", then it was widened to uint64_t as part of
        the usual arithmetic conversions,
      for the remainder and addition operators.
    
      After the patch,
      - "~TARGET_PAGE_MASK" expands to  ~~((1 << TARGET_PAGE_BITS) - 1). It
        has type "int" and positive value (only least significant bits set).
        That's converted (widened) to "uint64_t" for the bit-ands. No visible
        change.
      - The same holds for the (addr + TARGET_PAGE_SIZE) addition.
    
    - write_dump_pages():
      - TARGET_PAGE_SIZE passed as argument to a bunch of functions that all
        have prototypes. No change.
    
      - When incrementing "offset_data" (of type "off_t"): given that we never
        build for ILP32_OFF32 (see "-D_FILE_OFFSET_BITS=64" in configure),
        "off_t" is always "int64_t", and we only need to consider:
        - ILP32_OFFBIG: "size_t" is "uint32_t".
          - before: int64_t += uint32_t. Page size converted to int64_t for
            the addition.
          - after:  int64_t += int32_t. No change.
        - LP64_OFF64: "size_t" is "uint64_t".
          - before: int64_t += uint64_t. Offset converted to uint64_t for the
            addition, then the uint64_t result is converted to int64_t for
            storage.
          - after:  int64_t += int32_t. Same as the ILP32_OFFBIG/after case.
            No visible change.
    
      - (size_out < s->page_size) comparisons, and (size_out = s->page_size)
        assignment:
        - before: "size_out" is of type "size_t", no implicit conversion for
                  either operator.
        - after: TARGET_PAGE_SIZE (of type "int" and positive value) is
                 converted to "size_t" (for the relop because the latter is
                 one of "uint32_t" and "uint64_t"). No visible change.
    
    - dump_init():
      - DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size): The
        innermost "DumpState.max_mapnr" field has type uint64_t, which
        propagates through all implicit conversions at hand:
    
        #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
    
        regardless of the page size macro argument's type. In the outer macro
        replacement, the page size is converted from uint32_t and int32_t
        alike to uint64_t.
    
      - (tmp * s->page_size) multiplication: "tmp" has size "uint64_t"; the
        RHS is converted to that type from uint32_t and int32_t just the same
        if it's not uint64_t to begin with.
    
    Signed-off-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
    2f859f80
    dump: eliminate DumpState.page_size ("guest's page size")
    Laszlo Ersek authored
    
    
    Use TARGET_PAGE_SIZE and ~TARGET_PAGE_MASK instead.
    
    "DumpState.page_size" has type "size_t", whereas TARGET_PAGE_SIZE has type
    "int". TARGET_PAGE_MASK is of type "int" and has negative value. The patch
    affects the implicit type conversions as follows:
    
    - create_header32() and create_header64(): assigned to "block_size", which
      has type "uint32_t". No change.
    
    - get_next_page(): "block->target_start", "block->target_end" and "addr"
      have type "hwaddr" (uint64_t).
    
      Before the patch,
      - if "size_t" was "uint64_t", then no additional conversion was done as
        part of the usual arithmetic conversions,
      - If "size_t" was "uint32_t", then it was widened to uint64_t as part of
        the usual arithmetic conversions,
      for the remainder and addition operators.
    
      After the patch,
      - "~TARGET_PAGE_MASK" expands to  ~~((1 << TARGET_PAGE_BITS) - 1). It
        has type "int" and positive value (only least significant bits set).
        That's converted (widened) to "uint64_t" for the bit-ands. No visible
        change.
      - The same holds for the (addr + TARGET_PAGE_SIZE) addition.
    
    - write_dump_pages():
      - TARGET_PAGE_SIZE passed as argument to a bunch of functions that all
        have prototypes. No change.
    
      - When incrementing "offset_data" (of type "off_t"): given that we never
        build for ILP32_OFF32 (see "-D_FILE_OFFSET_BITS=64" in configure),
        "off_t" is always "int64_t", and we only need to consider:
        - ILP32_OFFBIG: "size_t" is "uint32_t".
          - before: int64_t += uint32_t. Page size converted to int64_t for
            the addition.
          - after:  int64_t += int32_t. No change.
        - LP64_OFF64: "size_t" is "uint64_t".
          - before: int64_t += uint64_t. Offset converted to uint64_t for the
            addition, then the uint64_t result is converted to int64_t for
            storage.
          - after:  int64_t += int32_t. Same as the ILP32_OFFBIG/after case.
            No visible change.
    
      - (size_out < s->page_size) comparisons, and (size_out = s->page_size)
        assignment:
        - before: "size_out" is of type "size_t", no implicit conversion for
                  either operator.
        - after: TARGET_PAGE_SIZE (of type "int" and positive value) is
                 converted to "size_t" (for the relop because the latter is
                 one of "uint32_t" and "uint64_t"). No visible change.
    
    - dump_init():
      - DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size): The
        innermost "DumpState.max_mapnr" field has type uint64_t, which
        propagates through all implicit conversions at hand:
    
        #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
    
        regardless of the page size macro argument's type. In the outer macro
        replacement, the page size is converted from uint32_t and int32_t
        alike to uint64_t.
    
      - (tmp * s->page_size) multiplication: "tmp" has size "uint64_t"; the
        RHS is converted to that type from uint32_t and int32_t just the same
        if it's not uint64_t to begin with.
    
    Signed-off-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
Loading