1 | Handful of bug fixes to sneak in before rc3. | 1 | v2: drop the 'merge the manuals' patch: it breaks the gitlab job which tries |
---|---|---|---|
2 | to publish the docs on gitlab, and I also realised I forgot to update the | ||
3 | Windows installer scripts. | ||
2 | 4 | ||
3 | thanks | ||
4 | -- PMM | 5 | -- PMM |
5 | 6 | ||
6 | The following changes since commit c985266ea5b50e46e07b3568c1346e10064205c9: | 7 | The following changes since commit b3f846c59d8405bb87c551187721fc92ff2f1b92: |
7 | 8 | ||
8 | Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190726' into staging (2019-07-26 13:52:06 +0100) | 9 | Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2021-01-11v2' into staging (2021-01-11 15:15:35 +0000) |
9 | 10 | ||
10 | are available in the Git repository at: | 11 | are available in the Git repository at: |
11 | 12 | ||
12 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190726 | 13 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210112-1 |
13 | 14 | ||
14 | for you to fetch changes up to 67505c114e6acc26f3a1a2b74833c61b6a34ff95: | 15 | for you to fetch changes up to 1ff5a063d60c7737de11465516331b8ca8700865: |
15 | 16 | ||
16 | hw/arm/boot: Further improve initrd positioning code (2019-07-26 16:17:56 +0100) | 17 | ui/cocoa: Fix openFile: deprecation on Big Sur (2021-01-12 21:19:02 +0000) |
17 | 18 | ||
18 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
19 | target-arm queue: | 20 | target-arm queue: |
20 | * Fix broken migration on pl330 device | 21 | * arm: Support emulation of ARMv8.4-TTST extension |
21 | * Fix broken migration on stellaris-input device | 22 | * arm: Update cpu.h ID register field definitions |
22 | * Add type checks to vmstate varry macros to avoid this class of bugs | 23 | * arm: Fix breakage of XScale instruction emulation |
23 | * hw/arm/boot: Fix some remaining cases where we would put the | 24 | * hw/net/lan9118: Fix RX Status FIFO PEEK value |
24 | initrd on top of the kernel image | 25 | * npcm7xx: Add ADC and PWM emulation |
26 | * ui/cocoa: Make "open docs" help menu entry work again when binary | ||
27 | is run from the build tree | ||
28 | * ui/cocoa: Fix openFile: deprecation on Big Sur | ||
29 | * docs: Add qemu-storage-daemon(1) manpage to meson.build | ||
25 | 30 | ||
26 | ---------------------------------------------------------------- | 31 | ---------------------------------------------------------------- |
27 | Damien Hedde (1): | 32 | Hao Wu (6): |
28 | pl330: fix vmstate description | 33 | hw/misc: Add clock converter in NPCM7XX CLK module |
34 | hw/timer: Refactor NPCM7XX Timer to use CLK clock | ||
35 | hw/adc: Add an ADC module for NPCM7XX | ||
36 | hw/misc: Add a PWM module for NPCM7XX | ||
37 | hw/misc: Add QTest for NPCM7XX PWM Module | ||
38 | hw/*: Use type casting for SysBusDevice in NPCM7XX | ||
39 | |||
40 | Leif Lindholm (6): | ||
41 | target/arm: fix typo in cpu.h ID_AA64PFR1 field name | ||
42 | target/arm: make ARMCPU.clidr 64-bit | ||
43 | target/arm: make ARMCPU.ctr 64-bit | ||
44 | target/arm: add descriptions of CLIDR_EL1, CCSIDR_EL1, CTR_EL0 to cpu.h | ||
45 | target/arm: add aarch64 ID register fields to cpu.h | ||
46 | target/arm: add aarch32 ID register fields to cpu.h | ||
29 | 47 | ||
30 | Peter Maydell (4): | 48 | Peter Maydell (4): |
31 | stellaris_input: Fix vmstate description of buttons field | 49 | docs: Add qemu-storage-daemon(1) manpage to meson.build |
32 | vmstate.h: Type check VMSTATE_STRUCT_VARRAY macros | 50 | target/arm: Don't decode insns in the XScale/iWMMXt space as cp insns |
33 | hw/arm/boot: Rename elf_{low, high}_addr to image_{low, high}_addr | 51 | hw/net/lan9118: Fix RX Status FIFO PEEK value |
34 | hw/arm/boot: Further improve initrd positioning code | 52 | hw/net/lan9118: Add symbolic constants for register offsets |
35 | 53 | ||
36 | include/migration/vmstate.h | 30 ++++++++++++++++++++++++------ | 54 | Roman Bolshakov (2): |
37 | hw/arm/boot.c | 37 +++++++++++++++++++++++++++---------- | 55 | ui/cocoa: Update path to docs in build tree |
38 | hw/dma/pl330.c | 17 +++++++++-------- | 56 | ui/cocoa: Fix openFile: deprecation on Big Sur |
39 | hw/input/stellaris_input.c | 10 ++++++---- | ||
40 | 4 files changed, 66 insertions(+), 28 deletions(-) | ||
41 | 57 | ||
58 | Rémi Denis-Courmont (2): | ||
59 | target/arm: ARMv8.4-TTST extension | ||
60 | target/arm: enable Small Translation tables in max CPU | ||
61 | |||
62 | docs/meson.build | 1 + | ||
63 | docs/system/arm/nuvoton.rst | 4 +- | ||
64 | meson.build | 1 + | ||
65 | hw/adc/trace.h | 1 + | ||
66 | include/hw/adc/npcm7xx_adc.h | 69 ++++ | ||
67 | include/hw/arm/npcm7xx.h | 4 + | ||
68 | include/hw/misc/npcm7xx_clk.h | 146 ++++++- | ||
69 | include/hw/misc/npcm7xx_pwm.h | 105 +++++ | ||
70 | include/hw/timer/npcm7xx_timer.h | 1 + | ||
71 | target/arm/cpu.h | 85 ++++- | ||
72 | hw/adc/npcm7xx_adc.c | 301 +++++++++++++++ | ||
73 | hw/arm/npcm7xx.c | 55 ++- | ||
74 | hw/arm/npcm7xx_boards.c | 2 +- | ||
75 | hw/mem/npcm7xx_mc.c | 2 +- | ||
76 | hw/misc/npcm7xx_clk.c | 807 ++++++++++++++++++++++++++++++++++++++- | ||
77 | hw/misc/npcm7xx_gcr.c | 2 +- | ||
78 | hw/misc/npcm7xx_pwm.c | 550 ++++++++++++++++++++++++++ | ||
79 | hw/misc/npcm7xx_rng.c | 2 +- | ||
80 | hw/net/lan9118.c | 26 +- | ||
81 | hw/nvram/npcm7xx_otp.c | 2 +- | ||
82 | hw/ssi/npcm7xx_fiu.c | 2 +- | ||
83 | hw/timer/npcm7xx_timer.c | 39 +- | ||
84 | target/arm/cpu64.c | 1 + | ||
85 | target/arm/helper.c | 15 +- | ||
86 | target/arm/translate.c | 7 + | ||
87 | tests/qtest/npcm7xx_adc-test.c | 377 ++++++++++++++++++ | ||
88 | tests/qtest/npcm7xx_pwm-test.c | 490 ++++++++++++++++++++++++ | ||
89 | hw/adc/meson.build | 1 + | ||
90 | hw/adc/trace-events | 5 + | ||
91 | hw/misc/meson.build | 1 + | ||
92 | hw/misc/trace-events | 6 + | ||
93 | tests/qtest/meson.build | 4 +- | ||
94 | ui/cocoa.m | 7 +- | ||
95 | 33 files changed, 3054 insertions(+), 67 deletions(-) | ||
96 | create mode 100644 hw/adc/trace.h | ||
97 | create mode 100644 include/hw/adc/npcm7xx_adc.h | ||
98 | create mode 100644 include/hw/misc/npcm7xx_pwm.h | ||
99 | create mode 100644 hw/adc/npcm7xx_adc.c | ||
100 | create mode 100644 hw/misc/npcm7xx_pwm.c | ||
101 | create mode 100644 tests/qtest/npcm7xx_adc-test.c | ||
102 | create mode 100644 tests/qtest/npcm7xx_pwm-test.c | ||
103 | create mode 100644 hw/adc/trace-events | ||
104 | 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 |