1 | ARM queue for 2.10: all M profile bugfixes... | 1 | A last handful of patches before the rc0. These are all bugfixes |
---|---|---|---|
2 | so they could equally well go into rc1, but since my pullreq | ||
3 | queue is otherwise empty I might as well push them out. The | ||
4 | FPSCR bugfix is definitely one I'd like in rc0; the rest are | ||
5 | not really user-visible I think. | ||
2 | 6 | ||
3 | thanks | 7 | thanks |
4 | -- PMM | 8 | -- PMM |
5 | 9 | ||
6 | The following changes since commit 25dd0e77898c3e10796d4cbeb35e8af5ba6ce975: | 10 | The following changes since commit c4107e8208d0222f9b328691b519aaee4101db87: |
7 | 11 | ||
8 | Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-fetch' into staging (2017-07-31 11:27:43 +0100) | 12 | Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2019-07-08 10:26:18 +0100) |
9 | 13 | ||
10 | are available in the git repository at: | 14 | are available in the Git repository at: |
11 | 15 | ||
12 | git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170731 | 16 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190708 |
13 | 17 | ||
14 | for you to fetch changes up to 89cbc3778a3d61761e2231e740269218c9a8a41d: | 18 | for you to fetch changes up to 85795187f416326f87177cabc39fae1911f04c50: |
15 | 19 | ||
16 | hw/mps2_scc: fix incorrect properties (2017-07-31 13:11:56 +0100) | 20 | target/arm/vfp_helper: Call set_fpscr_to_host before updating to FPSCR (2019-07-08 14:11:31 +0100) |
17 | 21 | ||
18 | ---------------------------------------------------------------- | 22 | ---------------------------------------------------------------- |
19 | target-arm queue: | 23 | target-arm queue: |
20 | * fix broken properties on MPS2 SCC device | 24 | * tests/migration-test: Fix read off end of aarch64_kernel array |
21 | * fix MPU trace handling of write vs exec | 25 | * Fix sve_zcr_len_for_el off-by-one error |
22 | * fix MPU M profile bugs: | 26 | * hw/arm/sbsa-ref: Silence Coverity nit |
23 | - not handling system space or PPB region correctly | 27 | * vfp_helper: Call set_fpscr_to_host before updating to FPSCR |
24 | - not resetting state | ||
25 | - not migrating MPU_RNR | ||
26 | 28 | ||
27 | ---------------------------------------------------------------- | 29 | ---------------------------------------------------------------- |
28 | Peter Maydell (6): | 30 | Peter Maydell (2): |
29 | target/arm: Correct MPU trace handling of write vs execute | 31 | tests/migration-test: Fix read off end of aarch64_kernel array |
30 | target/arm: Don't do MPU lookups for addresses in M profile PPB region | 32 | hw/arm/sbsa-ref: Remove unnecessary check for secure_sysmem == NULL |
31 | target/arm: Don't allow guest to make System space executable for M profile | ||
32 | target/arm: Rename cp15.c6_rgnr to pmsav7.rnr | ||
33 | target/arm: Move PMSAv7 reset into arm_cpu_reset() so M profile MPUs get reset | ||
34 | target/arm: Migrate MPU_RNR register state for M profile cores | ||
35 | 33 | ||
36 | Philippe Mathieu-Daudé (1): | 34 | Philippe Mathieu-Daudé (1): |
37 | hw/mps2_scc: fix incorrect properties | 35 | target/arm/vfp_helper: Call set_fpscr_to_host before updating to FPSCR |
38 | 36 | ||
39 | target/arm/cpu.h | 3 +-- | 37 | Richard Henderson (1): |
40 | hw/intc/armv7m_nvic.c | 14 +++++----- | 38 | target/arm: Fix sve_zcr_len_for_el |
41 | hw/misc/mps2-scc.c | 4 +-- | ||
42 | target/arm/cpu.c | 14 ++++++++++ | ||
43 | target/arm/helper.c | 71 ++++++++++++++++++++++++++++++++++----------------- | ||
44 | target/arm/machine.c | 30 +++++++++++++++++++++- | ||
45 | 6 files changed, 101 insertions(+), 35 deletions(-) | ||
46 | 39 | ||
40 | hw/arm/sbsa-ref.c | 8 ++------ | ||
41 | target/arm/helper.c | 4 ++-- | ||
42 | target/arm/vfp_helper.c | 4 ++-- | ||
43 | tests/migration-test.c | 22 +++++++--------------- | ||
44 | 4 files changed, 13 insertions(+), 25 deletions(-) | ||
45 | diff view generated by jsdifflib |
1 | Correct off-by-one bug in the PSMAv7 MPU tracing where it would print | 1 | From: Richard Henderson <richard.henderson@linaro.org> |
---|---|---|---|
2 | a write access as "reading", an insn fetch as "writing", and a read | ||
3 | access as "execute". | ||
4 | 2 | ||
5 | Since we have an MMUAccessType enum now, we can make the code clearer | 3 | Off by one error in the EL2 and EL3 tests. Remove the test |
6 | in the process by using that rather than the raw 0/1/2 values. | 4 | against EL3 entirely, since it must always be true. |
7 | 5 | ||
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
8 | Message-id: 20190702104732.31154-1-richard.henderson@linaro.org | ||
8 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
9 | Reviewed-by: Richard Henderson <rth@twiddle.net> | ||
10 | Message-id: 1500906792-18010-1-git-send-email-peter.maydell@linaro.org | ||
11 | --- | 10 | --- |
12 | target/arm/helper.c | 4 ++-- | 11 | target/arm/helper.c | 4 ++-- |
13 | 1 file changed, 2 insertions(+), 2 deletions(-) | 12 | 1 file changed, 2 insertions(+), 2 deletions(-) |
14 | 13 | ||
15 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 14 | diff --git a/target/arm/helper.c b/target/arm/helper.c |
16 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/helper.c | 16 | --- a/target/arm/helper.c |
18 | +++ b/target/arm/helper.c | 17 | +++ b/target/arm/helper.c |
19 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, | 18 | @@ -XXX,XX +XXX,XX @@ uint32_t sve_zcr_len_for_el(CPUARMState *env, int el) |
20 | phys_ptr, prot, fsr); | 19 | if (el <= 1) { |
21 | qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32 | 20 | zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]); |
22 | " mmu_idx %u -> %s (prot %c%c%c)\n", | 21 | } |
23 | - access_type == 1 ? "reading" : | 22 | - if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) { |
24 | - (access_type == 2 ? "writing" : "execute"), | 23 | + if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) { |
25 | + access_type == MMU_DATA_LOAD ? "reading" : | 24 | zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]); |
26 | + (access_type == MMU_DATA_STORE ? "writing" : "execute"), | 25 | } |
27 | (uint32_t)address, mmu_idx, | 26 | - if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) { |
28 | ret ? "Miss" : "Hit", | 27 | + if (arm_feature(env, ARM_FEATURE_EL3)) { |
29 | *prot & PAGE_READ ? 'r' : '-', | 28 | zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]); |
29 | } | ||
30 | return zcr_len; | ||
30 | -- | 31 | -- |
31 | 2.7.4 | 32 | 2.20.1 |
32 | 33 | ||
33 | 34 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | The M profile PMSAv7 specification says that if the address being looked | ||
2 | up is in the PPB region (0xe0000000 - 0xe00fffff) then we do not use | ||
3 | the MPU regions but always use the default memory map. Implement this | ||
4 | (we were previously behaving like an R profile PMSAv7, which does not | ||
5 | special case this). | ||
6 | 1 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Message-id: 1501153150-19984-2-git-send-email-peter.maydell@linaro.org | ||
10 | --- | ||
11 | target/arm/helper.c | 17 ++++++++++++++++- | ||
12 | 1 file changed, 16 insertions(+), 1 deletion(-) | ||
13 | |||
14 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/arm/helper.c | ||
17 | +++ b/target/arm/helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, | ||
19 | } | ||
20 | } | ||
21 | |||
22 | +static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address) | ||
23 | +{ | ||
24 | + /* True if address is in the M profile PPB region 0xe0000000 - 0xe00fffff */ | ||
25 | + return arm_feature(env, ARM_FEATURE_M) && | ||
26 | + extract32(address, 20, 12) == 0xe00; | ||
27 | +} | ||
28 | + | ||
29 | static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
30 | int access_type, ARMMMUIdx mmu_idx, | ||
31 | hwaddr *phys_ptr, int *prot, uint32_t *fsr) | ||
32 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
33 | *phys_ptr = address; | ||
34 | *prot = 0; | ||
35 | |||
36 | - if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ | ||
37 | + if (regime_translation_disabled(env, mmu_idx) || | ||
38 | + m_is_ppb_region(env, address)) { | ||
39 | + /* MPU disabled or M profile PPB access: use default memory map. | ||
40 | + * The other case which uses the default memory map in the | ||
41 | + * v7M ARM ARM pseudocode is exception vector reads from the vector | ||
42 | + * table. In QEMU those accesses are done in arm_v7m_load_vector(), | ||
43 | + * which always does a direct read using address_space_ldl(), rather | ||
44 | + * than going via this function, so we don't need to check that here. | ||
45 | + */ | ||
46 | get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); | ||
47 | } else { /* MPU enabled */ | ||
48 | for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { | ||
49 | -- | ||
50 | 2.7.4 | ||
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | For an M profile v7PMSA, the system space (0xe0000000 - 0xffffffff) can | ||
2 | never be executable, even if the guest tries to set the MPU registers | ||
3 | up that way. Enforce this restriction. | ||
4 | 1 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
6 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
7 | Message-id: 1501153150-19984-3-git-send-email-peter.maydell@linaro.org | ||
8 | --- | ||
9 | target/arm/helper.c | 16 +++++++++++++++- | ||
10 | 1 file changed, 15 insertions(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/arm/helper.c | ||
15 | +++ b/target/arm/helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address) | ||
17 | extract32(address, 20, 12) == 0xe00; | ||
18 | } | ||
19 | |||
20 | +static inline bool m_is_system_region(CPUARMState *env, uint32_t address) | ||
21 | +{ | ||
22 | + /* True if address is in the M profile system region | ||
23 | + * 0xe0000000 - 0xffffffff | ||
24 | + */ | ||
25 | + return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7; | ||
26 | +} | ||
27 | + | ||
28 | static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
29 | int access_type, ARMMMUIdx mmu_idx, | ||
30 | hwaddr *phys_ptr, int *prot, uint32_t *fsr) | ||
31 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
32 | get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); | ||
33 | } else { /* a MPU hit! */ | ||
34 | uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); | ||
35 | + uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1); | ||
36 | + | ||
37 | + if (m_is_system_region(env, address)) { | ||
38 | + /* System space is always execute never */ | ||
39 | + xn = 1; | ||
40 | + } | ||
41 | |||
42 | if (is_user) { /* User mode AP bit decoding */ | ||
43 | switch (ap) { | ||
44 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, | ||
45 | } | ||
46 | |||
47 | /* execute never */ | ||
48 | - if (env->pmsav7.dracr[n] & (1 << 12)) { | ||
49 | + if (xn) { | ||
50 | *prot &= ~PAGE_EXEC; | ||
51 | } | ||
52 | } | ||
53 | -- | ||
54 | 2.7.4 | ||
55 | |||
56 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Almost all of the PMSAv7 state is in the pmsav7 substruct of | ||
2 | the ARM CPU state structure. The exception is the region | ||
3 | number register, which is in cp15.c6_rgnr. This exception | ||
4 | is a bit odd for M profile, which otherwise generally does | ||
5 | not store state in the cp15 substruct. | ||
6 | 1 | ||
7 | Rename cp15.c6_rgnr to pmsav7.rnr accordingly. | ||
8 | |||
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
11 | Message-id: 1501153150-19984-4-git-send-email-peter.maydell@linaro.org | ||
12 | --- | ||
13 | target/arm/cpu.h | 3 +-- | ||
14 | hw/intc/armv7m_nvic.c | 14 +++++++------- | ||
15 | target/arm/helper.c | 6 +++--- | ||
16 | target/arm/machine.c | 2 +- | ||
17 | 4 files changed, 12 insertions(+), 13 deletions(-) | ||
18 | |||
19 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/arm/cpu.h | ||
22 | +++ b/target/arm/cpu.h | ||
23 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState { | ||
24 | uint64_t par_el[4]; | ||
25 | }; | ||
26 | |||
27 | - uint32_t c6_rgnr; | ||
28 | - | ||
29 | uint32_t c9_insn; /* Cache lockdown registers. */ | ||
30 | uint32_t c9_data; | ||
31 | uint64_t c9_pmcr; /* performance monitor control register */ | ||
32 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState { | ||
33 | uint32_t *drbar; | ||
34 | uint32_t *drsr; | ||
35 | uint32_t *dracr; | ||
36 | + uint32_t rnr; | ||
37 | } pmsav7; | ||
38 | |||
39 | void *nvic; | ||
40 | diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/hw/intc/armv7m_nvic.c | ||
43 | +++ b/hw/intc/armv7m_nvic.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) | ||
45 | case 0xd94: /* MPU_CTRL */ | ||
46 | return cpu->env.v7m.mpu_ctrl; | ||
47 | case 0xd98: /* MPU_RNR */ | ||
48 | - return cpu->env.cp15.c6_rgnr; | ||
49 | + return cpu->env.pmsav7.rnr; | ||
50 | case 0xd9c: /* MPU_RBAR */ | ||
51 | case 0xda4: /* MPU_RBAR_A1 */ | ||
52 | case 0xdac: /* MPU_RBAR_A2 */ | ||
53 | case 0xdb4: /* MPU_RBAR_A3 */ | ||
54 | { | ||
55 | - int region = cpu->env.cp15.c6_rgnr; | ||
56 | + int region = cpu->env.pmsav7.rnr; | ||
57 | |||
58 | if (region >= cpu->pmsav7_dregion) { | ||
59 | return 0; | ||
60 | @@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) | ||
61 | case 0xdb0: /* MPU_RASR_A2 */ | ||
62 | case 0xdb8: /* MPU_RASR_A3 */ | ||
63 | { | ||
64 | - int region = cpu->env.cp15.c6_rgnr; | ||
65 | + int region = cpu->env.pmsav7.rnr; | ||
66 | |||
67 | if (region >= cpu->pmsav7_dregion) { | ||
68 | return 0; | ||
69 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
70 | PRIu32 "/%" PRIu32 "\n", | ||
71 | value, cpu->pmsav7_dregion); | ||
72 | } else { | ||
73 | - cpu->env.cp15.c6_rgnr = value; | ||
74 | + cpu->env.pmsav7.rnr = value; | ||
75 | } | ||
76 | break; | ||
77 | case 0xd9c: /* MPU_RBAR */ | ||
78 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
79 | region, cpu->pmsav7_dregion); | ||
80 | return; | ||
81 | } | ||
82 | - cpu->env.cp15.c6_rgnr = region; | ||
83 | + cpu->env.pmsav7.rnr = region; | ||
84 | } else { | ||
85 | - region = cpu->env.cp15.c6_rgnr; | ||
86 | + region = cpu->env.pmsav7.rnr; | ||
87 | } | ||
88 | |||
89 | if (region >= cpu->pmsav7_dregion) { | ||
90 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) | ||
91 | case 0xdb0: /* MPU_RASR_A2 */ | ||
92 | case 0xdb8: /* MPU_RASR_A3 */ | ||
93 | { | ||
94 | - int region = cpu->env.cp15.c6_rgnr; | ||
95 | + int region = cpu->env.pmsav7.rnr; | ||
96 | |||
97 | if (region >= cpu->pmsav7_dregion) { | ||
98 | return; | ||
99 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/target/arm/helper.c | ||
102 | +++ b/target/arm/helper.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | - u32p += env->cp15.c6_rgnr; | ||
108 | + u32p += env->pmsav7.rnr; | ||
109 | return *u32p; | ||
110 | } | ||
111 | |||
112 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | - u32p += env->cp15.c6_rgnr; | ||
117 | + u32p += env->pmsav7.rnr; | ||
118 | tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ | ||
119 | *u32p = value; | ||
120 | } | ||
121 | @@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = { | ||
122 | .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | ||
123 | { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, | ||
124 | .access = PL1_RW, | ||
125 | - .fieldoffset = offsetof(CPUARMState, cp15.c6_rgnr), | ||
126 | + .fieldoffset = offsetof(CPUARMState, pmsav7.rnr), | ||
127 | .writefn = pmsav7_rgnr_write }, | ||
128 | REGINFO_SENTINEL | ||
129 | }; | ||
130 | diff --git a/target/arm/machine.c b/target/arm/machine.c | ||
131 | index XXXXXXX..XXXXXXX 100644 | ||
132 | --- a/target/arm/machine.c | ||
133 | +++ b/target/arm/machine.c | ||
134 | @@ -XXX,XX +XXX,XX @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) | ||
135 | { | ||
136 | ARMCPU *cpu = opaque; | ||
137 | |||
138 | - return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion; | ||
139 | + return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion; | ||
140 | } | ||
141 | |||
142 | static const VMStateDescription vmstate_pmsav7 = { | ||
143 | -- | ||
144 | 2.7.4 | ||
145 | |||
146 | diff view generated by jsdifflib |
1 | When the PMSAv7 implementation was originally added it was for R profile | 1 | The test aarch64 kernel is in an array defined with |
---|---|---|---|
2 | CPUs only, and reset was handled using the cpreg .resetfn hooks. | 2 | unsigned char aarch64_kernel[] = { [...] } |
3 | Unfortunately for M profile cores this doesn't work, because they do | 3 | |
4 | not register any cpregs. Move the reset handling into arm_cpu_reset(), | 4 | which means it could be any size; currently it's quite small. |
5 | where it will work for both R profile and M profile cores. | 5 | However we write it to a file using init_bootfile(), which |
6 | writes exactly 512 bytes to the file. This will break if | ||
7 | we ever end up with a kernel larger than that, and will | ||
8 | read garbage off the end of the array in the current setup | ||
9 | where the kernel is smaller. | ||
10 | |||
11 | Make init_bootfile() take an argument giving the length of | ||
12 | the data to write. This allows us to use it for all architectures | ||
13 | (previously s390 had a special-purpose init_bootfile_s390x | ||
14 | which hardcoded the file to write so it could write the | ||
15 | correct length). We assert that the x86 bootfile really is | ||
16 | exactly 512 bytes as it should be (and as we were previously | ||
17 | just assuming it was). | ||
18 | |||
19 | This was detected by the clang-7 asan: | ||
20 | ==15607==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55a796f51d20 at pc 0x55a796b89c2f bp 0x7ffc58e89160 sp 0x7ffc58e88908 | ||
21 | READ of size 512 at 0x55a796f51d20 thread T0 | ||
22 | #0 0x55a796b89c2e in fwrite (/home/petmay01/linaro/qemu-from-laptop/qemu/build/sanitizers/tests/migration-test+0xb0c2e) | ||
23 | #1 0x55a796c46492 in init_bootfile /home/petmay01/linaro/qemu-from-laptop/qemu/tests/migration-test.c:99:5 | ||
24 | #2 0x55a796c46492 in test_migrate_start /home/petmay01/linaro/qemu-from-laptop/qemu/tests/migration-test.c:593 | ||
25 | #3 0x55a796c44101 in test_baddest /home/petmay01/linaro/qemu-from-laptop/qemu/tests/migration-test.c:854:9 | ||
26 | #4 0x7f906ffd3cc9 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72cc9) | ||
27 | #5 0x7f906ffd3bfa (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72bfa) | ||
28 | #6 0x7f906ffd3bfa (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72bfa) | ||
29 | #7 0x7f906ffd3ea1 in g_test_run_suite (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72ea1) | ||
30 | #8 0x7f906ffd3ec0 in g_test_run (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72ec0) | ||
31 | #9 0x55a796c43707 in main /home/petmay01/linaro/qemu-from-laptop/qemu/tests/migration-test.c:1187:11 | ||
32 | #10 0x7f906e9abb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 | ||
33 | #11 0x55a796b6c2d9 in _start (/home/petmay01/linaro/qemu-from-laptop/qemu/build/sanitizers/tests/migration-test+0x932d9) | ||
6 | 34 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 35 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 36 | Reviewed-by: Laurent Vivier <lvivier@redhat.com> |
9 | Message-id: 1501153150-19984-5-git-send-email-peter.maydell@linaro.org | 37 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
38 | Message-id: 20190702150311.20467-1-peter.maydell@linaro.org | ||
10 | --- | 39 | --- |
11 | target/arm/cpu.c | 14 ++++++++++++++ | 40 | tests/migration-test.c | 22 +++++++--------------- |
12 | target/arm/helper.c | 28 ++++++++++++---------------- | 41 | 1 file changed, 7 insertions(+), 15 deletions(-) |
13 | 2 files changed, 26 insertions(+), 16 deletions(-) | ||
14 | 42 | ||
15 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | 43 | diff --git a/tests/migration-test.c b/tests/migration-test.c |
16 | index XXXXXXX..XXXXXXX 100644 | 44 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/cpu.c | 45 | --- a/tests/migration-test.c |
18 | +++ b/target/arm/cpu.c | 46 | +++ b/tests/migration-test.c |
19 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s) | 47 | @@ -XXX,XX +XXX,XX @@ static const char *tmpfs; |
20 | 48 | */ | |
21 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; | 49 | #include "tests/migration/i386/a-b-bootblock.h" |
22 | #endif | 50 | #include "tests/migration/aarch64/a-b-kernel.h" |
23 | + | 51 | - |
24 | + if (arm_feature(env, ARM_FEATURE_PMSA) && | 52 | -static void init_bootfile(const char *bootpath, void *content) |
25 | + arm_feature(env, ARM_FEATURE_V7)) { | ||
26 | + if (cpu->pmsav7_dregion > 0) { | ||
27 | + memset(env->pmsav7.drbar, 0, | ||
28 | + sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); | ||
29 | + memset(env->pmsav7.drsr, 0, | ||
30 | + sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); | ||
31 | + memset(env->pmsav7.dracr, 0, | ||
32 | + sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); | ||
33 | + } | ||
34 | + env->pmsav7.rnr = 0; | ||
35 | + } | ||
36 | + | ||
37 | set_flush_to_zero(1, &env->vfp.standard_fp_status); | ||
38 | set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); | ||
39 | set_default_nan_mode(1, &env->vfp.standard_fp_status); | ||
40 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/arm/helper.c | ||
43 | +++ b/target/arm/helper.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
45 | *u32p = value; | ||
46 | } | ||
47 | |||
48 | -static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri) | ||
49 | -{ | 53 | -{ |
50 | - ARMCPU *cpu = arm_env_get_cpu(env); | 54 | - FILE *bootfile = fopen(bootpath, "wb"); |
51 | - uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); | ||
52 | - | 55 | - |
53 | - if (!u32p) { | 56 | - g_assert_cmpint(fwrite(content, 512, 1, bootfile), ==, 1); |
54 | - return; | 57 | - fclose(bootfile); |
55 | - } | ||
56 | - | ||
57 | - memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion); | ||
58 | -} | 58 | -} |
59 | - | 59 | - |
60 | static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, | 60 | #include "tests/migration/s390x/a-b-bios.h" |
61 | uint64_t value) | 61 | |
62 | -static void init_bootfile_s390x(const char *bootpath) | ||
63 | +static void init_bootfile(const char *bootpath, void *content, size_t len) | ||
62 | { | 64 | { |
63 | @@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, | 65 | FILE *bootfile = fopen(bootpath, "wb"); |
66 | - size_t len = sizeof(s390x_elf); | ||
67 | |||
68 | - g_assert_cmpint(fwrite(s390x_elf, len, 1, bootfile), ==, 1); | ||
69 | + g_assert_cmpint(fwrite(content, len, 1, bootfile), ==, 1); | ||
70 | fclose(bootfile); | ||
64 | } | 71 | } |
65 | 72 | ||
66 | static const ARMCPRegInfo pmsav7_cp_reginfo[] = { | 73 | @@ -XXX,XX +XXX,XX @@ static int test_migrate_start(QTestState **from, QTestState **to, |
67 | + /* Reset for all these registers is handled in arm_cpu_reset(), | 74 | got_stop = false; |
68 | + * because the PMSAv7 is also used by M-profile CPUs, which do | 75 | bootpath = g_strdup_printf("%s/bootsect", tmpfs); |
69 | + * not register cpregs but still need the state to be reset. | 76 | if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { |
70 | + */ | 77 | - init_bootfile(bootpath, x86_bootsect); |
71 | { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, | 78 | + /* the assembled x86 boot sector should be exactly one sector large */ |
72 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | 79 | + assert(sizeof(x86_bootsect) == 512); |
73 | .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), | 80 | + init_bootfile(bootpath, x86_bootsect, sizeof(x86_bootsect)); |
74 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | 81 | extra_opts = use_shmem ? get_shmem_opts("150M", shmem_path) : NULL; |
75 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | 82 | cmd_src = g_strdup_printf("-machine accel=%s -m 150M" |
76 | + .resetfn = arm_cp_reset_ignore }, | 83 | " -name source,debug-threads=on" |
77 | { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, | 84 | @@ -XXX,XX +XXX,XX @@ static int test_migrate_start(QTestState **from, QTestState **to, |
78 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | 85 | start_address = X86_TEST_MEM_START; |
79 | .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), | 86 | end_address = X86_TEST_MEM_END; |
80 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | 87 | } else if (g_str_equal(arch, "s390x")) { |
81 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | 88 | - init_bootfile_s390x(bootpath); |
82 | + .resetfn = arm_cp_reset_ignore }, | 89 | + init_bootfile(bootpath, s390x_elf, sizeof(s390x_elf)); |
83 | { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, | 90 | extra_opts = use_shmem ? get_shmem_opts("128M", shmem_path) : NULL; |
84 | .access = PL1_RW, .type = ARM_CP_NO_RAW, | 91 | cmd_src = g_strdup_printf("-machine accel=%s -m 128M" |
85 | .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), | 92 | " -name source,debug-threads=on" |
86 | - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, | 93 | @@ -XXX,XX +XXX,XX @@ static int test_migrate_start(QTestState **from, QTestState **to, |
87 | + .readfn = pmsav7_read, .writefn = pmsav7_write, | 94 | start_address = PPC_TEST_MEM_START; |
88 | + .resetfn = arm_cp_reset_ignore }, | 95 | end_address = PPC_TEST_MEM_END; |
89 | { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, | 96 | } else if (strcmp(arch, "aarch64") == 0) { |
90 | .access = PL1_RW, | 97 | - init_bootfile(bootpath, aarch64_kernel); |
91 | .fieldoffset = offsetof(CPUARMState, pmsav7.rnr), | 98 | + init_bootfile(bootpath, aarch64_kernel, sizeof(aarch64_kernel)); |
92 | - .writefn = pmsav7_rgnr_write }, | 99 | extra_opts = use_shmem ? get_shmem_opts("150M", shmem_path) : NULL; |
93 | + .writefn = pmsav7_rgnr_write, | 100 | cmd_src = g_strdup_printf("-machine virt,accel=%s,gic-version=max " |
94 | + .resetfn = arm_cp_reset_ignore }, | 101 | "-name vmsource,debug-threads=on -cpu max " |
95 | REGINFO_SENTINEL | ||
96 | }; | ||
97 | |||
98 | -- | 102 | -- |
99 | 2.7.4 | 103 | 2.20.1 |
100 | 104 | ||
101 | 105 | diff view generated by jsdifflib |
1 | The PMSAv7 region number register is migrated for R profile | 1 | In the virt machine, we support TrustZone being either present or |
---|---|---|---|
2 | cores using the cpreg scheme, but M profile doesn't use | 2 | absent, and so the code must deal with the secure_sysmem pointer |
3 | cpregs, and so we weren't migrating the MPU_RNR register state | 3 | possibly being NULL. In the sbsa-ref machine, TrustZone is always |
4 | at all. Fix that by adding a migration subsection for the | 4 | present, but some code and comments copied from virt still treat |
5 | M profile case. | 5 | it as possibly not being present. |
6 | |||
7 | This causes Coverity to complain (CID 1407287) that we check | ||
8 | secure_sysmem for being NULL after an unconditional dereference. | ||
9 | Simplify the code so that instead of initializing the variable | ||
10 | to NULL, unconditionally assigning it, and then testing it for NULL, | ||
11 | we just initialize it correctly in the variable declaration and | ||
12 | then assume it to be non-NULL. We also delete a comment which | ||
13 | only applied to the non-TrustZone config. | ||
6 | 14 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 16 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
9 | Message-id: 1501153150-19984-6-git-send-email-peter.maydell@linaro.org | 17 | Message-id: 20190704142004.7150-1-peter.maydell@linaro.org |
18 | Tested-by: Radosław Biernacki <radoslaw.biernacki@linaro.org> | ||
19 | Reviewed-by: Radosław Biernacki <radoslaw.biernacki@linaro.org> | ||
10 | --- | 20 | --- |
11 | target/arm/machine.c | 28 ++++++++++++++++++++++++++++ | 21 | hw/arm/sbsa-ref.c | 8 ++------ |
12 | 1 file changed, 28 insertions(+) | 22 | 1 file changed, 2 insertions(+), 6 deletions(-) |
13 | 23 | ||
14 | diff --git a/target/arm/machine.c b/target/arm/machine.c | 24 | diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c |
15 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/target/arm/machine.c | 26 | --- a/hw/arm/sbsa-ref.c |
17 | +++ b/target/arm/machine.c | 27 | +++ b/hw/arm/sbsa-ref.c |
18 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav7 = { | 28 | @@ -XXX,XX +XXX,XX @@ static void sbsa_flash_map(SBSAMachineState *sms, |
19 | } | 29 | * sysmem is the system memory space. secure_sysmem is the secure view |
20 | }; | 30 | * of the system, and the first flash device should be made visible only |
21 | 31 | * there. The second flash device is visible to both secure and nonsecure. | |
22 | +static bool pmsav7_rnr_needed(void *opaque) | 32 | - * If sysmem == secure_sysmem this means there is no separate Secure |
23 | +{ | 33 | - * address space and both flash devices are generally visible. |
24 | + ARMCPU *cpu = opaque; | 34 | */ |
25 | + CPUARMState *env = &cpu->env; | 35 | hwaddr flashsize = sbsa_ref_memmap[SBSA_FLASH].size / 2; |
26 | + | 36 | hwaddr flashbase = sbsa_ref_memmap[SBSA_FLASH].base; |
27 | + /* For R profile cores pmsav7.rnr is migrated via the cpreg | 37 | @@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine) |
28 | + * "RGNR" definition in helper.h. For M profile we have to | 38 | SBSAMachineState *sms = SBSA_MACHINE(machine); |
29 | + * migrate it separately. | 39 | MachineClass *mc = MACHINE_GET_CLASS(machine); |
30 | + */ | 40 | MemoryRegion *sysmem = get_system_memory(); |
31 | + return arm_feature(env, ARM_FEATURE_M); | 41 | - MemoryRegion *secure_sysmem = NULL; |
32 | +} | 42 | + MemoryRegion *secure_sysmem = g_new(MemoryRegion, 1); |
33 | + | 43 | MemoryRegion *ram = g_new(MemoryRegion, 1); |
34 | +static const VMStateDescription vmstate_pmsav7_rnr = { | 44 | bool firmware_loaded; |
35 | + .name = "cpu/pmsav7-rnr", | 45 | const CPUArchIdList *possible_cpus; |
36 | + .version_id = 1, | 46 | @@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine) |
37 | + .minimum_version_id = 1, | 47 | * containing the system memory at low priority; any secure-only |
38 | + .needed = pmsav7_rnr_needed, | 48 | * devices go in at higher priority and take precedence. |
39 | + .fields = (VMStateField[]) { | 49 | */ |
40 | + VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU), | 50 | - secure_sysmem = g_new(MemoryRegion, 1); |
41 | + VMSTATE_END_OF_LIST() | 51 | memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory", |
42 | + } | 52 | UINT64_MAX); |
43 | +}; | 53 | memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1); |
44 | + | 54 | |
45 | static int get_cpsr(QEMUFile *f, void *opaque, size_t size, | 55 | - firmware_loaded = sbsa_firmware_init(sms, sysmem, |
46 | VMStateField *field) | 56 | - secure_sysmem ?: sysmem); |
47 | { | 57 | + firmware_loaded = sbsa_firmware_init(sms, sysmem, secure_sysmem); |
48 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = { | 58 | |
49 | &vmstate_iwmmxt, | 59 | if (machine->kernel_filename && firmware_loaded) { |
50 | &vmstate_m, | 60 | error_report("sbsa-ref: No fw_cfg device on this machine, " |
51 | &vmstate_thumb2ee, | ||
52 | + /* pmsav7_rnr must come before pmsav7 so that we have the | ||
53 | + * region number before we test it in the VMSTATE_VALIDATE | ||
54 | + * in vmstate_pmsav7. | ||
55 | + */ | ||
56 | + &vmstate_pmsav7_rnr, | ||
57 | &vmstate_pmsav7, | ||
58 | NULL | ||
59 | } | ||
60 | -- | 61 | -- |
61 | 2.7.4 | 62 | 2.20.1 |
62 | 63 | ||
63 | 64 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> | 1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 3 | In commit e9d652824b0 we extracted the vfp_set_fpscr_to_host() |
4 | Message-id: 20170729234930.725-1-f4bug@amsat.org | 4 | function but failed at calling it in the correct place, we call |
5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 5 | it after xregs[ARM_VFP_FPSCR] is modified. |
6 | |||
7 | Fix by calling this function before we update FPSCR. | ||
8 | |||
9 | Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com> | ||
10 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com> | ||
12 | Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com> | ||
13 | Message-id: 20190705124318.1075-1-philmd@redhat.com | ||
6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 14 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
7 | --- | 15 | --- |
8 | hw/misc/mps2-scc.c | 4 ++-- | 16 | target/arm/vfp_helper.c | 4 ++-- |
9 | 1 file changed, 2 insertions(+), 2 deletions(-) | 17 | 1 file changed, 2 insertions(+), 2 deletions(-) |
10 | 18 | ||
11 | diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c | 19 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c |
12 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/hw/misc/mps2-scc.c | 21 | --- a/target/arm/vfp_helper.c |
14 | +++ b/hw/misc/mps2-scc.c | 22 | +++ b/target/arm/vfp_helper.c |
15 | @@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = { | 23 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) |
16 | /* Values for various read-only ID registers (which are specific | 24 | val &= 0xf7c0009f; |
17 | * to the board model or FPGA image) | 25 | } |
18 | */ | 26 | |
19 | - DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, aid, 0), | 27 | + vfp_set_fpscr_to_host(env, val); |
20 | + DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0), | 28 | + |
21 | DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0), | 29 | /* |
22 | - DEFINE_PROP_UINT32("scc-id", MPS2SCC, aid, 0), | 30 | * We don't implement trapped exception handling, so the |
23 | + DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0), | 31 | * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!) |
24 | /* These are the initial settings for the source clocks on the board. | 32 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) |
25 | * In hardware they can be configured via a config file read by the | 33 | env->vfp.qc[1] = 0; |
26 | * motherboard configuration controller to suit the FPGA image. | 34 | env->vfp.qc[2] = 0; |
35 | env->vfp.qc[3] = 0; | ||
36 | - | ||
37 | - vfp_set_fpscr_to_host(env, val); | ||
38 | } | ||
39 | |||
40 | void vfp_set_fpscr(CPUARMState *env, uint32_t val) | ||
27 | -- | 41 | -- |
28 | 2.7.4 | 42 | 2.20.1 |
29 | 43 | ||
30 | 44 | diff view generated by jsdifflib |