1 | Changes from v1: dropped SVE patchset. | 1 | Small pullreq with some bug fixes to go into rc1. |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit 58560ad254fbda71d4daa6622d71683190070ee2: | 3 | -- PMM |
4 | 4 | ||
5 | Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191024' into staging (2019-10-24 16:22:58 +0100) | 5 | The following changes since commit 5ca634afcf83215a9a54ca6e66032325b5ffb5f6: |
6 | |||
7 | Merge remote-tracking branch 'remotes/philmd/tags/sdmmc-20210322' into staging (2021-03-22 18:50:25 +0000) | ||
6 | 8 | ||
7 | are available in the Git repository at: | 9 | are available in the Git repository at: |
8 | 10 | ||
9 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191025 | 11 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210323 |
10 | 12 | ||
11 | for you to fetch changes up to f9469c1a01c333c08980e083e0ad3417256c8b9c: | 13 | for you to fetch changes up to dad90de78e9e9d47cefcbcd30115706b98e6ec87: |
12 | 14 | ||
13 | hw/arm/highbank: Use AddressSpace when using write_secondary_boot() (2019-10-25 13:09:27 +0100) | 15 | target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill (2021-03-23 14:07:55 +0000) |
14 | 16 | ||
15 | ---------------------------------------------------------------- | 17 | ---------------------------------------------------------------- |
16 | target-arm queue: | 18 | target-arm queue: |
17 | * raspi boards: some cleanup | 19 | * hw/arm/virt: Disable pl011 clock migration if needed |
18 | * raspi: implement the bcm2835 system timer device | 20 | * target/arm: Make M-profile VTOR loads on reset handle memory aliasing |
19 | * raspi: implement a dummy thermal sensor | 21 | * target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill |
20 | * misc devices: switch to ptimer transaction API | ||
21 | * cache TB flag state to improve performance of cpu_get_tb_cpu_state | ||
22 | * aspeed: Add an AST2600 eval board | ||
23 | 22 | ||
24 | ---------------------------------------------------------------- | 23 | ---------------------------------------------------------------- |
25 | Cédric Le Goater (2): | 24 | Gavin Shan (1): |
26 | hw/gpio: Fix property accessors of the AST2600 GPIO 1.8V model | 25 | hw/arm/virt: Disable pl011 clock migration if needed |
27 | aspeed: Add an AST2600 eval board | ||
28 | 26 | ||
29 | Peter Maydell (8): | 27 | Peter Maydell (5): |
30 | hw/net/fsl_etsec/etsec.c: Switch to transaction-based ptimer API | 28 | memory: Make flatview_cb return bool, not int |
31 | hw/timer/xilinx_timer.c: Switch to transaction-based ptimer API | 29 | memory: Document flatview_for_each_range() |
32 | hw/dma/xilinx_axidma.c: Switch to transaction-based ptimer API | 30 | memory: Add offset_in_region to flatview_cb arguments |
33 | hw/timer/slavio_timer: Remove useless check for NULL t->timer | 31 | hw/core/loader: Add new function rom_ptr_for_as() |
34 | hw/timer/slavio_timer.c: Switch to transaction-based ptimer API | 32 | target/arm: Make M-profile VTOR loads on reset handle memory aliasing |
35 | hw/timer/grlib_gptimer.c: Switch to transaction-based ptimer API | ||
36 | hw/m68k/mcf5206.c: Switch to transaction-based ptimer API | ||
37 | hw/watchdog/milkymist-sysctl.c: Switch to transaction-based ptimer API | ||
38 | 33 | ||
39 | Philippe Mathieu-Daudé (8): | 34 | Richard Henderson (1): |
40 | hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor | 35 | target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill |
41 | hw/arm/bcm2835_peripherals: Use the thermal sensor block | ||
42 | hw/timer/bcm2835: Add the BCM2835 SYS_timer | ||
43 | hw/arm/bcm2835_peripherals: Use the SYS_timer | ||
44 | hw/arm/bcm2836: Make the SoC code modular | ||
45 | hw/arm/bcm2836: Rename cpus[] as cpu[].core | ||
46 | hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot | ||
47 | hw/arm/highbank: Use AddressSpace when using write_secondary_boot() | ||
48 | 36 | ||
49 | Richard Henderson (24): | 37 | include/exec/memory.h | 32 +++++++++++++++--- |
50 | target/arm: Split out rebuild_hflags_common | 38 | include/hw/char/pl011.h | 1 + |
51 | target/arm: Split out rebuild_hflags_a64 | 39 | include/hw/loader.h | 31 +++++++++++++++++ |
52 | target/arm: Split out rebuild_hflags_common_32 | 40 | hw/char/pl011.c | 9 +++++ |
53 | target/arm: Split arm_cpu_data_is_big_endian | 41 | hw/core/loader.c | 75 +++++++++++++++++++++++++++++++++++++++++ |
54 | target/arm: Split out rebuild_hflags_m32 | 42 | hw/core/machine.c | 1 + |
55 | target/arm: Reduce tests vs M-profile in cpu_get_tb_cpu_state | 43 | softmmu/memory.c | 4 ++- |
56 | target/arm: Split out rebuild_hflags_a32 | 44 | target/arm/cpu.c | 2 +- |
57 | target/arm: Split out rebuild_hflags_aprofile | 45 | target/arm/tlb_helper.c | 1 + |
58 | target/arm: Hoist XSCALE_CPAR, VECLEN, VECSTRIDE in cpu_get_tb_cpu_state | 46 | tests/qtest/fuzz/generic_fuzz.c | 11 +++--- |
59 | target/arm: Simplify set of PSTATE_SS in cpu_get_tb_cpu_state | 47 | 10 files changed, 157 insertions(+), 10 deletions(-) |
60 | target/arm: Hoist computation of TBFLAG_A32.VFPEN | ||
61 | target/arm: Add arm_rebuild_hflags | ||
62 | target/arm: Split out arm_mmu_idx_el | ||
63 | target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state | ||
64 | target/arm: Add HELPER(rebuild_hflags_{a32, a64, m32}) | ||
65 | target/arm: Rebuild hflags at EL changes | ||
66 | target/arm: Rebuild hflags at MSR writes | ||
67 | target/arm: Rebuild hflags at CPSR writes | ||
68 | target/arm: Rebuild hflags at Xscale SCTLR writes | ||
69 | target/arm: Rebuild hflags for M-profile | ||
70 | target/arm: Rebuild hflags for M-profile NVIC | ||
71 | linux-user/aarch64: Rebuild hflags for TARGET_WORDS_BIGENDIAN | ||
72 | linux-user/arm: Rebuild hflags for TARGET_WORDS_BIGENDIAN | ||
73 | target/arm: Rely on hflags correct in cpu_get_tb_cpu_state | ||
74 | 48 | ||
75 | hw/misc/Makefile.objs | 1 + | ||
76 | hw/timer/Makefile.objs | 1 + | ||
77 | hw/net/fsl_etsec/etsec.h | 1 - | ||
78 | include/hw/arm/aspeed.h | 1 + | ||
79 | include/hw/arm/bcm2835_peripherals.h | 5 +- | ||
80 | include/hw/arm/bcm2836.h | 4 +- | ||
81 | include/hw/arm/raspi_platform.h | 1 + | ||
82 | include/hw/misc/bcm2835_thermal.h | 27 +++ | ||
83 | include/hw/timer/bcm2835_systmr.h | 33 +++ | ||
84 | target/arm/cpu.h | 84 +++++--- | ||
85 | target/arm/helper.h | 4 + | ||
86 | target/arm/internals.h | 9 + | ||
87 | hw/arm/aspeed.c | 23 ++ | ||
88 | hw/arm/bcm2835_peripherals.c | 30 ++- | ||
89 | hw/arm/bcm2836.c | 44 ++-- | ||
90 | hw/arm/highbank.c | 3 +- | ||
91 | hw/arm/raspi.c | 14 +- | ||
92 | hw/dma/xilinx_axidma.c | 9 +- | ||
93 | hw/gpio/aspeed_gpio.c | 8 +- | ||
94 | hw/intc/armv7m_nvic.c | 22 +- | ||
95 | hw/m68k/mcf5206.c | 15 +- | ||
96 | hw/misc/bcm2835_thermal.c | 135 ++++++++++++ | ||
97 | hw/net/fsl_etsec/etsec.c | 9 +- | ||
98 | hw/timer/bcm2835_systmr.c | 163 +++++++++++++++ | ||
99 | hw/timer/grlib_gptimer.c | 28 ++- | ||
100 | hw/timer/milkymist-sysctl.c | 25 ++- | ||
101 | hw/timer/slavio_timer.c | 32 ++- | ||
102 | hw/timer/xilinx_timer.c | 13 +- | ||
103 | linux-user/aarch64/cpu_loop.c | 1 + | ||
104 | linux-user/arm/cpu_loop.c | 1 + | ||
105 | linux-user/syscall.c | 1 + | ||
106 | target/arm/cpu.c | 1 + | ||
107 | target/arm/helper-a64.c | 3 + | ||
108 | target/arm/helper.c | 393 +++++++++++++++++++++++------------ | ||
109 | target/arm/m_helper.c | 6 + | ||
110 | target/arm/machine.c | 1 + | ||
111 | target/arm/op_helper.c | 4 + | ||
112 | target/arm/translate-a64.c | 13 +- | ||
113 | target/arm/translate.c | 33 ++- | ||
114 | hw/timer/trace-events | 5 + | ||
115 | 40 files changed, 945 insertions(+), 261 deletions(-) | ||
116 | create mode 100644 include/hw/misc/bcm2835_thermal.h | ||
117 | create mode 100644 include/hw/timer/bcm2835_systmr.h | ||
118 | create mode 100644 hw/misc/bcm2835_thermal.c | ||
119 | create mode 100644 hw/timer/bcm2835_systmr.c | ||
120 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Gavin Shan <gshan@redhat.com> | ||
1 | 2 | ||
3 | A clock is added by commit aac63e0e6ea3 ("hw/char/pl011: add a clock | ||
4 | input") since v5.2.0 which corresponds to virt-5.2 machine type. It | ||
5 | causes backwards migration failure from upstream to downstream (v5.1.0) | ||
6 | when the machine type is specified with virt-5.1. | ||
7 | |||
8 | This fixes the issue by following instructions from section "Connecting | ||
9 | subsections to properties" in docs/devel/migration.rst. With this applied, | ||
10 | the PL011 clock is migrated based on the machine type. | ||
11 | |||
12 | virt-5.2 or newer: migration | ||
13 | virt-5.1 or older: non-migration | ||
14 | |||
15 | Cc: qemu-stable@nongnu.org # v5.2.0+ | ||
16 | Fixes: aac63e0e6ea3 ("hw/char/pl011: add a clock input") | ||
17 | Suggested-by: Andrew Jones <drjones@redhat.com> | ||
18 | Signed-off-by: Gavin Shan <gshan@redhat.com> | ||
19 | Reviewed-by: Andrew Jones <drjones@redhat.com> | ||
20 | Message-id: 20210318023801.18287-1-gshan@redhat.com | ||
21 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
22 | --- | ||
23 | include/hw/char/pl011.h | 1 + | ||
24 | hw/char/pl011.c | 9 +++++++++ | ||
25 | hw/core/machine.c | 1 + | ||
26 | 3 files changed, 11 insertions(+) | ||
27 | |||
28 | diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/include/hw/char/pl011.h | ||
31 | +++ b/include/hw/char/pl011.h | ||
32 | @@ -XXX,XX +XXX,XX @@ struct PL011State { | ||
33 | CharBackend chr; | ||
34 | qemu_irq irq[6]; | ||
35 | Clock *clk; | ||
36 | + bool migrate_clk; | ||
37 | const unsigned char *id; | ||
38 | }; | ||
39 | |||
40 | diff --git a/hw/char/pl011.c b/hw/char/pl011.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/hw/char/pl011.c | ||
43 | +++ b/hw/char/pl011.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pl011_ops = { | ||
45 | .endianness = DEVICE_NATIVE_ENDIAN, | ||
46 | }; | ||
47 | |||
48 | +static bool pl011_clock_needed(void *opaque) | ||
49 | +{ | ||
50 | + PL011State *s = PL011(opaque); | ||
51 | + | ||
52 | + return s->migrate_clk; | ||
53 | +} | ||
54 | + | ||
55 | static const VMStateDescription vmstate_pl011_clock = { | ||
56 | .name = "pl011/clock", | ||
57 | .version_id = 1, | ||
58 | .minimum_version_id = 1, | ||
59 | + .needed = pl011_clock_needed, | ||
60 | .fields = (VMStateField[]) { | ||
61 | VMSTATE_CLOCK(clk, PL011State), | ||
62 | VMSTATE_END_OF_LIST() | ||
63 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011 = { | ||
64 | |||
65 | static Property pl011_properties[] = { | ||
66 | DEFINE_PROP_CHR("chardev", PL011State, chr), | ||
67 | + DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true), | ||
68 | DEFINE_PROP_END_OF_LIST(), | ||
69 | }; | ||
70 | |||
71 | diff --git a/hw/core/machine.c b/hw/core/machine.c | ||
72 | index XXXXXXX..XXXXXXX 100644 | ||
73 | --- a/hw/core/machine.c | ||
74 | +++ b/hw/core/machine.c | ||
75 | @@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_5_1[] = { | ||
76 | { "virtio-scsi-device", "num_queues", "1"}, | ||
77 | { "nvme", "use-intel-id", "on"}, | ||
78 | { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */ | ||
79 | + { "pl011", "migrate-clk", "off" }, | ||
80 | }; | ||
81 | const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1); | ||
82 | |||
83 | -- | ||
84 | 2.20.1 | ||
85 | |||
86 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | The return value of the flatview_cb callback passed to the | ||
2 | flatview_for_each_range() function is zero if the iteration through | ||
3 | the ranges should continue, or non-zero to break out of it. Use a | ||
4 | bool for this rather than int. | ||
1 | 5 | ||
6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Message-id: 20210318174823.18066-2-peter.maydell@linaro.org | ||
10 | --- | ||
11 | include/exec/memory.h | 6 +++--- | ||
12 | tests/qtest/fuzz/generic_fuzz.c | 8 ++++---- | ||
13 | 2 files changed, 7 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/include/exec/memory.h b/include/exec/memory.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/exec/memory.h | ||
18 | +++ b/include/exec/memory.h | ||
19 | @@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as) | ||
20 | return qatomic_rcu_read(&as->current_map); | ||
21 | } | ||
22 | |||
23 | -typedef int (*flatview_cb)(Int128 start, | ||
24 | - Int128 len, | ||
25 | - const MemoryRegion*, void*); | ||
26 | +typedef bool (*flatview_cb)(Int128 start, | ||
27 | + Int128 len, | ||
28 | + const MemoryRegion*, void*); | ||
29 | |||
30 | void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque); | ||
31 | |||
32 | diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/tests/qtest/fuzz/generic_fuzz.c | ||
35 | +++ b/tests/qtest/fuzz/generic_fuzz.c | ||
36 | @@ -XXX,XX +XXX,XX @@ struct get_io_cb_info { | ||
37 | address_range result; | ||
38 | }; | ||
39 | |||
40 | -static int get_io_address_cb(Int128 start, Int128 size, | ||
41 | - const MemoryRegion *mr, void *opaque) { | ||
42 | +static bool get_io_address_cb(Int128 start, Int128 size, | ||
43 | + const MemoryRegion *mr, void *opaque) { | ||
44 | struct get_io_cb_info *info = opaque; | ||
45 | if (g_hash_table_lookup(fuzzable_memoryregions, mr)) { | ||
46 | if (info->index == 0) { | ||
47 | info->result.addr = (ram_addr_t)start; | ||
48 | info->result.size = (ram_addr_t)size; | ||
49 | info->found = 1; | ||
50 | - return 1; | ||
51 | + return true; | ||
52 | } | ||
53 | info->index--; | ||
54 | } | ||
55 | - return 0; | ||
56 | + return false; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | -- | ||
61 | 2.20.1 | ||
62 | |||
63 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Add a documentation comment describing flatview_for_each_range(). | ||
1 | 2 | ||
3 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
6 | Message-id: 20210318174823.18066-3-peter.maydell@linaro.org | ||
7 | --- | ||
8 | include/exec/memory.h | 26 ++++++++++++++++++++++++-- | ||
9 | 1 file changed, 24 insertions(+), 2 deletions(-) | ||
10 | |||
11 | diff --git a/include/exec/memory.h b/include/exec/memory.h | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/include/exec/memory.h | ||
14 | +++ b/include/exec/memory.h | ||
15 | @@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as) | ||
16 | return qatomic_rcu_read(&as->current_map); | ||
17 | } | ||
18 | |||
19 | +/** | ||
20 | + * typedef flatview_cb: callback for flatview_for_each_range() | ||
21 | + * | ||
22 | + * @start: start address of the range within the FlatView | ||
23 | + * @len: length of the range in bytes | ||
24 | + * @mr: MemoryRegion covering this range | ||
25 | + * @opaque: data pointer passed to flatview_for_each_range() | ||
26 | + * | ||
27 | + * Returns: true to stop the iteration, false to keep going. | ||
28 | + */ | ||
29 | typedef bool (*flatview_cb)(Int128 start, | ||
30 | Int128 len, | ||
31 | - const MemoryRegion*, void*); | ||
32 | + const MemoryRegion *mr, | ||
33 | + void *opaque); | ||
34 | |||
35 | -void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque); | ||
36 | +/** | ||
37 | + * flatview_for_each_range: Iterate through a FlatView | ||
38 | + * @fv: the FlatView to iterate through | ||
39 | + * @cb: function to call for each range | ||
40 | + * @opaque: opaque data pointer to pass to @cb | ||
41 | + * | ||
42 | + * A FlatView is made up of a list of non-overlapping ranges, each of | ||
43 | + * which is a slice of a MemoryRegion. This function iterates through | ||
44 | + * each range in @fv, calling @cb. The callback function can terminate | ||
45 | + * iteration early by returning 'true'. | ||
46 | + */ | ||
47 | +void flatview_for_each_range(FlatView *fv, flatview_cb cb, void *opaque); | ||
48 | |||
49 | /** | ||
50 | * struct MemoryRegionSection: describes a fragment of a #MemoryRegion | ||
51 | -- | ||
52 | 2.20.1 | ||
53 | |||
54 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | The function flatview_for_each_range() calls a callback for each | ||
2 | range in a FlatView. Currently the callback gets the start and | ||
3 | length of the range and the MemoryRegion involved, but not the offset | ||
4 | within the MemoryRegion. Add this to the callback's arguments; we're | ||
5 | going to want it for a new use in the next commit. | ||
1 | 6 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
10 | Message-id: 20210318174823.18066-4-peter.maydell@linaro.org | ||
11 | --- | ||
12 | include/exec/memory.h | 2 ++ | ||
13 | softmmu/memory.c | 4 +++- | ||
14 | tests/qtest/fuzz/generic_fuzz.c | 5 ++++- | ||
15 | 3 files changed, 9 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/include/exec/memory.h b/include/exec/memory.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/include/exec/memory.h | ||
20 | +++ b/include/exec/memory.h | ||
21 | @@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as) | ||
22 | * @start: start address of the range within the FlatView | ||
23 | * @len: length of the range in bytes | ||
24 | * @mr: MemoryRegion covering this range | ||
25 | + * @offset_in_region: offset of the first byte of the range within @mr | ||
26 | * @opaque: data pointer passed to flatview_for_each_range() | ||
27 | * | ||
28 | * Returns: true to stop the iteration, false to keep going. | ||
29 | @@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as) | ||
30 | typedef bool (*flatview_cb)(Int128 start, | ||
31 | Int128 len, | ||
32 | const MemoryRegion *mr, | ||
33 | + hwaddr offset_in_region, | ||
34 | void *opaque); | ||
35 | |||
36 | /** | ||
37 | diff --git a/softmmu/memory.c b/softmmu/memory.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/softmmu/memory.c | ||
40 | +++ b/softmmu/memory.c | ||
41 | @@ -XXX,XX +XXX,XX @@ void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque) | ||
42 | assert(cb); | ||
43 | |||
44 | FOR_EACH_FLAT_RANGE(fr, fv) { | ||
45 | - if (cb(fr->addr.start, fr->addr.size, fr->mr, opaque)) | ||
46 | + if (cb(fr->addr.start, fr->addr.size, fr->mr, | ||
47 | + fr->offset_in_region, opaque)) { | ||
48 | break; | ||
49 | + } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/tests/qtest/fuzz/generic_fuzz.c | ||
56 | +++ b/tests/qtest/fuzz/generic_fuzz.c | ||
57 | @@ -XXX,XX +XXX,XX @@ struct get_io_cb_info { | ||
58 | }; | ||
59 | |||
60 | static bool get_io_address_cb(Int128 start, Int128 size, | ||
61 | - const MemoryRegion *mr, void *opaque) { | ||
62 | + const MemoryRegion *mr, | ||
63 | + hwaddr offset_in_region, | ||
64 | + void *opaque) | ||
65 | +{ | ||
66 | struct get_io_cb_info *info = opaque; | ||
67 | if (g_hash_table_lookup(fuzzable_memoryregions, mr)) { | ||
68 | if (info->index == 0) { | ||
69 | -- | ||
70 | 2.20.1 | ||
71 | |||
72 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | For accesses to rom blob data before or during reset, we have a | ||
2 | function rom_ptr() which looks for a rom blob that would be loaded to | ||
3 | the specified address, and returns a pointer into the rom blob data | ||
4 | corresponding to that address. This allows board or CPU code to say | ||
5 | "what is the data that is going to be loaded to this address?". | ||
1 | 6 | ||
7 | However, this function does not take account of memory region | ||
8 | aliases. If for instance a machine model has RAM at address | ||
9 | 0x0000_0000 which is aliased to also appear at 0x1000_0000, a | ||
10 | rom_ptr() query for address 0x0000_0000 will only return a match if | ||
11 | the guest image provided by the user was loaded at 0x0000_0000 and | ||
12 | not if it was loaded at 0x1000_0000, even though they are the same | ||
13 | RAM and a run-time guest CPU read of 0x0000_0000 will read the data | ||
14 | loaded to 0x1000_0000. | ||
15 | |||
16 | Provide a new function rom_ptr_for_as() which takes an AddressSpace | ||
17 | argument, so that it can check whether the MemoryRegion corresponding | ||
18 | to the address is also mapped anywhere else in the AddressSpace and | ||
19 | look for rom blobs that loaded to that alias. | ||
20 | |||
21 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
22 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
23 | Message-id: 20210318174823.18066-5-peter.maydell@linaro.org | ||
24 | --- | ||
25 | include/hw/loader.h | 31 +++++++++++++++++++ | ||
26 | hw/core/loader.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ | ||
27 | 2 files changed, 106 insertions(+) | ||
28 | |||
29 | diff --git a/include/hw/loader.h b/include/hw/loader.h | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/include/hw/loader.h | ||
32 | +++ b/include/hw/loader.h | ||
33 | @@ -XXX,XX +XXX,XX @@ void rom_transaction_end(bool commit); | ||
34 | |||
35 | int rom_copy(uint8_t *dest, hwaddr addr, size_t size); | ||
36 | void *rom_ptr(hwaddr addr, size_t size); | ||
37 | +/** | ||
38 | + * rom_ptr_for_as: Return a pointer to ROM blob data for the address | ||
39 | + * @as: AddressSpace to look for the ROM blob in | ||
40 | + * @addr: Address within @as | ||
41 | + * @size: size of data required in bytes | ||
42 | + * | ||
43 | + * Returns: pointer into the data which backs the matching ROM blob, | ||
44 | + * or NULL if no blob covers the address range. | ||
45 | + * | ||
46 | + * This function looks for a ROM blob which covers the specified range | ||
47 | + * of bytes of length @size starting at @addr within the address space | ||
48 | + * @as. This is useful for code which runs as part of board | ||
49 | + * initialization or CPU reset which wants to read data that is part | ||
50 | + * of a user-supplied guest image or other guest memory contents, but | ||
51 | + * which runs before the ROM loader's reset function has copied the | ||
52 | + * blobs into guest memory. | ||
53 | + * | ||
54 | + * rom_ptr_for_as() will look not just for blobs loaded directly to | ||
55 | + * the specified address, but also for blobs which were loaded to an | ||
56 | + * alias of the region at a different location in the AddressSpace. | ||
57 | + * In other words, if a machine model has RAM at address 0x0000_0000 | ||
58 | + * which is aliased to also appear at 0x1000_0000, rom_ptr_for_as() | ||
59 | + * will return the correct data whether the guest image was linked and | ||
60 | + * loaded at 0x0000_0000 or 0x1000_0000. Contrast rom_ptr(), which | ||
61 | + * will only return data if the image load address is an exact match | ||
62 | + * with the queried address. | ||
63 | + * | ||
64 | + * New code should prefer to use rom_ptr_for_as() instead of | ||
65 | + * rom_ptr(). | ||
66 | + */ | ||
67 | +void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size); | ||
68 | void hmp_info_roms(Monitor *mon, const QDict *qdict); | ||
69 | |||
70 | #define rom_add_file_fixed(_f, _a, _i) \ | ||
71 | diff --git a/hw/core/loader.c b/hw/core/loader.c | ||
72 | index XXXXXXX..XXXXXXX 100644 | ||
73 | --- a/hw/core/loader.c | ||
74 | +++ b/hw/core/loader.c | ||
75 | @@ -XXX,XX +XXX,XX @@ void *rom_ptr(hwaddr addr, size_t size) | ||
76 | return rom->data + (addr - rom->addr); | ||
77 | } | ||
78 | |||
79 | +typedef struct FindRomCBData { | ||
80 | + size_t size; /* Amount of data we want from ROM, in bytes */ | ||
81 | + MemoryRegion *mr; /* MR at the unaliased guest addr */ | ||
82 | + hwaddr xlat; /* Offset of addr within mr */ | ||
83 | + void *rom; /* Output: rom data pointer, if found */ | ||
84 | +} FindRomCBData; | ||
85 | + | ||
86 | +static bool find_rom_cb(Int128 start, Int128 len, const MemoryRegion *mr, | ||
87 | + hwaddr offset_in_region, void *opaque) | ||
88 | +{ | ||
89 | + FindRomCBData *cbdata = opaque; | ||
90 | + hwaddr alias_addr; | ||
91 | + | ||
92 | + if (mr != cbdata->mr) { | ||
93 | + return false; | ||
94 | + } | ||
95 | + | ||
96 | + alias_addr = int128_get64(start) + cbdata->xlat - offset_in_region; | ||
97 | + cbdata->rom = rom_ptr(alias_addr, cbdata->size); | ||
98 | + if (!cbdata->rom) { | ||
99 | + return false; | ||
100 | + } | ||
101 | + /* Found a match, stop iterating */ | ||
102 | + return true; | ||
103 | +} | ||
104 | + | ||
105 | +void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size) | ||
106 | +{ | ||
107 | + /* | ||
108 | + * Find any ROM data for the given guest address range. If there | ||
109 | + * is a ROM blob then return a pointer to the host memory | ||
110 | + * corresponding to 'addr'; otherwise return NULL. | ||
111 | + * | ||
112 | + * We look not only for ROM blobs that were loaded directly to | ||
113 | + * addr, but also for ROM blobs that were loaded to aliases of | ||
114 | + * that memory at other addresses within the AddressSpace. | ||
115 | + * | ||
116 | + * Note that we do not check @as against the 'as' member in the | ||
117 | + * 'struct Rom' returned by rom_ptr(). The Rom::as is the | ||
118 | + * AddressSpace which the rom blob should be written to, whereas | ||
119 | + * our @as argument is the AddressSpace which we are (effectively) | ||
120 | + * reading from, and the same underlying RAM will often be visible | ||
121 | + * in multiple AddressSpaces. (A common example is a ROM blob | ||
122 | + * written to the 'system' address space but then read back via a | ||
123 | + * CPU's cpu->as pointer.) This does mean we might potentially | ||
124 | + * return a false-positive match if a ROM blob was loaded into an | ||
125 | + * AS which is entirely separate and distinct from the one we're | ||
126 | + * querying, but this issue exists also for rom_ptr() and hasn't | ||
127 | + * caused any problems in practice. | ||
128 | + */ | ||
129 | + FlatView *fv; | ||
130 | + void *rom; | ||
131 | + hwaddr len_unused; | ||
132 | + FindRomCBData cbdata = {}; | ||
133 | + | ||
134 | + /* Easy case: there's data at the actual address */ | ||
135 | + rom = rom_ptr(addr, size); | ||
136 | + if (rom) { | ||
137 | + return rom; | ||
138 | + } | ||
139 | + | ||
140 | + RCU_READ_LOCK_GUARD(); | ||
141 | + | ||
142 | + fv = address_space_to_flatview(as); | ||
143 | + cbdata.mr = flatview_translate(fv, addr, &cbdata.xlat, &len_unused, | ||
144 | + false, MEMTXATTRS_UNSPECIFIED); | ||
145 | + if (!cbdata.mr) { | ||
146 | + /* Nothing at this address, so there can't be any aliasing */ | ||
147 | + return NULL; | ||
148 | + } | ||
149 | + cbdata.size = size; | ||
150 | + flatview_for_each_range(fv, find_rom_cb, &cbdata); | ||
151 | + return cbdata.rom; | ||
152 | +} | ||
153 | + | ||
154 | void hmp_info_roms(Monitor *mon, const QDict *qdict) | ||
155 | { | ||
156 | Rom *rom; | ||
157 | -- | ||
158 | 2.20.1 | ||
159 | |||
160 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | For Arm M-profile CPUs, on reset the CPU must load its initial PC and | ||
2 | SP from a vector table in guest memory. Because we can't guarantee | ||
3 | reset ordering, we have to handle the possibility that the ROM blob | ||
4 | loader's reset function has not yet run when the CPU resets, in which | ||
5 | case the data in an ELF file specified by the user won't be in guest | ||
6 | memory to be read yet. | ||
1 | 7 | ||
8 | We work around the reset ordering problem by checking whether the ROM | ||
9 | blob loader has any data for the address where the vector table is, | ||
10 | using rom_ptr(). Unfortunately this does not handle the possibility | ||
11 | of memory aliasing. For many M-profile boards, memory can be | ||
12 | accessed via multiple possible physical addresses; if the board has | ||
13 | the vector table at address X but the user's ELF file loads data via | ||
14 | a different address Y which is an alias to the same underlying guest | ||
15 | RAM then rom_ptr() will not find it. | ||
16 | |||
17 | Use the new rom_ptr_for_as() function, which deals with memory | ||
18 | aliasing when locating a relevant ROM blob. | ||
19 | |||
20 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
21 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
22 | Message-id: 20210318174823.18066-6-peter.maydell@linaro.org | ||
23 | --- | ||
24 | target/arm/cpu.c | 2 +- | ||
25 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
26 | |||
27 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/arm/cpu.c | ||
30 | +++ b/target/arm/cpu.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev) | ||
32 | |||
33 | /* Load the initial SP and PC from offset 0 and 4 in the vector table */ | ||
34 | vecbase = env->v7m.vecbase[env->v7m.secure]; | ||
35 | - rom = rom_ptr(vecbase, 8); | ||
36 | + rom = rom_ptr_for_as(s->as, vecbase, 8); | ||
37 | if (rom) { | ||
38 | /* Address zero is covered by ROM which hasn't yet been | ||
39 | * copied into physical memory. | ||
40 | -- | ||
41 | 2.20.1 | ||
42 | |||
43 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Richard Henderson <richard.henderson@linaro.org> | ||
1 | 2 | ||
3 | Pretend the fault always happens at page table level 3. | ||
4 | |||
5 | Failure to set this leaves level = 0, which is impossible for | ||
6 | ARMFault_Permission, and produces an invalid syndrome, which | ||
7 | reaches g_assert_not_reached in cpu_loop. | ||
8 | |||
9 | Fixes: 8db94ab4e5db ("linux-user/aarch64: Pass syndrome to EXC_*_ABORT") | ||
10 | Reported-by: Laurent Vivier <laurent@vivier.eu> | ||
11 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | Message-id: 20210320000606.1788699-1-richard.henderson@linaro.org | ||
14 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
15 | --- | ||
16 | target/arm/tlb_helper.c | 1 + | ||
17 | 1 file changed, 1 insertion(+) | ||
18 | |||
19 | diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/arm/tlb_helper.c | ||
22 | +++ b/target/arm/tlb_helper.c | ||
23 | @@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
24 | } else { | ||
25 | fi.type = ARMFault_Translation; | ||
26 | } | ||
27 | + fi.level = 3; | ||
28 | |||
29 | /* now we have a real cpu fault */ | ||
30 | cpu_restore_state(cs, retaddr, true); | ||
31 | -- | ||
32 | 2.20.1 | ||
33 | |||
34 | diff view generated by jsdifflib |