diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-02-05 19:39:22 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-02-05 19:39:22 +0000 |
commit | 3e29da9fd81002a0c03041aaa26dea6d9dd9bd65 (patch) | |
tree | acd21f31ace26a41b261fe462ae26c782ffb42d2 /include/hw | |
parent | 47994e16b1d66411953623e7c0bf0cdcd50bd507 (diff) | |
parent | 5ed76a4c63db9295c6c5d67895925810050d4a46 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* cpu-exec fixes (Emilio, Laurent)
* TCG bugfix in queue.h (Paolo)
* high address load for linuxboot (Zhijian)
* PVH support (Liam, Stefano)
* misc i386 changes (Paolo, Robert, Doug)
* configure tweak for openpty (Thomas)
* elf2dmp port to Windows (Viktor)
* initial improvements to Makefile infrastructure (Yang + GSoC 2013)
# gpg: Signature made Tue 05 Feb 2019 17:34:42 GMT
# 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: (76 commits)
queue: fix QTAILQ_FOREACH_REVERSE_SAFE
scsi-generic: Convert from DPRINTF() macro to trace events
scsi-disk: Convert from DPRINTF() macro to trace events
pc: Use hotplug_handler_(plug|unplug|unplug_request)
i386: hvf: Fix smp boot hangs
hw/vfio/Makefile.objs: Create new CONFIG_* variables for VFIO core and PCI
hw/i2c/Makefile.objs: Create new CONFIG_* variables for EEPROM and ACPI controller
hw/tricore/Makefile.objs: Create CONFIG_* for tricore
hw/openrisc/Makefile.objs: Create CONFIG_* for openrisc
hw/moxie/Makefile.objs: Conditionally build moxie
hw/hppa/Makefile.objs: Create CONFIG_* for hppa
hw/cris/Makefile.objs: Create CONFIG_* for cris
hw/alpha/Makefile.objs: Create CONFIG_* for alpha
hw/sparc64/Makefile.objs: Create CONFIG_* for sparc64
hw/riscv/Makefile.objs: Create CONFIG_* for riscv boards
hw/nios2/Makefile.objs: Conditionally build nios2
hw/xtensa/Makefile.objs: Build xtensa_sim and xtensa_fpga conditionally
hw/lm32/Makefile.objs: Conditionally build lm32 and milkmyst
hw/sparc/Makefile.objs: CONFIG_* for sun4m and leon3 created
hw/s390/Makefile.objs: Create new CONFIG_* variables for s390x boards and devices
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
# Conflicts:
# qemu-deprecated.texi
Diffstat (limited to 'include/hw')
-rw-r--r-- | include/hw/boards.h | 1 | ||||
-rw-r--r-- | include/hw/elf_ops.h | 77 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 3 | ||||
-rw-r--r-- | include/hw/loader.h | 9 | ||||
-rw-r--r-- | include/hw/xen/start_info.h | 146 |
5 files changed, 234 insertions, 2 deletions
diff --git a/include/hw/boards.h b/include/hw/boards.h index 02f114085f..05f9f45c3d 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -180,7 +180,6 @@ struct MachineClass { int default_cpus; unsigned int no_serial:1, no_parallel:1, - use_virtcon:1, no_floppy:1, no_cdrom:1, no_sdcard:1, diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index e2cb675195..690f9238c8 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -265,7 +265,53 @@ fail: return ret; } +/* + * Given 'nhdr', a pointer to a range of ELF Notes, search through them + * for a note matching type 'elf_note_type' and return a pointer to + * the matching ELF note. + */ +static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, + elf_word note_size, + elf_word phdr_align, + elf_word elf_note_type) +{ + elf_word nhdr_size = sizeof(struct elf_note); + elf_word elf_note_entry_offset = 0; + elf_word note_type; + elf_word nhdr_namesz; + elf_word nhdr_descsz; + + if (nhdr == NULL) { + return NULL; + } + + note_type = nhdr->n_type; + while (note_type != elf_note_type) { + nhdr_namesz = nhdr->n_namesz; + nhdr_descsz = nhdr->n_descsz; + + elf_note_entry_offset = nhdr_size + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align) + + QEMU_ALIGN_UP(nhdr_descsz, phdr_align); + + /* + * If the offset calculated in this iteration exceeds the + * supplied size, we are done and no matching note was found. + */ + if (elf_note_entry_offset > note_size) { + return NULL; + } + + /* skip to the next ELF Note entry */ + nhdr = (void *)nhdr + elf_note_entry_offset; + note_type = nhdr->n_type; + } + + return nhdr; +} + static int glue(load_elf, SZ)(const char *name, int fd, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, int must_swab, uint64_t *pentry, @@ -496,8 +542,39 @@ static int glue(load_elf, SZ)(const char *name, int fd, high = addr + mem_size; data = NULL; + + } else if (ph->p_type == PT_NOTE && elf_note_fn) { + 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) { + goto fail; + } + } + + /* + * Search the ELF notes to find one with a type matching the + * value passed in via 'translate_opaque' + */ + nhdr = (struct elf_note *)data; + assert(translate_opaque != NULL); + nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align, + *(uint64_t *)translate_opaque); + if (nhdr != NULL) { + bool is64 = + 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; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 882fd8dfd2..3ff127ebd0 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -133,6 +133,9 @@ typedef struct PCMachineClass { /* use DMA capable linuxboot option rom */ bool linuxboot_dma_enabled; + + /* use PVH to load kernels that support this feature */ + bool pvh_enabled; } PCMachineClass; #define TYPE_PC_MACHINE "generic-pc-machine" diff --git a/include/hw/loader.h b/include/hw/loader.h index de8a29603b..3e1b3a4566 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -93,6 +93,8 @@ const char *load_elf_strerror(int error); /** load_elf_ram_sym: * @filename: Path of ELF file + * @elf_note_fn: optional function to parse ELF Note type + * passed via @translate_opaque * @translate_fn: optional function to translate load addresses * @translate_opaque: opaque data passed to @translate_fn * @pentry: Populated with program entry point. Ignored if NULL. @@ -125,6 +127,7 @@ typedef void (*symbol_fn_t)(const char *st_name, int st_info, uint64_t st_value, uint64_t st_size); int load_elf_ram_sym(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, @@ -136,6 +139,7 @@ int load_elf_ram_sym(const char *filename, * symbol callback function */ int load_elf_ram(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -146,6 +150,7 @@ int load_elf_ram(const char *filename, * Same as load_elf_ram(), but always loads the elf as ROM */ int load_elf_as(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -155,7 +160,9 @@ int load_elf_as(const char *filename, * Same as load_elf_as(), but doesn't allow the caller to specify an * AddressSpace. */ -int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), +int load_elf(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), + uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab); diff --git a/include/hw/xen/start_info.h b/include/hw/xen/start_info.h new file mode 100644 index 0000000000..348779eb10 --- /dev/null +++ b/include/hw/xen/start_info.h @@ -0,0 +1,146 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016, Citrix Systems, Inc. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ +#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ + +/* + * Start of day structure passed to PVH guests and to HVM guests in %ebx. + * + * NOTE: nothing will be loaded at physical address 0, so a 0 value in any + * of the address fields should be treated as not present. + * + * 0 +----------------+ + * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE + * | | ("xEn3" with the 0x80 bit of the "E" set). + * 4 +----------------+ + * | version | Version of this structure. Current version is 1. New + * | | versions are guaranteed to be backwards-compatible. + * 8 +----------------+ + * | flags | SIF_xxx flags. + * 12 +----------------+ + * | nr_modules | Number of modules passed to the kernel. + * 16 +----------------+ + * | modlist_paddr | Physical address of an array of modules + * | | (layout of the structure below). + * 24 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 32 +----------------+ + * | rsdp_paddr | Physical address of the RSDP ACPI data structure. + * 40 +----------------+ + * | memmap_paddr | Physical address of the (optional) memory map. Only + * | | present in version 1 and newer of the structure. + * 48 +----------------+ + * | memmap_entries | Number of entries in the memory map table. Only + * | | present in version 1 and newer of the structure. + * | | Zero if there is no memory map being provided. + * 52 +----------------+ + * | reserved | Version 1 and newer only. + * 56 +----------------+ + * + * The layout of each entry in the module structure is the following: + * + * 0 +----------------+ + * | paddr | Physical address of the module. + * 8 +----------------+ + * | size | Size of the module in bytes. + * 16 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 24 +----------------+ + * | reserved | + * 32 +----------------+ + * + * The layout of each entry in the memory map table is as follows: + * + * 0 +----------------+ + * | addr | Base address + * 8 +----------------+ + * | size | Size of mapping in bytes + * 16 +----------------+ + * | type | Type of mapping as defined between the hypervisor + * | | and guest it's starting. E820_TYPE_xxx, for example. + * 20 +----------------| + * | reserved | + * 24 +----------------+ + * + * The address and sizes are always a 64bit little endian unsigned integer. + * + * NB: Xen on x86 will always try to place all the data below the 4GiB + * boundary. + * + * Version numbers of the hvm_start_info structure have evolved like this: + * + * Version 0: + * + * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes of + * padding) to the end of the hvm_start_info struct. These new + * fields can be used to pass a memory map to the guest. The + * memory map is optional and so guests that understand version 1 + * of the structure must check that memmap_entries is non-zero + * before trying to read the memory map. + */ +#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 + +/* + * C representation of the x86/HVM start info layout. + * + * The canonical definition of this layout is above, this is just a way to + * represent the layout described there using C types. + */ +struct hvm_start_info { + uint32_t magic; /* Contains the magic value 0x336ec578 */ + /* ("xEn3" with the 0x80 bit of the "E" set).*/ + uint32_t version; /* Version of this structure. */ + uint32_t flags; /* SIF_xxx flags. */ + uint32_t nr_modules; /* Number of modules passed to the kernel. */ + uint64_t modlist_paddr; /* Physical address of an array of */ + /* hvm_modlist_entry. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */ + /* structure. */ + uint64_t memmap_paddr; /* Physical address of an array of */ + /* hvm_memmap_table_entry. Only present in */ + /* version 1 and newer of the structure */ + uint32_t memmap_entries; /* Number of entries in the memmap table. */ + /* Only present in version 1 and newer of */ + /* the structure. Value will be zero if */ + /* there is no memory map being provided. */ + uint32_t reserved; +}; + +struct hvm_modlist_entry { + uint64_t paddr; /* Physical address of the module. */ + uint64_t size; /* Size of the module in bytes. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t reserved; +}; + +struct hvm_memmap_table_entry { + uint64_t addr; /* Base address of the memory region */ + uint64_t size; /* Size of the memory region in bytes */ + uint32_t type; /* Mapping type */ + uint32_t reserved; +}; + +#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ |