1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
1
target-arm queue: two bug fixes, plus the KVM/SVE patchset,
2
which is a new feature but one which was in my pre-softfreeze
3
pullreq (it just had to be dropped due to an unexpected test failure.)
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
8
The following changes since commit b7c9a7f353c0e260519bf735ff0d4aa01e72784b:
7
9
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
10
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (2019-10-31 15:57:30 +0000)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191101-1
13
15
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
16
for you to fetch changes up to d9ae7624b659362cb2bb2b04fee53bf50829ca56:
15
17
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
18
target/arm: Allow reading flags from FPSCR for M-profile (2019-11-01 08:49:10 +0000)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* ITS: error reporting cleanup
22
* Support SVE in KVM guests
21
* aspeed: improve documentation
23
* Don't UNDEF on M-profile 'vmrs apsr_nzcv, fpscr'
22
* Fix STM32F2XX USART data register readout
24
* Update hflags after boot.c modifies CPU state
23
* allow emulated GICv3 to be disabled in non-TCG builds
24
* fix exception priority for singlestep, misaligned PC, bp, etc
25
* Correct calculation of tlb range invalidate length
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
30
25
31
----------------------------------------------------------------
26
----------------------------------------------------------------
32
Alex Bennée (1):
27
Andrew Jones (9):
33
hw/intc: clean-up error reporting for failed ITS cmd
28
target/arm/monitor: Introduce qmp_query_cpu_model_expansion
29
tests: arm: Introduce cpu feature tests
30
target/arm: Allow SVE to be disabled via a CPU property
31
target/arm/cpu64: max cpu: Introduce sve<N> properties
32
target/arm/kvm64: Add kvm_arch_get/put_sve
33
target/arm/kvm64: max cpu: Enable SVE when available
34
target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features
35
target/arm/cpu64: max cpu: Support sve properties with KVM
36
target/arm/kvm: host cpu: Add support for sve<N> properties
34
37
35
Jean-Philippe Brucker (8):
38
Christophe Lyon (1):
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
39
target/arm: Allow reading flags from FPSCR for M-profile
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
40
tests/acpi: allow updates of VIOT expected data files
41
tests/acpi: add test case for VIOT
42
tests/acpi: add expected blobs for VIOT test on q35 machine
43
tests/acpi: add expected blob for VIOT test on virt machine
44
40
45
Joel Stanley (4):
41
Edgar E. Iglesias (1):
46
docs: aspeed: Add new boards
42
hw/arm/boot: Rebuild hflags when modifying CPUState at boot
47
docs: aspeed: Update OpenBMC image URL
48
docs: aspeed: Give an example of booting a kernel
49
docs: aspeed: ADC is now modelled
50
43
51
Olivier Hériveaux (1):
44
tests/Makefile.include | 5 +-
52
Fix STM32F2XX USART data register readout
45
qapi/machine-target.json | 6 +-
46
include/qemu/bitops.h | 1 +
47
target/arm/cpu.h | 21 ++
48
target/arm/kvm_arm.h | 39 +++
49
hw/arm/boot.c | 1 +
50
target/arm/cpu.c | 25 +-
51
target/arm/cpu64.c | 364 +++++++++++++++++++++++++--
52
target/arm/helper.c | 10 +-
53
target/arm/kvm.c | 25 +-
54
target/arm/kvm32.c | 6 +-
55
target/arm/kvm64.c | 325 +++++++++++++++++++++---
56
target/arm/monitor.c | 158 ++++++++++++
57
target/arm/translate-vfp.inc.c | 5 +-
58
tests/arm-cpu-features.c | 551 +++++++++++++++++++++++++++++++++++++++++
59
docs/arm-cpu-features.rst | 317 ++++++++++++++++++++++++
60
16 files changed, 1795 insertions(+), 64 deletions(-)
61
create mode 100644 tests/arm-cpu-features.c
62
create mode 100644 docs/arm-cpu-features.rst
53
63
54
Patrick Venture (1):
55
hw/net: npcm7xx_emc fix missing queue_flush
56
57
Peter Maydell (6):
58
target/i386: Use assert() to sanity-check b1 in SSE decode
59
include/hw/i386: Don't include qemu-common.h in .h files
60
target/hexagon/cpu.h: don't include qemu-common.h
61
target/rx/cpu.h: Don't include qemu-common.h
62
hw/arm: Don't include qemu-common.h unnecessarily
63
target/arm: Correct calculation of tlb range invalidate length
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
3
Add support for the query-cpu-model-expansion QMP command to Arm. We
4
arm_gicv3_common_realize(). Since we want to restrict
4
do this selectively, only exposing CPU properties which represent
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
5
optional CPU features which the user may want to enable/disable.
6
to a new file. Add this file to the meson 'specific'
6
Additionally we restrict the list of queryable cpu models to 'max',
7
source set, since it needs access to "cpu.h".
7
'host', or the current type when KVM is in use. And, finally, we only
8
8
implement expansion type 'full', as Arm does not yet have a "base"
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
CPU type. More details and example queries are described in a new
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
document (docs/arm-cpu-features.rst).
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
11
12
Note, certainly more features may be added to the list of advertised
13
features, e.g. 'vfp' and 'neon'. The only requirement is that we can
14
detect invalid configurations and emit failures at QMP query time.
15
For 'vfp' and 'neon' this will require some refactoring to share a
16
validation function between the QMP query and the CPU realize
17
functions.
18
19
Signed-off-by: Andrew Jones <drjones@redhat.com>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
23
Message-id: 20191031142734.8590-2-drjones@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
25
---
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
26
qapi/machine-target.json | 6 +-
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
27
target/arm/monitor.c | 146 ++++++++++++++++++++++++++++++++++++++
16
hw/intc/meson.build | 1 +
28
docs/arm-cpu-features.rst | 137 +++++++++++++++++++++++++++++++++++
17
3 files changed, 24 insertions(+), 9 deletions(-)
29
3 files changed, 286 insertions(+), 3 deletions(-)
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
30
create mode 100644 docs/arm-cpu-features.rst
19
31
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
32
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
21
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_cpuif.c
34
--- a/qapi/machine-target.json
23
+++ b/hw/intc/arm_gicv3_cpuif.c
35
+++ b/qapi/machine-target.json
24
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
25
/*
37
##
26
- * ARM Generic Interrupt Controller v3
38
{ 'struct': 'CpuModelExpansionInfo',
27
+ * ARM Generic Interrupt Controller v3 (emulation)
39
'data': { 'model': 'CpuModelInfo' },
28
*
40
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
29
* Copyright (c) 2016 Linaro Limited
41
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
30
* Written by Peter Maydell
42
31
@@ -XXX,XX +XXX,XX @@
43
##
32
#include "hw/irq.h"
44
# @query-cpu-model-expansion:
33
#include "cpu.h"
45
@@ -XXX,XX +XXX,XX @@
34
46
# query-cpu-model-expansion while using these is not advised.
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
47
#
36
-{
48
# Some architectures may not support all expansion types. s390x supports
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
49
-# "full" and "static".
38
- CPUARMState *env = &arm_cpu->env;
50
+# "full" and "static". Arm only supports "full".
39
-
51
#
40
- env->gicv3state = (void *)s;
52
# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
41
-};
53
# not supported, if the model cannot be expanded, if the model contains
42
-
54
@@ -XXX,XX +XXX,XX @@
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
55
'data': { 'type': 'CpuModelExpansionType',
56
'model': 'CpuModelInfo' },
57
'returns': 'CpuModelExpansionInfo',
58
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
59
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
60
61
##
62
# @CpuDefinitionInfo:
63
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/monitor.c
66
+++ b/target/arm/monitor.c
67
@@ -XXX,XX +XXX,XX @@
68
*/
69
70
#include "qemu/osdep.h"
71
+#include "hw/boards.h"
72
#include "kvm_arm.h"
73
+#include "qapi/error.h"
74
+#include "qapi/visitor.h"
75
+#include "qapi/qobject-input-visitor.h"
76
+#include "qapi/qapi-commands-machine-target.h"
77
#include "qapi/qapi-commands-misc-target.h"
78
+#include "qapi/qmp/qerror.h"
79
+#include "qapi/qmp/qdict.h"
80
+#include "qom/qom-qobject.h"
81
82
static GICCapability *gic_cap_new(int version)
44
{
83
{
45
return env->gicv3state;
84
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
85
86
return head;
87
}
88
+
89
+/*
90
+ * These are cpu model features we want to advertise. The order here
91
+ * matters as this is the order in which qmp_query_cpu_model_expansion
92
+ * will attempt to set them. If there are dependencies between features,
93
+ * then the order that considers those dependencies must be used.
94
+ */
95
+static const char *cpu_model_advertised_features[] = {
96
+ "aarch64", "pmu",
97
+ NULL
98
+};
99
+
100
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
101
+ CpuModelInfo *model,
102
+ Error **errp)
103
+{
104
+ CpuModelExpansionInfo *expansion_info;
105
+ const QDict *qdict_in = NULL;
106
+ QDict *qdict_out;
107
+ ObjectClass *oc;
108
+ Object *obj;
109
+ const char *name;
110
+ int i;
111
+
112
+ if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
113
+ error_setg(errp, "The requested expansion type is not supported");
114
+ return NULL;
115
+ }
116
+
117
+ if (!kvm_enabled() && !strcmp(model->name, "host")) {
118
+ error_setg(errp, "The CPU type '%s' requires KVM", model->name);
119
+ return NULL;
120
+ }
121
+
122
+ oc = cpu_class_by_name(TYPE_ARM_CPU, model->name);
123
+ if (!oc) {
124
+ error_setg(errp, "The CPU type '%s' is not a recognized ARM CPU type",
125
+ model->name);
126
+ return NULL;
127
+ }
128
+
129
+ if (kvm_enabled()) {
130
+ const char *cpu_type = current_machine->cpu_type;
131
+ int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
132
+ bool supported = false;
133
+
134
+ if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) {
135
+ /* These are kvmarm's recommended cpu types */
136
+ supported = true;
137
+ } else if (strlen(model->name) == len &&
138
+ !strncmp(model->name, cpu_type, len)) {
139
+ /* KVM is enabled and we're using this type, so it works. */
140
+ supported = true;
141
+ }
142
+ if (!supported) {
143
+ error_setg(errp, "We cannot guarantee the CPU type '%s' works "
144
+ "with KVM on this host", model->name);
145
+ return NULL;
146
+ }
147
+ }
148
+
149
+ if (model->props) {
150
+ qdict_in = qobject_to(QDict, model->props);
151
+ if (!qdict_in) {
152
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
153
+ return NULL;
154
+ }
155
+ }
156
+
157
+ obj = object_new(object_class_get_name(oc));
158
+
159
+ if (qdict_in) {
160
+ Visitor *visitor;
161
+ Error *err = NULL;
162
+
163
+ visitor = qobject_input_visitor_new(model->props);
164
+ visit_start_struct(visitor, NULL, NULL, 0, &err);
165
+ if (err) {
166
+ visit_free(visitor);
167
+ object_unref(obj);
168
+ error_propagate(errp, err);
169
+ return NULL;
170
+ }
171
+
172
+ i = 0;
173
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
174
+ if (qdict_get(qdict_in, name)) {
175
+ object_property_set(obj, visitor, name, &err);
176
+ if (err) {
177
+ break;
178
+ }
179
+ }
180
+ }
181
+
182
+ if (!err) {
183
+ visit_check_struct(visitor, &err);
184
+ }
185
+ visit_end_struct(visitor, NULL);
186
+ visit_free(visitor);
187
+ if (err) {
188
+ object_unref(obj);
189
+ error_propagate(errp, err);
190
+ return NULL;
191
+ }
192
+ }
193
+
194
+ expansion_info = g_new0(CpuModelExpansionInfo, 1);
195
+ expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
196
+ expansion_info->model->name = g_strdup(model->name);
197
+
198
+ qdict_out = qdict_new();
199
+
200
+ i = 0;
201
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
202
+ ObjectProperty *prop = object_property_find(obj, name, NULL);
203
+ if (prop) {
204
+ Error *err = NULL;
205
+ QObject *value;
206
+
207
+ assert(prop->get);
208
+ value = object_property_get_qobject(obj, name, &err);
209
+ assert(!err);
210
+
211
+ qdict_put_obj(qdict_out, name, value);
212
+ }
213
+ }
214
+
215
+ if (!qdict_size(qdict_out)) {
216
+ qobject_unref(qdict_out);
217
+ } else {
218
+ expansion_info->model->props = QOBJECT(qdict_out);
219
+ expansion_info->model->has_props = true;
220
+ }
221
+
222
+ object_unref(obj);
223
+
224
+ return expansion_info;
225
+}
226
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
47
new file mode 100644
227
new file mode 100644
48
index XXXXXXX..XXXXXXX
228
index XXXXXXX..XXXXXXX
49
--- /dev/null
229
--- /dev/null
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
230
+++ b/docs/arm-cpu-features.rst
51
@@ -XXX,XX +XXX,XX @@
231
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
232
+================
53
+/*
233
+ARM CPU Features
54
+ * ARM Generic Interrupt Controller v3
234
+================
55
+ *
235
+
56
+ * Copyright (c) 2016 Linaro Limited
236
+Examples of probing and using ARM CPU features
57
+ * Written by Peter Maydell
237
+
58
+ *
238
+Introduction
59
+ * This code is licensed under the GPL, version 2 or (at your option)
239
+============
60
+ * any later version.
240
+
61
+ */
241
+CPU features are optional features that a CPU of supporting type may
62
+
242
+choose to implement or not. In QEMU, optional CPU features have
63
+#include "qemu/osdep.h"
243
+corresponding boolean CPU proprieties that, when enabled, indicate
64
+#include "gicv3_internal.h"
244
+that the feature is implemented, and, conversely, when disabled,
65
+#include "cpu.h"
245
+indicate that it is not implemented. An example of an ARM CPU feature
66
+
246
+is the Performance Monitoring Unit (PMU). CPU types such as the
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
247
+Cortex-A15 and the Cortex-A57, which respectively implement ARM
68
+{
248
+architecture reference manuals ARMv7-A and ARMv8-A, may both optionally
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
249
+implement PMUs. For example, if a user wants to use a Cortex-A15 without
70
+ CPUARMState *env = &arm_cpu->env;
250
+a PMU, then the `-cpu` parameter should contain `pmu=off` on the QEMU
71
+
251
+command line, i.e. `-cpu cortex-a15,pmu=off`.
72
+ env->gicv3state = (void *)s;
252
+
73
+};
253
+As not all CPU types support all optional CPU features, then whether or
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
254
+not a CPU property exists depends on the CPU type. For example, CPUs
75
index XXXXXXX..XXXXXXX 100644
255
+that implement the ARMv8-A architecture reference manual may optionally
76
--- a/hw/intc/meson.build
256
+support the AArch32 CPU feature, which may be enabled by disabling the
77
+++ b/hw/intc/meson.build
257
+`aarch64` CPU property. A CPU type such as the Cortex-A15, which does
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
258
+not implement ARMv8-A, will not have the `aarch64` CPU property.
79
259
+
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
260
+QEMU's support may be limited for some CPU features, only partially
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
261
+supporting the feature or only supporting the feature under certain
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
262
+configurations. For example, the `aarch64` CPU feature, which, when
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
263
+disabled, enables the optional AArch32 CPU feature, is only supported
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
264
+when using the KVM accelerator and when running on a host CPU type that
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
265
+supports the feature.
266
+
267
+CPU Feature Probing
268
+===================
269
+
270
+Determining which CPU features are available and functional for a given
271
+CPU type is possible with the `query-cpu-model-expansion` QMP command.
272
+Below are some examples where `scripts/qmp/qmp-shell` (see the top comment
273
+block in the script for usage) is used to issue the QMP commands.
274
+
275
+(1) Determine which CPU features are available for the `max` CPU type
276
+ (Note, we started QEMU with qemu-system-aarch64, so `max` is
277
+ implementing the ARMv8-A reference manual in this case)::
278
+
279
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max"}
280
+ { "return": {
281
+ "model": { "name": "max", "props": {
282
+ "pmu": true, "aarch64": true
283
+ }}}}
284
+
285
+We see that the `max` CPU type has the `pmu` and `aarch64` CPU features.
286
+We also see that the CPU features are enabled, as they are all `true`.
287
+
288
+(2) Let's try to disable the PMU::
289
+
290
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
291
+ { "return": {
292
+ "model": { "name": "max", "props": {
293
+ "pmu": false, "aarch64": true
294
+ }}}}
295
+
296
+We see it worked, as `pmu` is now `false`.
297
+
298
+(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature::
299
+
300
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"aarch64":false}}
301
+ {"error": {
302
+ "class": "GenericError", "desc":
303
+ "'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported"
304
+ }}
305
+
306
+It looks like this feature is limited to a configuration we do not
307
+currently have.
308
+
309
+(4) Let's try probing CPU features for the Cortex-A15 CPU type::
310
+
311
+ (QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
312
+ {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
313
+
314
+Only the `pmu` CPU feature is available.
315
+
316
+A note about CPU feature dependencies
317
+-------------------------------------
318
+
319
+It's possible for features to have dependencies on other features. I.e.
320
+it may be possible to change one feature at a time without error, but
321
+when attempting to change all features at once an error could occur
322
+depending on the order they are processed. It's also possible changing
323
+all at once doesn't generate an error, because a feature's dependencies
324
+are satisfied with other features, but the same feature cannot be changed
325
+independently without error. For these reasons callers should always
326
+attempt to make their desired changes all at once in order to ensure the
327
+collection is valid.
328
+
329
+A note about CPU models and KVM
330
+-------------------------------
331
+
332
+Named CPU models generally do not work with KVM. There are a few cases
333
+that do work, e.g. using the named CPU model `cortex-a57` with KVM on a
334
+seattle host, but mostly if KVM is enabled the `host` CPU type must be
335
+used. This means the guest is provided all the same CPU features as the
336
+host CPU type has. And, for this reason, the `host` CPU type should
337
+enable all CPU features that the host has by default. Indeed it's even
338
+a bit strange to allow disabling CPU features that the host has when using
339
+the `host` CPU type, but in the absence of CPU models it's the best we can
340
+do if we want to launch guests without all the host's CPU features enabled.
341
+
342
+Enabling KVM also affects the `query-cpu-model-expansion` QMP command. The
343
+affect is not only limited to specific features, as pointed out in example
344
+(3) of "CPU Feature Probing", but also to which CPU types may be expanded.
345
+When KVM is enabled, only the `max`, `host`, and current CPU type may be
346
+expanded. This restriction is necessary as it's not possible to know all
347
+CPU types that may work with KVM, but it does impose a small risk of users
348
+experiencing unexpected errors. For example on a seattle, as mentioned
349
+above, the `cortex-a57` CPU type is also valid when KVM is enabled.
350
+Therefore a user could use the `host` CPU type for the current type, but
351
+then attempt to query `cortex-a57`, however that query will fail with our
352
+restrictions. This shouldn't be an issue though as management layers and
353
+users have been preferring the `host` CPU type for use with KVM for quite
354
+some time. Additionally, if the KVM-enabled QEMU instance running on a
355
+seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57`
356
+will work.
357
+
358
+Using CPU Features
359
+==================
360
+
361
+After determining which CPU features are available and supported for a
362
+given CPU type, then they may be selectively enabled or disabled on the
363
+QEMU command line with that CPU type::
364
+
365
+ $ qemu-system-aarch64 -M virt -cpu max,pmu=off
366
+
367
+The example above disables the PMU for the `max` CPU type.
368
+
86
--
369
--
87
2.25.1
370
2.20.1
88
371
89
372
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Now that Arm CPUs have advertised features lets add tests to ensure
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
we maintain their expected availability with and without KVM.
5
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20191031142734.8590-3-drjones@redhat.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
10
---
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
11
tests/Makefile.include | 5 +-
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
12
tests/arm-cpu-features.c | 253 +++++++++++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
13
2 files changed, 257 insertions(+), 1 deletion(-)
10
tests/tcg/arm/Makefile.target | 4 +++
14
create mode 100644 tests/arm-cpu-features.c
11
4 files changed, 89 insertions(+), 2 deletions(-)
15
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
16
diff --git a/tests/Makefile.include b/tests/Makefile.include
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
17
index XXXXXXX..XXXXXXX 100644
14
18
--- a/tests/Makefile.include
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
19
+++ b/tests/Makefile.include
20
@@ -XXX,XX +XXX,XX @@ check-qtest-sparc64-$(CONFIG_ISA_TESTDEV) = tests/endianness-test$(EXESUF)
21
check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
22
check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
23
24
+check-qtest-arm-y += tests/arm-cpu-features$(EXESUF)
25
check-qtest-arm-y += tests/microbit-test$(EXESUF)
26
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
27
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
28
@@ -XXX,XX +XXX,XX @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
29
check-qtest-arm-y += tests/hexloader-test$(EXESUF)
30
check-qtest-arm-$(CONFIG_PFLASH_CFI02) += tests/pflash-cfi02-test$(EXESUF)
31
32
-check-qtest-aarch64-y = tests/numa-test$(EXESUF)
33
+check-qtest-aarch64-y += tests/arm-cpu-features$(EXESUF)
34
+check-qtest-aarch64-y += tests/numa-test$(EXESUF)
35
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
36
check-qtest-aarch64-y += tests/migration-test$(EXESUF)
37
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make test unconditional
38
@@ -XXX,XX +XXX,XX @@ tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
39
tests/numa-test$(EXESUF): tests/numa-test.o
40
tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o
41
tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y)
42
+tests/arm-cpu-features$(EXESUF): tests/arm-cpu-features.o
43
44
tests/migration/stress$(EXESUF): tests/migration/stress.o
45
    $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"LINK","$(TARGET_DIR)$@")
46
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
16
new file mode 100644
47
new file mode 100644
17
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
18
--- /dev/null
49
--- /dev/null
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
50
+++ b/tests/arm-cpu-features.c
20
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
21
+/* Test PC misalignment exception */
52
+/*
22
+
53
+ * Arm CPU feature test cases
23
+#include <assert.h>
54
+ *
24
+#include <signal.h>
55
+ * Copyright (c) 2019 Red Hat Inc.
25
+#include <stdlib.h>
56
+ * Authors:
26
+#include <stdio.h>
57
+ * Andrew Jones <drjones@redhat.com>
27
+
58
+ *
28
+static void *expected;
59
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
29
+
60
+ * See the COPYING file in the top-level directory.
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
61
+ */
31
+{
62
+#include "qemu/osdep.h"
32
+ assert(info->si_code == BUS_ADRALN);
63
+#include "libqtest.h"
33
+ assert(info->si_addr == expected);
64
+#include "qapi/qmp/qdict.h"
34
+ exit(EXIT_SUCCESS);
65
+#include "qapi/qmp/qjson.h"
35
+}
66
+
36
+
67
+#define MACHINE "-machine virt,gic-version=max,accel=tcg "
37
+int main()
68
+#define MACHINE_KVM "-machine virt,gic-version=max,accel=kvm:tcg "
38
+{
69
+#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
39
+ void *tmp;
70
+ " 'arguments': { 'type': 'full', "
40
+
71
+#define QUERY_TAIL "}}"
41
+ struct sigaction sa = {
72
+
42
+ .sa_sigaction = sigbus,
73
+static bool kvm_enabled(QTestState *qts)
43
+ .sa_flags = SA_SIGINFO
74
+{
44
+ };
75
+ QDict *resp, *qdict;
45
+
76
+ bool enabled;
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
77
+
47
+ perror("sigaction");
78
+ resp = qtest_qmp(qts, "{ 'execute': 'query-kvm' }");
48
+ return EXIT_FAILURE;
79
+ g_assert(qdict_haskey(resp, "return"));
49
+ }
80
+ qdict = qdict_get_qdict(resp, "return");
50
+
81
+ g_assert(qdict_haskey(qdict, "enabled"));
51
+ asm volatile("adr %0, 1f + 1\n\t"
82
+ enabled = qdict_get_bool(qdict, "enabled");
52
+ "str %0, %1\n\t"
83
+ qobject_unref(resp);
53
+ "br %0\n"
84
+
54
+ "1:"
85
+ return enabled;
55
+ : "=&r"(tmp), "=m"(expected));
86
+}
56
+ abort();
87
+
57
+}
88
+static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
89
+{
59
new file mode 100644
90
+ return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
60
index XXXXXXX..XXXXXXX
91
+ QUERY_TAIL, cpu_type);
61
--- /dev/null
92
+}
62
+++ b/tests/tcg/arm/pcalign-a32.c
93
+
63
@@ -XXX,XX +XXX,XX @@
94
+static QDict *do_query(QTestState *qts, const char *cpu_type,
64
+/* Test PC misalignment exception */
95
+ const char *fmt, ...)
65
+
96
+{
66
+#ifdef __thumb__
97
+ QDict *resp;
67
+#error "This test must be compiled for ARM"
98
+
68
+#endif
99
+ if (fmt) {
69
+
100
+ QDict *args;
70
+#include <assert.h>
101
+ va_list ap;
71
+#include <signal.h>
102
+
72
+#include <stdlib.h>
103
+ va_start(ap, fmt);
73
+#include <stdio.h>
104
+ args = qdict_from_vjsonf_nofail(fmt, ap);
74
+
105
+ va_end(ap);
75
+static void *expected;
106
+
76
+
107
+ resp = qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s, "
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
108
+ "'props': %p }"
78
+{
109
+ QUERY_TAIL, cpu_type, args);
79
+ assert(info->si_code == BUS_ADRALN);
110
+ } else {
80
+ assert(info->si_addr == expected);
111
+ resp = do_query_no_props(qts, cpu_type);
81
+ exit(EXIT_SUCCESS);
112
+ }
82
+}
113
+
83
+
114
+ return resp;
84
+int main()
115
+}
85
+{
116
+
86
+ void *tmp;
117
+static const char *resp_get_error(QDict *resp)
87
+
118
+{
88
+ struct sigaction sa = {
119
+ QDict *qdict;
89
+ .sa_sigaction = sigbus,
120
+
90
+ .sa_flags = SA_SIGINFO
121
+ g_assert(resp);
91
+ };
122
+
92
+
123
+ qdict = qdict_get_qdict(resp, "error");
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
124
+ if (qdict) {
94
+ perror("sigaction");
125
+ return qdict_get_str(qdict, "desc");
95
+ return EXIT_FAILURE;
126
+ }
96
+ }
127
+
97
+
128
+ return NULL;
98
+ asm volatile("adr %0, 1f + 2\n\t"
129
+}
99
+ "str %0, %1\n\t"
130
+
100
+ "bx %0\n"
131
+#define assert_error(qts, cpu_type, expected_error, fmt, ...) \
101
+ "1:"
132
+({ \
102
+ : "=&r"(tmp), "=m"(expected));
133
+ QDict *_resp; \
134
+ const char *_error; \
135
+ \
136
+ _resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \
137
+ g_assert(_resp); \
138
+ _error = resp_get_error(_resp); \
139
+ g_assert(_error); \
140
+ g_assert(g_str_equal(_error, expected_error)); \
141
+ qobject_unref(_resp); \
142
+})
143
+
144
+static bool resp_has_props(QDict *resp)
145
+{
146
+ QDict *qdict;
147
+
148
+ g_assert(resp);
149
+
150
+ if (!qdict_haskey(resp, "return")) {
151
+ return false;
152
+ }
153
+ qdict = qdict_get_qdict(resp, "return");
154
+
155
+ if (!qdict_haskey(qdict, "model")) {
156
+ return false;
157
+ }
158
+ qdict = qdict_get_qdict(qdict, "model");
159
+
160
+ return qdict_haskey(qdict, "props");
161
+}
162
+
163
+static QDict *resp_get_props(QDict *resp)
164
+{
165
+ QDict *qdict;
166
+
167
+ g_assert(resp);
168
+ g_assert(resp_has_props(resp));
169
+
170
+ qdict = qdict_get_qdict(resp, "return");
171
+ qdict = qdict_get_qdict(qdict, "model");
172
+ qdict = qdict_get_qdict(qdict, "props");
173
+
174
+ return qdict;
175
+}
176
+
177
+#define assert_has_feature(qts, cpu_type, feature) \
178
+({ \
179
+ QDict *_resp = do_query_no_props(qts, cpu_type); \
180
+ g_assert(_resp); \
181
+ g_assert(resp_has_props(_resp)); \
182
+ g_assert(qdict_get(resp_get_props(_resp), feature)); \
183
+ qobject_unref(_resp); \
184
+})
185
+
186
+#define assert_has_not_feature(qts, cpu_type, feature) \
187
+({ \
188
+ QDict *_resp = do_query_no_props(qts, cpu_type); \
189
+ g_assert(_resp); \
190
+ g_assert(!resp_has_props(_resp) || \
191
+ !qdict_get(resp_get_props(_resp), feature)); \
192
+ qobject_unref(_resp); \
193
+})
194
+
195
+static void assert_type_full(QTestState *qts)
196
+{
197
+ const char *error;
198
+ QDict *resp;
199
+
200
+ resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
201
+ "'arguments': { 'type': 'static', "
202
+ "'model': { 'name': 'foo' }}}");
203
+ g_assert(resp);
204
+ error = resp_get_error(resp);
205
+ g_assert(error);
206
+ g_assert(g_str_equal(error,
207
+ "The requested expansion type is not supported"));
208
+ qobject_unref(resp);
209
+}
210
+
211
+static void assert_bad_props(QTestState *qts, const char *cpu_type)
212
+{
213
+ const char *error;
214
+ QDict *resp;
215
+
216
+ resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
217
+ "'arguments': { 'type': 'full', "
218
+ "'model': { 'name': %s, "
219
+ "'props': false }}}",
220
+ cpu_type);
221
+ g_assert(resp);
222
+ error = resp_get_error(resp);
223
+ g_assert(error);
224
+ g_assert(g_str_equal(error,
225
+ "Invalid parameter type for 'props', expected: dict"));
226
+ qobject_unref(resp);
227
+}
228
+
229
+static void test_query_cpu_model_expansion(const void *data)
230
+{
231
+ QTestState *qts;
232
+
233
+ qts = qtest_init(MACHINE "-cpu max");
234
+
235
+ /* Test common query-cpu-model-expansion input validation */
236
+ assert_type_full(qts);
237
+ assert_bad_props(qts, "max");
238
+ assert_error(qts, "foo", "The CPU type 'foo' is not a recognized "
239
+ "ARM CPU type", NULL);
240
+ assert_error(qts, "max", "Parameter 'not-a-prop' is unexpected",
241
+ "{ 'not-a-prop': false }");
242
+ assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
243
+
244
+ /* Test expected feature presence/absence for some cpu types */
245
+ assert_has_feature(qts, "max", "pmu");
246
+ assert_has_feature(qts, "cortex-a15", "pmu");
247
+ assert_has_not_feature(qts, "cortex-a15", "aarch64");
248
+
249
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
250
+ assert_has_feature(qts, "max", "aarch64");
251
+ assert_has_feature(qts, "cortex-a57", "pmu");
252
+ assert_has_feature(qts, "cortex-a57", "aarch64");
253
+
254
+ /* Test that features that depend on KVM generate errors without. */
255
+ assert_error(qts, "max",
256
+ "'aarch64' feature cannot be disabled "
257
+ "unless KVM is enabled and 32-bit EL1 "
258
+ "is supported",
259
+ "{ 'aarch64': false }");
260
+ }
261
+
262
+ qtest_quit(qts);
263
+}
264
+
265
+static void test_query_cpu_model_expansion_kvm(const void *data)
266
+{
267
+ QTestState *qts;
268
+
269
+ qts = qtest_init(MACHINE_KVM "-cpu max");
103
+
270
+
104
+ /*
271
+ /*
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
272
+ * These tests target the 'host' CPU type, so KVM must be enabled.
106
+ * the address or not. If so, we can legitimately fall through.
107
+ */
273
+ */
108
+ return EXIT_SUCCESS;
274
+ if (!kvm_enabled(qts)) {
109
+}
275
+ qtest_quit(qts);
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
276
+ return;
111
index XXXXXXX..XXXXXXX 100644
277
+ }
112
--- a/tests/tcg/aarch64/Makefile.target
278
+
113
+++ b/tests/tcg/aarch64/Makefile.target
279
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
280
+ assert_has_feature(qts, "host", "aarch64");
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
281
+ assert_has_feature(qts, "host", "pmu");
116
VPATH         += $(AARCH64_SRC)
282
+
117
283
+ assert_error(qts, "cortex-a15",
118
-# Float-convert Tests
284
+ "We cannot guarantee the CPU type 'cortex-a15' works "
119
-AARCH64_TESTS=fcvt
285
+ "with KVM on this host", NULL);
120
+# Base architecture tests
286
+ } else {
121
+AARCH64_TESTS=fcvt pcalign-a64
287
+ assert_has_not_feature(qts, "host", "aarch64");
122
288
+ assert_has_not_feature(qts, "host", "pmu");
123
fcvt: LDFLAGS+=-lm
289
+ }
124
290
+
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
291
+ qtest_quit(qts);
126
index XXXXXXX..XXXXXXX 100644
292
+}
127
--- a/tests/tcg/arm/Makefile.target
293
+
128
+++ b/tests/tcg/arm/Makefile.target
294
+int main(int argc, char **argv)
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
295
+{
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
296
+ g_test_init(&argc, &argv, NULL);
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
297
+
132
298
+ qtest_add_data_func("/arm/query-cpu-model-expansion",
133
+# PC alignment test
299
+ NULL, test_query_cpu_model_expansion);
134
+ARM_TESTS += pcalign-a32
300
+ qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
135
+pcalign-a32: CFLAGS+=-marm
301
+ NULL, test_query_cpu_model_expansion_kvm);
136
+
302
+
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
303
+ return g_test_run();
138
304
+}
139
# Semihosting smoke test for linux-user
140
--
305
--
141
2.25.1
306
2.20.1
142
307
143
308
diff view generated by jsdifflib
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Add two test cases for VIOT, one on the q35 machine and the other on
3
Since 97a28b0eeac14 ("target/arm: Allow VFP and Neon to be disabled via
4
virt. To test complex topologies the q35 test has two PCIe buses that
4
a CPU property") we can disable the 'max' cpu model's VFP and neon
5
bypass the IOMMU (and are therefore not described by VIOT), and two
5
features, but there's no way to disable SVE. Add the 'sve=on|off'
6
buses that are translated by virtio-iommu.
6
property to give it that flexibility. We also rename
7
cpu_max_get/set_sve_vq to cpu_max_get/set_sve_max_vq in order for them
8
to follow the typical *_get/set_<property-name> pattern.
7
9
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
13
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
14
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
15
Message-id: 20191031142734.8590-4-drjones@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
17
---
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
18
target/arm/cpu.c | 3 ++-
15
1 file changed, 38 insertions(+)
19
target/arm/cpu64.c | 52 ++++++++++++++++++++++++++++++++++------
20
target/arm/monitor.c | 2 +-
21
tests/arm-cpu-features.c | 1 +
22
4 files changed, 49 insertions(+), 9 deletions(-)
16
23
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
24
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/bios-tables-test.c
26
--- a/target/arm/cpu.c
20
+++ b/tests/qtest/bios-tables-test.c
27
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
28
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
22
free_test_data(&data);
29
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
30
env->cp15.cptr_el[3] |= CPTR_EZ;
31
/* with maximum vector length */
32
- env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
33
+ env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
34
+ cpu->sve_max_vq - 1 : 0;
35
env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
36
env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
37
/*
38
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/cpu64.c
41
+++ b/target/arm/cpu64.c
42
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
43
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
23
}
44
}
24
45
25
+static void test_acpi_q35_viot(void)
46
-static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
47
- void *opaque, Error **errp)
48
+static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
49
+ void *opaque, Error **errp)
50
{
51
ARMCPU *cpu = ARM_CPU(obj);
52
- visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
53
+ uint32_t value;
54
+
55
+ /* All vector lengths are disabled when SVE is off. */
56
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
57
+ value = 0;
58
+ } else {
59
+ value = cpu->sve_max_vq;
60
+ }
61
+ visit_type_uint32(v, name, &value, errp);
62
}
63
64
-static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
65
- void *opaque, Error **errp)
66
+static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
67
+ void *opaque, Error **errp)
68
{
69
ARMCPU *cpu = ARM_CPU(obj);
70
Error *err = NULL;
71
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
72
error_propagate(errp, err);
73
}
74
75
+static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
76
+ void *opaque, Error **errp)
26
+{
77
+{
27
+ test_data data = {
78
+ ARMCPU *cpu = ARM_CPU(obj);
28
+ .machine = MACHINE_Q35,
79
+ bool value = cpu_isar_feature(aa64_sve, cpu);
29
+ .variant = ".viot",
30
+ };
31
+
80
+
32
+ /*
81
+ visit_type_bool(v, name, &value, errp);
33
+ * To keep things interesting, two buses bypass the IOMMU.
34
+ * VIOT should only describes the other two buses.
35
+ */
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
37
+ "-device virtio-iommu-pci "
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
41
+ &data);
42
+ free_test_data(&data);
43
+}
82
+}
44
+
83
+
45
+static void test_acpi_virt_viot(void)
84
+static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
85
+ void *opaque, Error **errp)
46
+{
86
+{
47
+ test_data data = {
87
+ ARMCPU *cpu = ARM_CPU(obj);
48
+ .machine = "virt",
88
+ Error *err = NULL;
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
89
+ bool value;
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
90
+ uint64_t t;
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
52
+ .ram_start = 0x40000000ULL,
53
+ .scan_len = 128ULL * 1024 * 1024,
54
+ };
55
+
91
+
56
+ test_acpi_one("-cpu cortex-a57 "
92
+ visit_type_bool(v, name, &value, &err);
57
+ "-device virtio-iommu-pci", &data);
93
+ if (err) {
58
+ free_test_data(&data);
94
+ error_propagate(errp, err);
95
+ return;
96
+ }
97
+
98
+ t = cpu->isar.id_aa64pfr0;
99
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
100
+ cpu->isar.id_aa64pfr0 = t;
59
+}
101
+}
60
+
102
+
61
static void test_oem_fields(test_data *data)
103
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
62
{
104
* otherwise, a CPU with as many features enabled as our emulation supports.
63
int i;
105
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
106
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
107
#endif
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
108
67
}
109
cpu->sve_max_vq = ARM_MAX_VQ;
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
110
- object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
69
} else if (strcmp(arch, "aarch64") == 0) {
111
- cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
70
if (has_tcg) {
112
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
113
+ cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
114
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
115
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
77
}
78
}
116
}
79
ret = g_test_run();
117
}
118
119
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/monitor.c
122
+++ b/target/arm/monitor.c
123
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
124
* then the order that considers those dependencies must be used.
125
*/
126
static const char *cpu_model_advertised_features[] = {
127
- "aarch64", "pmu",
128
+ "aarch64", "pmu", "sve",
129
NULL
130
};
131
132
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/tests/arm-cpu-features.c
135
+++ b/tests/arm-cpu-features.c
136
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
137
138
if (g_str_equal(qtest_get_arch(), "aarch64")) {
139
assert_has_feature(qts, "max", "aarch64");
140
+ assert_has_feature(qts, "max", "sve");
141
assert_has_feature(qts, "cortex-a57", "pmu");
142
assert_has_feature(qts, "cortex-a57", "aarch64");
143
80
--
144
--
81
2.25.1
145
2.20.1
82
146
83
147
diff view generated by jsdifflib
1
The calculation of the length of TLB range invalidate operations
1
From: Andrew Jones <drjones@redhat.com>
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
* the NUM field is 5 bits, but we read only 4 bits
4
* we miscalculate the page_shift value, because of an
5
off-by-one error:
6
TG 0b00 is invalid
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
11
2
12
Thanks to the bug report submitter Cha HyunSoo for identifying
3
Introduce cpu properties to give fine control over SVE vector lengths.
13
both these errors.
4
We introduce a property for each valid length up to the current
5
maximum supported, which is 2048-bits. The properties are named, e.g.
6
sve128, sve256, sve384, sve512, ..., where the number is the number of
7
bits. See the updates to docs/arm-cpu-features.rst for a description
8
of the semantics and for example uses.
14
9
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
10
Note, as sve-max-vq is still present and we'd like to be able to
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
11
support qmp_query_cpu_model_expansion with guests launched with e.g.
12
-cpu max,sve-max-vq=8 on their command lines, then we do allow
13
sve-max-vq and sve<N> properties to be provided at the same time, but
14
this is not recommended, and is why sve-max-vq is not mentioned in the
15
document. If sve-max-vq is provided then it enables all lengths smaller
16
than and including the max and disables all lengths larger. It also has
17
the side-effect that no larger lengths may be enabled and that the max
18
itself cannot be disabled. Smaller non-power-of-two lengths may,
19
however, be disabled, e.g. -cpu max,sve-max-vq=4,sve384=off provides a
20
guest the vector lengths 128, 256, and 512 bits.
21
22
This patch has been co-authored with Richard Henderson, who reworked
23
the target/arm/cpu64.c changes in order to push all the validation and
24
auto-enabling/disabling steps into the finalizer, resulting in a nice
25
LOC reduction.
26
27
Signed-off-by: Andrew Jones <drjones@redhat.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Eric Auger <eric.auger@redhat.com>
30
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
31
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
32
Message-id: 20191031142734.8590-5-drjones@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
22
---
34
---
23
target/arm/helper.c | 6 +++---
35
include/qemu/bitops.h | 1 +
24
1 file changed, 3 insertions(+), 3 deletions(-)
36
target/arm/cpu.h | 19 ++++
37
target/arm/cpu.c | 19 ++++
38
target/arm/cpu64.c | 192 ++++++++++++++++++++++++++++++++++++-
39
target/arm/helper.c | 10 +-
40
target/arm/monitor.c | 12 +++
41
tests/arm-cpu-features.c | 194 ++++++++++++++++++++++++++++++++++++++
42
docs/arm-cpu-features.rst | 168 +++++++++++++++++++++++++++++++--
43
8 files changed, 606 insertions(+), 9 deletions(-)
25
44
45
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/qemu/bitops.h
48
+++ b/include/qemu/bitops.h
49
@@ -XXX,XX +XXX,XX @@
50
#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
51
52
#define BIT(nr) (1UL << (nr))
53
+#define BIT_ULL(nr) (1ULL << (nr))
54
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
55
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
56
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
57
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/cpu.h
60
+++ b/target/arm/cpu.h
61
@@ -XXX,XX +XXX,XX @@ typedef struct {
62
63
#ifdef TARGET_AARCH64
64
# define ARM_MAX_VQ 16
65
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
66
+uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq);
67
#else
68
# define ARM_MAX_VQ 1
69
+static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
70
+static inline uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq)
71
+{ return 0; }
72
#endif
73
74
typedef struct ARMVectorReg {
75
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
76
77
/* Used to set the maximum vector length the cpu will support. */
78
uint32_t sve_max_vq;
79
+
80
+ /*
81
+ * In sve_vq_map each set bit is a supported vector length of
82
+ * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
83
+ * length in quadwords.
84
+ *
85
+ * While processing properties during initialization, corresponding
86
+ * sve_vq_init bits are set for bits in sve_vq_map that have been
87
+ * set by properties.
88
+ */
89
+ DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ);
90
+ DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ);
91
};
92
93
void arm_cpu_post_init(Object *obj);
94
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
95
return (env->features & (1ULL << feature)) != 0;
96
}
97
98
+void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
99
+
100
#if !defined(CONFIG_USER_ONLY)
101
/* Return true if exception levels below EL3 are in secure state,
102
* or would be following an exception return to that level.
103
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/cpu.c
106
+++ b/target/arm/cpu.c
107
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
108
#endif
109
}
110
111
+void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
112
+{
113
+ Error *local_err = NULL;
114
+
115
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
116
+ arm_cpu_sve_finalize(cpu, &local_err);
117
+ if (local_err != NULL) {
118
+ error_propagate(errp, local_err);
119
+ return;
120
+ }
121
+ }
122
+}
123
+
124
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
125
{
126
CPUState *cs = CPU(dev);
127
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
128
return;
129
}
130
131
+ arm_cpu_finalize_features(cpu, &local_err);
132
+ if (local_err != NULL) {
133
+ error_propagate(errp, local_err);
134
+ return;
135
+ }
136
+
137
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
138
cpu->has_vfp != cpu->has_neon) {
139
/*
140
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/target/arm/cpu64.c
143
+++ b/target/arm/cpu64.c
144
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
145
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
146
}
147
148
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
149
+{
150
+ /*
151
+ * If any vector lengths are explicitly enabled with sve<N> properties,
152
+ * then all other lengths are implicitly disabled. If sve-max-vq is
153
+ * specified then it is the same as explicitly enabling all lengths
154
+ * up to and including the specified maximum, which means all larger
155
+ * lengths will be implicitly disabled. If no sve<N> properties
156
+ * are enabled and sve-max-vq is not specified, then all lengths not
157
+ * explicitly disabled will be enabled. Additionally, all power-of-two
158
+ * vector lengths less than the maximum enabled length will be
159
+ * automatically enabled and all vector lengths larger than the largest
160
+ * disabled power-of-two vector length will be automatically disabled.
161
+ * Errors are generated if the user provided input that interferes with
162
+ * any of the above. Finally, if SVE is not disabled, then at least one
163
+ * vector length must be enabled.
164
+ */
165
+ DECLARE_BITMAP(tmp, ARM_MAX_VQ);
166
+ uint32_t vq, max_vq = 0;
167
+
168
+ /*
169
+ * Process explicit sve<N> properties.
170
+ * From the properties, sve_vq_map<N> implies sve_vq_init<N>.
171
+ * Check first for any sve<N> enabled.
172
+ */
173
+ if (!bitmap_empty(cpu->sve_vq_map, ARM_MAX_VQ)) {
174
+ max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
175
+
176
+ if (cpu->sve_max_vq && max_vq > cpu->sve_max_vq) {
177
+ error_setg(errp, "cannot enable sve%d", max_vq * 128);
178
+ error_append_hint(errp, "sve%d is larger than the maximum vector "
179
+ "length, sve-max-vq=%d (%d bits)\n",
180
+ max_vq * 128, cpu->sve_max_vq,
181
+ cpu->sve_max_vq * 128);
182
+ return;
183
+ }
184
+
185
+ /* Propagate enabled bits down through required powers-of-two. */
186
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
187
+ if (!test_bit(vq - 1, cpu->sve_vq_init)) {
188
+ set_bit(vq - 1, cpu->sve_vq_map);
189
+ }
190
+ }
191
+ } else if (cpu->sve_max_vq == 0) {
192
+ /*
193
+ * No explicit bits enabled, and no implicit bits from sve-max-vq.
194
+ */
195
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
196
+ /* SVE is disabled and so are all vector lengths. Good. */
197
+ return;
198
+ }
199
+
200
+ /* Disabling a power-of-two disables all larger lengths. */
201
+ if (test_bit(0, cpu->sve_vq_init)) {
202
+ error_setg(errp, "cannot disable sve128");
203
+ error_append_hint(errp, "Disabling sve128 results in all vector "
204
+ "lengths being disabled.\n");
205
+ error_append_hint(errp, "With SVE enabled, at least one vector "
206
+ "length must be enabled.\n");
207
+ return;
208
+ }
209
+ for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
210
+ if (test_bit(vq - 1, cpu->sve_vq_init)) {
211
+ break;
212
+ }
213
+ }
214
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
215
+
216
+ bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
217
+ max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
218
+ }
219
+
220
+ /*
221
+ * Process the sve-max-vq property.
222
+ * Note that we know from the above that no bit above
223
+ * sve-max-vq is currently set.
224
+ */
225
+ if (cpu->sve_max_vq != 0) {
226
+ max_vq = cpu->sve_max_vq;
227
+
228
+ if (!test_bit(max_vq - 1, cpu->sve_vq_map) &&
229
+ test_bit(max_vq - 1, cpu->sve_vq_init)) {
230
+ error_setg(errp, "cannot disable sve%d", max_vq * 128);
231
+ error_append_hint(errp, "The maximum vector length must be "
232
+ "enabled, sve-max-vq=%d (%d bits)\n",
233
+ max_vq, max_vq * 128);
234
+ return;
235
+ }
236
+
237
+ /* Set all bits not explicitly set within sve-max-vq. */
238
+ bitmap_complement(tmp, cpu->sve_vq_init, max_vq);
239
+ bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
240
+ }
241
+
242
+ /*
243
+ * We should know what max-vq is now. Also, as we're done
244
+ * manipulating sve-vq-map, we ensure any bits above max-vq
245
+ * are clear, just in case anybody looks.
246
+ */
247
+ assert(max_vq != 0);
248
+ bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
249
+
250
+ /* Ensure all required powers-of-two are enabled. */
251
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
252
+ if (!test_bit(vq - 1, cpu->sve_vq_map)) {
253
+ error_setg(errp, "cannot disable sve%d", vq * 128);
254
+ error_append_hint(errp, "sve%d is required as it "
255
+ "is a power-of-two length smaller than "
256
+ "the maximum, sve%d\n",
257
+ vq * 128, max_vq * 128);
258
+ return;
259
+ }
260
+ }
261
+
262
+ /*
263
+ * Now that we validated all our vector lengths, the only question
264
+ * left to answer is if we even want SVE at all.
265
+ */
266
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
267
+ error_setg(errp, "cannot enable sve%d", max_vq * 128);
268
+ error_append_hint(errp, "SVE must be enabled to enable vector "
269
+ "lengths.\n");
270
+ error_append_hint(errp, "Add sve=on to the CPU property list.\n");
271
+ return;
272
+ }
273
+
274
+ /* From now on sve_max_vq is the actual maximum supported length. */
275
+ cpu->sve_max_vq = max_vq;
276
+}
277
+
278
+uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq)
279
+{
280
+ uint32_t bitnum;
281
+
282
+ /*
283
+ * We allow vq == ARM_MAX_VQ + 1 to be input because the caller may want
284
+ * to find the maximum vq enabled, which may be ARM_MAX_VQ, but this
285
+ * function always returns the next smaller than the input.
286
+ */
287
+ assert(vq && vq <= ARM_MAX_VQ + 1);
288
+
289
+ bitnum = find_last_bit(cpu->sve_vq_map, vq - 1);
290
+ return bitnum == vq - 1 ? 0 : bitnum + 1;
291
+}
292
+
293
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
294
void *opaque, Error **errp)
295
{
296
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
297
error_propagate(errp, err);
298
}
299
300
+static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
301
+ void *opaque, Error **errp)
302
+{
303
+ ARMCPU *cpu = ARM_CPU(obj);
304
+ uint32_t vq = atoi(&name[3]) / 128;
305
+ bool value;
306
+
307
+ /* All vector lengths are disabled when SVE is off. */
308
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
309
+ value = false;
310
+ } else {
311
+ value = test_bit(vq - 1, cpu->sve_vq_map);
312
+ }
313
+ visit_type_bool(v, name, &value, errp);
314
+}
315
+
316
+static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
317
+ void *opaque, Error **errp)
318
+{
319
+ ARMCPU *cpu = ARM_CPU(obj);
320
+ uint32_t vq = atoi(&name[3]) / 128;
321
+ Error *err = NULL;
322
+ bool value;
323
+
324
+ visit_type_bool(v, name, &value, &err);
325
+ if (err) {
326
+ error_propagate(errp, err);
327
+ return;
328
+ }
329
+
330
+ if (value) {
331
+ set_bit(vq - 1, cpu->sve_vq_map);
332
+ } else {
333
+ clear_bit(vq - 1, cpu->sve_vq_map);
334
+ }
335
+ set_bit(vq - 1, cpu->sve_vq_init);
336
+}
337
+
338
static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
339
void *opaque, Error **errp)
340
{
341
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
342
static void aarch64_max_initfn(Object *obj)
343
{
344
ARMCPU *cpu = ARM_CPU(obj);
345
+ uint32_t vq;
346
347
if (kvm_enabled()) {
348
kvm_arm_set_cpu_features_from_host(cpu);
349
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
350
cpu->dcz_blocksize = 7; /* 512 bytes */
351
#endif
352
353
- cpu->sve_max_vq = ARM_MAX_VQ;
354
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
355
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
356
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
357
cpu_arm_set_sve, NULL, NULL, &error_fatal);
358
+
359
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
360
+ char name[8];
361
+ sprintf(name, "sve%d", vq * 128);
362
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
363
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
364
+ }
365
}
366
}
367
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
368
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
index XXXXXXX..XXXXXXX 100644
369
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.c
370
--- a/target/arm/helper.c
29
+++ b/target/arm/helper.c
371
+++ b/target/arm/helper.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
372
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
31
uint64_t exponent;
373
return 0;
32
uint64_t length;
374
}
33
375
34
- num = extract64(value, 39, 4);
376
+static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
35
+ num = extract64(value, 39, 5);
377
+{
36
scale = extract64(value, 44, 2);
378
+ uint32_t start_vq = (start_len & 0xf) + 1;
37
page_size_granule = extract64(value, 46, 2);
379
+
38
380
+ return arm_cpu_vq_map_next_smaller(cpu, start_vq + 1) - 1;
39
- page_shift = page_size_granule * 2 + 12;
381
+}
40
-
382
+
41
if (page_size_granule == 0) {
383
/*
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
384
* Given that SVE is enabled, return the vector length for EL.
43
page_size_granule);
385
*/
44
return 0;
386
@@ -XXX,XX +XXX,XX @@ uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
387
if (arm_feature(env, ARM_FEATURE_EL3)) {
388
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
45
}
389
}
46
390
- return zcr_len;
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
391
+
48
+
392
+ return sve_zcr_get_valid_len(cpu, zcr_len);
49
exponent = (5 * scale) + 1;
393
}
50
length = (num + 1) << (exponent + page_shift);
394
395
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
396
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
397
index XXXXXXX..XXXXXXX 100644
398
--- a/target/arm/monitor.c
399
+++ b/target/arm/monitor.c
400
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
401
return head;
402
}
403
404
+QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
405
+
406
/*
407
* These are cpu model features we want to advertise. The order here
408
* matters as this is the order in which qmp_query_cpu_model_expansion
409
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
410
*/
411
static const char *cpu_model_advertised_features[] = {
412
"aarch64", "pmu", "sve",
413
+ "sve128", "sve256", "sve384", "sve512",
414
+ "sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
415
+ "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
416
NULL
417
};
418
419
@@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
420
if (!err) {
421
visit_check_struct(visitor, &err);
422
}
423
+ if (!err) {
424
+ arm_cpu_finalize_features(ARM_CPU(obj), &err);
425
+ }
426
visit_end_struct(visitor, NULL);
427
visit_free(visitor);
428
if (err) {
429
@@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
430
error_propagate(errp, err);
431
return NULL;
432
}
433
+ } else {
434
+ Error *err = NULL;
435
+ arm_cpu_finalize_features(ARM_CPU(obj), &err);
436
+ assert(err == NULL);
437
}
438
439
expansion_info = g_new0(CpuModelExpansionInfo, 1);
440
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
441
index XXXXXXX..XXXXXXX 100644
442
--- a/tests/arm-cpu-features.c
443
+++ b/tests/arm-cpu-features.c
444
@@ -XXX,XX +XXX,XX @@
445
* See the COPYING file in the top-level directory.
446
*/
447
#include "qemu/osdep.h"
448
+#include "qemu/bitops.h"
449
#include "libqtest.h"
450
#include "qapi/qmp/qdict.h"
451
#include "qapi/qmp/qjson.h"
452
453
+/*
454
+ * We expect the SVE max-vq to be 16. Also it must be <= 64
455
+ * for our test code, otherwise 'vls' can't just be a uint64_t.
456
+ */
457
+#define SVE_MAX_VQ 16
458
+
459
#define MACHINE "-machine virt,gic-version=max,accel=tcg "
460
#define MACHINE_KVM "-machine virt,gic-version=max,accel=kvm:tcg "
461
#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
462
@@ -XXX,XX +XXX,XX @@ static void assert_bad_props(QTestState *qts, const char *cpu_type)
463
qobject_unref(resp);
464
}
465
466
+static uint64_t resp_get_sve_vls(QDict *resp)
467
+{
468
+ QDict *props;
469
+ const QDictEntry *e;
470
+ uint64_t vls = 0;
471
+ int n = 0;
472
+
473
+ g_assert(resp);
474
+ g_assert(resp_has_props(resp));
475
+
476
+ props = resp_get_props(resp);
477
+
478
+ for (e = qdict_first(props); e; e = qdict_next(props, e)) {
479
+ if (strlen(e->key) > 3 && !strncmp(e->key, "sve", 3) &&
480
+ g_ascii_isdigit(e->key[3])) {
481
+ char *endptr;
482
+ int bits;
483
+
484
+ bits = g_ascii_strtoll(&e->key[3], &endptr, 10);
485
+ if (!bits || *endptr != '\0') {
486
+ continue;
487
+ }
488
+
489
+ if (qdict_get_bool(props, e->key)) {
490
+ vls |= BIT_ULL((bits / 128) - 1);
491
+ }
492
+ ++n;
493
+ }
494
+ }
495
+
496
+ g_assert(n == SVE_MAX_VQ);
497
+
498
+ return vls;
499
+}
500
+
501
+#define assert_sve_vls(qts, cpu_type, expected_vls, fmt, ...) \
502
+({ \
503
+ QDict *_resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \
504
+ g_assert(_resp); \
505
+ g_assert(resp_has_props(_resp)); \
506
+ g_assert(resp_get_sve_vls(_resp) == expected_vls); \
507
+ qobject_unref(_resp); \
508
+})
509
+
510
+static void sve_tests_default(QTestState *qts, const char *cpu_type)
511
+{
512
+ /*
513
+ * With no sve-max-vq or sve<N> properties on the command line
514
+ * the default is to have all vector lengths enabled. This also
515
+ * tests that 'sve' is 'on' by default.
516
+ */
517
+ assert_sve_vls(qts, cpu_type, BIT_ULL(SVE_MAX_VQ) - 1, NULL);
518
+
519
+ /* With SVE off, all vector lengths should also be off. */
520
+ assert_sve_vls(qts, cpu_type, 0, "{ 'sve': false }");
521
+
522
+ /* With SVE on, we must have at least one vector length enabled. */
523
+ assert_error(qts, cpu_type, "cannot disable sve128", "{ 'sve128': false }");
524
+
525
+ /* Basic enable/disable tests. */
526
+ assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve384': true }");
527
+ assert_sve_vls(qts, cpu_type, ((BIT_ULL(SVE_MAX_VQ) - 1) & ~BIT_ULL(2)),
528
+ "{ 'sve384': false }");
529
+
530
+ /*
531
+ * ---------------------------------------------------------------------
532
+ * power-of-two(vq) all-power- can can
533
+ * of-two(< vq) enable disable
534
+ * ---------------------------------------------------------------------
535
+ * vq < max_vq no MUST* yes yes
536
+ * vq < max_vq yes MUST* yes no
537
+ * ---------------------------------------------------------------------
538
+ * vq == max_vq n/a MUST* yes** yes**
539
+ * ---------------------------------------------------------------------
540
+ * vq > max_vq n/a no no yes
541
+ * vq > max_vq n/a yes yes yes
542
+ * ---------------------------------------------------------------------
543
+ *
544
+ * [*] "MUST" means this requirement must already be satisfied,
545
+ * otherwise 'max_vq' couldn't itself be enabled.
546
+ *
547
+ * [**] Not testable with the QMP interface, only with the command line.
548
+ */
549
+
550
+ /* max_vq := 8 */
551
+ assert_sve_vls(qts, cpu_type, 0x8b, "{ 'sve1024': true }");
552
+
553
+ /* max_vq := 8, vq < max_vq, !power-of-two(vq) */
554
+ assert_sve_vls(qts, cpu_type, 0x8f,
555
+ "{ 'sve1024': true, 'sve384': true }");
556
+ assert_sve_vls(qts, cpu_type, 0x8b,
557
+ "{ 'sve1024': true, 'sve384': false }");
558
+
559
+ /* max_vq := 8, vq < max_vq, power-of-two(vq) */
560
+ assert_sve_vls(qts, cpu_type, 0x8b,
561
+ "{ 'sve1024': true, 'sve256': true }");
562
+ assert_error(qts, cpu_type, "cannot disable sve256",
563
+ "{ 'sve1024': true, 'sve256': false }");
564
+
565
+ /* max_vq := 3, vq > max_vq, !all-power-of-two(< vq) */
566
+ assert_error(qts, cpu_type, "cannot disable sve512",
567
+ "{ 'sve384': true, 'sve512': false, 'sve640': true }");
568
+
569
+ /*
570
+ * We can disable power-of-two vector lengths when all larger lengths
571
+ * are also disabled. We only need to disable the power-of-two length,
572
+ * as all non-enabled larger lengths will then be auto-disabled.
573
+ */
574
+ assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve512': false }");
575
+
576
+ /* max_vq := 3, vq > max_vq, all-power-of-two(< vq) */
577
+ assert_sve_vls(qts, cpu_type, 0x1f,
578
+ "{ 'sve384': true, 'sve512': true, 'sve640': true }");
579
+ assert_sve_vls(qts, cpu_type, 0xf,
580
+ "{ 'sve384': true, 'sve512': true, 'sve640': false }");
581
+}
582
+
583
+static void sve_tests_sve_max_vq_8(const void *data)
584
+{
585
+ QTestState *qts;
586
+
587
+ qts = qtest_init(MACHINE "-cpu max,sve-max-vq=8");
588
+
589
+ assert_sve_vls(qts, "max", BIT_ULL(8) - 1, NULL);
590
+
591
+ /*
592
+ * Disabling the max-vq set by sve-max-vq is not allowed, but
593
+ * of course enabling it is OK.
594
+ */
595
+ assert_error(qts, "max", "cannot disable sve1024", "{ 'sve1024': false }");
596
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve1024': true }");
597
+
598
+ /*
599
+ * Enabling anything larger than max-vq set by sve-max-vq is not
600
+ * allowed, but of course disabling everything larger is OK.
601
+ */
602
+ assert_error(qts, "max", "cannot enable sve1152", "{ 'sve1152': true }");
603
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve1152': false }");
604
+
605
+ /*
606
+ * We can enable/disable non power-of-two lengths smaller than the
607
+ * max-vq set by sve-max-vq, but, while we can enable power-of-two
608
+ * lengths, we can't disable them.
609
+ */
610
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve384': true }");
611
+ assert_sve_vls(qts, "max", 0xfb, "{ 'sve384': false }");
612
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve256': true }");
613
+ assert_error(qts, "max", "cannot disable sve256", "{ 'sve256': false }");
614
+
615
+ qtest_quit(qts);
616
+}
617
+
618
+static void sve_tests_sve_off(const void *data)
619
+{
620
+ QTestState *qts;
621
+
622
+ qts = qtest_init(MACHINE "-cpu max,sve=off");
623
+
624
+ /* SVE is off, so the map should be empty. */
625
+ assert_sve_vls(qts, "max", 0, NULL);
626
+
627
+ /* The map stays empty even if we turn lengths off. */
628
+ assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
629
+
630
+ /* It's an error to enable lengths when SVE is off. */
631
+ assert_error(qts, "max", "cannot enable sve128", "{ 'sve128': true }");
632
+
633
+ /* With SVE re-enabled we should get all vector lengths enabled. */
634
+ assert_sve_vls(qts, "max", BIT_ULL(SVE_MAX_VQ) - 1, "{ 'sve': true }");
635
+
636
+ /* Or enable SVE with just specific vector lengths. */
637
+ assert_sve_vls(qts, "max", 0x3,
638
+ "{ 'sve': true, 'sve128': true, 'sve256': true }");
639
+
640
+ qtest_quit(qts);
641
+}
642
+
643
static void test_query_cpu_model_expansion(const void *data)
644
{
645
QTestState *qts;
646
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
647
if (g_str_equal(qtest_get_arch(), "aarch64")) {
648
assert_has_feature(qts, "max", "aarch64");
649
assert_has_feature(qts, "max", "sve");
650
+ assert_has_feature(qts, "max", "sve128");
651
assert_has_feature(qts, "cortex-a57", "pmu");
652
assert_has_feature(qts, "cortex-a57", "aarch64");
653
654
+ sve_tests_default(qts, "max");
655
+
656
/* Test that features that depend on KVM generate errors without. */
657
assert_error(qts, "max",
658
"'aarch64' feature cannot be disabled "
659
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
660
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
661
NULL, test_query_cpu_model_expansion_kvm);
662
663
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
664
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
665
+ NULL, sve_tests_sve_max_vq_8);
666
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
667
+ NULL, sve_tests_sve_off);
668
+ }
669
+
670
return g_test_run();
671
}
672
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
673
index XXXXXXX..XXXXXXX 100644
674
--- a/docs/arm-cpu-features.rst
675
+++ b/docs/arm-cpu-features.rst
676
@@ -XXX,XX +XXX,XX @@ block in the script for usage) is used to issue the QMP commands.
677
(QEMU) query-cpu-model-expansion type=full model={"name":"max"}
678
{ "return": {
679
"model": { "name": "max", "props": {
680
- "pmu": true, "aarch64": true
681
+ "sve1664": true, "pmu": true, "sve1792": true, "sve1920": true,
682
+ "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
683
+ "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
684
+ "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
685
+ "sve896": true, "sve1280": true, "sve2048": true
686
}}}}
687
688
-We see that the `max` CPU type has the `pmu` and `aarch64` CPU features.
689
-We also see that the CPU features are enabled, as they are all `true`.
690
+We see that the `max` CPU type has the `pmu`, `aarch64`, `sve`, and many
691
+`sve<N>` CPU features. We also see that all the CPU features are
692
+enabled, as they are all `true`. (The `sve<N>` CPU features are all
693
+optional SVE vector lengths (see "SVE CPU Properties"). While with TCG
694
+all SVE vector lengths can be supported, when KVM is in use it's more
695
+likely that only a few lengths will be supported, if SVE is supported at
696
+all.)
697
698
(2) Let's try to disable the PMU::
699
700
(QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
701
{ "return": {
702
"model": { "name": "max", "props": {
703
- "pmu": false, "aarch64": true
704
+ "sve1664": true, "pmu": false, "sve1792": true, "sve1920": true,
705
+ "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
706
+ "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
707
+ "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
708
+ "sve896": true, "sve1280": true, "sve2048": true
709
}}}}
710
711
We see it worked, as `pmu` is now `false`.
712
@@ -XXX,XX +XXX,XX @@ We see it worked, as `pmu` is now `false`.
713
It looks like this feature is limited to a configuration we do not
714
currently have.
715
716
-(4) Let's try probing CPU features for the Cortex-A15 CPU type::
717
+(4) Let's disable `sve` and see what happens to all the optional SVE
718
+ vector lengths::
719
+
720
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"sve":false}}
721
+ { "return": {
722
+ "model": { "name": "max", "props": {
723
+ "sve1664": false, "pmu": true, "sve1792": false, "sve1920": false,
724
+ "sve128": false, "aarch64": true, "sve1024": false, "sve": false,
725
+ "sve640": false, "sve768": false, "sve1408": false, "sve256": false,
726
+ "sve1152": false, "sve512": false, "sve384": false, "sve1536": false,
727
+ "sve896": false, "sve1280": false, "sve2048": false
728
+ }}}}
729
+
730
+As expected they are now all `false`.
731
+
732
+(5) Let's try probing CPU features for the Cortex-A15 CPU type::
733
734
(QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
735
{"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
736
@@ -XXX,XX +XXX,XX @@ After determining which CPU features are available and supported for a
737
given CPU type, then they may be selectively enabled or disabled on the
738
QEMU command line with that CPU type::
739
740
- $ qemu-system-aarch64 -M virt -cpu max,pmu=off
741
+ $ qemu-system-aarch64 -M virt -cpu max,pmu=off,sve=on,sve128=on,sve256=on
742
743
-The example above disables the PMU for the `max` CPU type.
744
+The example above disables the PMU and enables the first two SVE vector
745
+lengths for the `max` CPU type. Note, the `sve=on` isn't actually
746
+necessary, because, as we observed above with our probe of the `max` CPU
747
+type, `sve` is already on by default. Also, based on our probe of
748
+defaults, it would seem we need to disable many SVE vector lengths, rather
749
+than only enabling the two we want. This isn't the case, because, as
750
+disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
751
+properties have special semantics (see "SVE CPU Property Parsing
752
+Semantics").
753
+
754
+SVE CPU Properties
755
+==================
756
+
757
+There are two types of SVE CPU properties: `sve` and `sve<N>`. The first
758
+is used to enable or disable the entire SVE feature, just as the `pmu`
759
+CPU property completely enables or disables the PMU. The second type
760
+is used to enable or disable specific vector lengths, where `N` is the
761
+number of bits of the length. The `sve<N>` CPU properties have special
762
+dependencies and constraints, see "SVE CPU Property Dependencies and
763
+Constraints" below. Additionally, as we want all supported vector lengths
764
+to be enabled by default, then, in order to avoid overly verbose command
765
+lines (command lines full of `sve<N>=off`, for all `N` not wanted), we
766
+provide the parsing semantics listed in "SVE CPU Property Parsing
767
+Semantics".
768
+
769
+SVE CPU Property Dependencies and Constraints
770
+---------------------------------------------
771
+
772
+ 1) At least one vector length must be enabled when `sve` is enabled.
773
+
774
+ 2) If a vector length `N` is enabled, then all power-of-two vector
775
+ lengths smaller than `N` must also be enabled. E.g. if `sve512`
776
+ is enabled, then the 128-bit and 256-bit vector lengths must also
777
+ be enabled.
778
+
779
+SVE CPU Property Parsing Semantics
780
+----------------------------------
781
+
782
+ 1) If SVE is disabled (`sve=off`), then which SVE vector lengths
783
+ are enabled or disabled is irrelevant to the guest, as the entire
784
+ SVE feature is disabled and that disables all vector lengths for
785
+ the guest. However QEMU will still track any `sve<N>` CPU
786
+ properties provided by the user. If later an `sve=on` is provided,
787
+ then the guest will get only the enabled lengths. If no `sve=on`
788
+ is provided and there are explicitly enabled vector lengths, then
789
+ an error is generated.
790
+
791
+ 2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
792
+ provided, then all supported vector lengths are enabled, including
793
+ the non-power-of-two lengths.
794
+
795
+ 3) If SVE is enabled, then an error is generated when attempting to
796
+ disable the last enabled vector length (see constraint (1) of "SVE
797
+ CPU Property Dependencies and Constraints").
798
+
799
+ 4) If one or more vector lengths have been explicitly enabled and at
800
+ at least one of the dependency lengths of the maximum enabled length
801
+ has been explicitly disabled, then an error is generated (see
802
+ constraint (2) of "SVE CPU Property Dependencies and Constraints").
803
+
804
+ 5) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
805
+ CPU properties are set `on`, then the specified vector lengths are
806
+ disabled but the default for any unspecified lengths remains enabled.
807
+ Disabling a power-of-two vector length also disables all vector
808
+ lengths larger than the power-of-two length (see constraint (2) of
809
+ "SVE CPU Property Dependencies and Constraints").
810
+
811
+ 6) If one or more `sve<N>` CPU properties are set to `on`, then they
812
+ are enabled and all unspecified lengths default to disabled, except
813
+ for the required lengths per constraint (2) of "SVE CPU Property
814
+ Dependencies and Constraints", which will even be auto-enabled if
815
+ they were not explicitly enabled.
816
+
817
+ 7) If SVE was disabled (`sve=off`), allowing all vector lengths to be
818
+ explicitly disabled (i.e. avoiding the error specified in (3) of
819
+ "SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
820
+ provided an error will be generated. To avoid this error, one must
821
+ enable at least one vector length prior to enabling SVE.
822
+
823
+SVE CPU Property Examples
824
+-------------------------
825
+
826
+ 1) Disable SVE::
827
+
828
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off
829
+
830
+ 2) Implicitly enable all vector lengths for the `max` CPU type::
831
+
832
+ $ qemu-system-aarch64 -M virt -cpu max
833
+
834
+ 3) Only enable the 128-bit vector length::
835
+
836
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=on
837
+
838
+ 4) Disable the 512-bit vector length and all larger vector lengths,
839
+ since 512 is a power-of-two. This results in all the smaller,
840
+ uninitialized lengths (128, 256, and 384) defaulting to enabled::
841
+
842
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=off
843
+
844
+ 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
845
+
846
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
847
+
848
+ 6) The same as (5), but since the 128-bit and 256-bit vector
849
+ lengths are required for the 512-bit vector length to be enabled,
850
+ then allow them to be auto-enabled::
851
+
852
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=on
853
+
854
+ 7) Do the same as (6), but by first disabling SVE and then re-enabling it::
855
+
856
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
857
+
858
+ 8) Force errors regarding the last vector length::
859
+
860
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=off
861
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
862
+
863
+SVE CPU Property Recommendations
864
+--------------------------------
865
+
866
+The examples in "SVE CPU Property Examples" exhibit many ways to select
867
+vector lengths which developers may find useful in order to avoid overly
868
+verbose command lines. However, the recommended way to select vector
869
+lengths is to explicitly enable each desired length. Therefore only
870
+example's (1), (3), and (5) exhibit recommended uses of the properties.
51
871
52
--
872
--
53
2.25.1
873
2.20.1
54
874
55
875
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Misaligned thumb PC is architecturally impossible.
3
These are the SVE equivalents to kvm_arch_get/put_fpsimd. Note, the
4
Assert is better than proceeding, in case we've missed
4
swabbing is different than it is for fpsmid because the vector format
5
something somewhere.
5
is a little-endian stream of words.
6
6
7
Expand a comment about aligning the pc in gdbstub.
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Fail an incoming migrate if a thumb pc is misaligned.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20191031142734.8590-6-drjones@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/gdbstub.c | 9 +++++++--
14
target/arm/kvm64.c | 185 ++++++++++++++++++++++++++++++++++++++-------
15
target/arm/machine.c | 10 ++++++++++
15
1 file changed, 156 insertions(+), 29 deletions(-)
16
target/arm/translate.c | 3 +++
16
17
3 files changed, 20 insertions(+), 2 deletions(-)
17
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
18
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/gdbstub.c
19
--- a/target/arm/kvm64.c
22
+++ b/target/arm/gdbstub.c
20
+++ b/target/arm/kvm64.c
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
21
@@ -XXX,XX +XXX,XX @@ int kvm_arch_destroy_vcpu(CPUState *cs)
24
22
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
25
tmp = ldl_p(mem_buf);
23
{
26
24
/* Return true if the regidx is a register we should synchronize
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
25
- * via the cpreg_tuples array (ie is not a core reg we sync by
28
- cause problems if we ever implement the Jazelle DBX extensions. */
26
- * hand in kvm_arch_get/put_registers())
29
+ /*
27
+ * via the cpreg_tuples array (ie is not a core or sve reg that
30
+ * Mask out low bits of PC to workaround gdb bugs.
28
+ * we sync by hand in kvm_arch_get/put_registers())
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
29
*/
32
+ * architecturally impossible to misalign the pc.
30
switch (regidx & KVM_REG_ARM_COPROC_MASK) {
33
+ * This will probably cause problems if we ever implement the
31
case KVM_REG_ARM_CORE:
34
+ * Jazelle DBX extensions.
32
+ case KVM_REG_ARM64_SVE:
35
+ */
33
return false;
36
if (n == 15) {
34
default:
37
tmp &= ~1;
35
return true;
38
}
36
@@ -XXX,XX +XXX,XX @@ int kvm_arm_cpreg_level(uint64_t regidx)
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
37
40
index XXXXXXX..XXXXXXX 100644
38
static int kvm_arch_put_fpsimd(CPUState *cs)
41
--- a/target/arm/machine.c
39
{
42
+++ b/target/arm/machine.c
40
- ARMCPU *cpu = ARM_CPU(cs);
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
41
- CPUARMState *env = &cpu->env;
44
return -1;
42
+ CPUARMState *env = &ARM_CPU(cs)->env;
43
struct kvm_one_reg reg;
44
- uint32_t fpr;
45
int i, ret;
46
47
for (i = 0; i < 32; i++) {
48
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs)
45
}
49
}
46
}
50
}
47
+
51
48
+ /*
52
- reg.addr = (uintptr_t)(&fpr);
49
+ * Misaligned thumb pc is architecturally impossible.
53
- fpr = vfp_get_fpsr(env);
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
54
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
51
+ * Fail an incoming migrate to avoid this assert.
55
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
52
+ */
56
- if (ret) {
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
57
- return ret;
54
+ return -1;
58
+ return 0;
55
+ }
59
+}
56
+
60
+
57
if (!kvm_enabled()) {
61
+/*
58
pmu_op_finish(&cpu->env);
62
+ * SVE registers are encoded in KVM's memory in an endianness-invariant format.
59
}
63
+ * The byte at offset i from the start of the in-memory representation contains
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
+ * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
61
index XXXXXXX..XXXXXXX 100644
65
+ * lowest offsets are stored in the lowest memory addresses, then that nearly
62
--- a/target/arm/translate.c
66
+ * matches QEMU's representation, which is to use an array of host-endian
63
+++ b/target/arm/translate.c
67
+ * uint64_t's, where the lower offsets are at the lower indices. To complete
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
68
+ * the translation we just need to byte swap the uint64_t's on big-endian hosts.
65
uint32_t insn;
69
+ */
66
bool is_16bit;
70
+static uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
67
71
+{
68
+ /* Misaligned thumb PC is architecturally impossible. */
72
+#ifdef HOST_WORDS_BIGENDIAN
69
+ assert((dc->base.pc_next & 1) == 0);
73
+ int i;
70
+
74
+
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
75
+ for (i = 0; i < nr; ++i) {
72
dc->base.pc_next = pc + 2;
76
+ dst[i] = bswap64(src[i]);
73
return;
77
}
78
79
- reg.addr = (uintptr_t)(&fpr);
80
- fpr = vfp_get_fpcr(env);
81
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
82
+ return dst;
83
+#else
84
+ return src;
85
+#endif
86
+}
87
+
88
+/*
89
+ * KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
90
+ * and PREGS and the FFR have a slice size of 256 bits. However we simply hard
91
+ * code the slice index to zero for now as it's unlikely we'll need more than
92
+ * one slice for quite some time.
93
+ */
94
+static int kvm_arch_put_sve(CPUState *cs)
95
+{
96
+ ARMCPU *cpu = ARM_CPU(cs);
97
+ CPUARMState *env = &cpu->env;
98
+ uint64_t tmp[ARM_MAX_VQ * 2];
99
+ uint64_t *r;
100
+ struct kvm_one_reg reg;
101
+ int n, ret;
102
+
103
+ for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
104
+ r = sve_bswap64(tmp, &env->vfp.zregs[n].d[0], cpu->sve_max_vq * 2);
105
+ reg.addr = (uintptr_t)r;
106
+ reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
107
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
108
+ if (ret) {
109
+ return ret;
110
+ }
111
+ }
112
+
113
+ for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
114
+ r = sve_bswap64(tmp, r = &env->vfp.pregs[n].p[0],
115
+ DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
116
+ reg.addr = (uintptr_t)r;
117
+ reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
118
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
119
+ if (ret) {
120
+ return ret;
121
+ }
122
+ }
123
+
124
+ r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0],
125
+ DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
126
+ reg.addr = (uintptr_t)r;
127
+ reg.id = KVM_REG_ARM64_SVE_FFR(0);
128
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
129
if (ret) {
130
return ret;
131
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
132
{
133
struct kvm_one_reg reg;
134
uint64_t val;
135
+ uint32_t fpr;
136
int i, ret;
137
unsigned int el;
138
139
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
140
}
141
}
142
143
- ret = kvm_arch_put_fpsimd(cs);
144
+ if (cpu_isar_feature(aa64_sve, cpu)) {
145
+ ret = kvm_arch_put_sve(cs);
146
+ } else {
147
+ ret = kvm_arch_put_fpsimd(cs);
148
+ }
149
+ if (ret) {
150
+ return ret;
151
+ }
152
+
153
+ reg.addr = (uintptr_t)(&fpr);
154
+ fpr = vfp_get_fpsr(env);
155
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
156
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
157
+ if (ret) {
158
+ return ret;
159
+ }
160
+
161
+ reg.addr = (uintptr_t)(&fpr);
162
+ fpr = vfp_get_fpcr(env);
163
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
164
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
165
if (ret) {
166
return ret;
167
}
168
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
169
170
static int kvm_arch_get_fpsimd(CPUState *cs)
171
{
172
- ARMCPU *cpu = ARM_CPU(cs);
173
- CPUARMState *env = &cpu->env;
174
+ CPUARMState *env = &ARM_CPU(cs)->env;
175
struct kvm_one_reg reg;
176
- uint32_t fpr;
177
int i, ret;
178
179
for (i = 0; i < 32; i++) {
180
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_fpsimd(CPUState *cs)
181
}
182
}
183
184
- reg.addr = (uintptr_t)(&fpr);
185
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
186
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
187
- if (ret) {
188
- return ret;
189
- }
190
- vfp_set_fpsr(env, fpr);
191
+ return 0;
192
+}
193
194
- reg.addr = (uintptr_t)(&fpr);
195
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
196
+/*
197
+ * KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
198
+ * and PREGS and the FFR have a slice size of 256 bits. However we simply hard
199
+ * code the slice index to zero for now as it's unlikely we'll need more than
200
+ * one slice for quite some time.
201
+ */
202
+static int kvm_arch_get_sve(CPUState *cs)
203
+{
204
+ ARMCPU *cpu = ARM_CPU(cs);
205
+ CPUARMState *env = &cpu->env;
206
+ struct kvm_one_reg reg;
207
+ uint64_t *r;
208
+ int n, ret;
209
+
210
+ for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
211
+ r = &env->vfp.zregs[n].d[0];
212
+ reg.addr = (uintptr_t)r;
213
+ reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
214
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
215
+ if (ret) {
216
+ return ret;
217
+ }
218
+ sve_bswap64(r, r, cpu->sve_max_vq * 2);
219
+ }
220
+
221
+ for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
222
+ r = &env->vfp.pregs[n].p[0];
223
+ reg.addr = (uintptr_t)r;
224
+ reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
225
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
226
+ if (ret) {
227
+ return ret;
228
+ }
229
+ sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
230
+ }
231
+
232
+ r = &env->vfp.pregs[FFR_PRED_NUM].p[0];
233
+ reg.addr = (uintptr_t)r;
234
+ reg.id = KVM_REG_ARM64_SVE_FFR(0);
235
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
236
if (ret) {
237
return ret;
238
}
239
- vfp_set_fpcr(env, fpr);
240
+ sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
241
242
return 0;
243
}
244
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
245
struct kvm_one_reg reg;
246
uint64_t val;
247
unsigned int el;
248
+ uint32_t fpr;
249
int i, ret;
250
251
ARMCPU *cpu = ARM_CPU(cs);
252
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
253
env->spsr = env->banked_spsr[i];
254
}
255
256
- ret = kvm_arch_get_fpsimd(cs);
257
+ if (cpu_isar_feature(aa64_sve, cpu)) {
258
+ ret = kvm_arch_get_sve(cs);
259
+ } else {
260
+ ret = kvm_arch_get_fpsimd(cs);
261
+ }
262
if (ret) {
263
return ret;
264
}
265
266
+ reg.addr = (uintptr_t)(&fpr);
267
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
268
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
269
+ if (ret) {
270
+ return ret;
271
+ }
272
+ vfp_set_fpsr(env, fpr);
273
+
274
+ reg.addr = (uintptr_t)(&fpr);
275
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
276
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
277
+ if (ret) {
278
+ return ret;
279
+ }
280
+ vfp_set_fpcr(env, fpr);
281
+
282
ret = kvm_get_vcpu_events(cpu);
283
if (ret) {
284
return ret;
74
--
285
--
75
2.25.1
286
2.20.1
76
287
77
288
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
For A64, any input to an indirect branch can cause this.
3
Enable SVE in the KVM guest when the 'max' cpu type is configured
4
4
and KVM supports it. KVM SVE requires use of the new finalize
5
For A32, many indirect branch paths force the branch to be aligned,
5
vcpu ioctl, so we add that now too. For starters SVE can only be
6
but BXWritePC does not. This includes the BX instruction but also
6
turned on or off, getting all vector lengths the host CPU supports
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
7
when on. We'll add the other SVE CPU properties in later patches.
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
8
9
exception or force align the PC.
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
We choose to raise an exception because we have the infrastructure,
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
it makes the generated code for gen_bx simpler, and it has the
12
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
13
possibility of catching more guest bugs.
13
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
14
14
Message-id: 20191031142734.8590-7-drjones@redhat.com
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
16
---
19
target/arm/helper.h | 1 +
17
target/arm/kvm_arm.h | 27 +++++++++++++++++++++++++++
20
target/arm/syndrome.h | 5 ++++
18
target/arm/cpu64.c | 17 ++++++++++++++---
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
19
target/arm/kvm.c | 5 +++++
22
target/arm/tlb_helper.c | 18 ++++++++++++++
20
target/arm/kvm64.c | 20 +++++++++++++++++++-
23
target/arm/translate-a64.c | 15 ++++++++++++
21
tests/arm-cpu-features.c | 4 ++++
24
target/arm/translate.c | 22 ++++++++++++++++-
22
5 files changed, 69 insertions(+), 4 deletions(-)
25
6 files changed, 87 insertions(+), 20 deletions(-)
23
26
24
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/kvm_arm.h
29
--- a/target/arm/helper.h
27
+++ b/target/arm/kvm_arm.h
30
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
29
*/
32
DEF_HELPER_2(exception_internal, void, env, i32)
30
int kvm_arm_vcpu_init(CPUState *cs);
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
31
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
32
+/**
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
33
+ * kvm_arm_vcpu_finalize
36
DEF_HELPER_1(setend, void, env)
34
+ * @cs: CPUState
37
DEF_HELPER_2(wfi, void, env, i32)
35
+ * @feature: int
38
DEF_HELPER_1(wfe, void, env)
36
+ *
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
37
+ * Finalizes the configuration of the specified VCPU feature by
40
index XXXXXXX..XXXXXXX 100644
38
+ * invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring
41
--- a/target/arm/syndrome.h
39
+ * this are documented in the "KVM_ARM_VCPU_FINALIZE" section of
42
+++ b/target/arm/syndrome.h
40
+ * KVM's API documentation.
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
41
+ *
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
42
+ * Returns: 0 if success else < 0 error code
45
}
43
+ */
46
44
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature);
47
+static inline uint32_t syn_pcalignment(void)
45
+
46
/**
47
* kvm_arm_register_device:
48
* @mr: memory region for this device
49
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(CPUState *cs);
50
*/
51
bool kvm_arm_pmu_supported(CPUState *cs);
52
53
+/**
54
+ * bool kvm_arm_sve_supported:
55
+ * @cs: CPUState
56
+ *
57
+ * Returns true if the KVM VCPU can enable SVE and false otherwise.
58
+ */
59
+bool kvm_arm_sve_supported(CPUState *cs);
60
+
61
/**
62
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
63
* IPA address space supported by KVM
64
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_pmu_supported(CPUState *cs)
65
return false;
66
}
67
68
+static inline bool kvm_arm_sve_supported(CPUState *cs)
48
+{
69
+{
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
70
+ return false;
50
+}
71
+}
51
+
72
+
52
#endif /* TARGET_ARM_SYNDROME_H */
73
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
74
{
54
index XXXXXXX..XXXXXXX 100644
75
return -ENOENT;
55
--- a/linux-user/aarch64/cpu_loop.c
76
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
56
+++ b/linux-user/aarch64/cpu_loop.c
77
index XXXXXXX..XXXXXXX 100644
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
78
--- a/target/arm/cpu64.c
58
break;
79
+++ b/target/arm/cpu64.c
59
case EXCP_PREFETCH_ABORT:
80
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
60
case EXCP_DATA_ABORT:
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
62
ec = syn_get_ec(env->exception.syndrome);
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
64
-
65
- /* Both EC have the same format for FSC, or close enough. */
66
- fsc = extract32(env->exception.syndrome, 0, 6);
67
- switch (fsc) {
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
69
- si_signo = TARGET_SIGSEGV;
70
- si_code = TARGET_SEGV_MAPERR;
71
+ switch (ec) {
72
+ case EC_DATAABORT:
73
+ case EC_INSNABORT:
74
+ /* Both EC have the same format for FSC, or close enough. */
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
76
+ switch (fsc) {
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
78
+ si_signo = TARGET_SIGSEGV;
79
+ si_code = TARGET_SEGV_MAPERR;
80
+ break;
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
83
+ si_signo = TARGET_SIGSEGV;
84
+ si_code = TARGET_SEGV_ACCERR;
85
+ break;
86
+ case 0x11: /* Synchronous Tag Check Fault */
87
+ si_signo = TARGET_SIGSEGV;
88
+ si_code = TARGET_SEGV_MTESERR;
89
+ break;
90
+ case 0x21: /* Alignment fault */
91
+ si_signo = TARGET_SIGBUS;
92
+ si_code = TARGET_BUS_ADRALN;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "cpu.h"
118
#include "internals.h"
119
#include "exec/exec-all.h"
120
+#include "exec/helper-proto.h"
121
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
123
unsigned int target_el,
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
129
+{
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
131
+ int target_el = exception_target_el(env);
132
+ int mmu_idx = cpu_mmu_index(env, true);
133
+ uint32_t fsc;
134
+
135
+ env->exception.vaddress = pc;
136
+
137
+ /*
138
+ * Note that the fsc is not applicable to this exception,
139
+ * since any syndrome is pcalignment not insn_abort.
140
+ */
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
143
+}
144
+
145
#if !defined(CONFIG_USER_ONLY)
146
147
/*
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/translate-a64.c
151
+++ b/target/arm/translate-a64.c
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
153
uint64_t pc = s->base.pc_next;
154
uint32_t insn;
155
156
+ /* Singlestep exceptions have the highest priority. */
157
if (s->ss_active && !s->pstate_ss) {
158
/* Singlestep state is Active-pending.
159
* If we're in this state at the start of a TB then either
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
161
return;
81
return;
162
}
82
}
163
83
164
+ if (pc & 3) {
84
+ if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
165
+ /*
85
+ error_setg(errp, "'sve' feature not supported by KVM on this host");
166
+ * PC alignment fault. This has priority over the instruction abort
167
+ * that we would receive from a translation fault via arm_ldl_code.
168
+ * This should only be possible after an indirect branch, at the
169
+ * start of the TB.
170
+ */
171
+ assert(s->base.num_insns == 1);
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
173
+ s->base.is_jmp = DISAS_NORETURN;
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
175
+ return;
86
+ return;
176
+ }
87
+ }
177
+
88
+
178
s->pc_curr = pc;
89
t = cpu->isar.id_aa64pfr0;
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
90
t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
180
s->insn = insn;
91
cpu->isar.id_aa64pfr0 = t;
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
92
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
182
index XXXXXXX..XXXXXXX 100644
93
{
183
--- a/target/arm/translate.c
94
ARMCPU *cpu = ARM_CPU(obj);
184
+++ b/target/arm/translate.c
95
uint32_t vq;
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
96
+ uint64_t t;
186
uint32_t pc = dc->base.pc_next;
97
187
unsigned int insn;
98
if (kvm_enabled()) {
188
99
kvm_arm_set_cpu_features_from_host(cpu);
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
100
+ if (kvm_arm_sve_supported(CPU(cpu))) {
190
+ /* Singlestep exceptions have the highest priority. */
101
+ t = cpu->isar.id_aa64pfr0;
191
+ if (arm_check_ss_active(dc)) {
102
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
192
+ dc->base.pc_next = pc + 4;
103
+ cpu->isar.id_aa64pfr0 = t;
193
+ return;
104
+ }
105
} else {
106
- uint64_t t;
107
uint32_t u;
108
aarch64_a57_initfn(obj);
109
110
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
111
112
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
113
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
114
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
115
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
116
117
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
118
char name[8];
119
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
120
cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
121
}
122
}
123
+
124
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
125
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
126
}
127
128
struct ARMCPUInfo {
129
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/kvm.c
132
+++ b/target/arm/kvm.c
133
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs)
134
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
135
}
136
137
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature)
138
+{
139
+ return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_FINALIZE, &feature);
140
+}
141
+
142
void kvm_arm_init_serror_injection(CPUState *cs)
143
{
144
cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
145
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/kvm64.c
148
+++ b/target/arm/kvm64.c
149
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(CPUState *cpu)
150
return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
151
}
152
153
+bool kvm_arm_sve_supported(CPUState *cpu)
154
+{
155
+ KVMState *s = KVM_STATE(current_machine->accelerator);
156
+
157
+ return kvm_check_extension(s, KVM_CAP_ARM_SVE);
158
+}
159
+
160
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
161
162
int kvm_arch_init_vcpu(CPUState *cs)
163
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
164
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
165
}
166
if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
167
- cpu->has_pmu = false;
168
+ cpu->has_pmu = false;
169
}
170
if (cpu->has_pmu) {
171
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
172
} else {
173
unset_feature(&env->features, ARM_FEATURE_PMU);
174
}
175
+ if (cpu_isar_feature(aa64_sve, cpu)) {
176
+ assert(kvm_arm_sve_supported(cs));
177
+ cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
194
+ }
178
+ }
195
+
179
196
+ if (pc & 3) {
180
/* Do KVM_ARM_VCPU_INIT ioctl */
197
+ /*
181
ret = kvm_arm_vcpu_init(cs);
198
+ * PC alignment fault. This has priority over the instruction abort
182
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
199
+ * that we would receive from a translation fault via arm_ldl_code
183
return ret;
200
+ * (or the execution of the kernelpage entrypoint). This should only
184
}
201
+ * be possible after an indirect branch, at the start of the TB.
185
202
+ */
186
+ if (cpu_isar_feature(aa64_sve, cpu)) {
203
+ assert(dc->base.num_insns == 1);
187
+ ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE);
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
188
+ if (ret) {
205
+ dc->base.is_jmp = DISAS_NORETURN;
189
+ return ret;
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
190
+ }
207
+ return;
208
+ }
191
+ }
209
+
192
+
210
+ if (arm_check_kernelpage(dc)) {
193
/*
211
dc->base.pc_next = pc + 4;
194
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
212
return;
195
* Currently KVM has its own idea about MPIDR assignment, so we
213
}
196
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/tests/arm-cpu-features.c
199
+++ b/tests/arm-cpu-features.c
200
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
201
assert_has_feature(qts, "host", "aarch64");
202
assert_has_feature(qts, "host", "pmu");
203
204
+ assert_has_feature(qts, "max", "sve");
205
+
206
assert_error(qts, "cortex-a15",
207
"We cannot guarantee the CPU type 'cortex-a15' works "
208
"with KVM on this host", NULL);
209
} else {
210
assert_has_not_feature(qts, "host", "aarch64");
211
assert_has_not_feature(qts, "host", "pmu");
212
+
213
+ assert_has_not_feature(qts, "max", "sve");
214
}
215
216
qtest_quit(qts);
214
--
217
--
215
2.25.1
218
2.20.1
216
219
217
220
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
We will reuse this section of arm_deliver_fault for
3
kvm_arm_create_scratch_host_vcpu() takes a struct kvm_vcpu_init
4
raising pc alignment faults.
4
parameter. Rather than just using it as an output parameter to
5
pass back the preferred target, use it also as an input parameter,
6
allowing a caller to pass a selected target if they wish and to
7
also pass cpu features. If the caller doesn't want to select a
8
target they can pass -1 for the target which indicates they want
9
to use the preferred target and have it passed back like before.
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
15
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
16
Message-id: 20191031142734.8590-8-drjones@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
19
target/arm/kvm.c | 20 +++++++++++++++-----
11
1 file changed, 28 insertions(+), 17 deletions(-)
20
target/arm/kvm32.c | 6 +++++-
21
target/arm/kvm64.c | 6 +++++-
22
3 files changed, 25 insertions(+), 7 deletions(-)
12
23
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
24
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tlb_helper.c
26
--- a/target/arm/kvm.c
16
+++ b/target/arm/tlb_helper.c
27
+++ b/target/arm/kvm.c
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
28
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
18
return syn;
29
int *fdarray,
19
}
30
struct kvm_vcpu_init *init)
20
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
22
- MMUAccessType access_type,
23
- int mmu_idx, ARMMMUFaultInfo *fi)
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
26
{
31
{
27
- CPUARMState *env = &cpu->env;
32
- int ret, kvmfd = -1, vmfd = -1, cpufd = -1;
28
- int target_el;
33
+ int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
29
- bool same_el;
34
30
- uint32_t syn, exc, fsr, fsc;
35
kvmfd = qemu_open("/dev/kvm", O_RDWR);
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
36
if (kvmfd < 0) {
32
-
37
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
33
- target_el = exception_target_el(env);
38
goto finish;
34
- if (fi->stage2) {
35
- target_el = 2;
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
39
- }
40
- }
41
- same_el = (arm_current_el(env) == target_el);
42
+ uint32_t fsr, fsc;
43
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
47
fsc = 0x3f;
48
}
39
}
49
40
50
+ *ret_fsc = fsc;
41
- ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
51
+ return fsr;
42
+ if (init->target == -1) {
52
+}
43
+ struct kvm_vcpu_init preferred;
53
+
44
+
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
45
+ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
55
+ MMUAccessType access_type,
46
+ if (!ret) {
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
47
+ init->target = preferred.target;
57
+{
58
+ CPUARMState *env = &cpu->env;
59
+ int target_el;
60
+ bool same_el;
61
+ uint32_t syn, exc, fsr, fsc;
62
+
63
+ target_el = exception_target_el(env);
64
+ if (fi->stage2) {
65
+ target_el = 2;
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
69
+ }
48
+ }
70
+ }
49
+ }
71
+ same_el = (arm_current_el(env) == target_el);
50
if (ret >= 0) {
51
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
52
if (ret < 0) {
53
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
54
* creating one kind of guest CPU which is its preferred
55
* CPU type.
56
*/
57
+ struct kvm_vcpu_init try;
72
+
58
+
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
59
while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
74
+
60
- init->target = *cpus_to_try++;
75
if (access_type == MMU_INST_FETCH) {
61
- memset(init->features, 0, sizeof(init->features));
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
62
- ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
77
exc = EXCP_PREFETCH_ABORT;
63
+ try.target = *cpus_to_try++;
64
+ memcpy(try.features, init->features, sizeof(init->features));
65
+ ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try);
66
if (ret >= 0) {
67
break;
68
}
69
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
70
if (ret < 0) {
71
goto err;
72
}
73
+ init->target = try.target;
74
} else {
75
/* Treat a NULL cpus_to_try argument the same as an empty
76
* list, which means we will fail the call since this must
77
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/kvm32.c
80
+++ b/target/arm/kvm32.c
81
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
82
QEMU_KVM_ARM_TARGET_CORTEX_A15,
83
QEMU_KVM_ARM_TARGET_NONE
84
};
85
- struct kvm_vcpu_init init;
86
+ /*
87
+ * target = -1 informs kvm_arm_create_scratch_host_vcpu()
88
+ * to use the preferred target
89
+ */
90
+ struct kvm_vcpu_init init = { .target = -1, };
91
92
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
93
return false;
94
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/kvm64.c
97
+++ b/target/arm/kvm64.c
98
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
99
KVM_ARM_TARGET_CORTEX_A57,
100
QEMU_KVM_ARM_TARGET_NONE
101
};
102
- struct kvm_vcpu_init init;
103
+ /*
104
+ * target = -1 informs kvm_arm_create_scratch_host_vcpu()
105
+ * to use the preferred target
106
+ */
107
+ struct kvm_vcpu_init init = { .target = -1, };
108
109
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
110
return false;
78
--
111
--
79
2.25.1
112
2.20.1
80
113
81
114
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
While trying to debug a GIC ITS failure I saw some guest errors that
3
Extend the SVE vq map initialization and validation with KVM's
4
had poor formatting as well as leaving me confused as to what failed.
4
supported vector lengths when KVM is enabled. In order to determine
5
As most of the checks aren't possible without a valid dte split that
5
and select supported lengths we add two new KVM functions for getting
6
check apart and then check the other conditions in steps. This avoids
6
and setting the KVM_REG_ARM64_SVE_VLS pseudo-register.
7
us relying on undefined data.
8
7
9
I still get a failure with the current kvm-unit-tests but at least I
8
This patch has been co-authored with Richard Henderson, who reworked
10
know (partially) why now:
9
the target/arm/cpu64.c changes in order to push all the validation and
10
auto-enabling/disabling steps into the finalizer, resulting in a nice
11
LOC reduction.
11
12
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
13
Signed-off-by: Andrew Jones <drjones@redhat.com>
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
INT dev_id=2 event_id=20
16
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
Message-id: 20191031142734.8590-9-drjones@redhat.com
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
19
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
19
---
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
20
target/arm/kvm_arm.h | 12 +++
28
1 file changed, 27 insertions(+), 12 deletions(-)
21
target/arm/cpu64.c | 176 ++++++++++++++++++++++++++++----------
22
target/arm/kvm64.c | 100 +++++++++++++++++++++-
23
tests/arm-cpu-features.c | 104 +++++++++++++++++++++-
24
docs/arm-cpu-features.rst | 45 +++++++---
25
5 files changed, 379 insertions(+), 58 deletions(-)
29
26
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
27
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
31
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/intc/arm_gicv3_its.c
29
--- a/target/arm/kvm_arm.h
33
+++ b/hw/intc/arm_gicv3_its.c
30
+++ b/target/arm/kvm_arm.h
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
31
@@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUFeatures {
35
if (res != MEMTX_OK) {
32
*/
36
return result;
33
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
34
35
+/**
36
+ * kvm_arm_sve_get_vls:
37
+ * @cs: CPUState
38
+ * @map: bitmap to fill in
39
+ *
40
+ * Get all the SVE vector lengths supported by the KVM host, setting
41
+ * the bits corresponding to their length in quadwords minus one
42
+ * (vq - 1) in @map up to ARM_MAX_VQ.
43
+ */
44
+void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map);
45
+
46
/**
47
* kvm_arm_set_cpu_features_from_host:
48
* @cpu: ARMCPU to set the features for
49
@@ -XXX,XX +XXX,XX @@ static inline int kvm_arm_vgic_probe(void)
50
static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {}
51
static inline void kvm_arm_pmu_init(CPUState *cs) {}
52
53
+static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) {}
54
#endif
55
56
static inline const char *gic_class_name(void)
57
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/cpu64.c
60
+++ b/target/arm/cpu64.c
61
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
62
* any of the above. Finally, if SVE is not disabled, then at least one
63
* vector length must be enabled.
64
*/
65
+ DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
66
DECLARE_BITMAP(tmp, ARM_MAX_VQ);
67
uint32_t vq, max_vq = 0;
68
69
+ /* Collect the set of vector lengths supported by KVM. */
70
+ bitmap_zero(kvm_supported, ARM_MAX_VQ);
71
+ if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
72
+ kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
73
+ } else if (kvm_enabled()) {
74
+ assert(!cpu_isar_feature(aa64_sve, cpu));
75
+ }
76
+
77
/*
78
* Process explicit sve<N> properties.
79
* From the properties, sve_vq_map<N> implies sve_vq_init<N>.
80
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
81
return;
82
}
83
84
- /* Propagate enabled bits down through required powers-of-two. */
85
- for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
86
- if (!test_bit(vq - 1, cpu->sve_vq_init)) {
87
- set_bit(vq - 1, cpu->sve_vq_map);
88
+ if (kvm_enabled()) {
89
+ /*
90
+ * For KVM we have to automatically enable all supported unitialized
91
+ * lengths, even when the smaller lengths are not all powers-of-two.
92
+ */
93
+ bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq);
94
+ bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
95
+ } else {
96
+ /* Propagate enabled bits down through required powers-of-two. */
97
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
98
+ if (!test_bit(vq - 1, cpu->sve_vq_init)) {
99
+ set_bit(vq - 1, cpu->sve_vq_map);
100
+ }
101
}
102
}
103
} else if (cpu->sve_max_vq == 0) {
104
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
105
return;
106
}
107
108
- /* Disabling a power-of-two disables all larger lengths. */
109
- if (test_bit(0, cpu->sve_vq_init)) {
110
- error_setg(errp, "cannot disable sve128");
111
- error_append_hint(errp, "Disabling sve128 results in all vector "
112
- "lengths being disabled.\n");
113
- error_append_hint(errp, "With SVE enabled, at least one vector "
114
- "length must be enabled.\n");
115
- return;
116
- }
117
- for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
118
- if (test_bit(vq - 1, cpu->sve_vq_init)) {
119
- break;
120
+ if (kvm_enabled()) {
121
+ /* Disabling a supported length disables all larger lengths. */
122
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
123
+ if (test_bit(vq - 1, cpu->sve_vq_init) &&
124
+ test_bit(vq - 1, kvm_supported)) {
125
+ break;
126
+ }
127
}
128
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
129
+ bitmap_andnot(cpu->sve_vq_map, kvm_supported,
130
+ cpu->sve_vq_init, max_vq);
131
+ if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
132
+ error_setg(errp, "cannot disable sve%d", vq * 128);
133
+ error_append_hint(errp, "Disabling sve%d results in all "
134
+ "vector lengths being disabled.\n",
135
+ vq * 128);
136
+ error_append_hint(errp, "With SVE enabled, at least one "
137
+ "vector length must be enabled.\n");
138
+ return;
139
+ }
140
+ } else {
141
+ /* Disabling a power-of-two disables all larger lengths. */
142
+ if (test_bit(0, cpu->sve_vq_init)) {
143
+ error_setg(errp, "cannot disable sve128");
144
+ error_append_hint(errp, "Disabling sve128 results in all "
145
+ "vector lengths being disabled.\n");
146
+ error_append_hint(errp, "With SVE enabled, at least one "
147
+ "vector length must be enabled.\n");
148
+ return;
149
+ }
150
+ for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
151
+ if (test_bit(vq - 1, cpu->sve_vq_init)) {
152
+ break;
153
+ }
154
+ }
155
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
156
+ bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
157
}
158
- max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
159
160
- bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
161
max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
165
assert(max_vq != 0);
166
bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
167
168
- /* Ensure all required powers-of-two are enabled. */
169
- for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
170
- if (!test_bit(vq - 1, cpu->sve_vq_map)) {
171
- error_setg(errp, "cannot disable sve%d", vq * 128);
172
- error_append_hint(errp, "sve%d is required as it "
173
- "is a power-of-two length smaller than "
174
- "the maximum, sve%d\n",
175
- vq * 128, max_vq * 128);
176
+ if (kvm_enabled()) {
177
+ /* Ensure the set of lengths matches what KVM supports. */
178
+ bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq);
179
+ if (!bitmap_empty(tmp, max_vq)) {
180
+ vq = find_last_bit(tmp, max_vq) + 1;
181
+ if (test_bit(vq - 1, cpu->sve_vq_map)) {
182
+ if (cpu->sve_max_vq) {
183
+ error_setg(errp, "cannot set sve-max-vq=%d",
184
+ cpu->sve_max_vq);
185
+ error_append_hint(errp, "This KVM host does not support "
186
+ "the vector length %d-bits.\n",
187
+ vq * 128);
188
+ error_append_hint(errp, "It may not be possible to use "
189
+ "sve-max-vq with this KVM host. Try "
190
+ "using only sve<N> properties.\n");
191
+ } else {
192
+ error_setg(errp, "cannot enable sve%d", vq * 128);
193
+ error_append_hint(errp, "This KVM host does not support "
194
+ "the vector length %d-bits.\n",
195
+ vq * 128);
196
+ }
197
+ } else {
198
+ error_setg(errp, "cannot disable sve%d", vq * 128);
199
+ error_append_hint(errp, "The KVM host requires all "
200
+ "supported vector lengths smaller "
201
+ "than %d bits to also be enabled.\n",
202
+ max_vq * 128);
203
+ }
204
return;
37
}
205
}
38
+ } else {
206
+ } else {
39
+ qemu_log_mask(LOG_GUEST_ERROR,
207
+ /* Ensure all required powers-of-two are enabled. */
40
+ "%s: invalid command attributes: "
208
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
209
+ if (!test_bit(vq - 1, cpu->sve_vq_map)) {
42
+ __func__, dte, devid, res);
210
+ error_setg(errp, "cannot disable sve%d", vq * 128);
43
+ return result;
211
+ error_append_hint(errp, "sve%d is required as it "
44
}
212
+ "is a power-of-two length smaller than "
45
213
+ "the maximum, sve%d\n",
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
214
+ vq * 128, max_vq * 128);
47
- !cte_valid || (eventid > max_eventid)) {
215
+ return;
216
+ }
217
+ }
218
}
219
220
/*
221
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
222
{
223
ARMCPU *cpu = ARM_CPU(obj);
224
Error *err = NULL;
225
+ uint32_t max_vq;
226
227
- visit_type_uint32(v, name, &cpu->sve_max_vq, &err);
228
-
229
- if (!err && (cpu->sve_max_vq == 0 || cpu->sve_max_vq > ARM_MAX_VQ)) {
230
- error_setg(&err, "unsupported SVE vector length");
231
- error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n",
232
- ARM_MAX_VQ);
233
+ visit_type_uint32(v, name, &max_vq, &err);
234
+ if (err) {
235
+ error_propagate(errp, err);
236
+ return;
237
}
238
- error_propagate(errp, err);
239
+
240
+ if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
241
+ error_setg(errp, "cannot set sve-max-vq");
242
+ error_append_hint(errp, "SVE not supported by KVM on this host\n");
243
+ return;
244
+ }
245
+
246
+ if (max_vq == 0 || max_vq > ARM_MAX_VQ) {
247
+ error_setg(errp, "unsupported SVE vector length");
248
+ error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n",
249
+ ARM_MAX_VQ);
250
+ return;
251
+ }
252
+
253
+ cpu->sve_max_vq = max_vq;
254
}
255
256
static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
257
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
258
return;
259
}
260
261
+ if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
262
+ error_setg(errp, "cannot enable %s", name);
263
+ error_append_hint(errp, "SVE not supported by KVM on this host\n");
264
+ return;
265
+ }
266
+
267
if (value) {
268
set_bit(vq - 1, cpu->sve_vq_map);
269
} else {
270
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
271
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
272
cpu->dcz_blocksize = 7; /* 512 bytes */
273
#endif
274
-
275
- object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
276
- cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
277
-
278
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
279
- char name[8];
280
- sprintf(name, "sve%d", vq * 128);
281
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
282
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
283
- }
284
}
285
286
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
287
cpu_arm_set_sve, NULL, NULL, &error_fatal);
288
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
289
+ cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
290
+
291
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
292
+ char name[8];
293
+ sprintf(name, "sve%d", vq * 128);
294
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
295
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
296
+ }
297
}
298
299
struct ARMCPUInfo {
300
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/target/arm/kvm64.c
303
+++ b/target/arm/kvm64.c
304
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_sve_supported(CPUState *cpu)
305
return kvm_check_extension(s, KVM_CAP_ARM_SVE);
306
}
307
308
+QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
309
+
310
+void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
311
+{
312
+ /* Only call this function if kvm_arm_sve_supported() returns true. */
313
+ static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];
314
+ static bool probed;
315
+ uint32_t vq = 0;
316
+ int i, j;
317
+
318
+ bitmap_clear(map, 0, ARM_MAX_VQ);
48
+
319
+
49
+ /*
320
+ /*
50
+ * In this implementation, in case of guest errors we ignore the
321
+ * KVM ensures all host CPUs support the same set of vector lengths.
51
+ * command and move onto the next command in the queue.
322
+ * So we only need to create the scratch VCPUs once and then cache
323
+ * the results.
52
+ */
324
+ */
53
+ if (devid > s->dt.maxids.max_devids) {
325
+ if (!probed) {
54
qemu_log_mask(LOG_GUEST_ERROR,
326
+ struct kvm_vcpu_init init = {
55
- "%s: invalid command attributes "
327
+ .target = -1,
56
- "devid %d or eventid %d or invalid dte %d or"
328
+ .features[0] = (1 << KVM_ARM_VCPU_SVE),
57
- "invalid cte %d or invalid ite %d\n",
329
+ };
58
- __func__, devid, eventid, dte_valid, cte_valid,
330
+ struct kvm_one_reg reg = {
59
- ite_valid);
331
+ .id = KVM_REG_ARM64_SVE_VLS,
60
- /*
332
+ .addr = (uint64_t)&vls[0],
61
- * in this implementation, in case of error
333
+ };
62
- * we ignore this command and move onto the next
334
+ int fdarray[3], ret;
63
- * command in the queue
335
+
64
- */
336
+ probed = true;
65
+ "%s: invalid command attributes: devid %d>%d",
337
+
66
+ __func__, devid, s->dt.maxids.max_devids);
338
+ if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, &init)) {
67
+
339
+ error_report("failed to create scratch VCPU with SVE enabled");
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
340
+ abort();
69
+ qemu_log_mask(LOG_GUEST_ERROR,
341
+ }
70
+ "%s: invalid command attributes: "
342
+ ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &reg);
71
+ "dte: %s, ite: %s, cte: %s\n",
343
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
72
+ __func__,
344
+ if (ret) {
73
+ dte_valid ? "valid" : "invalid",
345
+ error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s",
74
+ ite_valid ? "valid" : "invalid",
346
+ strerror(errno));
75
+ cte_valid ? "valid" : "invalid");
347
+ abort();
76
+ } else if (eventid > max_eventid) {
348
+ }
77
+ qemu_log_mask(LOG_GUEST_ERROR,
349
+
78
+ "%s: invalid command attributes: eventid %d > %d\n",
350
+ for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) {
79
+ __func__, eventid, max_eventid);
351
+ if (vls[i]) {
352
+ vq = 64 - clz64(vls[i]) + i * 64;
353
+ break;
354
+ }
355
+ }
356
+ if (vq > ARM_MAX_VQ) {
357
+ warn_report("KVM supports vector lengths larger than "
358
+ "QEMU can enable");
359
+ }
360
+ }
361
+
362
+ for (i = 0; i < KVM_ARM64_SVE_VLS_WORDS; ++i) {
363
+ if (!vls[i]) {
364
+ continue;
365
+ }
366
+ for (j = 1; j <= 64; ++j) {
367
+ vq = j + i * 64;
368
+ if (vq > ARM_MAX_VQ) {
369
+ return;
370
+ }
371
+ if (vls[i] & (1UL << (j - 1))) {
372
+ set_bit(vq - 1, map);
373
+ }
374
+ }
375
+ }
376
+}
377
+
378
+static int kvm_arm_sve_set_vls(CPUState *cs)
379
+{
380
+ uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = {0};
381
+ struct kvm_one_reg reg = {
382
+ .id = KVM_REG_ARM64_SVE_VLS,
383
+ .addr = (uint64_t)&vls[0],
384
+ };
385
+ ARMCPU *cpu = ARM_CPU(cs);
386
+ uint32_t vq;
387
+ int i, j;
388
+
389
+ assert(cpu->sve_max_vq <= KVM_ARM64_SVE_VQ_MAX);
390
+
391
+ for (vq = 1; vq <= cpu->sve_max_vq; ++vq) {
392
+ if (test_bit(vq - 1, cpu->sve_vq_map)) {
393
+ i = (vq - 1) / 64;
394
+ j = (vq - 1) % 64;
395
+ vls[i] |= 1UL << j;
396
+ }
397
+ }
398
+
399
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
400
+}
401
+
402
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
403
404
int kvm_arch_init_vcpu(CPUState *cs)
405
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
406
407
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
408
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
409
- fprintf(stderr, "KVM is not supported for this guest CPU type\n");
410
+ error_report("KVM is not supported for this guest CPU type");
411
return -EINVAL;
412
}
413
414
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
415
}
416
417
if (cpu_isar_feature(aa64_sve, cpu)) {
418
+ ret = kvm_arm_sve_set_vls(cs);
419
+ if (ret) {
420
+ return ret;
421
+ }
422
ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE);
423
if (ret) {
424
return ret;
425
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
426
index XXXXXXX..XXXXXXX 100644
427
--- a/tests/arm-cpu-features.c
428
+++ b/tests/arm-cpu-features.c
429
@@ -XXX,XX +XXX,XX @@ static QDict *resp_get_props(QDict *resp)
430
return qdict;
431
}
432
433
+static bool resp_get_feature(QDict *resp, const char *feature)
434
+{
435
+ QDict *props;
436
+
437
+ g_assert(resp);
438
+ g_assert(resp_has_props(resp));
439
+ props = resp_get_props(resp);
440
+ g_assert(qdict_get(props, feature));
441
+ return qdict_get_bool(props, feature);
442
+}
443
+
444
#define assert_has_feature(qts, cpu_type, feature) \
445
({ \
446
QDict *_resp = do_query_no_props(qts, cpu_type); \
447
@@ -XXX,XX +XXX,XX @@ static void sve_tests_sve_off(const void *data)
448
qtest_quit(qts);
449
}
450
451
+static void sve_tests_sve_off_kvm(const void *data)
452
+{
453
+ QTestState *qts;
454
+
455
+ qts = qtest_init(MACHINE_KVM "-cpu max,sve=off");
456
+
457
+ /*
458
+ * We don't know if this host supports SVE so we don't
459
+ * attempt to test enabling anything. We only test that
460
+ * everything is disabled (as it should be with sve=off)
461
+ * and that using sve<N>=off to explicitly disable vector
462
+ * lengths is OK too.
463
+ */
464
+ assert_sve_vls(qts, "max", 0, NULL);
465
+ assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
466
+
467
+ qtest_quit(qts);
468
+}
469
+
470
static void test_query_cpu_model_expansion(const void *data)
471
{
472
QTestState *qts;
473
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
474
}
475
476
if (g_str_equal(qtest_get_arch(), "aarch64")) {
477
+ bool kvm_supports_sve;
478
+ char max_name[8], name[8];
479
+ uint32_t max_vq, vq;
480
+ uint64_t vls;
481
+ QDict *resp;
482
+ char *error;
483
+
484
assert_has_feature(qts, "host", "aarch64");
485
assert_has_feature(qts, "host", "pmu");
486
487
- assert_has_feature(qts, "max", "sve");
488
-
489
assert_error(qts, "cortex-a15",
490
"We cannot guarantee the CPU type 'cortex-a15' works "
491
"with KVM on this host", NULL);
492
+
493
+ assert_has_feature(qts, "max", "sve");
494
+ resp = do_query_no_props(qts, "max");
495
+ kvm_supports_sve = resp_get_feature(resp, "sve");
496
+ vls = resp_get_sve_vls(resp);
497
+ qobject_unref(resp);
498
+
499
+ if (kvm_supports_sve) {
500
+ g_assert(vls != 0);
501
+ max_vq = 64 - __builtin_clzll(vls);
502
+ sprintf(max_name, "sve%d", max_vq * 128);
503
+
504
+ /* Enabling a supported length is of course fine. */
505
+ assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name);
506
+
507
+ /* Get the next supported length smaller than max-vq. */
508
+ vq = 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1));
509
+ if (vq) {
510
+ /*
511
+ * We have at least one length smaller than max-vq,
512
+ * so we can disable max-vq.
513
+ */
514
+ assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)),
515
+ "{ %s: false }", max_name);
516
+
517
+ /*
518
+ * Smaller, supported vector lengths cannot be disabled
519
+ * unless all larger, supported vector lengths are also
520
+ * disabled.
521
+ */
522
+ sprintf(name, "sve%d", vq * 128);
523
+ error = g_strdup_printf("cannot disable %s", name);
524
+ assert_error(qts, "max", error,
525
+ "{ %s: true, %s: false }",
526
+ max_name, name);
527
+ g_free(error);
528
+ }
529
+
530
+ /*
531
+ * The smallest, supported vector length is required, because
532
+ * we need at least one vector length enabled.
533
+ */
534
+ vq = __builtin_ffsll(vls);
535
+ sprintf(name, "sve%d", vq * 128);
536
+ error = g_strdup_printf("cannot disable %s", name);
537
+ assert_error(qts, "max", error, "{ %s: false }", name);
538
+ g_free(error);
539
+
540
+ /* Get an unsupported length. */
541
+ for (vq = 1; vq <= max_vq; ++vq) {
542
+ if (!(vls & BIT_ULL(vq - 1))) {
543
+ break;
544
+ }
545
+ }
546
+ if (vq <= SVE_MAX_VQ) {
547
+ sprintf(name, "sve%d", vq * 128);
548
+ error = g_strdup_printf("cannot enable %s", name);
549
+ assert_error(qts, "max", error, "{ %s: true }", name);
550
+ g_free(error);
551
+ }
552
+ } else {
553
+ g_assert(vls == 0);
554
+ }
80
} else {
555
} else {
81
/*
556
assert_has_not_feature(qts, "host", "aarch64");
82
* Current implementation only supports rdbase == procnum
557
assert_has_not_feature(qts, "host", "pmu");
558
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
559
NULL, sve_tests_sve_max_vq_8);
560
qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
561
NULL, sve_tests_sve_off);
562
+ qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
563
+ NULL, sve_tests_sve_off_kvm);
564
}
565
566
return g_test_run();
567
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
568
index XXXXXXX..XXXXXXX 100644
569
--- a/docs/arm-cpu-features.rst
570
+++ b/docs/arm-cpu-features.rst
571
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Dependencies and Constraints
572
573
1) At least one vector length must be enabled when `sve` is enabled.
574
575
- 2) If a vector length `N` is enabled, then all power-of-two vector
576
- lengths smaller than `N` must also be enabled. E.g. if `sve512`
577
- is enabled, then the 128-bit and 256-bit vector lengths must also
578
- be enabled.
579
+ 2) If a vector length `N` is enabled, then, when KVM is enabled, all
580
+ smaller, host supported vector lengths must also be enabled. If
581
+ KVM is not enabled, then only all the smaller, power-of-two vector
582
+ lengths must be enabled. E.g. with KVM if the host supports all
583
+ vector lengths up to 512-bits (128, 256, 384, 512), then if `sve512`
584
+ is enabled, the 128-bit vector length, 256-bit vector length, and
585
+ 384-bit vector length must also be enabled. Without KVM, the 384-bit
586
+ vector length would not be required.
587
+
588
+ 3) If KVM is enabled then only vector lengths that the host CPU type
589
+ support may be enabled. If SVE is not supported by the host, then
590
+ no `sve*` properties may be enabled.
591
592
SVE CPU Property Parsing Semantics
593
----------------------------------
594
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Parsing Semantics
595
an error is generated.
596
597
2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
598
- provided, then all supported vector lengths are enabled, including
599
- the non-power-of-two lengths.
600
+ provided, then all supported vector lengths are enabled, which when
601
+ KVM is not in use means including the non-power-of-two lengths, and,
602
+ when KVM is in use, it means all vector lengths supported by the host
603
+ processor.
604
605
3) If SVE is enabled, then an error is generated when attempting to
606
disable the last enabled vector length (see constraint (1) of "SVE
607
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Parsing Semantics
608
has been explicitly disabled, then an error is generated (see
609
constraint (2) of "SVE CPU Property Dependencies and Constraints").
610
611
- 5) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
612
+ 5) When KVM is enabled, if the host does not support SVE, then an error
613
+ is generated when attempting to enable any `sve*` properties (see
614
+ constraint (3) of "SVE CPU Property Dependencies and Constraints").
615
+
616
+ 6) When KVM is enabled, if the host does support SVE, then an error is
617
+ generated when attempting to enable any vector lengths not supported
618
+ by the host (see constraint (3) of "SVE CPU Property Dependencies and
619
+ Constraints").
620
+
621
+ 7) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
622
CPU properties are set `on`, then the specified vector lengths are
623
disabled but the default for any unspecified lengths remains enabled.
624
- Disabling a power-of-two vector length also disables all vector
625
- lengths larger than the power-of-two length (see constraint (2) of
626
- "SVE CPU Property Dependencies and Constraints").
627
+ When KVM is not enabled, disabling a power-of-two vector length also
628
+ disables all vector lengths larger than the power-of-two length.
629
+ When KVM is enabled, then disabling any supported vector length also
630
+ disables all larger vector lengths (see constraint (2) of "SVE CPU
631
+ Property Dependencies and Constraints").
632
633
- 6) If one or more `sve<N>` CPU properties are set to `on`, then they
634
+ 8) If one or more `sve<N>` CPU properties are set to `on`, then they
635
are enabled and all unspecified lengths default to disabled, except
636
for the required lengths per constraint (2) of "SVE CPU Property
637
Dependencies and Constraints", which will even be auto-enabled if
638
they were not explicitly enabled.
639
640
- 7) If SVE was disabled (`sve=off`), allowing all vector lengths to be
641
+ 9) If SVE was disabled (`sve=off`), allowing all vector lengths to be
642
explicitly disabled (i.e. avoiding the error specified in (3) of
643
"SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
644
provided an error will be generated. To avoid this error, one must
83
--
645
--
84
2.25.1
646
2.20.1
85
647
86
648
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
removed in v7.0.
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
24
AST2500 SoC based machines :
25
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
44
--
45
2.25.1
46
47
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
redirects.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
19
load a Linux kernel or from a firmware. Images can be downloaded from
20
the OpenBMC jenkins :
21
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
24
25
or directly from the OpenBMC GitHub release repository :
26
27
--
28
2.25.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
12
1 file changed, 12 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Missing devices
19
Boot options
20
------------
21
22
-The Aspeed machines can be started using the ``-kernel`` option to
23
-load a Linux kernel or from a firmware. Images can be downloaded from
24
-the OpenBMC jenkins :
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
27
+OpenBMC jenkins :
28
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
30
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
32
33
https://github.com/openbmc/openbmc/releases
34
35
+To boot a kernel directly from a Linux build tree:
36
+
37
+.. code-block:: bash
38
+
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
40
+ -kernel arch/arm/boot/zImage \
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
42
+ -initrd rootfs.cpio
43
+
44
The image should be attached as an MTD drive. Run :
45
46
.. code-block:: bash
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Move it to the supported list.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/system/arm/aspeed.rst | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
13
index XXXXXXX..XXXXXXX 100644
14
--- a/docs/system/arm/aspeed.rst
15
+++ b/docs/system/arm/aspeed.rst
16
@@ -XXX,XX +XXX,XX @@ Supported devices
17
* Front LEDs (PCA9552 on I2C bus)
18
* LPC Peripheral Controller (a subset of subdevices are supported)
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
20
+ * ADC
21
22
23
Missing devices
24
---------------
25
26
* Coprocessor support
27
- * ADC (out of tree implementation)
28
* PWM and Fan Controller
29
* Slave GPIO Controller
30
* Super I/O Controller
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
2
1
3
Fix issue where the data register may be overwritten by next character
4
reception before being read and returned.
5
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/char/stm32f2xx_usart.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/stm32f2xx_usart.c
18
+++ b/hw/char/stm32f2xx_usart.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
20
return retvalue;
21
case USART_DR:
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
23
+ retvalue = s->usart_dr & 0x3FF;
24
s->usart_sr &= ~USART_SR_RXNE;
25
qemu_chr_fe_accept_input(&s->chr);
26
qemu_set_irq(s->irq, 0);
27
- return s->usart_dr & 0x3FF;
28
+ return retvalue;
29
case USART_BRR:
30
return s->usart_brr;
31
case USART_CR1:
32
--
33
2.25.1
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
(which uses in-kernel support).
6
7
When using --with-devices-FOO, it is possible to build a
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/intc/arm_gicv3.c | 2 +-
22
hw/intc/Kconfig | 5 +++++
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
25
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3.c
29
+++ b/hw/intc/arm_gicv3.c
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM Generic Interrupt Controller v3
33
+ * ARM Generic Interrupt Controller v3 (emulation)
34
*
35
* Copyright (c) 2015 Huawei.
36
* Copyright (c) 2016 Linaro Limited
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/Kconfig
40
+++ b/hw/intc/Kconfig
41
@@ -XXX,XX +XXX,XX @@ config APIC
42
select MSI_NONBROKEN
43
select I8259
44
45
+config ARM_GIC_TCG
46
+ bool
47
+ default y
48
+ depends on ARM_GIC && TCG
49
+
50
config ARM_GIC_KVM
51
bool
52
default y
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/meson.build
56
+++ b/hw/intc/meson.build
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
58
'arm_gic.c',
59
'arm_gic_common.c',
60
'arm_gicv2m.c',
61
- 'arm_gicv3.c',
62
'arm_gicv3_common.c',
63
- 'arm_gicv3_dist.c',
64
'arm_gicv3_its_common.c',
65
- 'arm_gicv3_redist.c',
66
+))
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
68
+ 'arm_gicv3.c',
69
+ 'arm_gicv3_dist.c',
70
'arm_gicv3_its.c',
71
+ 'arm_gicv3_redist.c',
72
))
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
84
--
85
2.25.1
86
87
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
target/arm/translate-a64.c | 7 ++++---
8
1 file changed, 4 insertions(+), 3 deletions(-)
9
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
15
{
16
DisasContext *s = container_of(dcbase, DisasContext, base);
17
CPUARMState *env = cpu->env_ptr;
18
+ uint64_t pc = s->base.pc_next;
19
uint32_t insn;
20
21
if (s->ss_active && !s->pstate_ss) {
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
23
return;
24
}
25
26
- s->pc_curr = s->base.pc_next;
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
28
+ s->pc_curr = pc;
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
30
s->insn = insn;
31
- s->base.pc_next += 4;
32
+ s->base.pc_next = pc + 4;
33
34
s->fp_access_checked = false;
35
s->sve_access_checked = false;
36
--
37
2.25.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
target/arm/translate.c | 9 +++++----
8
1 file changed, 5 insertions(+), 4 deletions(-)
9
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/translate.c
13
+++ b/target/arm/translate.c
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
15
{
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
17
CPUARMState *env = cpu->env_ptr;
18
+ uint32_t pc = dc->base.pc_next;
19
unsigned int insn;
20
21
if (arm_pre_translate_insn(dc)) {
22
- dc->base.pc_next += 4;
23
+ dc->base.pc_next = pc + 4;
24
return;
25
}
26
27
- dc->pc_curr = dc->base.pc_next;
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
29
+ dc->pc_curr = pc;
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
31
dc->insn = insn;
32
- dc->base.pc_next += 4;
33
+ dc->base.pc_next = pc + 4;
34
disas_arm_insn(dc, insn);
35
36
arm_post_translate_insn(dc);
37
--
38
2.25.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
target/arm/translate.c | 16 ++++++++--------
8
1 file changed, 8 insertions(+), 8 deletions(-)
9
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/translate.c
13
+++ b/target/arm/translate.c
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
15
{
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
17
CPUARMState *env = cpu->env_ptr;
18
+ uint32_t pc = dc->base.pc_next;
19
uint32_t insn;
20
bool is_16bit;
21
22
if (arm_pre_translate_insn(dc)) {
23
- dc->base.pc_next += 2;
24
+ dc->base.pc_next = pc + 2;
25
return;
26
}
27
28
- dc->pc_curr = dc->base.pc_next;
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
30
+ dc->pc_curr = pc;
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
33
- dc->base.pc_next += 2;
34
+ pc += 2;
35
if (!is_16bit) {
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
37
- dc->sctlr_b);
38
-
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
48
--
49
2.25.1
50
51
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
The rx_active boolean change to true should always trigger a try_read
3
Allow cpu 'host' to enable SVE when it's available, unless the
4
call that flushes the queue.
4
user chooses to disable it with the added 'sve=off' cpu property.
5
5
Also give the user the ability to select vector lengths with the
6
Signed-off-by: Patrick Venture <venture@google.com>
6
sve<N> properties. We don't adopt 'max' cpu's other sve property,
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
sve-max-vq, because that property is difficult to use with KVM.
8
Message-id: 20211203221002.1719306-1-venture@google.com
8
That property assumes all vector lengths in the range from 1 up
9
to and including the specified maximum length are supported, but
10
there may be optional lengths not supported by the host in that
11
range. With KVM one must be more specific when enabling vector
12
lengths.
13
14
Signed-off-by: Andrew Jones <drjones@redhat.com>
15
Reviewed-by: Eric Auger <eric.auger@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
18
Message-id: 20191031142734.8590-10-drjones@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
20
---
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
21
target/arm/cpu.h | 2 ++
12
1 file changed, 8 insertions(+), 10 deletions(-)
22
target/arm/cpu.c | 3 +++
13
23
target/arm/cpu64.c | 33 +++++++++++++++++----------------
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
24
target/arm/kvm64.c | 14 +++++++++++++-
15
index XXXXXXX..XXXXXXX 100644
25
tests/arm-cpu-features.c | 17 ++++++++---------
16
--- a/hw/net/npcm7xx_emc.c
26
docs/arm-cpu-features.rst | 19 ++++++++++++-------
17
+++ b/hw/net/npcm7xx_emc.c
27
6 files changed, 55 insertions(+), 33 deletions(-)
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
28
19
emc_set_mista(emc, mista_flag);
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
34
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
35
void aarch64_sve_change_el(CPUARMState *env, int old_el,
36
int new_el, bool el0_a64);
37
+void aarch64_add_sve_properties(Object *obj);
38
#else
39
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
40
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
41
int n, bool a)
42
{ }
43
+static inline void aarch64_add_sve_properties(Object *obj) { }
44
#endif
45
46
#if !defined(CONFIG_TCG)
47
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu.c
50
+++ b/target/arm/cpu.c
51
@@ -XXX,XX +XXX,XX @@ static void arm_host_initfn(Object *obj)
52
ARMCPU *cpu = ARM_CPU(obj);
53
54
kvm_arm_set_cpu_features_from_host(cpu);
55
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
56
+ aarch64_add_sve_properties(obj);
57
+ }
58
arm_cpu_post_init(obj);
20
}
59
}
21
60
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
61
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/cpu64.c
64
+++ b/target/arm/cpu64.c
65
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
66
cpu->isar.id_aa64pfr0 = t;
67
}
68
69
+void aarch64_add_sve_properties(Object *obj)
23
+{
70
+{
24
+ emc->rx_active = true;
71
+ uint32_t vq;
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
72
+
73
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
74
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
75
+
76
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
77
+ char name[8];
78
+ sprintf(name, "sve%d", vq * 128);
79
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
80
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
81
+ }
26
+}
82
+}
27
+
83
+
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
84
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
29
const NPCM7xxEMCTxDesc *tx_desc,
85
* otherwise, a CPU with as many features enabled as our emulation supports.
30
uint32_t desc_addr)
86
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
87
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
32
return len;
88
static void aarch64_max_initfn(Object *obj)
89
{
90
ARMCPU *cpu = ARM_CPU(obj);
91
- uint32_t vq;
92
- uint64_t t;
93
94
if (kvm_enabled()) {
95
kvm_arm_set_cpu_features_from_host(cpu);
96
- if (kvm_arm_sve_supported(CPU(cpu))) {
97
- t = cpu->isar.id_aa64pfr0;
98
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
99
- cpu->isar.id_aa64pfr0 = t;
100
- }
101
} else {
102
+ uint64_t t;
103
uint32_t u;
104
aarch64_a57_initfn(obj);
105
106
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
107
#endif
108
}
109
110
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
111
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
112
+ aarch64_add_sve_properties(obj);
113
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
114
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
115
-
116
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
117
- char name[8];
118
- sprintf(name, "sve%d", vq * 128);
119
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
120
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
121
- }
33
}
122
}
34
123
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
124
struct ARMCPUInfo {
36
-{
125
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
126
index XXXXXXX..XXXXXXX 100644
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
127
--- a/target/arm/kvm64.c
39
- }
128
+++ b/target/arm/kvm64.c
40
-}
129
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
130
* and then query that CPU for the relevant ID registers.
131
*/
132
int fdarray[3];
133
+ bool sve_supported;
134
uint64_t features = 0;
135
+ uint64_t t;
136
int err;
137
138
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
139
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
140
ARM64_SYS_REG(3, 0, 0, 3, 2));
141
}
142
143
+ sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
144
+
145
kvm_arm_destroy_scratch_host_vcpu(fdarray);
146
147
if (err < 0) {
148
return false;
149
}
150
151
- /* We can assume any KVM supporting CPU is at least a v8
152
+ /* Add feature bits that can't appear until after VCPU init. */
153
+ if (sve_supported) {
154
+ t = ahcf->isar.id_aa64pfr0;
155
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
156
+ ahcf->isar.id_aa64pfr0 = t;
157
+ }
158
+
159
+ /*
160
+ * We can assume any KVM supporting CPU is at least a v8
161
* with VFPv4+Neon; this in turn implies most of the other
162
* feature bits.
163
*/
164
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/tests/arm-cpu-features.c
167
+++ b/tests/arm-cpu-features.c
168
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
169
"We cannot guarantee the CPU type 'cortex-a15' works "
170
"with KVM on this host", NULL);
171
172
- assert_has_feature(qts, "max", "sve");
173
- resp = do_query_no_props(qts, "max");
174
+ assert_has_feature(qts, "host", "sve");
175
+ resp = do_query_no_props(qts, "host");
176
kvm_supports_sve = resp_get_feature(resp, "sve");
177
vls = resp_get_sve_vls(resp);
178
qobject_unref(resp);
179
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
180
sprintf(max_name, "sve%d", max_vq * 128);
181
182
/* Enabling a supported length is of course fine. */
183
- assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name);
184
+ assert_sve_vls(qts, "host", vls, "{ %s: true }", max_name);
185
186
/* Get the next supported length smaller than max-vq. */
187
vq = 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1));
188
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
189
* We have at least one length smaller than max-vq,
190
* so we can disable max-vq.
191
*/
192
- assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)),
193
+ assert_sve_vls(qts, "host", (vls & ~BIT_ULL(max_vq - 1)),
194
"{ %s: false }", max_name);
195
196
/*
197
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
198
*/
199
sprintf(name, "sve%d", vq * 128);
200
error = g_strdup_printf("cannot disable %s", name);
201
- assert_error(qts, "max", error,
202
+ assert_error(qts, "host", error,
203
"{ %s: true, %s: false }",
204
max_name, name);
205
g_free(error);
206
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
207
vq = __builtin_ffsll(vls);
208
sprintf(name, "sve%d", vq * 128);
209
error = g_strdup_printf("cannot disable %s", name);
210
- assert_error(qts, "max", error, "{ %s: false }", name);
211
+ assert_error(qts, "host", error, "{ %s: false }", name);
212
g_free(error);
213
214
/* Get an unsupported length. */
215
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
216
if (vq <= SVE_MAX_VQ) {
217
sprintf(name, "sve%d", vq * 128);
218
error = g_strdup_printf("cannot enable %s", name);
219
- assert_error(qts, "max", error, "{ %s: true }", name);
220
+ assert_error(qts, "host", error, "{ %s: true }", name);
221
g_free(error);
222
}
223
} else {
224
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
225
} else {
226
assert_has_not_feature(qts, "host", "aarch64");
227
assert_has_not_feature(qts, "host", "pmu");
41
-
228
-
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
229
- assert_has_not_feature(qts, "max", "sve");
43
{
230
+ assert_has_not_feature(qts, "host", "sve");
44
NPCM7xxEMCState *emc = opaque;
231
}
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
232
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
233
qtest_quit(qts);
47
}
234
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
48
if (value & REG_MCMDR_RXON) {
235
index XXXXXXX..XXXXXXX 100644
49
- emc->rx_active = true;
236
--- a/docs/arm-cpu-features.rst
50
+ emc_enable_rx_and_flush(emc);
237
+++ b/docs/arm-cpu-features.rst
51
} else {
238
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Examples
52
emc_halt_rx(emc, 0);
239
53
}
240
$ qemu-system-aarch64 -M virt -cpu max
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
241
55
break;
242
- 3) Only enable the 128-bit vector length::
56
case REG_RSDR:
243
+ 3) When KVM is enabled, implicitly enable all host CPU supported vector
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
244
+ lengths with the `host` CPU type::
58
- emc->rx_active = true;
245
+
59
- emc_try_receive_next_packet(emc);
246
+ $ qemu-system-aarch64 -M virt,accel=kvm -cpu host
60
+ emc_enable_rx_and_flush(emc);
247
+
61
}
248
+ 4) Only enable the 128-bit vector length::
62
break;
249
63
case REG_MIIDA:
250
$ qemu-system-aarch64 -M virt -cpu max,sve128=on
251
252
- 4) Disable the 512-bit vector length and all larger vector lengths,
253
+ 5) Disable the 512-bit vector length and all larger vector lengths,
254
since 512 is a power-of-two. This results in all the smaller,
255
uninitialized lengths (128, 256, and 384) defaulting to enabled::
256
257
$ qemu-system-aarch64 -M virt -cpu max,sve512=off
258
259
- 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
260
+ 6) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
261
262
$ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
263
264
- 6) The same as (5), but since the 128-bit and 256-bit vector
265
+ 7) The same as (6), but since the 128-bit and 256-bit vector
266
lengths are required for the 512-bit vector length to be enabled,
267
then allow them to be auto-enabled::
268
269
$ qemu-system-aarch64 -M virt -cpu max,sve512=on
270
271
- 7) Do the same as (6), but by first disabling SVE and then re-enabling it::
272
+ 8) Do the same as (7), but by first disabling SVE and then re-enabling it::
273
274
$ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
275
276
- 8) Force errors regarding the last vector length::
277
+ 9) Force errors regarding the last vector length::
278
279
$ qemu-system-aarch64 -M virt -cpu max,sve128=off
280
$ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
281
@@ -XXX,XX +XXX,XX @@ The examples in "SVE CPU Property Examples" exhibit many ways to select
282
vector lengths which developers may find useful in order to avoid overly
283
verbose command lines. However, the recommended way to select vector
284
lengths is to explicitly enable each desired length. Therefore only
285
-example's (1), (3), and (5) exhibit recommended uses of the properties.
286
+example's (1), (4), and (6) exhibit recommended uses of the properties.
287
64
--
288
--
65
2.25.1
289
2.20.1
66
290
67
291
diff view generated by jsdifflib
1
A lot of C files in hw/arm include qemu-common.h when they don't
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
need anything from it. Drop the include lines.
3
2
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
3
Rebuild hflags when modifying CPUState at boot.
5
use it for the prototype of qemu_get_timedate().
6
4
5
Fixes: e979972a6a
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20191031040830.18800-2-edgar.iglesias@xilinx.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
13
---
12
---
14
hw/arm/boot.c | 1 -
13
hw/arm/boot.c | 1 +
15
hw/arm/digic_boards.c | 1 -
14
1 file changed, 1 insertion(+)
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
23
15
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/boot.c
18
--- a/hw/arm/boot.c
27
+++ b/hw/arm/boot.c
19
+++ b/hw/arm/boot.c
28
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
29
*/
21
info->secondary_cpu_reset_hook(cpu, info);
30
22
}
31
#include "qemu/osdep.h"
23
}
32
-#include "qemu-common.h"
24
+ arm_rebuild_hflags(env);
33
#include "qemu/datadir.h"
25
}
34
#include "qemu/error-report.h"
26
}
35
#include "qapi/error.h"
27
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/digic_boards.c
39
+++ b/hw/arm/digic_boards.c
40
@@ -XXX,XX +XXX,XX @@
41
42
#include "qemu/osdep.h"
43
#include "qapi/error.h"
44
-#include "qemu-common.h"
45
#include "qemu/datadir.h"
46
#include "hw/boards.h"
47
#include "qemu/error-report.h"
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/highbank.c
51
+++ b/hw/arm/highbank.c
52
@@ -XXX,XX +XXX,XX @@
53
*/
54
55
#include "qemu/osdep.h"
56
-#include "qemu-common.h"
57
#include "qemu/datadir.h"
58
#include "qapi/error.h"
59
#include "hw/sysbus.h"
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx_boards.c
63
+++ b/hw/arm/npcm7xx_boards.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "hw/qdev-core.h"
66
#include "hw/qdev-properties.h"
67
#include "qapi/error.h"
68
-#include "qemu-common.h"
69
#include "qemu/datadir.h"
70
#include "qemu/units.h"
71
#include "sysemu/blockdev.h"
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/arm/sbsa-ref.c
75
+++ b/hw/arm/sbsa-ref.c
76
@@ -XXX,XX +XXX,XX @@
77
*/
78
79
#include "qemu/osdep.h"
80
-#include "qemu-common.h"
81
#include "qemu/datadir.h"
82
#include "qapi/error.h"
83
#include "qemu/error-report.h"
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/stm32f405_soc.c
87
+++ b/hw/arm/stm32f405_soc.c
88
@@ -XXX,XX +XXX,XX @@
89
90
#include "qemu/osdep.h"
91
#include "qapi/error.h"
92
-#include "qemu-common.h"
93
#include "exec/address-spaces.h"
94
#include "sysemu/sysemu.h"
95
#include "hw/arm/stm32f405_soc.h"
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/arm/vexpress.c
99
+++ b/hw/arm/vexpress.c
100
@@ -XXX,XX +XXX,XX @@
101
102
#include "qemu/osdep.h"
103
#include "qapi/error.h"
104
-#include "qemu-common.h"
105
#include "qemu/datadir.h"
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@
113
*/
114
115
#include "qemu/osdep.h"
116
-#include "qemu-common.h"
117
#include "qemu/datadir.h"
118
#include "qemu/units.h"
119
#include "qemu/option.h"
120
--
28
--
121
2.25.1
29
2.20.1
122
30
123
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Christophe Lyon <christophe.lyon@linaro.org>
2
2
3
Create arm_check_ss_active and arm_check_kernelpage.
3
rt==15 is a special case when reading the flags: it means the
4
destination is APSR. This patch avoids rejecting
5
vmrs apsr_nzcv, fpscr
6
as illegal instruction.
4
7
5
Reverse the order of the tests. While it doesn't matter in practice,
8
Cc: qemu-stable@nongnu.org
6
because only user-only has a kernel page and user-only never sets
9
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
7
ss_active, ss_active has priority over execution exceptions and it
10
Message-id: 20191025095711.10853-1-christophe.lyon@linaro.org
8
is best to keep them in the proper order.
11
[PMM: updated the comment]
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
---
14
target/arm/translate.c | 10 +++++++---
15
target/arm/translate-vfp.inc.c | 5 +++--
15
1 file changed, 7 insertions(+), 3 deletions(-)
16
1 file changed, 3 insertions(+), 2 deletions(-)
16
17
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
20
--- a/target/arm/translate-vfp.inc.c
20
+++ b/target/arm/translate.c
21
+++ b/target/arm/translate-vfp.inc.c
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
22
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
22
dc->insn_start = tcg_last_op();
23
if (arm_dc_feature(s, ARM_FEATURE_M)) {
23
}
24
/*
24
25
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
25
-static bool arm_pre_translate_insn(DisasContext *dc)
26
- * Writes to R15 are UNPREDICTABLE; we choose to undef.
26
+static bool arm_check_kernelpage(DisasContext *dc)
27
+ * Accesses to R15 are UNPREDICTABLE; we choose to undef.
27
{
28
+ * (FPSCR -> r15 is a special case which writes to the PSR flags.)
28
#ifdef CONFIG_USER_ONLY
29
*/
29
/* Intercept jump to the magic kernel page. */
30
- if (a->rt == 15 || a->reg != ARM_VFP_FPSCR) {
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
31
+ if (a->rt == 15 && (!a->l || a->reg != ARM_VFP_FPSCR)) {
31
return true;
32
return false;
32
}
33
}
33
#endif
34
+ return false;
35
+}
36
37
+static bool arm_check_ss_active(DisasContext *dc)
38
+{
39
if (dc->ss_active && !dc->pstate_ss) {
40
/* Singlestep state is Active-pending.
41
* If we're in this state at the start of a TB then either
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
43
uint32_t pc = dc->base.pc_next;
44
unsigned int insn;
45
46
- if (arm_pre_translate_insn(dc)) {
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
48
dc->base.pc_next = pc + 4;
49
return;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
52
uint32_t insn;
53
bool is_16bit;
54
55
- if (arm_pre_translate_insn(dc)) {
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
57
dc->base.pc_next = pc + 2;
58
return;
59
}
34
}
60
--
35
--
61
2.25.1
36
2.20.1
62
37
63
38
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The size of the code covered by a TranslationBlock cannot be 0;
4
this is checked via assert in tb_gen_code.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
18
assert(s->base.num_insns == 1);
19
gen_swstep_exception(s, 0, 0);
20
s->base.is_jmp = DISAS_NORETURN;
21
+ s->base.pc_next = pc + 4;
22
return;
23
}
24
25
--
26
2.25.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Both single-step and pc alignment faults have priority over
4
breakpoint exceptions.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
11
1 file changed, 23 insertions(+)
12
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/debug_helper.c
16
+++ b/target/arm/debug_helper.c
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
18
{
19
ARMCPU *cpu = ARM_CPU(cs);
20
CPUARMState *env = &cpu->env;
21
+ target_ulong pc;
22
int n;
23
24
/*
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
26
return false;
27
}
28
29
+ /*
30
+ * Single-step exceptions have priority over breakpoint exceptions.
31
+ * If single-step state is active-pending, suppress the bp.
32
+ */
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
34
+ return false;
35
+ }
36
+
37
+ /*
38
+ * PC alignment faults have priority over breakpoint exceptions.
39
+ */
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
42
+ return false;
43
+ }
44
+
45
+ /*
46
+ * Instruction aborts have priority over breakpoint exceptions.
47
+ * TODO: We would need to look up the page for PC and verify that
48
+ * it is present and executable.
49
+ */
50
+
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
52
if (bp_wp_matches(cpu, n, false)) {
53
return true;
54
--
55
2.25.1
56
57
diff view generated by jsdifflib
Deleted patch
1
In the SSE decode function gen_sse(), we combine a byte
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
b |= (b1 << 8);
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
11
1
12
In three cases inside this switch, we were then also checking for
13
"if (b1 >= 2) { goto unknown_op; }".
14
However, this can never happen, because the 'case' values in each place
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
16
cases to the default already.
17
18
This check was added in commit c045af25a52e9 in 2010; the added code
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
---
31
target/i386/tcg/translate.c | 12 +++---------
32
1 file changed, 3 insertions(+), 9 deletions(-)
33
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/i386/tcg/translate.c
37
+++ b/target/i386/tcg/translate.c
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
39
case 0x171: /* shift xmm, im */
40
case 0x172:
41
case 0x173:
42
- if (b1 >= 2) {
43
- goto unknown_op;
44
- }
45
val = x86_ldub_code(env, s);
46
if (is_xmm) {
47
tcg_gen_movi_tl(s->T0, val);
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
50
op1_offset = offsetof(CPUX86State,mmx_t0);
51
}
52
+ assert(b1 < 2);
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
54
(((modrm >> 3)) & 7)][b1];
55
if (!sse_fn_epp) {
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
57
rm = modrm & 7;
58
reg = ((modrm >> 3) & 7) | REX_R(s);
59
mod = (modrm >> 6) & 3;
60
- if (b1 >= 2) {
61
- goto unknown_op;
62
- }
63
64
+ assert(b1 < 2);
65
sse_fn_epp = sse_op_table6[b].op[b1];
66
if (!sse_fn_epp) {
67
goto unknown_op;
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
69
rm = modrm & 7;
70
reg = ((modrm >> 3) & 7) | REX_R(s);
71
mod = (modrm >> 6) & 3;
72
- if (b1 >= 2) {
73
- goto unknown_op;
74
- }
75
76
+ assert(b1 < 2);
77
sse_fn_eppi = sse_op_table7[b].op[b1];
78
if (!sse_fn_eppi) {
79
goto unknown_op;
80
--
81
2.25.1
82
83
diff view generated by jsdifflib
Deleted patch
1
The qemu-common.h header is not supposed to be included from any
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
1
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
6
In fact, the include is not required at all, so we can just drop it
7
from both files.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
13
---
14
include/hw/i386/microvm.h | 1 -
15
include/hw/i386/x86.h | 1 -
16
2 files changed, 2 deletions(-)
17
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/i386/microvm.h
21
+++ b/include/hw/i386/microvm.h
22
@@ -XXX,XX +XXX,XX @@
23
#ifndef HW_I386_MICROVM_H
24
#define HW_I386_MICROVM_H
25
26
-#include "qemu-common.h"
27
#include "exec/hwaddr.h"
28
#include "qemu/notify.h"
29
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/i386/x86.h
33
+++ b/include/hw/i386/x86.h
34
@@ -XXX,XX +XXX,XX @@
35
#ifndef HW_I386_X86_H
36
#define HW_I386_X86_H
37
38
-#include "qemu-common.h"
39
#include "exec/hwaddr.h"
40
#include "qemu/notify.h"
41
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
Deleted patch
1
The qemu-common.h header is not supposed to be included from any
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
1
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
the declaration of cpu_exec_step_atomic().
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
13
---
14
target/hexagon/cpu.h | 1 -
15
linux-user/hexagon/cpu_loop.c | 1 +
16
2 files changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/hexagon/cpu.h
21
+++ b/target/hexagon/cpu.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
23
24
#include "fpu/softfloat-types.h"
25
26
-#include "qemu-common.h"
27
#include "exec/cpu-defs.h"
28
#include "hex_regs.h"
29
#include "mmvec/mmvec.h"
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/linux-user/hexagon/cpu_loop.c
33
+++ b/linux-user/hexagon/cpu_loop.c
34
@@ -XXX,XX +XXX,XX @@
35
*/
36
37
#include "qemu/osdep.h"
38
+#include "qemu-common.h"
39
#include "qemu.h"
40
#include "user-internals.h"
41
#include "cpu_loop-common.h"
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
Deleted patch
1
The qemu-common.h header is not supposed to be included from any
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
1
5
Nothing actually relies on target/rx/cpu.h including it, so we can
6
just drop the include.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
14
---
15
target/rx/cpu.h | 1 -
16
1 file changed, 1 deletion(-)
17
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/rx/cpu.h
21
+++ b/target/rx/cpu.h
22
@@ -XXX,XX +XXX,XX @@
23
#define RX_CPU_H
24
25
#include "qemu/bitops.h"
26
-#include "qemu-common.h"
27
#include "hw/registerfields.h"
28
#include "cpu-qom.h"
29
30
--
31
2.25.1
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
table.
5
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/virt-acpi-build.c | 7 +++++++
13
hw/arm/Kconfig | 1 +
14
2 files changed, 8 insertions(+)
15
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt-acpi-build.c
19
+++ b/hw/arm/virt-acpi-build.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "kvm_arm.h"
22
#include "migration/vmstate.h"
23
#include "hw/acpi/ghes.h"
24
+#include "hw/acpi/viot.h"
25
26
#define ARM_SPI_BASE 32
27
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
29
}
30
#endif
31
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
33
+ acpi_add_table(table_offsets, tables_blob);
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
35
+ vms->oem_id, vms->oem_table_id);
36
+ }
37
+
38
/* XSDT is pointed to by RSDP */
39
xsdt = tables_blob->len;
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/Kconfig
44
+++ b/hw/arm/Kconfig
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
46
select DIMM
47
select ACPI_HW_REDUCED
48
select ACPI_APEI
49
+ select ACPI_VIOT
50
51
config CHEETAH
52
bool
53
--
54
2.25.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
6
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/virt.c | 10 ++--------
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
23
24
if (device_is_dynamic_sysbus(mc, dev) ||
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
28
return HOTPLUG_HANDLER(machine);
29
}
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
32
-
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
34
- return HOTPLUG_HANDLER(machine);
35
- }
36
- }
37
return NULL;
38
}
39
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/virtio/virtio-iommu-pci.c
43
+++ b/hw/virtio/virtio-iommu-pci.c
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
46
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
49
-
50
- error_setg(errp,
51
- "%s machine fails to create iommu-map device tree bindings",
52
- mc->name);
53
- error_append_hint(errp,
54
- "Check your machine implements a hotplug handler "
55
- "for the virtio-iommu-pci device\n");
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
57
- "-no-acpi\n");
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
59
+ "for the virtio-iommu-pci device");
60
return;
61
}
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
63
--
64
2.25.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
We do not support instantiating multiple IOMMUs. Before adding a
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
6
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt.c | 5 +++++
15
1 file changed, 5 insertions(+)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
22
hwaddr db_start = 0, db_end = 0;
23
char *resv_prop_str;
24
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
27
+ return;
28
+ }
29
+
30
switch (vms->msi_controller) {
31
case VIRT_MSI_CTRL_NONE:
32
return;
33
--
34
2.25.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
To propagate errors to the caller of the pre_plug callback, use the
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
helpers.
6
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt.c | 5 +++--
15
1 file changed, 3 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
22
db_start, db_end,
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
24
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
29
+ resv_prop_str, errp);
30
g_free(resv_prop_str);
31
}
32
}
33
--
34
2.25.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
12
tests/data/acpi/q35/DSDT.viot | 0
13
tests/data/acpi/q35/VIOT.viot | 0
14
tests/data/acpi/virt/VIOT | 0
15
4 files changed, 3 insertions(+)
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
19
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
24
@@ -1 +1,4 @@
25
/* List of comma-separated changed AML files to ignore */
26
+"tests/data/acpi/virt/VIOT",
27
+"tests/data/acpi/q35/DSDT.viot",
28
+"tests/data/acpi/q35/VIOT.viot",
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
q35 machine.
5
6
Since the test instantiates a virtio device and two PCIe expander
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
9
The VIOT table generated for the q35 test is:
10
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
[004h 0004 4] Table Length : 00000070
13
[008h 0008 1] Revision : 00
14
[009h 0009 1] Checksum : 3D
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
[010h 0016 8] Oem Table ID : "BXPC "
17
[018h 0024 4] Oem Revision : 00000001
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
21
[024h 0036 2] Node count : 0003
22
[026h 0038 2] Node offset : 0030
23
[028h 0040 8] Reserved : 0000000000000000
24
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
[031h 0049 1] Reserved : 00
27
[032h 0050 2] Length : 0010
28
29
[034h 0052 2] PCI Segment : 0000
30
[036h 0054 2] PCI BDF number : 0010
31
[038h 0056 8] Reserved : 0000000000000000
32
33
[040h 0064 1] Type : 01 [PCI Range]
34
[041h 0065 1] Reserved : 00
35
[042h 0066 2] Length : 0018
36
37
[044h 0068 4] Endpoint start : 00003000
38
[048h 0072 2] PCI Segment start : 0000
39
[04Ah 0074 2] PCI Segment end : 0000
40
[04Ch 0076 2] PCI BDF start : 3000
41
[04Eh 0078 2] PCI BDF end : 30FF
42
[050h 0080 2] Output node : 0030
43
[052h 0082 6] Reserved : 000000000000
44
45
[058h 0088 1] Type : 01 [PCI Range]
46
[059h 0089 1] Reserved : 00
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
77
}
78
}
79
80
+ Scope (\_SB)
81
+ {
82
+ Device (PC30)
83
+ {
84
+ Name (_UID, 0x30) // _UID: Unique ID
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
89
+ {
90
+ CreateDWordField (Arg3, Zero, CDW1)
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
92
+ {
93
+ CreateDWordField (Arg3, 0x04, CDW2)
94
+ CreateDWordField (Arg3, 0x08, CDW3)
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
96
+ Local0 &= 0x1F
97
+ If ((Arg1 != One))
98
+ {
99
+ CDW1 |= 0x08
100
+ }
101
+
102
+ If ((CDW3 != Local0))
103
+ {
104
+ CDW1 |= 0x10
105
+ }
106
+
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
188
+ }
189
+ }
190
+
191
+ Scope (\_SB)
192
+ {
193
+ Device (PC20)
194
+ {
195
+ Name (_UID, 0x20) // _UID: Unique ID
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
299
+ }
300
+ }
301
+
302
+ Scope (\_SB)
303
+ {
304
+ Device (PC10)
305
+ {
306
+ Name (_UID, 0x10) // _UID: Unique ID
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
311
+ {
312
+ CreateDWordField (Arg3, Zero, CDW1)
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
314
+ {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
316
+ CreateDWordField (Arg3, 0x08, CDW3)
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
318
+ Local0 &= 0x1F
319
+ If ((Arg1 != One))
320
+ {
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
410
+ }
411
+ }
412
+
413
Scope (\_SB.PCI0)
414
{
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
416
@@ -XXX,XX +XXX,XX @@
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
418
0x0000, // Granularity
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
429
}
430
}
431
432
+ Device (S10)
433
+ {
434
+ Name (_ADR, 0x00020000) // _ADR: Address
435
+ }
436
+
437
+ Device (S18)
438
+ {
439
+ Name (_ADR, 0x00030000) // _ADR: Address
440
+ }
441
+
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
558
--
559
2.25.1
560
561
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
1
3
The VIOT blob contains the following:
4
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
6
[004h 0004 4] Table Length : 00000058
7
[008h 0008 1] Revision : 00
8
[009h 0009 1] Checksum : 66
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
---
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
47
2 files changed, 1 deletion(-)
48
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
53
@@ -1,2 +1 @@
54
/* List of comma-separated changed AML files to ignore */
55
-"tests/data/acpi/virt/VIOT",
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
57
index XXXXXXX..XXXXXXX 100644
58
GIT binary patch
59
literal 88
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
61
I{D-Rq0Q5fy0RR91
62
63
literal 0
64
HcmV?d00001
65
66
--
67
2.25.1
68
69
diff view generated by jsdifflib