1
target-arm queue for rc1 -- these are all bug fixes.
1
Just a collection of bug fixes this time around...
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit b9404bf592e7ba74180e1a54ed7a266ec6ee67f2:
6
The following changes since commit 2a6ae69154542caa91dd17c40fd3f5ffbec300de:
7
7
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-hmp-20190715' into staging (2019-07-15 12:22:07 +0100)
8
Merge tag 'pull-maintainer-ominbus-030723-1' of https://gitlab.com/stsquad/qemu into staging (2023-07-04 08:36:44 +0200)
9
9
10
are available in the Git repository at:
10
are available in the Git repository at:
11
11
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190715
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230704
13
13
14
for you to fetch changes up to 51c9122e92b776a3f16af0b9282f1dc5012e2a19:
14
for you to fetch changes up to 86a78272f094857b4eda79d721c116e93942aa9a:
15
15
16
target/arm: NS BusFault on vector table fetch escalates to NS HardFault (2019-07-15 14:17:04 +0100)
16
target/xtensa: Assert that interrupt level is within bounds (2023-07-04 14:27:08 +0100)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* report ARMv8-A FP support for AArch32 -cpu max
20
* Add raw_writes ops for register whose write induce TLB maintenance
21
* hw/ssi/xilinx_spips: Avoid AXI writes to the LQSPI linear memory
21
* hw/arm/sbsa-ref: use XHCI to replace EHCI
22
* hw/ssi/xilinx_spips: Avoid out-of-bound access to lqspi_buf[]
22
* Avoid splitting Zregs across lines in dump
23
* hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO
23
* Dump ZA[] when active
24
* hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO
24
* Fix SME full tile indexing
25
* hw/arm/virt: Fix non-secure flash mode
25
* Handle IC IVAU to improve compatibility with JITs
26
* pl031: Correctly migrate state when using -rtc clock=host
26
* xlnx-canfd-test: Fix code coverity issues
27
* fix regression that meant arm926 and arm1026 lost VFP
27
* gdbstub: Guard M-profile code with CONFIG_TCG
28
double-precision support
28
* allwinner-sramc: Set class_size
29
* v8M: NS BusFault on vector table fetch escalates to NS HardFault
29
* target/xtensa: Assert that interrupt level is within bounds
30
30
31
----------------------------------------------------------------
31
----------------------------------------------------------------
32
Alex Bennée (1):
32
Akihiko Odaki (1):
33
target/arm: report ARMv8-A FP support for AArch32 -cpu max
33
hw: arm: allwinner-sramc: Set class_size
34
34
35
David Engraf (1):
35
Eric Auger (1):
36
hw/arm/virt: Fix non-secure flash mode
36
target/arm: Add raw_writes ops for register whose write induce TLB maintenance
37
37
38
Peter Maydell (3):
38
Fabiano Rosas (1):
39
pl031: Correctly migrate state when using -rtc clock=host
39
target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
40
target/arm: Set VFP-related MVFR0 fields for arm926 and arm1026
41
target/arm: NS BusFault on vector table fetch escalates to NS HardFault
42
40
43
Philippe Mathieu-Daudé (5):
41
John Högberg (2):
44
hw/ssi/xilinx_spips: Convert lqspi_read() to read_with_attrs
42
target/arm: Handle IC IVAU to improve compatibility with JITs
45
hw/ssi/xilinx_spips: Avoid AXI writes to the LQSPI linear memory
43
tests/tcg/aarch64: Add testcases for IC IVAU and dual-mapped code
46
hw/ssi/xilinx_spips: Avoid out-of-bound access to lqspi_buf[]
47
hw/ssi/mss-spi: Avoid crash when reading empty RX FIFO
48
hw/display/xlnx_dp: Avoid crash when reading empty RX FIFO
49
44
50
include/hw/timer/pl031.h | 2 ++
45
Peter Maydell (1):
51
hw/arm/virt.c | 2 +-
46
target/xtensa: Assert that interrupt level is within bounds
52
hw/core/machine.c | 1 +
53
hw/display/xlnx_dp.c | 15 +++++---
54
hw/ssi/mss-spi.c | 8 ++++-
55
hw/ssi/xilinx_spips.c | 43 +++++++++++++++-------
56
hw/timer/pl031.c | 92 +++++++++++++++++++++++++++++++++++++++++++++---
57
target/arm/cpu.c | 16 +++++++++
58
target/arm/m_helper.c | 21 ++++++++---
59
9 files changed, 174 insertions(+), 26 deletions(-)
60
47
48
Richard Henderson (3):
49
target/arm: Avoid splitting Zregs across lines in dump
50
target/arm: Dump ZA[] when active
51
target/arm: Fix SME full tile indexing
52
53
Vikram Garhwal (1):
54
tests/qtest: xlnx-canfd-test: Fix code coverity issues
55
56
Yuquan Wang (1):
57
hw/arm/sbsa-ref: use XHCI to replace EHCI
58
59
docs/system/arm/sbsa.rst | 5 +-
60
hw/arm/sbsa-ref.c | 23 +++--
61
hw/misc/allwinner-sramc.c | 1 +
62
target/arm/cpu.c | 65 ++++++++-----
63
target/arm/gdbstub.c | 4 +
64
target/arm/helper.c | 70 +++++++++++---
65
target/arm/tcg/translate-sme.c | 24 +++--
66
target/xtensa/exc_helper.c | 3 +
67
tests/qtest/xlnx-canfd-test.c | 33 +++----
68
tests/tcg/aarch64/icivau.c | 189 ++++++++++++++++++++++++++++++++++++++
69
tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++
70
hw/arm/Kconfig | 2 +-
71
tests/tcg/aarch64/Makefile.target | 13 ++-
72
13 files changed, 436 insertions(+), 79 deletions(-)
73
create mode 100644 tests/tcg/aarch64/icivau.c
74
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
75
diff view generated by jsdifflib
1
The PL031 RTC tracks the difference between the guest RTC
1
From: Eric Auger <eric.auger@redhat.com>
2
and the host RTC using a tick_offset field. For migration,
3
however, we currently always migrate the offset between
4
the guest and the vm_clock, even if the RTC clock is not
5
the same as the vm_clock; this was an attempt to retain
6
migration backwards compatibility.
7
2
8
Unfortunately this results in the RTC behaving oddly across
3
Some registers whose 'cooked' writefns induce TLB maintenance do
9
a VM state save and restore -- since the VM clock stands still
4
not have raw_writefn ops defined. If only the writefn ops is set
10
across save-then-restore, regardless of how much real world
5
(ie. no raw_writefn is provided), it is assumed the cooked also
11
time has elapsed, the guest RTC ends up out of sync with the
6
work as the raw one. For those registers it is not obvious the
12
host RTC in the restored VM.
7
tlb_flush works on KVM mode so better/safer setting the raw write.
13
8
14
Fix this by migrating the raw tick_offset. To retain migration
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
compatibility as far as possible, we have a new property
10
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
16
migrate-tick-offset; by default this is 'true' and we will
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
migrate the true tick offset in a new subsection; if the
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
incoming data has no subsection we fall back to the old
13
---
19
vm_clock-based offset information, so old->new migration
14
target/arm/helper.c | 23 +++++++++++++----------
20
compatibility is preserved. For complete new->old migration
15
1 file changed, 13 insertions(+), 10 deletions(-)
21
compatibility, the property is set to 'false' for 4.0 and
22
earlier machine types (this will only affect 'virt-4.0'
23
and below, as none of the other pl031-using machines are
24
versioned).
25
16
26
Reported-by: Russell King <rmk@armlinux.org.uk>
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
29
Message-id: 20190709143912.28905-1-peter.maydell@linaro.org
30
---
31
include/hw/timer/pl031.h | 2 +
32
hw/core/machine.c | 1 +
33
hw/timer/pl031.c | 92 ++++++++++++++++++++++++++++++++++++++--
34
3 files changed, 91 insertions(+), 4 deletions(-)
35
36
diff --git a/include/hw/timer/pl031.h b/include/hw/timer/pl031.h
37
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/timer/pl031.h
19
--- a/target/arm/helper.c
39
+++ b/include/hw/timer/pl031.h
20
+++ b/target/arm/helper.c
40
@@ -XXX,XX +XXX,XX @@ typedef struct PL031State {
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
41
*/
22
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
42
uint32_t tick_offset_vmstate;
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
43
uint32_t tick_offset;
24
.fgt = FGT_TTBR0_EL1,
44
+ bool tick_offset_migrated;
25
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
45
+ bool migrate_tick_offset;
26
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
46
27
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
47
uint32_t mr;
28
offsetof(CPUARMState, cp15.ttbr0_ns) } },
48
uint32_t lr;
29
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
49
diff --git a/hw/core/machine.c b/hw/core/machine.c
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
50
index XXXXXXX..XXXXXXX 100644
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
51
--- a/hw/core/machine.c
32
.fgt = FGT_TTBR1_EL1,
52
+++ b/hw/core/machine.c
33
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
53
@@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_4_0[] = {
34
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
54
{ "virtio-gpu-pci", "edid", "false" },
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
55
{ "virtio-device", "use-started", "false" },
36
offsetof(CPUARMState, cp15.ttbr1_ns) } },
56
{ "virtio-balloon-device", "qemu-4-0-config-size", "true" },
37
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
57
+ { "pl031", "migrate-tick-offset", "false" },
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
39
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
40
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
41
offsetof(CPUARMState, cp15.ttbr0_ns) },
42
- .writefn = vmsa_ttbr_write, },
43
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
44
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
45
.access = PL1_RW, .accessfn = access_tvm_trvm,
46
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
47
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
48
offsetof(CPUARMState, cp15.ttbr1_ns) },
49
- .writefn = vmsa_ttbr_write, },
50
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
58
};
51
};
59
const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0);
52
60
53
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
61
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
62
index XXXXXXX..XXXXXXX 100644
55
.type = ARM_CP_IO,
63
--- a/hw/timer/pl031.c
56
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
64
+++ b/hw/timer/pl031.c
57
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
65
@@ -XXX,XX +XXX,XX @@ static int pl031_pre_save(void *opaque)
58
- .writefn = hcr_write },
66
{
59
+ .writefn = hcr_write, .raw_writefn = raw_write },
67
PL031State *s = opaque;
60
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
68
61
.type = ARM_CP_ALIAS | ARM_CP_IO,
69
- /* tick_offset is base_time - rtc_clock base time. Instead, we want to
62
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
70
- * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
71
+ /*
64
{ .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
72
+ * The PL031 device model code uses the tick_offset field, which is
65
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
73
+ * the offset between what the guest RTC should read and what the
66
.access = PL2_RW, .writefn = vmsa_tcr_el12_write,
74
+ * QEMU rtc_clock reads:
67
+ .raw_writefn = raw_write,
75
+ * guest_rtc = rtc_clock + tick_offset
68
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
76
+ * and so
69
{ .name = "VTCR", .state = ARM_CP_STATE_AA32,
77
+ * tick_offset = guest_rtc - rtc_clock
70
.cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
78
+ *
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
79
+ * We want to migrate this offset, which sounds straightforward.
72
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
80
+ * Unfortunately older versions of QEMU migrated a conversion of this
73
.access = PL2_RW, .accessfn = access_el3_aa32ns,
81
+ * offset into an offset from the vm_clock. (This was in turn an
74
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
82
+ * attempt to be compatible with even older QEMU versions, but it
75
- .writefn = vttbr_write },
83
+ * has incorrect behaviour if the rtc_clock is not the same as the
76
+ .writefn = vttbr_write, .raw_writefn = raw_write },
84
+ * vm_clock.) So we put the actual tick_offset into a migration
77
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
85
+ * subsection, and the backwards-compatible time-relative-to-vm_clock
78
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
86
+ * in the main migration state.
79
- .access = PL2_RW, .writefn = vttbr_write,
87
+ *
80
+ .access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
88
+ * Calculate base time relative to QEMU_CLOCK_VIRTUAL:
81
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
89
+ */
82
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
90
int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
83
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
91
s->tick_offset_vmstate = s->tick_offset + delta / NANOSECONDS_PER_SECOND;
84
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
92
85
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
93
return 0;
86
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
94
}
87
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
95
88
- .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
96
+static int pl031_pre_load(void *opaque)
89
+ .access = PL2_RW, .resetvalue = 0,
97
+{
90
+ .writefn = vmsa_tcr_ttbr_el2_write, .raw_writefn = raw_write,
98
+ PL031State *s = opaque;
91
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
99
+
92
{ .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
100
+ s->tick_offset_migrated = false;
93
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
101
+ return 0;
94
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
102
+}
95
{ .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
103
+
96
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
104
static int pl031_post_load(void *opaque, int version_id)
97
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
105
{
98
- .resetfn = scr_reset, .writefn = scr_write },
106
PL031State *s = opaque;
99
+ .resetfn = scr_reset, .writefn = scr_write, .raw_writefn = raw_write },
107
100
{ .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
108
- int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
101
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
109
- s->tick_offset = s->tick_offset_vmstate - delta / NANOSECONDS_PER_SECOND;
102
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
110
+ /*
103
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
111
+ * If we got the tick_offset subsection, then we can just use
104
- .writefn = scr_write },
112
+ * the value in that. Otherwise the source is an older QEMU and
105
+ .writefn = scr_write, .raw_writefn = raw_write },
113
+ * has given us the offset from the vm_clock; convert it back to
106
{ .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
114
+ * an offset from the rtc_clock. This will cause time to incorrectly
107
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
115
+ * go backwards compared to the host RTC, but this is unavoidable.
108
.access = PL3_RW, .resetvalue = 0,
116
+ */
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
117
+
110
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
118
+ if (!s->tick_offset_migrated) {
111
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
119
+ int64_t delta = qemu_clock_get_ns(rtc_clock) -
112
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
120
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
113
+ .raw_writefn = raw_write,
121
+ s->tick_offset = s->tick_offset_vmstate -
114
.fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
122
+ delta / NANOSECONDS_PER_SECOND;
115
#ifndef CONFIG_USER_ONLY
123
+ }
116
{ .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
124
pl031_set_alarm(s);
125
return 0;
126
}
127
128
+static int pl031_tick_offset_post_load(void *opaque, int version_id)
129
+{
130
+ PL031State *s = opaque;
131
+
132
+ s->tick_offset_migrated = true;
133
+ return 0;
134
+}
135
+
136
+static bool pl031_tick_offset_needed(void *opaque)
137
+{
138
+ PL031State *s = opaque;
139
+
140
+ return s->migrate_tick_offset;
141
+}
142
+
143
+static const VMStateDescription vmstate_pl031_tick_offset = {
144
+ .name = "pl031/tick-offset",
145
+ .version_id = 1,
146
+ .minimum_version_id = 1,
147
+ .needed = pl031_tick_offset_needed,
148
+ .post_load = pl031_tick_offset_post_load,
149
+ .fields = (VMStateField[]) {
150
+ VMSTATE_UINT32(tick_offset, PL031State),
151
+ VMSTATE_END_OF_LIST()
152
+ }
153
+};
154
+
155
static const VMStateDescription vmstate_pl031 = {
156
.name = "pl031",
157
.version_id = 1,
158
.minimum_version_id = 1,
159
.pre_save = pl031_pre_save,
160
+ .pre_load = pl031_pre_load,
161
.post_load = pl031_post_load,
162
.fields = (VMStateField[]) {
163
VMSTATE_UINT32(tick_offset_vmstate, PL031State),
164
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl031 = {
165
VMSTATE_UINT32(im, PL031State),
166
VMSTATE_UINT32(is, PL031State),
167
VMSTATE_END_OF_LIST()
168
+ },
169
+ .subsections = (const VMStateDescription*[]) {
170
+ &vmstate_pl031_tick_offset,
171
+ NULL
172
}
173
};
174
175
+static Property pl031_properties[] = {
176
+ /*
177
+ * True to correctly migrate the tick offset of the RTC. False to
178
+ * obtain backward migration compatibility with older QEMU versions,
179
+ * at the expense of the guest RTC going backwards compared with the
180
+ * host RTC when the VM is saved/restored if using -rtc host.
181
+ * (Even if set to 'true' older QEMU can migrate forward to newer QEMU;
182
+ * 'false' also permits newer QEMU to migrate to older QEMU.)
183
+ */
184
+ DEFINE_PROP_BOOL("migrate-tick-offset",
185
+ PL031State, migrate_tick_offset, true),
186
+ DEFINE_PROP_END_OF_LIST()
187
+};
188
+
189
static void pl031_class_init(ObjectClass *klass, void *data)
190
{
191
DeviceClass *dc = DEVICE_CLASS(klass);
192
193
dc->vmsd = &vmstate_pl031;
194
+ dc->props = pl031_properties;
195
}
196
197
static const TypeInfo pl031_info = {
198
--
117
--
199
2.20.1
118
2.34.1
200
201
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Yuquan Wang <wangyuquan1236@phytium.com.cn>
2
2
3
In the next commit we will implement the write_with_attrs()
3
The current sbsa-ref cannot use EHCI controller which is only
4
handler. To avoid using different APIs, convert the read()
4
able to do 32-bit DMA, since sbsa-ref doesn't have RAM below 4GB.
5
handler first.
5
Hence, this uses XHCI to provide a usb controller with 64-bit
6
DMA capablity instead of EHCI.
6
7
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
We bump the platform version to 0.3 with this change. Although the
8
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
hardware at the USB controller address changes, the firmware and
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Linux can both cope with this -- on an older non-XHCI-aware
11
firmware/kernel setup the probe routine simply fails and the guest
12
proceeds without any USB. (This isn't a loss of functionality,
13
because the old USB controller never worked in the first place.) So
14
we can call this a backwards-compatible change and only bump the
15
minor version.
16
17
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
18
Message-id: 20230621103847.447508-2-wangyuquan1236@phytium.com.cn
19
[PMM: tweaked commit message; add line to docs about what
20
changes in platform version 0.3]
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
23
---
12
hw/ssi/xilinx_spips.c | 23 +++++++++++------------
24
docs/system/arm/sbsa.rst | 5 ++++-
13
1 file changed, 11 insertions(+), 12 deletions(-)
25
hw/arm/sbsa-ref.c | 23 +++++++++++++----------
26
hw/arm/Kconfig | 2 +-
27
3 files changed, 18 insertions(+), 12 deletions(-)
14
28
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
29
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
31
--- a/docs/system/arm/sbsa.rst
18
+++ b/hw/ssi/xilinx_spips.c
32
+++ b/docs/system/arm/sbsa.rst
19
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
33
@@ -XXX,XX +XXX,XX @@ The ``sbsa-ref`` board supports:
34
- A configurable number of AArch64 CPUs
35
- GIC version 3
36
- System bus AHCI controller
37
- - System bus EHCI controller
38
+ - System bus XHCI controller
39
- CDROM and hard disc on AHCI bus
40
- E1000E ethernet card on PCIe bus
41
- Bochs display adapter on PCIe bus
42
@@ -XXX,XX +XXX,XX @@ Platform version changes:
43
44
0.2
45
GIC ITS information is present in devicetree.
46
+
47
+0.3
48
+ The USB controller is an XHCI device, not EHCI
49
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/sbsa-ref.c
52
+++ b/hw/arm/sbsa-ref.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "hw/pci-host/gpex.h"
55
#include "hw/qdev-properties.h"
56
#include "hw/usb.h"
57
+#include "hw/usb/xhci.h"
58
#include "hw/char/pl011.h"
59
#include "hw/watchdog/sbsa_gwdt.h"
60
#include "net/net.h"
61
@@ -XXX,XX +XXX,XX @@ enum {
62
SBSA_SECURE_UART_MM,
63
SBSA_SECURE_MEM,
64
SBSA_AHCI,
65
- SBSA_EHCI,
66
+ SBSA_XHCI,
67
};
68
69
struct SBSAMachineState {
70
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
71
[SBSA_SMMU] = { 0x60050000, 0x00020000 },
72
/* Space here reserved for more SMMUs */
73
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
74
- [SBSA_EHCI] = { 0x60110000, 0x00010000 },
75
+ [SBSA_XHCI] = { 0x60110000, 0x00010000 },
76
/* Space here reserved for other devices */
77
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
78
/* 32-bit address PCIE MMIO space */
79
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
80
[SBSA_SECURE_UART] = 8,
81
[SBSA_SECURE_UART_MM] = 9,
82
[SBSA_AHCI] = 10,
83
- [SBSA_EHCI] = 11,
84
+ [SBSA_XHCI] = 11,
85
[SBSA_SMMU] = 12, /* ... to 15 */
86
[SBSA_GWDT_WS0] = 16,
87
};
88
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
89
* fw compatibility.
90
*/
91
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
92
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
93
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 3);
94
95
if (ms->numa_state->have_numa_distance) {
96
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
97
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms)
20
}
98
}
21
}
99
}
22
100
23
-static uint64_t
101
-static void create_ehci(const SBSAMachineState *sms)
24
-lqspi_read(void *opaque, hwaddr addr, unsigned int size)
102
+static void create_xhci(const SBSAMachineState *sms)
25
+static MemTxResult lqspi_read(void *opaque, hwaddr addr, uint64_t *value,
26
+ unsigned size, MemTxAttrs attrs)
27
{
103
{
28
- XilinxQSPIPS *q = opaque;
104
- hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
29
- uint32_t ret;
105
- int irq = sbsa_ref_irqmap[SBSA_EHCI];
30
+ XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
106
+ hwaddr base = sbsa_ref_memmap[SBSA_XHCI].base;
31
107
+ int irq = sbsa_ref_irqmap[SBSA_XHCI];
32
if (addr >= q->lqspi_cached_addr &&
108
+ DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS);
33
addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
109
34
uint8_t *retp = &q->lqspi_buf[addr - q->lqspi_cached_addr];
110
- sysbus_create_simple("platform-ehci-usb", base,
35
- ret = cpu_to_le32(*(uint32_t *)retp);
111
- qdev_get_gpio_in(sms->gic, irq));
36
- DB_PRINT_L(1, "addr: %08x, data: %08x\n", (unsigned)addr,
112
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
37
- (unsigned)ret);
113
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
38
- return ret;
114
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
39
- } else {
40
- lqspi_load_cache(opaque, addr);
41
- return lqspi_read(opaque, addr, size);
42
+ *value = cpu_to_le32(*(uint32_t *)retp);
43
+ DB_PRINT_L(1, "addr: %08" HWADDR_PRIx ", data: %08" PRIx64 "\n",
44
+ addr, *value);
45
+ return MEMTX_OK;
46
}
47
+
48
+ lqspi_load_cache(opaque, addr);
49
+ return lqspi_read(opaque, addr, value, size, attrs);
50
}
115
}
51
116
52
static const MemoryRegionOps lqspi_ops = {
117
static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
53
- .read = lqspi_read,
118
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
54
+ .read_with_attrs = lqspi_read,
119
55
.endianness = DEVICE_NATIVE_ENDIAN,
120
create_ahci(sms);
56
.valid = {
121
57
.min_access_size = 1,
122
- create_ehci(sms);
123
+ create_xhci(sms);
124
125
create_pcie(sms);
126
127
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
128
index XXXXXXX..XXXXXXX 100644
129
--- a/hw/arm/Kconfig
130
+++ b/hw/arm/Kconfig
131
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
132
select PL011 # UART
133
select PL031 # RTC
134
select PL061 # GPIO
135
- select USB_EHCI_SYSBUS
136
+ select USB_XHCI_SYSBUS
137
select WDT_SBSA
138
select BOCHS_DISPLAY
139
58
--
140
--
59
2.20.1
141
2.34.1
60
61
diff view generated by jsdifflib
1
From: David Engraf <david.engraf@sysgo.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Using the whole 128 MiB flash in non-secure mode is not working because
3
Allow the line length to extend to 548 columns. While annoyingly wide,
4
virt_flash_fdt() expects the same address for secure_sysmem and sysmem.
4
it's still less confusing than the continuations we print. Also, the
5
This is not correctly handled by caller because it forwards NULL for
5
default VL used by Linux (and max for A64FX) uses only 140 columns.
6
secure_sysmem in non-secure flash mode.
7
6
8
Fixed by using sysmem when secure_sysmem is NULL.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
8
Message-id: 20230622151201.1578522-2-richard.henderson@linaro.org
10
Signed-off-by: David Engraf <david.engraf@sysgo.com>
11
Message-id: 20190712075002.14326-1-david.engraf@sysgo.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/arm/virt.c | 2 +-
12
target/arm/cpu.c | 36 ++++++++++++++----------------------
16
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 14 insertions(+), 22 deletions(-)
17
14
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
17
--- a/target/arm/cpu.c
21
+++ b/hw/arm/virt.c
18
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
23
&machine->device_memory->mr);
20
ARMCPU *cpu = ARM_CPU(cs);
21
CPUARMState *env = &cpu->env;
22
uint32_t psr = pstate_read(env);
23
- int i;
24
+ int i, j;
25
int el = arm_current_el(env);
26
const char *ns_status;
27
bool sve;
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
24
}
29
}
25
30
26
- virt_flash_fdt(vms, sysmem, secure_sysmem);
31
if (sve) {
27
+ virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
32
- int j, zcr_len = sve_vqm1_for_el(env, el);
28
33
+ int zcr_len = sve_vqm1_for_el(env, el);
29
create_gic(vms, pic);
34
30
35
for (i = 0; i <= FFR_PRED_NUM; i++) {
36
bool eol;
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
38
}
39
}
40
41
- for (i = 0; i < 32; i++) {
42
- if (zcr_len == 0) {
43
+ if (zcr_len == 0) {
44
+ /*
45
+ * With vl=16, there are only 37 columns per register,
46
+ * so output two registers per line.
47
+ */
48
+ for (i = 0; i < 32; i++) {
49
qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
50
i, env->vfp.zregs[i].d[1],
51
env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
52
- } else if (zcr_len == 1) {
53
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
54
- ":%016" PRIx64 ":%016" PRIx64 "\n",
55
- i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
56
- env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
57
- } else {
58
+ }
59
+ } else {
60
+ for (i = 0; i < 32; i++) {
61
+ qemu_fprintf(f, "Z%02d=", i);
62
for (j = zcr_len; j >= 0; j--) {
63
- bool odd = (zcr_len - j) % 2 != 0;
64
- if (j == zcr_len) {
65
- qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
66
- } else if (!odd) {
67
- if (j > 0) {
68
- qemu_fprintf(f, " [%x-%x]=", j, j - 1);
69
- } else {
70
- qemu_fprintf(f, " [%x]=", j);
71
- }
72
- }
73
qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
74
env->vfp.zregs[i].d[j * 2 + 1],
75
- env->vfp.zregs[i].d[j * 2],
76
- odd || j == 0 ? "\n" : ":");
77
+ env->vfp.zregs[i].d[j * 2 + 0],
78
+ j ? ":" : "\n");
79
}
80
}
81
}
31
--
82
--
32
2.20.1
83
2.34.1
33
34
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When we converted to using feature bits in 602f6e42cfbf we missed out
3
Always print each matrix row whole, one per line, so that we
4
the fact (dp && arm_dc_feature(s, ARM_FEATURE_V8)) was supported for
4
get the entire matrix in the proper shape.
5
-cpu max configurations. This caused a regression in the GCC test
6
suite. Fix this by setting the appropriate bits in mvfr1.FPHP to
7
report ARMv8-A with FP support (but not ARMv8.2-FP16).
8
5
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1836078
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20230622151201.1578522-3-richard.henderson@linaro.org
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20190711103737.10017-1-alex.bennee@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/cpu.c | 4 ++++
11
target/arm/cpu.c | 18 ++++++++++++++++++
16
1 file changed, 4 insertions(+)
12
1 file changed, 18 insertions(+)
17
13
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
23
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
19
i, q[1], q[0], (i & 1 ? "\n" : " "));
24
cpu->isar.id_isar6 = t;
20
}
25
21
}
26
+ t = cpu->isar.mvfr1;
27
+ t = FIELD_DP32(t, MVFR1, FPHP, 2); /* v8.0 FP support */
28
+ cpu->isar.mvfr1 = t;
29
+
22
+
30
t = cpu->isar.mvfr2;
23
+ if (cpu_isar_feature(aa64_sme, cpu) &&
31
t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
24
+ FIELD_EX64(env->svcr, SVCR, ZA) &&
32
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
25
+ sme_exception_el(env, el) == 0) {
26
+ int zcr_len = sve_vqm1_for_el_sm(env, el, true);
27
+ int svl = (zcr_len + 1) * 16;
28
+ int svl_lg10 = svl < 100 ? 2 : 3;
29
+
30
+ for (i = 0; i < svl; i++) {
31
+ qemu_fprintf(f, "ZA[%0*d]=", svl_lg10, i);
32
+ for (j = zcr_len; j >= 0; --j) {
33
+ qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%c",
34
+ env->zarray[i].d[2 * j + 1],
35
+ env->zarray[i].d[2 * j],
36
+ j ? ':' : '\n');
37
+ }
38
+ }
39
+ }
40
}
41
42
#else
33
--
43
--
34
2.20.1
44
2.34.1
35
36
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Lei Sun found while auditing the code that a CPU write would
3
For the outer product set of insns, which take an entire matrix
4
trigger a NULL pointer dereference.
4
tile as output, the argument is not a combined tile+column.
5
5
Therefore using get_tile_rowcol was incorrect, as we extracted
6
>From UG1085 datasheet [*] AXI writes in this region are ignored
6
the tile number from itself.
7
and generates an AXI Slave Error (SLVERR).
7
8
8
The test case relies only on assembler support for SME, since
9
Fix by implementing the write_with_attrs() handler.
9
no release of GCC recognizes -march=armv9-a+sme yet.
10
Return MEMTX_ERROR when the region is accessed (this error maps
10
11
to an AXI slave error).
11
Cc: qemu-stable@nongnu.org
12
12
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1620
13
[*] https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
14
Message-id: 20230622151201.1578522-5-richard.henderson@linaro.org
15
Reported-by: Lei Sun <slei.casper@gmail.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
17
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
18
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
17
---
21
hw/ssi/xilinx_spips.c | 16 ++++++++++++++++
18
target/arm/tcg/translate-sme.c | 24 ++++++---
22
1 file changed, 16 insertions(+)
19
tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++++++++++++++++
23
20
tests/tcg/aarch64/Makefile.target | 10 ++--
24
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
21
3 files changed, 108 insertions(+), 9 deletions(-)
22
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
23
24
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
25
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/ssi/xilinx_spips.c
26
--- a/target/arm/tcg/translate-sme.c
27
+++ b/hw/ssi/xilinx_spips.c
27
+++ b/target/arm/tcg/translate-sme.c
28
@@ -XXX,XX +XXX,XX @@ static MemTxResult lqspi_read(void *opaque, hwaddr addr, uint64_t *value,
28
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
29
return lqspi_read(opaque, addr, value, size, attrs);
29
return addr;
30
}
30
}
31
31
32
+static MemTxResult lqspi_write(void *opaque, hwaddr offset, uint64_t value,
32
+/*
33
+ unsigned size, MemTxAttrs attrs)
33
+ * Resolve tile.size[0] to a host pointer.
34
+ * Used by e.g. outer product insns where we require the entire tile.
35
+ */
36
+static TCGv_ptr get_tile(DisasContext *s, int esz, int tile)
34
+{
37
+{
35
+ /*
38
+ TCGv_ptr addr = tcg_temp_new_ptr();
36
+ * From UG1085, Chapter 24 (Quad-SPI controllers):
39
+ int offset;
37
+ * - Writes are ignored
40
+
38
+ * - AXI writes generate an external AXI slave error (SLVERR)
41
+ offset = tile * sizeof(ARMVectorReg) + offsetof(CPUARMState, zarray);
39
+ */
42
+
40
+ qemu_log_mask(LOG_GUEST_ERROR, "%s Unexpected %u-bit access to 0x%" PRIx64
43
+ tcg_gen_addi_ptr(addr, cpu_env, offset);
41
+ " (value: 0x%" PRIx64 "\n",
44
+ return addr;
42
+ __func__, size << 3, offset, value);
43
+
44
+ return MEMTX_ERROR;
45
+}
45
+}
46
+
46
+
47
static const MemoryRegionOps lqspi_ops = {
47
static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
48
.read_with_attrs = lqspi_read,
48
{
49
+ .write_with_attrs = lqspi_write,
49
if (!dc_isar_feature(aa64_sme, s)) {
50
.endianness = DEVICE_NATIVE_ENDIAN,
50
@@ -XXX,XX +XXX,XX @@ static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz,
51
.valid = {
51
return true;
52
.min_access_size = 1,
52
}
53
54
- /* Sum XZR+zad to find ZAd. */
55
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
56
+ za = get_tile(s, esz, a->zad);
57
zn = vec_full_reg_ptr(s, a->zn);
58
pn = pred_full_reg_ptr(s, a->pn);
59
pm = pred_full_reg_ptr(s, a->pm);
60
@@ -XXX,XX +XXX,XX @@ static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
61
return true;
62
}
63
64
- /* Sum XZR+zad to find ZAd. */
65
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
66
+ za = get_tile(s, esz, a->zad);
67
zn = vec_full_reg_ptr(s, a->zn);
68
zm = vec_full_reg_ptr(s, a->zm);
69
pn = pred_full_reg_ptr(s, a->pn);
70
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
71
return true;
72
}
73
74
- /* Sum XZR+zad to find ZAd. */
75
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
76
+ za = get_tile(s, esz, a->zad);
77
zn = vec_full_reg_ptr(s, a->zn);
78
zm = vec_full_reg_ptr(s, a->zm);
79
pn = pred_full_reg_ptr(s, a->pn);
80
diff --git a/tests/tcg/aarch64/sme-outprod1.c b/tests/tcg/aarch64/sme-outprod1.c
81
new file mode 100644
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/tests/tcg/aarch64/sme-outprod1.c
85
@@ -XXX,XX +XXX,XX @@
86
+/*
87
+ * SME outer product, 1 x 1.
88
+ * SPDX-License-Identifier: GPL-2.0-or-later
89
+ */
90
+
91
+#include <stdio.h>
92
+
93
+extern void foo(float *dst);
94
+
95
+asm(
96
+"    .arch_extension sme\n"
97
+"    .type foo, @function\n"
98
+"foo:\n"
99
+"    stp x29, x30, [sp, -80]!\n"
100
+"    mov x29, sp\n"
101
+"    stp d8, d9, [sp, 16]\n"
102
+"    stp d10, d11, [sp, 32]\n"
103
+"    stp d12, d13, [sp, 48]\n"
104
+"    stp d14, d15, [sp, 64]\n"
105
+"    smstart\n"
106
+"    ptrue p0.s, vl4\n"
107
+"    fmov z0.s, #1.0\n"
108
+/*
109
+ * An outer product of a vector of 1.0 by itself should be a matrix of 1.0.
110
+ * Note that we are using tile 1 here (za1.s) rather than tile 0.
111
+ */
112
+"    zero {za}\n"
113
+"    fmopa za1.s, p0/m, p0/m, z0.s, z0.s\n"
114
+/*
115
+ * Read the first 4x4 sub-matrix of elements from tile 1:
116
+ * Note that za1h should be interchangable here.
117
+ */
118
+"    mov w12, #0\n"
119
+"    mova z0.s, p0/m, za1v.s[w12, #0]\n"
120
+"    mova z1.s, p0/m, za1v.s[w12, #1]\n"
121
+"    mova z2.s, p0/m, za1v.s[w12, #2]\n"
122
+"    mova z3.s, p0/m, za1v.s[w12, #3]\n"
123
+/*
124
+ * And store them to the input pointer (dst in the C code):
125
+ */
126
+"    st1w {z0.s}, p0, [x0]\n"
127
+"    add x0, x0, #16\n"
128
+"    st1w {z1.s}, p0, [x0]\n"
129
+"    add x0, x0, #16\n"
130
+"    st1w {z2.s}, p0, [x0]\n"
131
+"    add x0, x0, #16\n"
132
+"    st1w {z3.s}, p0, [x0]\n"
133
+"    smstop\n"
134
+"    ldp d8, d9, [sp, 16]\n"
135
+"    ldp d10, d11, [sp, 32]\n"
136
+"    ldp d12, d13, [sp, 48]\n"
137
+"    ldp d14, d15, [sp, 64]\n"
138
+"    ldp x29, x30, [sp], 80\n"
139
+"    ret\n"
140
+"    .size foo, . - foo"
141
+);
142
+
143
+int main()
144
+{
145
+ float dst[16];
146
+ int i, j;
147
+
148
+ foo(dst);
149
+
150
+ for (i = 0; i < 16; i++) {
151
+ if (dst[i] != 1.0f) {
152
+ break;
153
+ }
154
+ }
155
+
156
+ if (i == 16) {
157
+ return 0; /* success */
158
+ }
159
+
160
+ /* failure */
161
+ for (i = 0; i < 4; ++i) {
162
+ for (j = 0; j < 4; ++j) {
163
+ printf("%f ", (double)dst[i * 4 + j]);
164
+ }
165
+ printf("\n");
166
+ }
167
+ return 1;
168
+}
169
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
170
index XXXXXXX..XXXXXXX 100644
171
--- a/tests/tcg/aarch64/Makefile.target
172
+++ b/tests/tcg/aarch64/Makefile.target
173
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
174
     $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
175
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
176
     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
177
-     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
178
+     $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
179
-include config-cc.mak
180
181
ifneq ($(CROSS_CC_HAS_ARMV8_2),)
182
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
183
mte-%: CFLAGS += -march=armv8.5-a+memtag
184
endif
185
186
+ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
187
+AARCH64_TESTS += sme-outprod1
188
+endif
189
+
190
ifneq ($(CROSS_CC_HAS_SVE),)
191
# System Registers Tests
192
AARCH64_TESTS += sysregs
193
-ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
194
-sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
195
+ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
196
+sysregs: CFLAGS+=-Wa,-march=armv9-a+sme -DHAS_ARMV9_SME
197
else
198
sysregs: CFLAGS+=-march=armv8.1-a+sve
199
endif
53
--
200
--
54
2.20.1
201
2.34.1
55
56
diff view generated by jsdifflib
1
The ARMv5 architecture didn't specify detailed per-feature ID
1
From: John Högberg <john.hogberg@ericsson.com>
2
registers. Now that we're using the MVFR0 register fields to
3
gate the existence of VFP instructions, we need to set up
4
the correct values in the cpu->isar structure so that we still
5
provide an FPU to the guest.
6
2
7
This fixes a regression in the arm926 and arm1026 CPUs, which
3
Unlike architectures with precise self-modifying code semantics
8
are the only ones that both have VFP and are ARMv5 or earlier.
4
(e.g. x86) ARM processors do not maintain coherency for instruction
9
This regression was introduced by the VFP refactoring, and more
5
execution and memory, requiring an instruction synchronization
10
specifically by commits 1120827fa182f0e76 and 266bd25c485597c,
6
barrier on every core that will execute the new code, and on many
11
which accidentally disabled VFP short-vector support and
7
models also the explicit use of cache management instructions.
12
double-precision support on these CPUs.
13
8
14
Fixes: 1120827fa182f0e
9
While this is required to make JITs work on actual hardware, QEMU
15
Fixes: 266bd25c485597c
10
has gotten away with not handling this since it does not emulate
16
Fixes: https://bugs.launchpad.net/qemu/+bug/1836192
11
caches, and unconditionally invalidates code whenever the softmmu
17
Reported-by: Christophe Lyon <christophe.lyon@linaro.org>
12
or the user-mode page protection logic detects that code has been
13
modified.
14
15
Unfortunately the latter does not work in the face of dual-mapped
16
code (a common W^X workaround), where one page is executable and
17
the other is writable: user-mode has no way to connect one with the
18
other as that is only known to the kernel and the emulated
19
application.
20
21
This commit works around the issue by telling software that
22
instruction cache invalidation is required by clearing the
23
CPR_EL0.DIC flag (regardless of whether the emulated processor
24
needs it), and then invalidating code in IC IVAU instructions.
25
26
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1034
27
28
Co-authored-by: Richard Henderson <richard.henderson@linaro.org>
29
Signed-off-by: John Högberg <john.hogberg@ericsson.com>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Message-id: 168778890374.24232.3402138851538068785-1@git.sr.ht
32
[PMM: removed unnecessary AArch64 feature check; moved
33
"clear CTR_EL1.DIC" code up a bit so it's not in the middle
34
of the vfp/neon related tests]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Tested-by: Christophe Lyon <christophe.lyon@linaro.org>
22
Message-id: 20190711131241.22231-1-peter.maydell@linaro.org
23
---
36
---
24
target/arm/cpu.c | 12 ++++++++++++
37
target/arm/cpu.c | 11 +++++++++++
25
1 file changed, 12 insertions(+)
38
target/arm/helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++---
39
2 files changed, 55 insertions(+), 3 deletions(-)
26
40
27
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.c
43
--- a/target/arm/cpu.c
30
+++ b/target/arm/cpu.c
44
+++ b/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
32
* set the field to indicate Jazelle support within QEMU.
46
return;
33
*/
47
}
34
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
48
49
+#ifdef CONFIG_USER_ONLY
35
+ /*
50
+ /*
36
+ * Similarly, we need to set MVFR0 fields to enable double precision
51
+ * User mode relies on IC IVAU instructions to catch modification of
37
+ * and short vector support even though ARMv5 doesn't have this register.
52
+ * dual-mapped code.
53
+ *
54
+ * Clear CTR_EL0.DIC to ensure that software that honors these flags uses
55
+ * IC IVAU even if the emulated processor does not normally require it.
38
+ */
56
+ */
39
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
57
+ cpu->ctr = FIELD_DP64(cpu->ctr, CTR_EL0, DIC, 0);
40
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
58
+#endif
59
+
60
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
61
cpu->has_vfp != cpu->has_neon) {
62
/*
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
68
}
41
}
69
}
42
70
43
static void arm946_initfn(Object *obj)
71
+#ifdef CONFIG_USER_ONLY
44
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
72
+/*
45
* set the field to indicate Jazelle support within QEMU.
73
+ * `IC IVAU` is handled to improve compatibility with JITs that dual-map their
46
*/
74
+ * code to get around W^X restrictions, where one region is writable and the
47
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
75
+ * other is executable.
76
+ *
77
+ * Since the executable region is never written to we cannot detect code
78
+ * changes when running in user mode, and rely on the emulated JIT telling us
79
+ * that the code has changed by executing this instruction.
80
+ */
81
+static void ic_ivau_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
+ uint64_t value)
83
+{
84
+ uint64_t icache_line_mask, start_address, end_address;
85
+ const ARMCPU *cpu;
86
+
87
+ cpu = env_archcpu(env);
88
+
89
+ icache_line_mask = (4 << extract32(cpu->ctr, 0, 4)) - 1;
90
+ start_address = value & ~icache_line_mask;
91
+ end_address = value | icache_line_mask;
92
+
93
+ mmap_lock();
94
+
95
+ tb_invalidate_phys_range(start_address, end_address);
96
+
97
+ mmap_unlock();
98
+}
99
+#endif
100
+
101
static const ARMCPRegInfo v8_cp_reginfo[] = {
102
/*
103
* Minimal set of EL0-visible registers. This will need to be expanded
104
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
105
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
107
.access = PL1_R, .type = ARM_CP_CURRENTEL },
108
- /* Cache ops: all NOPs since we don't emulate caches */
48
+ /*
109
+ /*
49
+ * Similarly, we need to set MVFR0 fields to enable double precision
110
+ * Instruction cache ops. All of these except `IC IVAU` NOP because we
50
+ * and short vector support even though ARMv5 doesn't have this register.
111
+ * don't emulate caches.
51
+ */
112
+ */
52
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
113
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
53
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
114
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
54
115
.access = PL1_W, .type = ARM_CP_NOP,
55
{
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
56
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
117
.accessfn = access_tocu },
118
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
119
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
120
- .access = PL0_W, .type = ARM_CP_NOP,
121
+ .access = PL0_W,
122
.fgt = FGT_ICIVAU,
123
- .accessfn = access_tocu },
124
+ .accessfn = access_tocu,
125
+#ifdef CONFIG_USER_ONLY
126
+ .type = ARM_CP_NO_RAW,
127
+ .writefn = ic_ivau_write
128
+#else
129
+ .type = ARM_CP_NOP
130
+#endif
131
+ },
132
+ /* Cache ops: all NOPs since we don't emulate caches */
133
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
134
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
135
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
57
--
136
--
58
2.20.1
137
2.34.1
59
138
60
139
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: John Högberg <john.hogberg@ericsson.com>
2
2
3
Reading the RX_DATA register when the RX_FIFO is empty triggers
3
https://gitlab.com/qemu-project/qemu/-/issues/1034
4
an abort. This can be easily reproduced:
4
5
5
Signed-off-by: John Högberg <john.hogberg@ericsson.com>
6
$ qemu-system-arm -M emcraft-sf2 -monitor stdio -S
6
Message-id: 168778890374.24232.3402138851538068785-2@git.sr.ht
7
QEMU 4.0.50 monitor - type 'help' for more information
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
(qemu) x 0x40001010
8
[PMM: fixed typo in comment]
9
Aborted (core dumped)
10
11
(gdb) bt
12
#1 0x00007f035874f895 in abort () at /lib64/libc.so.6
13
#2 0x00005628686591ff in fifo8_pop (fifo=0x56286a9a4c68) at util/fifo8.c:66
14
#3 0x00005628683e0b8e in fifo32_pop (fifo=0x56286a9a4c68) at include/qemu/fifo32.h:137
15
#4 0x00005628683e0efb in spi_read (opaque=0x56286a9a4850, addr=4, size=4) at hw/ssi/mss-spi.c:168
16
#5 0x0000562867f96801 in memory_region_read_accessor (mr=0x56286a9a4b60, addr=16, value=0x7ffeecb0c5c8, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
17
#6 0x0000562867f96cdb in access_with_adjusted_size (addr=16, value=0x7ffeecb0c5c8, size=4, access_size_min=1, access_size_max=4, access_fn=0x562867f967c3 <memory_region_read_accessor>, mr=0x56286a9a4b60, attrs=...) at memory.c:569
18
#7 0x0000562867f99940 in memory_region_dispatch_read1 (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1420
19
#8 0x0000562867f99a08 in memory_region_dispatch_read (mr=0x56286a9a4b60, addr=16, pval=0x7ffeecb0c5c8, size=4, attrs=...) at memory.c:1447
20
#9 0x0000562867f38721 in flatview_read_continue (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, addr1=16, l=4, mr=0x56286a9a4b60) at exec.c:3385
21
#10 0x0000562867f38874 in flatview_read (fv=0x56286aec6360, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3423
22
#11 0x0000562867f388ea in address_space_read_full (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4) at exec.c:3436
23
#12 0x0000562867f389c5 in address_space_rw (as=0x56286aa3e890, addr=1073745936, attrs=..., buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=false) at exec.c:3466
24
#13 0x0000562867f3bdd7 in cpu_memory_rw_debug (cpu=0x56286aa19d00, addr=1073745936, buf=0x7ffeecb0c7c0 "\340ǰ\354\376\177", len=4, is_write=0) at exec.c:3976
25
#14 0x000056286811ed51 in memory_dump (mon=0x56286a8c32d0, count=1, format=120, wsize=4, addr=1073745936, is_physical=0) at monitor/misc.c:730
26
#15 0x000056286811eff1 in hmp_memory_dump (mon=0x56286a8c32d0, qdict=0x56286b15c400) at monitor/misc.c:785
27
#16 0x00005628684740ee in handle_hmp_command (mon=0x56286a8c32d0, cmdline=0x56286a8caeb2 "0x40001010") at monitor/hmp.c:1082
28
29
From the datasheet "Actel SmartFusion Microcontroller Subsystem
30
User's Guide" Rev.1, Table 13-3 "SPI Register Summary", this
31
register has a reset value of 0.
32
33
Check the FIFO is not empty before accessing it, else log an
34
error message.
35
36
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
37
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
38
Message-id: 20190709113715.7761-3-philmd@redhat.com
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
---
10
---
41
hw/ssi/mss-spi.c | 8 +++++++-
11
tests/tcg/aarch64/icivau.c | 189 ++++++++++++++++++++++++++++++
42
1 file changed, 7 insertions(+), 1 deletion(-)
12
tests/tcg/aarch64/Makefile.target | 3 +-
43
13
2 files changed, 191 insertions(+), 1 deletion(-)
44
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
14
create mode 100644 tests/tcg/aarch64/icivau.c
15
16
diff --git a/tests/tcg/aarch64/icivau.c b/tests/tcg/aarch64/icivau.c
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/tests/tcg/aarch64/icivau.c
21
@@ -XXX,XX +XXX,XX @@
22
+/*
23
+ * Tests the IC IVAU-driven workaround for catching changes made to dual-mapped
24
+ * code that would otherwise go unnoticed in user mode.
25
+ *
26
+ * Copyright (c) 2023 Ericsson AB
27
+ * SPDX-License-Identifier: GPL-2.0-or-later
28
+ */
29
+
30
+#include <sys/mman.h>
31
+#include <sys/stat.h>
32
+#include <string.h>
33
+#include <stdint.h>
34
+#include <stdlib.h>
35
+#include <unistd.h>
36
+#include <fcntl.h>
37
+
38
+#define MAX_CODE_SIZE 128
39
+
40
+typedef int (SelfModTest)(uint32_t, uint32_t*);
41
+typedef int (BasicTest)(int);
42
+
43
+static void mark_code_modified(const uint32_t *exec_data, size_t length)
44
+{
45
+ int dc_required, ic_required;
46
+ unsigned long ctr_el0;
47
+
48
+ /*
49
+ * Clear the data/instruction cache, as indicated by the CTR_ELO.{DIC,IDC}
50
+ * flags.
51
+ *
52
+ * For completeness we might be tempted to assert that we should fail when
53
+ * the whole code update sequence is omitted, but that would make the test
54
+ * flaky as it can succeed by coincidence on actual hardware.
55
+ */
56
+ asm ("mrs %0, ctr_el0\n" : "=r"(ctr_el0));
57
+
58
+ /* CTR_EL0.IDC */
59
+ dc_required = !((ctr_el0 >> 28) & 1);
60
+
61
+ /* CTR_EL0.DIC */
62
+ ic_required = !((ctr_el0 >> 29) & 1);
63
+
64
+ if (dc_required) {
65
+ size_t dcache_stride, i;
66
+
67
+ /*
68
+ * Step according to the minimum cache size, as the cache maintenance
69
+ * instructions operate on the cache line of the given address.
70
+ *
71
+ * We assume that exec_data is properly aligned.
72
+ */
73
+ dcache_stride = (4 << ((ctr_el0 >> 16) & 0xF));
74
+
75
+ for (i = 0; i < length; i += dcache_stride) {
76
+ const char *dc_addr = &((const char *)exec_data)[i];
77
+ asm volatile ("dc cvau, %x[dc_addr]\n"
78
+ : /* no outputs */
79
+ : [dc_addr] "r"(dc_addr)
80
+ : "memory");
81
+ }
82
+
83
+ asm volatile ("dmb ish\n");
84
+ }
85
+
86
+ if (ic_required) {
87
+ size_t icache_stride, i;
88
+
89
+ icache_stride = (4 << (ctr_el0 & 0xF));
90
+
91
+ for (i = 0; i < length; i += icache_stride) {
92
+ const char *ic_addr = &((const char *)exec_data)[i];
93
+ asm volatile ("ic ivau, %x[ic_addr]\n"
94
+ : /* no outputs */
95
+ : [ic_addr] "r"(ic_addr)
96
+ : "memory");
97
+ }
98
+
99
+ asm volatile ("dmb ish\n");
100
+ }
101
+
102
+ asm volatile ("isb sy\n");
103
+}
104
+
105
+static int basic_test(uint32_t *rw_data, const uint32_t *exec_data)
106
+{
107
+ /*
108
+ * As user mode only misbehaved for dual-mapped code when previously
109
+ * translated code had been changed, we'll start off with this basic test
110
+ * function to ensure that there's already some translated code at
111
+ * exec_data before the next test. This should cause the next test to fail
112
+ * if `mark_code_modified` fails to invalidate the code.
113
+ *
114
+ * Note that the payload is in binary form instead of inline assembler
115
+ * because we cannot use __attribute__((naked)) on this platform and the
116
+ * workarounds are at least as ugly as this is.
117
+ */
118
+ static const uint32_t basic_payload[] = {
119
+ 0xD65F03C0 /* 0x00: RET */
120
+ };
121
+
122
+ BasicTest *copied_ptr = (BasicTest *)exec_data;
123
+
124
+ memcpy(rw_data, basic_payload, sizeof(basic_payload));
125
+ mark_code_modified(exec_data, sizeof(basic_payload));
126
+
127
+ return copied_ptr(1234) == 1234;
128
+}
129
+
130
+static int self_modification_test(uint32_t *rw_data, const uint32_t *exec_data)
131
+{
132
+ /*
133
+ * This test is self-modifying in an attempt to cover an edge case where
134
+ * the IC IVAU instruction invalidates itself.
135
+ *
136
+ * Note that the IC IVAU instruction is 16 bytes into the function, in what
137
+ * will be the same cache line as the modified instruction on machines with
138
+ * a cache line size >= 16 bytes.
139
+ */
140
+ static const uint32_t self_mod_payload[] = {
141
+ /* Overwrite the placeholder instruction with the new one. */
142
+ 0xB9001C20, /* 0x00: STR w0, [x1, 0x1C] */
143
+
144
+ /* Get the executable address of the modified instruction. */
145
+ 0x100000A8, /* 0x04: ADR x8, <0x1C> */
146
+
147
+ /* Mark the modified instruction as updated. */
148
+ 0xD50B7B28, /* 0x08: DC CVAU x8 */
149
+ 0xD5033BBF, /* 0x0C: DMB ISH */
150
+ 0xD50B7528, /* 0x10: IC IVAU x8 */
151
+ 0xD5033BBF, /* 0x14: DMB ISH */
152
+ 0xD5033FDF, /* 0x18: ISB */
153
+
154
+ /* Placeholder instruction, overwritten above. */
155
+ 0x52800000, /* 0x1C: MOV w0, 0 */
156
+
157
+ 0xD65F03C0 /* 0x20: RET */
158
+ };
159
+
160
+ SelfModTest *copied_ptr = (SelfModTest *)exec_data;
161
+ int i;
162
+
163
+ memcpy(rw_data, self_mod_payload, sizeof(self_mod_payload));
164
+ mark_code_modified(exec_data, sizeof(self_mod_payload));
165
+
166
+ for (i = 1; i < 10; i++) {
167
+ /* Replace the placeholder instruction with `MOV w0, i` */
168
+ uint32_t new_instr = 0x52800000 | (i << 5);
169
+
170
+ if (copied_ptr(new_instr, rw_data) != i) {
171
+ return 0;
172
+ }
173
+ }
174
+
175
+ return 1;
176
+}
177
+
178
+int main(int argc, char **argv)
179
+{
180
+ const char *shm_name = "qemu-test-tcg-aarch64-icivau";
181
+ int fd;
182
+
183
+ fd = shm_open(shm_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
184
+
185
+ if (fd < 0) {
186
+ return EXIT_FAILURE;
187
+ }
188
+
189
+ /* Unlink early to avoid leaving garbage in case the test crashes. */
190
+ shm_unlink(shm_name);
191
+
192
+ if (ftruncate(fd, MAX_CODE_SIZE) == 0) {
193
+ const uint32_t *exec_data;
194
+ uint32_t *rw_data;
195
+
196
+ rw_data = mmap(0, MAX_CODE_SIZE, PROT_READ | PROT_WRITE,
197
+ MAP_SHARED, fd, 0);
198
+ exec_data = mmap(0, MAX_CODE_SIZE, PROT_READ | PROT_EXEC,
199
+ MAP_SHARED, fd, 0);
200
+
201
+ if (rw_data && exec_data) {
202
+ if (basic_test(rw_data, exec_data) &&
203
+ self_modification_test(rw_data, exec_data)) {
204
+ return EXIT_SUCCESS;
205
+ }
206
+ }
207
+ }
208
+
209
+ return EXIT_FAILURE;
210
+}
211
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
45
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/ssi/mss-spi.c
213
--- a/tests/tcg/aarch64/Makefile.target
47
+++ b/hw/ssi/mss-spi.c
214
+++ b/tests/tcg/aarch64/Makefile.target
48
@@ -XXX,XX +XXX,XX @@ spi_read(void *opaque, hwaddr addr, unsigned int size)
215
@@ -XXX,XX +XXX,XX @@ AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
49
case R_SPI_RX:
216
VPATH         += $(AARCH64_SRC)
50
s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
217
51
s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF;
218
# Base architecture tests
52
- ret = fifo32_pop(&s->rx_fifo);
219
-AARCH64_TESTS=fcvt pcalign-a64
53
+ if (fifo32_is_empty(&s->rx_fifo)) {
220
+AARCH64_TESTS=fcvt pcalign-a64 icivau
54
+ qemu_log_mask(LOG_GUEST_ERROR,
221
55
+ "%s: Reading empty RX_FIFO\n",
222
fcvt: LDFLAGS+=-lm
56
+ __func__);
223
+icivau: LDFLAGS+=-lrt
57
+ } else {
224
58
+ ret = fifo32_pop(&s->rx_fifo);
225
run-fcvt: fcvt
59
+ }
226
    $(call run-test,$<,$(QEMU) $<, "$< on $(TARGET_NAME)")
60
if (fifo32_is_empty(&s->rx_fifo)) {
61
s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
62
}
63
--
227
--
64
2.20.1
228
2.34.1
65
229
66
230
diff view generated by jsdifflib
New patch
1
From: Vikram Garhwal <vikram.garhwal@amd.com>
1
2
3
Following are done to fix the coverity issues:
4
1. Change read_data to fix the CID 1512899: Out-of-bounds access (OVERRUN)
5
2. Fix match_rx_tx_data to fix CID 1512900: Logically dead code (DEADCODE)
6
3. Replace rand() in generate_random_data() with g_rand_int()
7
8
Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
9
Message-id: 20230628202758.16398-1-vikram.garhwal@amd.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
tests/qtest/xlnx-canfd-test.c | 33 +++++++++++----------------------
14
1 file changed, 11 insertions(+), 22 deletions(-)
15
16
diff --git a/tests/qtest/xlnx-canfd-test.c b/tests/qtest/xlnx-canfd-test.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/xlnx-canfd-test.c
19
+++ b/tests/qtest/xlnx-canfd-test.c
20
@@ -XXX,XX +XXX,XX @@ static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
21
/* Generate random TX data for CANFD frame. */
22
if (is_canfd_frame) {
23
for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
24
- buf_tx[2 + i] = rand();
25
+ buf_tx[2 + i] = g_random_int();
26
}
27
} else {
28
/* Generate random TX data for CAN frame. */
29
for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
30
- buf_tx[2 + i] = rand();
31
+ buf_tx[2 + i] = g_random_int();
32
}
33
}
34
}
35
36
-static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
37
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx,
38
+ uint32_t frame_size)
39
{
40
uint32_t int_status;
41
uint32_t fifo_status_reg_value;
42
/* At which RX FIFO the received data is stored. */
43
uint8_t store_ind = 0;
44
- bool is_canfd_frame = false;
45
46
/* Read the interrupt on CANFD rx. */
47
int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
48
@@ -XXX,XX +XXX,XX @@ static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
49
buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
50
buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
51
52
- is_canfd_frame = (buf_rx[1] >> DLC_FD_BIT_SHIFT) & 1;
53
-
54
- if (is_canfd_frame) {
55
- for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
56
- buf_rx[i + 2] = qtest_readl(qts,
57
- can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
58
- }
59
- } else {
60
- buf_rx[2] = qtest_readl(qts, can_base_addr + R_RX0_DATA1_OFFSET);
61
- buf_rx[3] = qtest_readl(qts, can_base_addr + R_RX0_DATA2_OFFSET);
62
+ for (int i = 0; i < frame_size - 2; i++) {
63
+ buf_rx[i + 2] = qtest_readl(qts,
64
+ can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
65
}
66
67
/* Clear the RX interrupt. */
68
@@ -XXX,XX +XXX,XX @@ static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
69
g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
70
(buf_tx[size] & DLC_FD_BIT_MASK));
71
} else {
72
- if (!is_canfd_frame && size == 4) {
73
- break;
74
- }
75
-
76
g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static void test_can_data_transfer(void)
80
write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
81
82
send_data(qts, CANFD0_BASE_ADDR);
83
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
84
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CAN_FRAME_SIZE);
85
match_rx_tx_data(buf_tx, buf_rx, false);
86
87
qtest_quit(qts);
88
@@ -XXX,XX +XXX,XX @@ static void test_canfd_data_transfer(void)
89
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
90
91
send_data(qts, CANFD0_BASE_ADDR);
92
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
93
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
94
match_rx_tx_data(buf_tx, buf_rx, true);
95
96
qtest_quit(qts);
97
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
98
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
99
100
send_data(qts, CANFD0_BASE_ADDR);
101
- read_data(qts, CANFD0_BASE_ADDR, buf_rx);
102
+ read_data(qts, CANFD0_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
103
match_rx_tx_data(buf_tx, buf_rx, true);
104
105
generate_random_data(buf_tx, true);
106
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
107
write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
108
109
send_data(qts, CANFD1_BASE_ADDR);
110
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
111
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
112
match_rx_tx_data(buf_tx, buf_rx, true);
113
114
qtest_quit(qts);
115
--
116
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Both lqspi_read() and lqspi_load_cache() expect a 32-bit
3
This code is only relevant when TCG is present in the build. Building
4
aligned address.
4
with --disable-tcg --enable-xen on an x86 host we get:
5
5
6
>From UG1085 datasheet [*] chapter on 'Quad-SPI Controller':
6
$ ../configure --target-list=x86_64-softmmu,aarch64-softmmu --disable-tcg --enable-xen
7
$ make -j$(nproc)
8
...
9
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `m_sysreg_ptr':
10
../target/arm/gdbstub.c:358: undefined reference to `arm_v7m_get_sp_ptr'
11
../target/arm/gdbstub.c:361: undefined reference to `arm_v7m_get_sp_ptr'
7
12
8
Transfer Size Limitations
13
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `arm_gdb_get_m_systemreg':
14
../target/arm/gdbstub.c:405: undefined reference to `arm_v7m_mrs_control'
9
15
10
Because of the 32-bit wide TX, RX, and generic FIFO, all
16
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
APB/AXI transfers must be an integer multiple of 4-bytes.
17
Message-id: 20230628164821.16771-1-farosas@suse.de
12
Shorter transfers are not possible.
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
14
Set MemoryRegionOps.impl values to force 32-bit accesses,
15
this way we are sure we do not access the lqspi_buf[] array
16
out of bound.
17
18
[*] https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
19
20
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
21
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
22
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
20
---
25
hw/ssi/xilinx_spips.c | 4 ++++
21
target/arm/gdbstub.c | 4 ++++
26
1 file changed, 4 insertions(+)
22
1 file changed, 4 insertions(+)
27
23
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
24
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
29
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/ssi/xilinx_spips.c
26
--- a/target/arm/gdbstub.c
31
+++ b/hw/ssi/xilinx_spips.c
27
+++ b/target/arm/gdbstub.c
32
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps lqspi_ops = {
28
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
33
.read_with_attrs = lqspi_read,
29
return cpu->dyn_sysreg_xml.num;
34
.write_with_attrs = lqspi_write,
30
}
35
.endianness = DEVICE_NATIVE_ENDIAN,
31
36
+ .impl = {
32
+#ifdef CONFIG_TCG
37
+ .min_access_size = 4,
33
typedef enum {
38
+ .max_access_size = 4,
34
M_SYSREG_MSP,
39
+ },
35
M_SYSREG_PSP,
40
.valid = {
36
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg)
41
.min_access_size = 1,
37
return cpu->dyn_m_secextreg_xml.num;
42
.max_access_size = 4
38
}
39
#endif
40
+#endif /* CONFIG_TCG */
41
42
const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
43
{
44
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
45
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
46
"system-registers.xml", 0);
47
48
+#ifdef CONFIG_TCG
49
if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
50
gdb_register_coprocessor(cs,
51
arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
52
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
53
}
54
#endif
55
}
56
+#endif /* CONFIG_TCG */
57
}
43
--
58
--
44
2.20.1
59
2.34.1
45
46
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
In the previous commit we fixed a crash when the guest read a
3
AwSRAMCClass is larger than SysBusDeviceClass so the class size must be
4
register that pop from an empty FIFO.
4
advertised accordingly.
5
By auditing the repository, we found another similar use with
6
an easy way to reproduce:
7
5
8
$ qemu-system-aarch64 -M xlnx-zcu102 -monitor stdio -S
6
Fixes: 05def917e1 ("hw: arm: allwinner-sramc: Add SRAM Controller support for R40")
9
QEMU 4.0.50 monitor - type 'help' for more information
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
(qemu) xp/b 0xfd4a0134
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Aborted (core dumped)
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
10
Message-id: 20230628110905.38125-1-akihiko.odaki@daynix.com
13
(gdb) bt
14
#0 0x00007f6936dea57f in raise () at /lib64/libc.so.6
15
#1 0x00007f6936dd4895 in abort () at /lib64/libc.so.6
16
#2 0x0000561ad32975ec in xlnx_dp_aux_pop_rx_fifo (s=0x7f692babee70) at hw/display/xlnx_dp.c:431
17
#3 0x0000561ad3297dc0 in xlnx_dp_read (opaque=0x7f692babee70, offset=77, size=4) at hw/display/xlnx_dp.c:667
18
#4 0x0000561ad321b896 in memory_region_read_accessor (mr=0x7f692babf620, addr=308, value=0x7ffe05c1db88, size=4, shift=0, mask=4294967295, attrs=...) at memory.c:439
19
#5 0x0000561ad321bd70 in access_with_adjusted_size (addr=308, value=0x7ffe05c1db88, size=1, access_size_min=4, access_size_max=4, access_fn=0x561ad321b858 <memory_region_read_accessor>, mr=0x7f692babf620, attrs=...) at memory.c:569
20
#6 0x0000561ad321e9d5 in memory_region_dispatch_read1 (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1420
21
#7 0x0000561ad321ea9d in memory_region_dispatch_read (mr=0x7f692babf620, addr=308, pval=0x7ffe05c1db88, size=1, attrs=...) at memory.c:1447
22
#8 0x0000561ad31bd742 in flatview_read_continue (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1, addr1=308, l=1, mr=0x7f692babf620) at exec.c:3385
23
#9 0x0000561ad31bd895 in flatview_read (fv=0x561ad69c04f0, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3423
24
#10 0x0000561ad31bd90b in address_space_read_full (as=0x561ad5bb3020, addr=4249485620, attrs=..., buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", len=1) at exec.c:3436
25
#11 0x0000561ad33b1c42 in address_space_read (len=1, buf=0x7ffe05c1dcf0 "\020\335\301\005\376\177", attrs=..., addr=4249485620, as=0x561ad5bb3020) at include/exec/memory.h:2131
26
#12 0x0000561ad33b1c42 in memory_dump (mon=0x561ad59c4530, count=1, format=120, wsize=1, addr=4249485620, is_physical=1) at monitor/misc.c:723
27
#13 0x0000561ad33b1fc1 in hmp_physical_memory_dump (mon=0x561ad59c4530, qdict=0x561ad6c6fd00) at monitor/misc.c:795
28
#14 0x0000561ad37b4a9f in handle_hmp_command (mon=0x561ad59c4530, cmdline=0x561ad59d0f22 "/b 0x00000000fd4a0134") at monitor/hmp.c:1082
29
30
Fix by checking the FIFO is not empty before popping from it.
31
32
The datasheet is not clear about the reset value of this register,
33
we choose to return '0'.
34
35
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
36
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
37
Message-id: 20190709113715.7761-4-philmd@redhat.com
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
---
12
---
40
hw/display/xlnx_dp.c | 15 +++++++++++----
13
hw/misc/allwinner-sramc.c | 1 +
41
1 file changed, 11 insertions(+), 4 deletions(-)
14
1 file changed, 1 insertion(+)
42
15
43
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
16
diff --git a/hw/misc/allwinner-sramc.c b/hw/misc/allwinner-sramc.c
44
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/display/xlnx_dp.c
18
--- a/hw/misc/allwinner-sramc.c
46
+++ b/hw/display/xlnx_dp.c
19
+++ b/hw/misc/allwinner-sramc.c
47
@@ -XXX,XX +XXX,XX @@ static uint8_t xlnx_dp_aux_pop_rx_fifo(XlnxDPState *s)
20
@@ -XXX,XX +XXX,XX @@ static const TypeInfo allwinner_sramc_info = {
48
uint8_t ret;
21
.parent = TYPE_SYS_BUS_DEVICE,
49
22
.instance_init = allwinner_sramc_init,
50
if (fifo8_is_empty(&s->rx_fifo)) {
23
.instance_size = sizeof(AwSRAMCState),
51
- DPRINTF("rx_fifo underflow..\n");
24
+ .class_size = sizeof(AwSRAMCClass),
52
- abort();
25
.class_init = allwinner_sramc_class_init,
53
+ qemu_log_mask(LOG_GUEST_ERROR,
26
};
54
+ "%s: Reading empty RX_FIFO\n",
55
+ __func__);
56
+ /*
57
+ * The datasheet is not clear about the reset value, it seems
58
+ * to be unspecified. We choose to return '0'.
59
+ */
60
+ ret = 0;
61
+ } else {
62
+ ret = fifo8_pop(&s->rx_fifo);
63
+ DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
64
}
65
- ret = fifo8_pop(&s->rx_fifo);
66
- DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
67
return ret;
68
}
69
27
70
--
28
--
71
2.20.1
29
2.34.1
72
30
73
31
diff view generated by jsdifflib
1
In the M-profile architecture, when we do a vector table fetch and it
1
In handle_interrupt() we use level as an index into the interrupt_vector[]
2
fails, we need to report a HardFault. Whether this is a Secure HF or
2
array. This is safe because we have checked it against env->config->nlevel,
3
a NonSecure HF depends on several things. If AIRCR.BFHFNMINS is 0
3
but Coverity can't see that (and it is only true because each CPU config
4
then HF is always Secure, because there is no NonSecure HardFault.
4
sets its XCHAL_NUM_INTLEVELS to something less than MAX_NLEVELS), so it
5
Otherwise, the answer depends on whether the 'underlying exception'
5
complains about a possible array overrun (CID 1507131)
6
(MemManage, BusFault, SecureFault) targets Secure or NonSecure. (In
7
the pseudocode, this is handled in the Vector() function: the final
8
exc.isSecure is calculated by looking at the exc.isSecure from the
9
exception returned from the memory access, not the isSecure input
10
argument.)
11
6
12
We weren't doing this correctly, because we were looking at
7
Add an assert() which will make Coverity happy and catch the unlikely
13
the target security domain of the exception we were trying to
8
case of a mis-set XCHAL_NUM_INTLEVELS in future.
14
load the vector table entry for. This produces errors of two kinds:
15
* a load from the NS vector table which hits the "NS access
16
to S memory" SecureFault should end up as a Secure HardFault,
17
but we were raising an NS HardFault
18
* a load from the S vector table which causes a BusFault
19
should raise an NS HardFault if BFHFNMINS == 1 (because
20
in that case all BusFaults are NonSecure), but we were raising
21
a Secure HardFault
22
23
Correct the logic.
24
25
We also fix a comment error where we claimed that we might
26
be escalating MemManage to HardFault, and forgot about SecureFault.
27
(Vector loads can never hit MPU access faults, because they're
28
always aligned and always use the default address map.)
29
9
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Message-id: 20190705094823.28905-1-peter.maydell@linaro.org
11
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
12
Message-id: 20230623154135.1930261-1-peter.maydell@linaro.org
32
---
13
---
33
target/arm/m_helper.c | 21 +++++++++++++++++----
14
target/xtensa/exc_helper.c | 3 +++
34
1 file changed, 17 insertions(+), 4 deletions(-)
15
1 file changed, 3 insertions(+)
35
16
36
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
17
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
37
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/m_helper.c
19
--- a/target/xtensa/exc_helper.c
39
+++ b/target/arm/m_helper.c
20
+++ b/target/xtensa/exc_helper.c
40
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
21
@@ -XXX,XX +XXX,XX @@ static void handle_interrupt(CPUXtensaState *env)
41
if (sattrs.ns) {
22
CPUState *cs = env_cpu(env);
42
attrs.secure = false;
23
43
} else if (!targets_secure) {
24
if (level > 1) {
44
- /* NS access to S memory */
25
+ /* env->config->nlevel check should have ensured this */
45
+ /*
26
+ assert(level < sizeof(env->config->interrupt_vector));
46
+ * NS access to S memory: the underlying exception which we escalate
27
+
47
+ * to HardFault is SecureFault, which always targets Secure.
28
env->sregs[EPC1 + level - 1] = env->pc;
48
+ */
29
env->sregs[EPS2 + level - 2] = env->sregs[PS];
49
+ exc_secure = true;
30
env->sregs[PS] =
50
goto load_fail;
51
}
52
}
53
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
54
vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
55
attrs, &result);
56
if (result != MEMTX_OK) {
57
+ /*
58
+ * Underlying exception is BusFault: its target security state
59
+ * depends on BFHFNMINS.
60
+ */
61
+ exc_secure = !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
62
goto load_fail;
63
}
64
*pvec = vector_entry;
65
@@ -XXX,XX +XXX,XX @@ load_fail:
66
/*
67
* All vector table fetch fails are reported as HardFault, with
68
* HFSR.VECTTBL and .FORCED set. (FORCED is set because
69
- * technically the underlying exception is a MemManage or BusFault
70
+ * technically the underlying exception is a SecureFault or BusFault
71
* that is escalated to HardFault.) This is a terminal exception,
72
* so we will either take the HardFault immediately or else enter
73
* lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
74
+ * The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
75
+ * secure); otherwise it targets the same security state as the
76
+ * underlying exception.
77
*/
78
- exc_secure = targets_secure ||
79
- !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
80
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
81
+ exc_secure = true;
82
+ }
83
env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
84
armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
85
return false;
86
--
31
--
87
2.20.1
32
2.34.1
88
89
diff view generated by jsdifflib