summaryrefslogtreecommitdiffstats
path: root/include/hw
diff options
context:
space:
mode:
authorPeter Maydell2019-08-21 10:00:49 +0200
committerPeter Maydell2019-08-21 10:00:49 +0200
commitf2cfa1229e539ee1bb1822912075cf25538ad6b9 (patch)
treeb0d325ec6f68410fd19615af2c47becdb365af07 /include/hw
parentMerge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2019-08-2... (diff)
parentx86: Intel AVX512_BF16 feature enabling (diff)
downloadqemu-f2cfa1229e539ee1bb1822912075cf25538ad6b9.tar.gz
qemu-f2cfa1229e539ee1bb1822912075cf25538ad6b9.tar.xz
qemu-f2cfa1229e539ee1bb1822912075cf25538ad6b9.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* New KVM PV features (Marcelo, Wanpeng) * valgrind fixes (Andrey) * Remove clock reset notifiers (David) * KConfig and Makefile cleanups (Paolo) * Replay and icount improvements (Pavel) * x86 FP fixes (Peter M.) * TCG locking assertions (Roman) * x86 support for mmap-ed -kernel/-initrd (Stefano) * Other cleanups (Wei Yang, Yan Zhao, Tony) * LSI fix for infinite loop (Prasad) * ARM migration fix (Catherine) * AVX512_BF16 feature (Jing) # gpg: Signature made Tue 20 Aug 2019 19:00:54 BST # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (33 commits) x86: Intel AVX512_BF16 feature enabling scsi: lsi: exit infinite loop while executing script (CVE-2019-12068) test-bitmap: test set 1 bit case for bitmap_set migration: do not rom_reset() during incoming migration HACKING: Document 'struct' keyword usage kvm: vmxcap: Enhance with latest features cpus-common: nuke finish_safe_work icount: remove unnecessary gen_io_end calls icount: clean up cpu_can_io at the entry to the block replay: rename step-related variables and functions replay: refine replay-time module replay: fix replay shutdown util/qemu-timer: refactor deadline calculation for external timers replay: document development rules replay: add missing fix for internal function timer: last, remove last bits of last replay: Remove host_clock_last timer: Remove reset notifiers mc146818rtc: Remove reset notifiers memory: fix race between TCG and accesses to dirty bitmap ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/elf_ops.h71
-rw-r--r--include/hw/i386/pc.h1
-rw-r--r--include/hw/loader.h5
3 files changed, 46 insertions, 31 deletions
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 690f9238c8..1496d7e753 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -323,8 +323,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
struct elfhdr ehdr;
struct elf_phdr *phdr = NULL, *ph;
int size, i, total_size;
- elf_word mem_size, file_size;
+ elf_word mem_size, file_size, data_offset;
uint64_t addr, low = (uint64_t)-1, high = 0;
+ GMappedFile *mapped_file = NULL;
uint8_t *data = NULL;
char label[128];
int ret = ELF_LOAD_FAILED;
@@ -409,20 +410,32 @@ static int glue(load_elf, SZ)(const char *name, int fd,
}
}
+ /*
+ * Since we want to be able to modify the mapped buffer, we set the
+ * 'writeble' parameter to 'true'. Modifications to the buffer are not
+ * written back to the file.
+ */
+ mapped_file = g_mapped_file_new_from_fd(fd, true, NULL);
+ if (!mapped_file) {
+ goto fail;
+ }
+
total_size = 0;
for(i = 0; i < ehdr.e_phnum; i++) {
ph = &phdr[i];
if (ph->p_type == PT_LOAD) {
mem_size = ph->p_memsz; /* Size of the ROM */
file_size = ph->p_filesz; /* Size of the allocated data */
- data = g_malloc0(file_size);
- if (ph->p_filesz > 0) {
- if (lseek(fd, ph->p_offset, SEEK_SET) < 0) {
- goto fail;
- }
- if (read(fd, data, file_size) != file_size) {
+ data_offset = ph->p_offset; /* Offset where the data is located */
+
+ if (file_size > 0) {
+ if (g_mapped_file_get_length(mapped_file) <
+ file_size + data_offset) {
goto fail;
}
+
+ data = (uint8_t *)g_mapped_file_get_contents(mapped_file);
+ data += data_offset;
}
/* The ELF spec is somewhat vague about the purpose of the
@@ -513,25 +526,25 @@ static int glue(load_elf, SZ)(const char *name, int fd,
*pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
}
- if (mem_size == 0) {
- /* Some ELF files really do have segments of zero size;
- * just ignore them rather than trying to create empty
- * ROM blobs, because the zero-length blob can falsely
- * trigger the overlapping-ROM-blobs check.
- */
- g_free(data);
- } else {
+ /* Some ELF files really do have segments of zero size;
+ * just ignore them rather than trying to create empty
+ * ROM blobs, because the zero-length blob can falsely
+ * trigger the overlapping-ROM-blobs check.
+ */
+ if (mem_size != 0) {
if (load_rom) {
snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
- /* rom_add_elf_program() seize the ownership of 'data' */
- rom_add_elf_program(label, data, file_size, mem_size,
- addr, as);
+ /*
+ * rom_add_elf_program() takes its own reference to
+ * 'mapped_file'.
+ */
+ rom_add_elf_program(label, mapped_file, data, file_size,
+ mem_size, addr, as);
} else {
address_space_write(as ? as : &address_space_memory,
addr, MEMTXATTRS_UNSPECIFIED,
data, file_size);
- g_free(data);
}
}
@@ -547,14 +560,16 @@ static int glue(load_elf, SZ)(const char *name, int fd,
struct elf_note *nhdr = NULL;
file_size = ph->p_filesz; /* Size of the range of ELF notes */
- data = g_malloc0(file_size);
- if (ph->p_filesz > 0) {
- if (lseek(fd, ph->p_offset, SEEK_SET) < 0) {
- goto fail;
- }
- if (read(fd, data, file_size) != file_size) {
+ data_offset = ph->p_offset; /* Offset where the notes are located */
+
+ if (file_size > 0) {
+ if (g_mapped_file_get_length(mapped_file) <
+ file_size + data_offset) {
goto fail;
}
+
+ data = (uint8_t *)g_mapped_file_get_contents(mapped_file);
+ data += data_offset;
}
/*
@@ -570,19 +585,17 @@ static int glue(load_elf, SZ)(const char *name, int fd,
sizeof(struct elf_note) == sizeof(struct elf64_note);
elf_note_fn((void *)nhdr, (void *)&ph->p_align, is64);
}
- g_free(data);
data = NULL;
}
}
- g_free(phdr);
if (lowaddr)
*lowaddr = (uint64_t)(elf_sword)low;
if (highaddr)
*highaddr = (uint64_t)(elf_sword)high;
- return total_size;
+ ret = total_size;
fail:
- g_free(data);
+ g_mapped_file_unref(mapped_file);
g_free(phdr);
return ret;
}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 4bb9e29114..2afe285009 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -41,6 +41,7 @@ struct PCMachineState {
FWCfgState *fw_cfg;
qemu_irq *gsi;
PFlashCFI01 *flash[2];
+ GMappedFile *initrd_mapped_file;
/* Configuration options: */
uint64_t max_ram_below_4g;
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 3e1b3a4566..07fd9286e7 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -258,8 +258,9 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
FWCfgCallback fw_callback,
void *callback_opaque, AddressSpace *as,
bool read_only);
-int rom_add_elf_program(const char *name, void *data, size_t datasize,
- size_t romsize, hwaddr addr, AddressSpace *as);
+int rom_add_elf_program(const char *name, GMappedFile *mapped_file, void *data,
+ size_t datasize, size_t romsize, hwaddr addr,
+ AddressSpace *as);
int rom_check_and_register_reset(void);
void rom_set_fw(FWCfgState *f);
void rom_set_order_override(int order);