diff options
| -rw-r--r-- | dump.c | 23 | ||||
| -rw-r--r-- | hw/tpm/tpm_crb.c | 14 | ||||
| -rw-r--r-- | linux-user/elfload.c | 49 | ||||
| -rw-r--r-- | scripts/dump-guest-memory.py | 7 |
4 files changed, 81 insertions, 12 deletions
diff --git a/dump.c b/dump.c index 6bdb0dbe23..669f715274 100644 --- a/dump.c +++ b/dump.c @@ -107,7 +107,7 @@ static int fd_write_vmcore(const void *buf, size_t size, void *opaque) written_size = qemu_write_full(s->fd, buf, size); if (written_size != size) { - return -1; + return -errno; } return 0; @@ -140,7 +140,7 @@ static void write_elf64_header(DumpState *s, Error **errp) ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s); if (ret < 0) { - error_setg(errp, "dump: failed to write elf header"); + error_setg_errno(errp, -ret, "dump: failed to write elf header"); } } @@ -171,7 +171,7 @@ static void write_elf32_header(DumpState *s, Error **errp) ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s); if (ret < 0) { - error_setg(errp, "dump: failed to write elf header"); + error_setg_errno(errp, -ret, "dump: failed to write elf header"); } } @@ -194,7 +194,8 @@ static void write_elf64_load(DumpState *s, MemoryMapping *memory_mapping, ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s); if (ret < 0) { - error_setg(errp, "dump: failed to write program header table"); + error_setg_errno(errp, -ret, + "dump: failed to write program header table"); } } @@ -217,7 +218,8 @@ static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping, ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s); if (ret < 0) { - error_setg(errp, "dump: failed to write program header table"); + error_setg_errno(errp, -ret, + "dump: failed to write program header table"); } } @@ -237,7 +239,8 @@ static void write_elf64_note(DumpState *s, Error **errp) ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s); if (ret < 0) { - error_setg(errp, "dump: failed to write program header table"); + error_setg_errno(errp, -ret, + "dump: failed to write program header table"); } } @@ -302,7 +305,8 @@ static void write_elf32_note(DumpState *s, Error **errp) ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s); if (ret < 0) { - error_setg(errp, "dump: failed to write program header table"); + error_setg_errno(errp, -ret, + "dump: failed to write program header table"); } } @@ -355,7 +359,8 @@ static void write_elf_section(DumpState *s, int type, Error **errp) ret = fd_write_vmcore(&shdr, shdr_size, s); if (ret < 0) { - error_setg(errp, "dump: failed to write section header table"); + error_setg_errno(errp, -ret, + "dump: failed to write section header table"); } } @@ -365,7 +370,7 @@ static void write_data(DumpState *s, void *buf, int length, Error **errp) ret = fd_write_vmcore(buf, length, s); if (ret < 0) { - error_setg(errp, "dump: failed to save memory"); + error_setg_errno(errp, -ret, "dump: failed to save memory"); } else { s->written_size += length; } diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c index d8917cb101..ef8b80e9aa 100644 --- a/hw/tpm/tpm_crb.c +++ b/hw/tpm/tpm_crb.c @@ -84,6 +84,12 @@ static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr, unsigned offset = addr & 3; uint32_t val = *(uint32_t *)regs >> (8 * offset); + switch (addr) { + case A_CRB_LOC_STATE: + val |= !tpm_backend_get_tpm_established_flag(s->tpmbe); + break; + } + trace_tpm_crb_mmio_read(addr, size, val); return val; @@ -137,6 +143,8 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr, /* not loc 3 or 4 */ break; case CRB_LOC_CTRL_RELINQUISH: + ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE, + locAssigned, 0); break; case CRB_LOC_CTRL_REQUEST_ACCESS: ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS, @@ -145,8 +153,6 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr, beenSeized, 0); ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE, locAssigned, 1); - ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE, - tpmRegValidSts, 1); break; } break; @@ -210,6 +216,10 @@ static void tpm_crb_reset(void *dev) tpm_backend_reset(s->tpmbe); + memset(s->regs, 0, sizeof(s->regs)); + + ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE, + tpmRegValidSts, 1); ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID, InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE); ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID, diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 4563a3190b..23e34957f9 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1889,6 +1889,55 @@ unsigned long init_guest_space(unsigned long host_start, /* Otherwise, a non-zero size region of memory needs to be mapped * and validated. */ + +#if defined(TARGET_ARM) && !defined(TARGET_AARCH64) + /* On 32-bit ARM, we need to map not just the usable memory, but + * also the commpage. Try to find a suitable place by allocating + * a big chunk for all of it. If host_start, then the naive + * strategy probably does good enough. + */ + if (!host_start) { + unsigned long guest_full_size, host_full_size, real_start; + + guest_full_size = + (0xffff0f00 & qemu_host_page_mask) + qemu_host_page_size; + host_full_size = guest_full_size - guest_start; + real_start = (unsigned long) + mmap(NULL, host_full_size, PROT_NONE, flags, -1, 0); + if (real_start == (unsigned long)-1) { + if (host_size < host_full_size - qemu_host_page_size) { + /* We failed to map a continous segment, but we're + * allowed to have a gap between the usable memory and + * the commpage where other things can be mapped. + * This sparseness gives us more flexibility to find + * an address range. + */ + goto naive; + } + return (unsigned long)-1; + } + munmap((void *)real_start, host_full_size); + if (real_start & ~qemu_host_page_mask) { + /* The same thing again, but with an extra qemu_host_page_size + * so that we can shift around alignment. + */ + unsigned long real_size = host_full_size + qemu_host_page_size; + real_start = (unsigned long) + mmap(NULL, real_size, PROT_NONE, flags, -1, 0); + if (real_start == (unsigned long)-1) { + if (host_size < host_full_size - qemu_host_page_size) { + goto naive; + } + return (unsigned long)-1; + } + munmap((void *)real_start, real_size); + real_start = HOST_PAGE_ALIGN(real_start); + } + current_start = real_start; + } + naive: +#endif + while (1) { unsigned long real_start, real_size, aligned_size; aligned_size = real_size = host_size; diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py index 51acfcd0c0..276eebf0c2 100644 --- a/scripts/dump-guest-memory.py +++ b/scripts/dump-guest-memory.py @@ -16,7 +16,12 @@ the COPYING file in the top-level directory. import ctypes import struct -UINTPTR_T = gdb.lookup_type("uintptr_t") +try: + UINTPTR_T = gdb.lookup_type("uintptr_t") +except Exception as inst: + raise gdb.GdbError("Symbols must be loaded prior to sourcing dump-guest-memory.\n" + "Symbols may be loaded by 'attach'ing a QEMU process id or by " + "'load'ing a QEMU binary.") TARGET_PAGE_SIZE = 0x1000 TARGET_PAGE_MASK = 0xFFFFFFFFFFFFF000 |