1 | Handful of bug fixes to sneak in before rc3. | 1 | v1->v2: fix up format string issues in aspeed_i3c.c |
---|---|---|---|
2 | 2 | ||
3 | thanks | ||
4 | -- PMM | 3 | -- PMM |
5 | 4 | ||
6 | The following changes since commit c985266ea5b50e46e07b3568c1346e10064205c9: | 5 | The following changes since commit b10d00d8811fa4eed4862963273d7353ce310c82: |
7 | 6 | ||
8 | Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190726' into staging (2019-07-26 13:52:06 +0100) | 7 | Merge remote-tracking branch 'remotes/kraxel/tags/seabios-20220118-pull-request' into staging (2022-01-19 18:46:28 +0000) |
9 | 8 | ||
10 | are available in the Git repository at: | 9 | are available in the Git repository at: |
11 | 10 | ||
12 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190726 | 11 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220120-1 |
13 | 12 | ||
14 | for you to fetch changes up to 67505c114e6acc26f3a1a2b74833c61b6a34ff95: | 13 | for you to fetch changes up to b9d383ab797f54ae5fa8746117770709921dc529: |
15 | 14 | ||
16 | hw/arm/boot: Further improve initrd positioning code (2019-07-26 16:17:56 +0100) | 15 | hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR (2022-01-20 16:04:58 +0000) |
17 | 16 | ||
18 | ---------------------------------------------------------------- | 17 | ---------------------------------------------------------------- |
19 | target-arm queue: | 18 | target-arm: |
20 | * Fix broken migration on pl330 device | 19 | * hw/intc/arm_gicv3_its: Fix various minor bugs |
21 | * Fix broken migration on stellaris-input device | 20 | * hw/arm/aspeed: Add the i3c device to the AST2600 SoC |
22 | * Add type checks to vmstate varry macros to avoid this class of bugs | 21 | * hw/arm: kudo: add lm75s behind bus 1 switch at 75 |
23 | * hw/arm/boot: Fix some remaining cases where we would put the | 22 | * hw/arm/virt: Fix support for running guests on hosts |
24 | initrd on top of the kernel image | 23 | with restricted IPA ranges |
24 | * hw/intc/arm_gic: Allow reset of the running priority | ||
25 | * hw/intc/arm_gic: Implement read of GICC_IIDR | ||
26 | * hw/arm/virt: Support for virtio-mem-pci | ||
27 | * hw/arm/virt: Support CPU cluster on ARM virt machine | ||
28 | * docs/can: convert to restructuredText | ||
29 | * hw/net: Move MV88W8618 network device out of hw/arm/ directory | ||
30 | * hw/arm/virt: KVM: Enable PAuth when supported by the host | ||
25 | 31 | ||
26 | ---------------------------------------------------------------- | 32 | ---------------------------------------------------------------- |
27 | Damien Hedde (1): | 33 | Gavin Shan (2): |
28 | pl330: fix vmstate description | 34 | virtio-mem: Correct default THP size for ARM64 |
35 | hw/arm/virt: Support for virtio-mem-pci | ||
29 | 36 | ||
30 | Peter Maydell (4): | 37 | Lucas Ramage (1): |
31 | stellaris_input: Fix vmstate description of buttons field | 38 | docs/can: convert to restructuredText |
32 | vmstate.h: Type check VMSTATE_STRUCT_VARRAY macros | ||
33 | hw/arm/boot: Rename elf_{low, high}_addr to image_{low, high}_addr | ||
34 | hw/arm/boot: Further improve initrd positioning code | ||
35 | 39 | ||
36 | include/migration/vmstate.h | 30 ++++++++++++++++++++++++------ | 40 | Marc Zyngier (7): |
37 | hw/arm/boot.c | 37 +++++++++++++++++++++++++++---------- | 41 | hw/arm/virt: KVM: Enable PAuth when supported by the host |
38 | hw/dma/pl330.c | 17 +++++++++-------- | 42 | hw/arm/virt: Add a control for the the highmem PCIe MMIO |
39 | hw/input/stellaris_input.c | 10 ++++++---- | 43 | hw/arm/virt: Add a control for the the highmem redistributors |
40 | 4 files changed, 66 insertions(+), 28 deletions(-) | 44 | hw/arm/virt: Honor highmem setting when computing the memory map |
45 | hw/arm/virt: Use the PA range to compute the memory map | ||
46 | hw/arm/virt: Disable highmem devices that don't fit in the PA range | ||
47 | hw/arm/virt: Drop superfluous checks against highmem | ||
41 | 48 | ||
49 | Patrick Venture (1): | ||
50 | hw/arm: kudo add lm75s behind bus 1 switch at 75 | ||
51 | |||
52 | Peter Maydell (13): | ||
53 | hw/intc/arm_gicv3_its: Fix event ID bounds checks | ||
54 | hw/intc/arm_gicv3_its: Convert int ID check to num_intids convention | ||
55 | hw/intc/arm_gicv3_its: Fix handling of process_its_cmd() return value | ||
56 | hw/intc/arm_gicv3_its: Don't use data if reading command failed | ||
57 | hw/intc/arm_gicv3_its: Use enum for return value of process_* functions | ||
58 | hw/intc/arm_gicv3_its: Fix return codes in process_its_cmd() | ||
59 | hw/intc/arm_gicv3_its: Refactor process_its_cmd() to reduce nesting | ||
60 | hw/intc/arm_gicv3_its: Fix return codes in process_mapti() | ||
61 | hw/intc/arm_gicv3_its: Fix return codes in process_mapc() | ||
62 | hw/intc/arm_gicv3_its: Fix return codes in process_mapd() | ||
63 | hw/intc/arm_gicv3_its: Factor out "find address of table entry" code | ||
64 | hw/intc/arm_gicv3_its: Check indexes before use, not after | ||
65 | hw/intc/arm_gicv3_its: Range-check ICID before indexing into collection table | ||
66 | |||
67 | Petr Pavlu (2): | ||
68 | hw/intc/arm_gic: Implement read of GICC_IIDR | ||
69 | hw/intc/arm_gic: Allow reset of the running priority | ||
70 | |||
71 | Philippe Mathieu-Daudé (4): | ||
72 | hw: Move MARVELL_88W8618 Kconfig from audio/ to arm/ | ||
73 | hw/arm/musicpal: Fix coding style of code related to MV88W8618 device | ||
74 | hw/net: Move MV88W8618 network device out of hw/arm/ directory | ||
75 | hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR | ||
76 | |||
77 | Troy Lee (2): | ||
78 | hw/misc/aspeed_i3c.c: Introduce a dummy AST2600 I3C model. | ||
79 | hw/arm/aspeed: Add the i3c device to the AST2600 SoC | ||
80 | |||
81 | Yanan Wang (6): | ||
82 | hw/arm/virt: Support CPU cluster on ARM virt machine | ||
83 | hw/arm/virt: Support cluster level in DT cpu-map | ||
84 | hw/acpi/aml-build: Improve scalability of PPTT generation | ||
85 | tests/acpi/bios-tables-test: Allow changes to virt/PPTT file | ||
86 | hw/acpi/aml-build: Support cluster level in PPTT generation | ||
87 | tests/acpi/bios-table-test: Update expected virt/PPTT file | ||
88 | |||
89 | docs/system/arm/cpu-features.rst | 4 - | ||
90 | docs/system/device-emulation.rst | 1 + | ||
91 | docs/{can.txt => system/devices/can.rst} | 90 +++--- | ||
92 | include/hw/arm/aspeed_soc.h | 3 + | ||
93 | include/hw/arm/virt.h | 5 +- | ||
94 | include/hw/misc/aspeed_i3c.h | 48 +++ | ||
95 | include/hw/net/mv88w8618_eth.h | 12 + | ||
96 | target/arm/cpu.h | 1 + | ||
97 | hw/acpi/aml-build.c | 68 +++-- | ||
98 | hw/arm/aspeed_ast2600.c | 16 + | ||
99 | hw/arm/musicpal.c | 381 +----------------------- | ||
100 | hw/arm/npcm7xx_boards.c | 10 +- | ||
101 | hw/arm/virt-acpi-build.c | 10 +- | ||
102 | hw/arm/virt.c | 184 ++++++++++-- | ||
103 | hw/intc/arm_gic.c | 11 + | ||
104 | hw/intc/arm_gicv3_its.c | 492 ++++++++++++++----------------- | ||
105 | hw/intc/arm_gicv3_redist.c | 4 +- | ||
106 | hw/misc/aspeed_i3c.c | 384 ++++++++++++++++++++++++ | ||
107 | hw/net/mv88w8618_eth.c | 403 +++++++++++++++++++++++++ | ||
108 | hw/virtio/virtio-mem.c | 36 ++- | ||
109 | target/arm/cpu.c | 16 +- | ||
110 | target/arm/cpu64.c | 31 +- | ||
111 | target/arm/kvm64.c | 21 ++ | ||
112 | MAINTAINERS | 2 + | ||
113 | hw/arm/Kconfig | 4 + | ||
114 | hw/audio/Kconfig | 3 - | ||
115 | hw/misc/meson.build | 1 + | ||
116 | hw/misc/trace-events | 6 + | ||
117 | hw/net/meson.build | 1 + | ||
118 | qemu-options.hx | 10 + | ||
119 | tests/data/acpi/virt/PPTT | Bin 76 -> 96 bytes | ||
120 | 31 files changed, 1476 insertions(+), 782 deletions(-) | ||
121 | rename docs/{can.txt => system/devices/can.rst} (68%) | ||
122 | create mode 100644 include/hw/misc/aspeed_i3c.h | ||
123 | create mode 100644 include/hw/net/mv88w8618_eth.h | ||
124 | create mode 100644 hw/misc/aspeed_i3c.c | ||
125 | create mode 100644 hw/net/mv88w8618_eth.c | ||
126 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Damien Hedde <damien.hedde@greensocs.com> | ||
2 | 1 | ||
3 | Fix the pl330 main and queue vmstate description. | ||
4 | There were missing POINTER flags causing crashes during | ||
5 | incoming migration because: | ||
6 | + PL330State chan field is a pointer to an array | ||
7 | + PL330Queue queue field is a pointer to an array | ||
8 | |||
9 | Also bump corresponding vmsd version numbers. | ||
10 | |||
11 | Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> | ||
12 | Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> | ||
13 | Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com> | ||
14 | Message-id: 20190724143553.21557-1-damien.hedde@greensocs.com | ||
15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | --- | ||
17 | hw/dma/pl330.c | 17 +++++++++-------- | ||
18 | 1 file changed, 9 insertions(+), 8 deletions(-) | ||
19 | |||
20 | diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/hw/dma/pl330.c | ||
23 | +++ b/hw/dma/pl330.c | ||
24 | @@ -XXX,XX +XXX,XX @@ typedef struct PL330Queue { | ||
25 | |||
26 | static const VMStateDescription vmstate_pl330_queue = { | ||
27 | .name = "pl330_queue", | ||
28 | - .version_id = 1, | ||
29 | - .minimum_version_id = 1, | ||
30 | + .version_id = 2, | ||
31 | + .minimum_version_id = 2, | ||
32 | .fields = (VMStateField[]) { | ||
33 | - VMSTATE_STRUCT_VARRAY_UINT32(queue, PL330Queue, queue_size, 1, | ||
34 | - vmstate_pl330_queue_entry, PL330QueueEntry), | ||
35 | + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(queue, PL330Queue, queue_size, | ||
36 | + vmstate_pl330_queue_entry, | ||
37 | + PL330QueueEntry), | ||
38 | VMSTATE_END_OF_LIST() | ||
39 | } | ||
40 | }; | ||
41 | @@ -XXX,XX +XXX,XX @@ struct PL330State { | ||
42 | |||
43 | static const VMStateDescription vmstate_pl330 = { | ||
44 | .name = "pl330", | ||
45 | - .version_id = 1, | ||
46 | - .minimum_version_id = 1, | ||
47 | + .version_id = 2, | ||
48 | + .minimum_version_id = 2, | ||
49 | .fields = (VMStateField[]) { | ||
50 | VMSTATE_STRUCT(manager, PL330State, 0, vmstate_pl330_chan, PL330Chan), | ||
51 | - VMSTATE_STRUCT_VARRAY_UINT32(chan, PL330State, num_chnls, 0, | ||
52 | - vmstate_pl330_chan, PL330Chan), | ||
53 | + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(chan, PL330State, num_chnls, | ||
54 | + vmstate_pl330_chan, PL330Chan), | ||
55 | VMSTATE_VBUFFER_UINT32(lo_seqn, PL330State, 1, NULL, num_chnls), | ||
56 | VMSTATE_VBUFFER_UINT32(hi_seqn, PL330State, 1, NULL, num_chnls), | ||
57 | VMSTATE_STRUCT(fifo, PL330State, 0, vmstate_pl330_fifo, PL330Fifo), | ||
58 | -- | ||
59 | 2.20.1 | ||
60 | |||
61 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | gamepad_state::buttons is a pointer to an array of structs, | ||
2 | not an array of structs, so should be declared in the vmstate | ||
3 | with VMSTATE_STRUCT_VARRAY_POINTER_INT32; otherwise we | ||
4 | corrupt memory on incoming migration. | ||
5 | 1 | ||
6 | We bump the vmstate version field as the easiest way to | ||
7 | deal with the migration break, since migration wouldn't have | ||
8 | worked reliably before anyway. | ||
9 | |||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
11 | Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> | ||
12 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
13 | Reviewed-by: Damien Hedde <damien.hedde@greensocs.com> | ||
14 | Message-id: 20190725163710.11703-2-peter.maydell@linaro.org | ||
15 | --- | ||
16 | hw/input/stellaris_input.c | 10 ++++++---- | ||
17 | 1 file changed, 6 insertions(+), 4 deletions(-) | ||
18 | |||
19 | diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/hw/input/stellaris_input.c | ||
22 | +++ b/hw/input/stellaris_input.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_button = { | ||
24 | |||
25 | static const VMStateDescription vmstate_stellaris_gamepad = { | ||
26 | .name = "stellaris_gamepad", | ||
27 | - .version_id = 1, | ||
28 | - .minimum_version_id = 1, | ||
29 | + .version_id = 2, | ||
30 | + .minimum_version_id = 2, | ||
31 | .fields = (VMStateField[]) { | ||
32 | VMSTATE_INT32(extension, gamepad_state), | ||
33 | - VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0, | ||
34 | - vmstate_stellaris_button, gamepad_button), | ||
35 | + VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state, | ||
36 | + num_buttons, | ||
37 | + vmstate_stellaris_button, | ||
38 | + gamepad_button), | ||
39 | VMSTATE_END_OF_LIST() | ||
40 | } | ||
41 | }; | ||
42 | -- | ||
43 | 2.20.1 | ||
44 | |||
45 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | The VMSTATE_STRUCT_VARRAY_UINT32 macro is intended to handle | ||
2 | migrating a field which is an array of structs, but where instead of | ||
3 | migrating the entire array we only migrate a variable number of | ||
4 | elements of it. | ||
5 | 1 | ||
6 | The VMSTATE_STRUCT_VARRAY_POINTER_UINT32 macro is intended to handle | ||
7 | migrating a field which is of pointer type, and points to a | ||
8 | dynamically allocated array of structs of variable size. | ||
9 | |||
10 | We weren't actually checking that the field passed to | ||
11 | VMSTATE_STRUCT_VARRAY_UINT32 really is an array, with the result that | ||
12 | accidentally using it where the _POINTER_ macro was intended would | ||
13 | compile but silently corrupt memory on migration. | ||
14 | |||
15 | Add type-checking that enforces that the field passed in is | ||
16 | really of the right array type. This applies to all the VMSTATE | ||
17 | macros which use flags including VMS_VARRAY_* but not VMS_POINTER. | ||
18 | |||
19 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
20 | Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> | ||
21 | Reviewed-by: Damien Hedde <damien.hedde@greensocs.com> | ||
22 | Tested-by: Damien Hedde <damien.hedde@greensocs.com> | ||
23 | Message-id: 20190725163710.11703-3-peter.maydell@linaro.org | ||
24 | --- | ||
25 | include/migration/vmstate.h | 30 ++++++++++++++++++++++++------ | ||
26 | 1 file changed, 24 insertions(+), 6 deletions(-) | ||
27 | |||
28 | diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/include/migration/vmstate.h | ||
31 | +++ b/include/migration/vmstate.h | ||
32 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_bitmap; | ||
33 | extern const VMStateInfo vmstate_info_qtailq; | ||
34 | |||
35 | #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) | ||
36 | +/* | ||
37 | + * Check that type t2 is an array of type t1 of size n, | ||
38 | + * e.g. if t1 is 'foo' and n is 32 then t2 must be 'foo[32]' | ||
39 | + */ | ||
40 | #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) | ||
41 | #define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0) | ||
42 | +/* | ||
43 | + * type of element 0 of the specified (array) field of the type. | ||
44 | + * Note that if the field is a pointer then this will return the | ||
45 | + * pointed-to type rather than complaining. | ||
46 | + */ | ||
47 | +#define typeof_elt_of_field(type, field) typeof(((type *)0)->field[0]) | ||
48 | +/* Check that field f in struct type t2 is an array of t1, of any size */ | ||
49 | +#define type_check_varray(t1, t2, f) \ | ||
50 | + (type_check(t1, typeof_elt_of_field(t2, f)) \ | ||
51 | + + QEMU_BUILD_BUG_ON_ZERO(!QEMU_IS_ARRAY(((t2 *)0)->f))) | ||
52 | |||
53 | #define vmstate_offset_value(_state, _field, _type) \ | ||
54 | (offsetof(_state, _field) + \ | ||
55 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
56 | vmstate_offset_array(_state, _field, uint8_t, \ | ||
57 | sizeof(typeof_field(_state, _field))) | ||
58 | |||
59 | +#define vmstate_offset_varray(_state, _field, _type) \ | ||
60 | + (offsetof(_state, _field) + \ | ||
61 | + type_check_varray(_type, _state, _field)) | ||
62 | + | ||
63 | /* In the macros below, if there is a _version, that means the macro's | ||
64 | * field will be processed only if the version being received is >= | ||
65 | * the _version specified. In general, if you add a new field, you | ||
66 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
67 | .info = &(_info), \ | ||
68 | .size = sizeof(_type), \ | ||
69 | .flags = VMS_VARRAY_UINT32|VMS_MULTIPLY_ELEMENTS, \ | ||
70 | - .offset = offsetof(_state, _field), \ | ||
71 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
72 | } | ||
73 | |||
74 | #define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\ | ||
75 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
76 | .info = &(_info), \ | ||
77 | .size = sizeof(_type), \ | ||
78 | .flags = VMS_VARRAY_INT32, \ | ||
79 | - .offset = offsetof(_state, _field), \ | ||
80 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
81 | } | ||
82 | |||
83 | #define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ | ||
84 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
85 | .info = &(_info), \ | ||
86 | .size = sizeof(_type), \ | ||
87 | .flags = VMS_VARRAY_UINT16, \ | ||
88 | - .offset = offsetof(_state, _field), \ | ||
89 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
90 | } | ||
91 | |||
92 | #define VMSTATE_VSTRUCT_TEST(_field, _state, _test, _version, _vmsd, _type, _struct_version) { \ | ||
93 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
94 | .vmsd = &(_vmsd), \ | ||
95 | .size = sizeof(_type), \ | ||
96 | .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ | ||
97 | - .offset = offsetof(_state, _field), \ | ||
98 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
99 | } | ||
100 | |||
101 | /* a variable length array (i.e. _type *_field) but we know the | ||
102 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
103 | .vmsd = &(_vmsd), \ | ||
104 | .size = sizeof(_type), \ | ||
105 | .flags = VMS_STRUCT|VMS_VARRAY_INT32, \ | ||
106 | - .offset = offsetof(_state, _field), \ | ||
107 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
108 | } | ||
109 | |||
110 | #define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \ | ||
111 | @@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq; | ||
112 | .vmsd = &(_vmsd), \ | ||
113 | .size = sizeof(_type), \ | ||
114 | .flags = VMS_STRUCT|VMS_VARRAY_UINT32, \ | ||
115 | - .offset = offsetof(_state, _field), \ | ||
116 | + .offset = vmstate_offset_varray(_state, _field, _type), \ | ||
117 | } | ||
118 | |||
119 | #define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\ | ||
120 | -- | ||
121 | 2.20.1 | ||
122 | |||
123 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Rename the elf_low_addr and elf_high_addr variables to image_low_addr | ||
2 | and image_high_addr -- in the next commit we will extend them to | ||
3 | be set for other kinds of image file and not just ELF files. | ||
4 | 1 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
6 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
7 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
8 | Tested-by: Mark Rutland <mark.rutland@arm.com> | ||
9 | Message-id: 20190722151804.25467-2-peter.maydell@linaro.org | ||
10 | --- | ||
11 | hw/arm/boot.c | 20 +++++++++++--------- | ||
12 | 1 file changed, 11 insertions(+), 9 deletions(-) | ||
13 | |||
14 | diff --git a/hw/arm/boot.c b/hw/arm/boot.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/hw/arm/boot.c | ||
17 | +++ b/hw/arm/boot.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, | ||
19 | int kernel_size; | ||
20 | int initrd_size; | ||
21 | int is_linux = 0; | ||
22 | - uint64_t elf_entry, elf_low_addr, elf_high_addr; | ||
23 | + uint64_t elf_entry; | ||
24 | + /* Addresses of first byte used and first byte not used by the image */ | ||
25 | + uint64_t image_low_addr, image_high_addr; | ||
26 | int elf_machine; | ||
27 | hwaddr entry; | ||
28 | static const ARMInsnFixup *primary_loader; | ||
29 | @@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, | ||
30 | info->nb_cpus = 1; | ||
31 | |||
32 | /* Assume that raw images are linux kernels, and ELF images are not. */ | ||
33 | - kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr, | ||
34 | - &elf_high_addr, elf_machine, as); | ||
35 | + kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr, | ||
36 | + &image_high_addr, elf_machine, as); | ||
37 | if (kernel_size > 0 && have_dtb(info)) { | ||
38 | /* | ||
39 | * If there is still some room left at the base of RAM, try and put | ||
40 | * the DTB there like we do for images loaded with -bios or -pflash. | ||
41 | */ | ||
42 | - if (elf_low_addr > info->loader_start | ||
43 | - || elf_high_addr < info->loader_start) { | ||
44 | + if (image_low_addr > info->loader_start | ||
45 | + || image_high_addr < info->loader_start) { | ||
46 | /* | ||
47 | - * Set elf_low_addr as address limit for arm_load_dtb if it may be | ||
48 | + * Set image_low_addr as address limit for arm_load_dtb if it may be | ||
49 | * pointing into RAM, otherwise pass '0' (no limit) | ||
50 | */ | ||
51 | - if (elf_low_addr < info->loader_start) { | ||
52 | - elf_low_addr = 0; | ||
53 | + if (image_low_addr < info->loader_start) { | ||
54 | + image_low_addr = 0; | ||
55 | } | ||
56 | info->dtb_start = info->loader_start; | ||
57 | - info->dtb_limit = elf_low_addr; | ||
58 | + info->dtb_limit = image_low_addr; | ||
59 | } | ||
60 | } | ||
61 | entry = elf_entry; | ||
62 | -- | ||
63 | 2.20.1 | ||
64 | |||
65 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | In commit e6b2b20d9735d4ef we made the boot loader code try to avoid | ||
2 | putting the initrd on top of the kernel. However the expression used | ||
3 | to calculate the start of the initrd: | ||
4 | 1 | ||
5 | info->initrd_start = info->loader_start + | ||
6 | MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size); | ||
7 | |||
8 | incorrectly uses 'kernel_size' as the offset within RAM of the | ||
9 | highest address to avoid. This is incorrect because the kernel | ||
10 | doesn't start at address 0, but slightly higher than that. This | ||
11 | means that we can still incorrectly end up overlaying the initrd on | ||
12 | the kernel in some cases, for example: | ||
13 | |||
14 | * The kernel's image_size is 0x0a7a8000 | ||
15 | * The kernel was loaded at 0x40080000 | ||
16 | * The end of the kernel is 0x4A828000 | ||
17 | * The DTB was loaded at 0x4a800000 | ||
18 | |||
19 | To get this right we need to track the actual highest address used | ||
20 | by the kernel and use that rather than kernel_size. We already | ||
21 | set image_low_addr and image_high_addr for ELF images; set them | ||
22 | also for the various other image types we support, and then use | ||
23 | image_high_addr as the lowest allowed address for the initrd. | ||
24 | (We don't use image_low_addr, but we set it for consistency | ||
25 | with the existing code path for ELF files.) | ||
26 | |||
27 | Fixes: e6b2b20d9735d4ef | ||
28 | Reported-by: Mark Rutland <mark.rutland@arm.com> | ||
29 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
30 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
31 | Tested-by: Mark Rutland <mark.rutland@arm.com> | ||
32 | Message-id: 20190722151804.25467-3-peter.maydell@linaro.org | ||
33 | --- | ||
34 | hw/arm/boot.c | 19 +++++++++++++++++-- | ||
35 | 1 file changed, 17 insertions(+), 2 deletions(-) | ||
36 | |||
37 | diff --git a/hw/arm/boot.c b/hw/arm/boot.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/hw/arm/boot.c | ||
40 | +++ b/hw/arm/boot.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, | ||
42 | int is_linux = 0; | ||
43 | uint64_t elf_entry; | ||
44 | /* Addresses of first byte used and first byte not used by the image */ | ||
45 | - uint64_t image_low_addr, image_high_addr; | ||
46 | + uint64_t image_low_addr = 0, image_high_addr = 0; | ||
47 | int elf_machine; | ||
48 | hwaddr entry; | ||
49 | static const ARMInsnFixup *primary_loader; | ||
50 | @@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, | ||
51 | uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR; | ||
52 | kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr, | ||
53 | &is_linux, NULL, NULL, as); | ||
54 | + if (kernel_size >= 0) { | ||
55 | + image_low_addr = loadaddr; | ||
56 | + image_high_addr = image_low_addr + kernel_size; | ||
57 | + } | ||
58 | } | ||
59 | if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) { | ||
60 | kernel_size = load_aarch64_image(info->kernel_filename, | ||
61 | info->loader_start, &entry, as); | ||
62 | is_linux = 1; | ||
63 | + if (kernel_size >= 0) { | ||
64 | + image_low_addr = entry; | ||
65 | + image_high_addr = image_low_addr + kernel_size; | ||
66 | + } | ||
67 | } else if (kernel_size < 0) { | ||
68 | /* 32-bit ARM */ | ||
69 | entry = info->loader_start + KERNEL_LOAD_ADDR; | ||
70 | kernel_size = load_image_targphys_as(info->kernel_filename, entry, | ||
71 | ram_end - KERNEL_LOAD_ADDR, as); | ||
72 | is_linux = 1; | ||
73 | + if (kernel_size >= 0) { | ||
74 | + image_low_addr = entry; | ||
75 | + image_high_addr = image_low_addr + kernel_size; | ||
76 | + } | ||
77 | } | ||
78 | if (kernel_size < 0) { | ||
79 | error_report("could not load kernel '%s'", info->kernel_filename); | ||
80 | @@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, | ||
81 | * we might still make a bad choice here. | ||
82 | */ | ||
83 | info->initrd_start = info->loader_start + | ||
84 | - MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size); | ||
85 | + MIN(info->ram_size / 2, 128 * 1024 * 1024); | ||
86 | + if (image_high_addr) { | ||
87 | + info->initrd_start = MAX(info->initrd_start, image_high_addr); | ||
88 | + } | ||
89 | info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start); | ||
90 | |||
91 | if (is_linux) { | ||
92 | -- | ||
93 | 2.20.1 | ||
94 | |||
95 | diff view generated by jsdifflib |