target-arm queue:

* Fix broken migration on pl330 device
  * Fix broken migration on stellaris-input device
  * Add type checks to vmstate varry macros to avoid this class of bugs
  * hw/arm/boot: Fix some remaining cases where we would put the
    initrd on top of the kernel image
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAl07GfUZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3lCNEACw3dTka4tHyObmf3a5KYcO
 tbPJPGXKexYW+Zx681qtqDN1pe4/2U42rSHjYYeOFoKMXrDc1Jr30upPxVsek8yk
 nUmYIZo89G4nP5G0EYWhwYZbIT7qsrT8mtx4KezS1l6pi8w+UVDb9N9TmcdcjvBP
 fxqofNczeoNKZz2T3229G2ENyhbU9Pq0h5LpvT7zNHAS5IE7Du2eb0PWQ1AH7cJN
 c8NY/24vNSzbxf0Zj9jFaKSc1LbxBgvqqb2KRTcVMl1pcIgY+Ljc+lN+bJVHPSZ/
 fx9zBbUh5OF3YNipYIRcjPOGTfKeGu9OyeDhAcI38QT00NfnjAWXcxjITijQBWnW
 IMsAbmLsamx/BvqW3D+F0kbRpJu4c+2Ge465PnvX7xduivm1kWoJM4Q8YvZWI5Y7
 TVLfvjNtg9sjOB5tmSNzlhRj7PrsyELhR2p9YWCqZKQmc0jRaQjYtRRduRKREfdT
 Vv/qTbQmiNMAxyP3v6C1jhk/t+NZ5l8PBwr1mYFYSUj4uhz09ckVatimJsd11hiZ
 TZRfBFIjKDFGO6/FeVBgN5lirlmlWF/HIbijGqh5A25eUsBMhitrkHIoDZxqnneG
 cdLpYB1SAT+oY97KYFynrhW9OErSrKHs5Of5c443CgWoZb7Q9rOhyJUqAdDf4MaZ
 LzcRBfrNoD4042GihD9XCg==
 =OwrX
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into staging

target-arm queue:
 * Fix broken migration on pl330 device
 * Fix broken migration on stellaris-input device
 * Add type checks to vmstate varry macros to avoid this class of bugs
 * hw/arm/boot: Fix some remaining cases where we would put the
   initrd on top of the kernel image

# gpg: Signature made Fri 26 Jul 2019 16:19:17 BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20190726:
  hw/arm/boot: Further improve initrd positioning code
  hw/arm/boot: Rename elf_{low, high}_addr to image_{low, high}_addr
  vmstate.h: Type check VMSTATE_STRUCT_VARRAY macros
  stellaris_input: Fix vmstate description of buttons field
  pl330: fix vmstate description

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-07-26 16:23:07 +01:00
commit fff3159900
4 changed files with 66 additions and 28 deletions

View File

@ -986,7 +986,9 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
int kernel_size;
int initrd_size;
int is_linux = 0;
uint64_t elf_entry, elf_low_addr, elf_high_addr;
uint64_t elf_entry;
/* Addresses of first byte used and first byte not used by the image */
uint64_t image_low_addr = 0, image_high_addr = 0;
int elf_machine;
hwaddr entry;
static const ARMInsnFixup *primary_loader;
@ -1014,24 +1016,24 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
info->nb_cpus = 1;
/* Assume that raw images are linux kernels, and ELF images are not. */
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
&elf_high_addr, elf_machine, as);
kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
&image_high_addr, elf_machine, as);
if (kernel_size > 0 && have_dtb(info)) {
/*
* If there is still some room left at the base of RAM, try and put
* the DTB there like we do for images loaded with -bios or -pflash.
*/
if (elf_low_addr > info->loader_start
|| elf_high_addr < info->loader_start) {
if (image_low_addr > info->loader_start
|| image_high_addr < info->loader_start) {
/*
* Set elf_low_addr as address limit for arm_load_dtb if it may be
* Set image_low_addr as address limit for arm_load_dtb if it may be
* pointing into RAM, otherwise pass '0' (no limit)
*/
if (elf_low_addr < info->loader_start) {
elf_low_addr = 0;
if (image_low_addr < info->loader_start) {
image_low_addr = 0;
}
info->dtb_start = info->loader_start;
info->dtb_limit = elf_low_addr;
info->dtb_limit = image_low_addr;
}
}
entry = elf_entry;
@ -1039,17 +1041,29 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
&is_linux, NULL, NULL, as);
if (kernel_size >= 0) {
image_low_addr = loadaddr;
image_high_addr = image_low_addr + kernel_size;
}
}
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
kernel_size = load_aarch64_image(info->kernel_filename,
info->loader_start, &entry, as);
is_linux = 1;
if (kernel_size >= 0) {
image_low_addr = entry;
image_high_addr = image_low_addr + kernel_size;
}
} else if (kernel_size < 0) {
/* 32-bit ARM */
entry = info->loader_start + KERNEL_LOAD_ADDR;
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
ram_end - KERNEL_LOAD_ADDR, as);
is_linux = 1;
if (kernel_size >= 0) {
image_low_addr = entry;
image_high_addr = image_low_addr + kernel_size;
}
}
if (kernel_size < 0) {
error_report("could not load kernel '%s'", info->kernel_filename);
@ -1081,7 +1095,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
* we might still make a bad choice here.
*/
info->initrd_start = info->loader_start +
MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
MIN(info->ram_size / 2, 128 * 1024 * 1024);
if (image_high_addr) {
info->initrd_start = MAX(info->initrd_start, image_high_addr);
}
info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
if (is_linux) {

View File

@ -218,11 +218,12 @@ typedef struct PL330Queue {
static const VMStateDescription vmstate_pl330_queue = {
.name = "pl330_queue",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_STRUCT_VARRAY_UINT32(queue, PL330Queue, queue_size, 1,
vmstate_pl330_queue_entry, PL330QueueEntry),
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(queue, PL330Queue, queue_size,
vmstate_pl330_queue_entry,
PL330QueueEntry),
VMSTATE_END_OF_LIST()
}
};
@ -278,12 +279,12 @@ struct PL330State {
static const VMStateDescription vmstate_pl330 = {
.name = "pl330",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(manager, PL330State, 0, vmstate_pl330_chan, PL330Chan),
VMSTATE_STRUCT_VARRAY_UINT32(chan, PL330State, num_chnls, 0,
vmstate_pl330_chan, PL330Chan),
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(chan, PL330State, num_chnls,
vmstate_pl330_chan, PL330Chan),
VMSTATE_VBUFFER_UINT32(lo_seqn, PL330State, 1, NULL, num_chnls),
VMSTATE_VBUFFER_UINT32(hi_seqn, PL330State, 1, NULL, num_chnls),
VMSTATE_STRUCT(fifo, PL330State, 0, vmstate_pl330_fifo, PL330Fifo),

View File

@ -60,12 +60,14 @@ static const VMStateDescription vmstate_stellaris_button = {
static const VMStateDescription vmstate_stellaris_gamepad = {
.name = "stellaris_gamepad",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_INT32(extension, gamepad_state),
VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
vmstate_stellaris_button, gamepad_button),
VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
num_buttons,
vmstate_stellaris_button,
gamepad_button),
VMSTATE_END_OF_LIST()
}
};

View File

@ -227,8 +227,22 @@ extern const VMStateInfo vmstate_info_bitmap;
extern const VMStateInfo vmstate_info_qtailq;
#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
/*
* Check that type t2 is an array of type t1 of size n,
* e.g. if t1 is 'foo' and n is 32 then t2 must be 'foo[32]'
*/
#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
/*
* type of element 0 of the specified (array) field of the type.
* Note that if the field is a pointer then this will return the
* pointed-to type rather than complaining.
*/
#define typeof_elt_of_field(type, field) typeof(((type *)0)->field[0])
/* Check that field f in struct type t2 is an array of t1, of any size */
#define type_check_varray(t1, t2, f) \
(type_check(t1, typeof_elt_of_field(t2, f)) \
+ QEMU_BUILD_BUG_ON_ZERO(!QEMU_IS_ARRAY(((t2 *)0)->f)))
#define vmstate_offset_value(_state, _field, _type) \
(offsetof(_state, _field) + \
@ -253,6 +267,10 @@ extern const VMStateInfo vmstate_info_qtailq;
vmstate_offset_array(_state, _field, uint8_t, \
sizeof(typeof_field(_state, _field)))
#define vmstate_offset_varray(_state, _field, _type) \
(offsetof(_state, _field) + \
type_check_varray(_type, _state, _field))
/* In the macros below, if there is a _version, that means the macro's
* field will be processed only if the version being received is >=
* the _version specified. In general, if you add a new field, you
@ -347,7 +365,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.info = &(_info), \
.size = sizeof(_type), \
.flags = VMS_VARRAY_UINT32|VMS_MULTIPLY_ELEMENTS, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
#define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
@ -376,7 +394,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.info = &(_info), \
.size = sizeof(_type), \
.flags = VMS_VARRAY_INT32, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\
@ -416,7 +434,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.info = &(_info), \
.size = sizeof(_type), \
.flags = VMS_VARRAY_UINT16, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
#define VMSTATE_VSTRUCT_TEST(_field, _state, _test, _version, _vmsd, _type, _struct_version) { \
@ -520,7 +538,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.vmsd = &(_vmsd), \
.size = sizeof(_type), \
.flags = VMS_STRUCT|VMS_VARRAY_UINT8, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
/* a variable length array (i.e. _type *_field) but we know the
@ -573,7 +591,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.vmsd = &(_vmsd), \
.size = sizeof(_type), \
.flags = VMS_STRUCT|VMS_VARRAY_INT32, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \
@ -583,7 +601,7 @@ extern const VMStateInfo vmstate_info_qtailq;
.vmsd = &(_vmsd), \
.size = sizeof(_type), \
.flags = VMS_STRUCT|VMS_VARRAY_UINT32, \
.offset = offsetof(_state, _field), \
.offset = vmstate_offset_varray(_state, _field, _type), \
}
#define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\